|
|
1.1 root 1: #ifndef lint
2: static char rcs_id[] = "$Header: commands.c,v 1.9 87/09/11 08:22:06 toddb Exp $";
3: #endif
4:
5: /*
6: * COPYRIGHT 1987
7: * DIGITAL EQUIPMENT CORPORATION
8: * MAYNARD, MASSACHUSETTS
9: * ALL RIGHTS RESERVED.
10: *
11: * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
12: * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
13: * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
14: * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
15: *
16: * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
17: * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
18: * SET FORTH ABOVE.
19: *
20: *
21: * Permission to use, copy, modify, and distribute this software and its
22: * documentation for any purpose and without fee is hereby granted, provided
23: * that the above copyright notice appear in all copies and that both that
24: * copyright notice and this permission notice appear in supporting documentation,
25: * and that the name of Digital Equipment Corporation not be used in advertising
26: * or publicity pertaining to distribution of the software without specific,
27: * written prior permission.
28: */
29:
30: #include "xedit.h"
31: #include <sys/types.h>
32: #include <sys/stat.h>
33:
34: static int loadChangeNumber;
35: static int quitChangeNumber;
36:
37: DoQuit()
38: {
39: if((lastChangeNumber == PSchanges(source)) ||
40: (quitChangeNumber == PSchanges(source))){
41: exit();
42: } else {
43: XeditPrintf("\nUnsaved changes. Save them, or press Quit again.");
44: Feep();
45: quitChangeNumber = PSchanges(source);
46: return;
47: }
48: }
49:
50: static int searchEndPos = 999;
51: static int searchBegPos = 999;
52: static int FileMode = 0640;
53: ReplaceOne()
54: {
55: int searchlen = strlen(searchstring);
56: int startpos = QXtTextGetInsertionPoint(CurDpy, textwindow);
57: int count, result;
58: XtTextPosition pos, destpos;
59: char *buf;
60: XtTextBlock t, *text;
61: text = &t;
62: if((startpos != searchEndPos) && (startpos != searchBegPos)){
63: return(0);
64: }
65: buf = malloc(searchlen);
66: count = searchlen;
67: destpos = 0;
68: pos = searchBegPos;
69: while(count){
70: pos = (*source->read)(source, pos, text, count);
71: strncpy(&buf[destpos], text->ptr, text->length);
72: count -= text->length;
73: destpos += text->length;
74: }
75: if(strncmp(buf, searchstring, searchlen)){
76: result = 0;
77: } else {
78: text->length = (strlen(replacestring));
79: text->firstPos = 0;
80: text->ptr = replacestring;
81: if(QXtTextReplace(CurDpy, textwindow, searchBegPos,searchEndPos,text) != EDITDONE)
82: result = 0;
83: else
84: result = 1;
85: }
86: free(buf);
87: return result;
88: }
89: DoReplaceOne()
90: {
91: if(!ReplaceOne()){
92: XeditPrintf("\nReplaceOne: nothing replaced");
93: Feep();
94: }
95: else
96: QXtTextUnsetSelection(CurDpy, textwindow);
97: if(SearchRight())
98: QXtTextSetNewSelection(CurDpy, textwindow, searchBegPos, searchEndPos);
99: }
100:
101: DoReplaceAll()
102: {
103: int count;
104: count = 0;
105: QXtTextSetInsertionPoint(CurDpy, textwindow, 0);
106: while(SearchRight()){
107: if(!ReplaceOne())
108: break;
109: count++;
110: }
111: if(!count){
112: XeditPrintf("\nReplaceAll: nothing replaced");
113: Feep();
114: } else {
115: XeditPrintf("\n%d Replacement%c made", count, (count>1)?'s':' ');
116: }
117: }
118:
119: DoSearchRight()
120: {
121: if(SearchRight()){
122: QXtTextSetNewSelection(CurDpy, textwindow, searchBegPos, searchEndPos);
123: } else {
124: Feep();
125: XeditPrintf("\nSearch: couldn't find ` %s ' ", searchstring);
126: }
127: }
128:
129: SearchRight()
130: {
131: XtTextPosition pos, startpos = QXtTextGetInsertionPoint(CurDpy, textwindow);
132: int searchlen;
133: int n, i, destpos, size = (*source->getLastPos)(source) - startpos;
134: char *s1, *s2, *buf = malloc(size);
135: XtTextBlock t, *text;
136: text = &t;
137: destpos = 0;
138: searchlen = strlen(searchstring);
139: if(!searchlen){
140: text->ptr = QXFetchBuffer(CurDpy, &(text->length), 0);
141: if(!text->length){
142: Feep();
143: XeditPrintf("\nSearch: nothing selected.");
144: return 0;
145: }
146: searchlen = text->length;
147: QXtTextReplace(CurDpy, searchstringwindow, 0,0, text);
148: free(text->ptr);
149: }
150: for(pos = startpos; pos < startpos + size; ){
151: pos = (*source->read)(source, pos, text, size);
152: strncpy(&buf[destpos], text->ptr, text->length);
153: destpos += text->length;
154: }
155: for( i = 0; i < size; i++){
156: n = searchlen;
157: s1 = &buf[i];
158: s2 = searchstring;
159: while (--n >= 0 && *s1++ == *s2++);
160: if(n < 0)
161: break;
162: }
163: free(buf);
164: if( n < 0){
165: i += startpos;
166: QXtTextSetInsertionPoint(CurDpy, textwindow, i + searchlen);
167: searchBegPos = i;
168: searchEndPos = i + searchlen;
169: return(1);
170: } else {
171: return(0);
172: }
173: }
174:
175: DoSearchLeft()
176: {
177: XtTextPosition end = (*source->getLastPos)(source);
178: XtTextPosition pos, startpos = QXtTextGetInsertionPoint(CurDpy, textwindow);
179: int searchlen = strlen(searchstring);
180: int n, i, destpos, count = startpos + searchlen;
181: char *s1, *s2, *buf = calloc(1, count);
182: XtTextBlock t, *text;
183: text = &t;
184: destpos = 0;
185: /* if there's a string in the window, use it, otherwize, use selected */
186: if(!searchlen){
187: text->ptr = QXFetchBuffer(CurDpy, &(text->length), 0);
188: if(!text->length){
189: XeditPrintf("\nSearch: nothing selected.");
190: Feep();
191: return;
192: }
193: searchlen = text->length;
194: QXtTextReplace(CurDpy, searchstringwindow, 0,0, text);
195: free(text->ptr);
196: }
197: /* buffer portion of file from insertion point, on */
198: for(pos = 0; pos < min(count, end);){
199: pos = (*source->read)(source, pos, text, (count - pos));
200: strncpy(&buf[destpos], text->ptr, text->length);
201: destpos += text->length;
202: }
203: /* search for the target string */
204: for( i = startpos-1; i >= 0; i--){
205: n = searchlen;
206: s1 = &buf[i];
207: s2 = searchstring;
208: while (--n >= 0 && *s1++ == *s2++);
209: if(n < 0)
210: break;
211: }
212: /* process result */
213: if(n < 0){
214: QXtTextSetInsertionPoint(CurDpy, textwindow, i);
215: searchBegPos = i;
216: searchEndPos = i + searchlen;
217: QXtTextSetNewSelection(CurDpy, textwindow, searchBegPos, searchEndPos);
218: }
219: else {
220: XeditPrintf("\nSearch: couldn't find ` %s ' ", searchstring);
221: Feep();
222: }
223: free(buf);
224: }
225: DoUndo()
226: {
227: XtTextPosition from;
228: from = (*source->replace)(source, -1, 0, 0);
229: FixScreen(from);
230: }
231: DoUndoMore()
232: {
233: XtTextPosition from;
234: from = (*source->replace)(source, 0, -1, 0);
235: FixScreen(from);
236: }
237: setLoadedFile(name)
238: char *name;
239: {
240: if(loadedfile) free(loadedfile);
241: loadedfile = malloc(strlen(name));
242: strcpy(loadedfile, name);
243: }
244:
245:
246: setSavedFile(name)
247: char *name;
248: {
249: if(savedfile) free(savedfile);
250: savedfile = malloc(strlen(name));
251: strcpy(savedfile, name);
252: }
253:
254: char *makeTempName()
255: {
256: extern char* mktemp();
257: char *tempname = malloc(1024);
258: sprintf(tempname, "%s.XXXXXX", filename);
259: return(mktemp(tempname));
260: }
261:
262: char *makeBackupName()
263: {
264: char *backupName = malloc(1024);
265: sprintf(backupName, "%s.BAK", filename);
266: return (backupName);
267: }
268: /*
269: error()
270: {
271: extern int errno, sys_nerr;
272: extern char *sys_errlist[];
273:
274: if (errno > 0 && errno < sys_nerr)
275: tvcprintf(stderr, "(%s)\n", sys_errlist[errno]);
276:
277: }
278: */
279:
280: DoSave()
281: {
282: char *backupFilename, *tempName;
283: XtTextPosition pos, end;
284: XtTextBlock t, *text;
285: FILE *outStream;
286: int outfid;
287: text = &t;
288: backupFilename = tempName = NULL;
289: if( (!filename) || (!strlen(filename)) ){
290: XeditPrintf("\nSave: no filename specified -- nothing saved");
291: Feep();
292: return;
293: }
294: if(((savedfile && !strcmp(savedfile, filename))
295: || (!strcmp(loadedfile,filename)))
296: && (lastChangeNumber == PSchanges(source))){
297: XeditPrintf("\nSave: no changes to save -- nothing saved");
298: Feep();
299: return;
300: }
301: if((!backedup) && (strlen(loadedfile)) && (!strcmp(filename, loadedfile))){
302: backupFilename = makeBackupName(filename);
303: unlink(backupFilename);
304: if(link(filename, backupFilename)){
305: XeditPrintf("\ncan't create backup file");
306: Feep();
307: return;
308: }
309: TDestroyEDiskSource(dsource);
310: dsource = (XtTextSource*)TCreateEDiskSource(backupFilename, XttextRead);
311: PSsetROsource(source, dsource);
312: backedup = 1;
313: }
314: if(editInPlace){
315: if(!(outStream = fopen(filename, "w"))){
316: XeditPrintf("\nfile is not writable: %s", filename);
317: return;
318: }
319: } else {
320: tempName = makeTempName();
321: if((outfid = creat(tempName, FileMode)) < 0){
322: XeditPrintf("\n??? Can't create temporary file");
323: return;
324: }
325: outStream = fdopen(outfid, "w");
326: }
327: /* WRITE ALL THE BITS OUT TO THE OUTPUT STREAM */
328: end = (*source->scan)(source, 0, XtstFile, XtsdRight, 1, FALSE);
329: for(pos = 0; pos < end; ){
330: pos = (*source->read)(source, pos, text, 1024);
331: if(text->length == 0)
332: break;
333: if(fwrite(text->ptr, 1, text->length, outStream) < text->length){
334: XeditPrintf("\nerror writing to output file");
335: break;
336: }
337: }
338: fclose(outStream);
339: if(!editInPlace)
340: if(rename(tempName, filename) < 0){
341: XeditPrintf("\nerror writing file. Edits will be left in: %s",
342: tempName);
343: Feep();
344: }
345: if(!enableBackups && backupFilename)
346: if(unlink(backupFilename) < 0)
347: XeditPrintf("\nerror deleting backupfile: %s", backupFilename); lastChangeNumber = PSchanges(source);
348: setSavedFile(filename);
349: XeditPrintf("\nSaved file: %s", savedfile);
350: loadChangeNumber = 0;
351: quitChangeNumber = 0;
352: if(backupFilename)
353: free(backupFilename);
354: if(tempName)
355: free(tempName);
356: PSbreakInput(source);
357: }
358:
359: DoLoad()
360: {
361: int numargs;
362: Arg args[2];
363: struct stat stats;
364: if((lastChangeNumber != PSchanges(source)) &&
365: (loadChangeNumber != PSchanges(source))){
366: XeditPrintf("\nUnsaved changes. Save them, or press Load again.");
367: Feep();
368: loadChangeNumber = PSchanges(source);
369: return;
370: }
371: numargs = 0;
372: MakeArg(XtNwindow, (caddr_t)editbutton);
373: MakeArg(XtNindex, (caddr_t)2);
374: if ((strlen(filename)&&access(filename, R_OK) == 0)) {
375: stat(filename, &stats);
376: FileMode = stats.st_mode;
377: TDestroyEDiskSource(dsource);
378: TDestroyApAsSource(asource);
379: DestroyPSource(source);
380: dsource = (XtTextSource*)TCreateEDiskSource(filename, XttextRead);
381: asource = TCreateApAsSource();
382: source = CreatePSource(dsource, asource);
383: QXtTextNewSource(CurDpy, textwindow, dsource, 0);
384: if(Editable){
385: QXtButtonBoxAddButton(CurDpy, Row1, args, numargs);
386: Editable = 0;
387: }
388: backedup = 0;
389: {
390: static Arg setargs[] = {
391: { XtNlabel, (caddr_t)0 }
392: };
393: setargs[0].value = (caddr_t)filename;
394: QXtLabelSetValues(CurDpy, labelwindow, setargs, XtNumber(setargs));
395: }
396: setLoadedFile(filename);
397: lastChangeNumber = 0;
398: }
399: else {
400: XeditPrintf("\nLoad: couldn't access file ` %s '", filename);
401: Feep();
402: }
403: }
404:
405: DoEdit()
406: {
407: XtTextPosition newInsertPos = QXtTextGetInsertionPoint(CurDpy, textwindow);
408: int numargs;
409: Arg args[1];
410: numargs = 0;
411: MakeArg(XtNwindow, (caddr_t)editbutton);
412: if (access(filename, W_OK) == 0) {
413: QXtTextNewSource(CurDpy, textwindow, source, 0);
414: QXUnmapWindow(CurDpy, editbutton);
415: QXtButtonBoxDeleteButton(CurDpy, Row1, args, numargs);
416: QXtTextSetInsertionPoint(CurDpy, textwindow, newInsertPos);
417: Editable = 1;
418: } else {
419: XeditPrintf("\nEdit: File is not writable");
420: Feep();
421: }
422: }
423:
424: static Jump(line)
425: int line;
426: {
427: XtTextPosition pos;
428: if(line <= 1)
429: pos = 0;
430: else
431: pos = (*source->scan)(source, 0, XtstEOL, XtsdRight, line-1, 1);
432: QXtTextSetInsertionPoint(CurDpy, textwindow, pos);
433: }
434:
435: DoJump()
436: {
437: char *XcutBuf, *buf;
438: int XcutSize, line;
439:
440: XcutBuf = QXFetchBuffer( CurDpy, &(XcutSize), 0);
441: buf = malloc(XcutSize+1);
442: strncpy(buf, XcutBuf, XcutSize);
443: free(XcutBuf);
444: buf[XcutSize] = 0;
445: if(sscanf(buf, "%d", &line) > 0){
446: Jump(line);
447: } else {
448: XeditPrintf("\nPlease 'Select' a line number and try again");
449: }
450: free(buf);
451: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.