|
|
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.