|
|
1.1 ! root 1: /* EMACS_MODES: c, !fill */ ! 2: #include "emacs_io.h" ! 3: #include "emacs_gb.h" ! 4: #include "emacs_cmds.h" ! 5: #include <signal.h> ! 6: #ifdef ux3 ! 7: #include <fcntl.h> ! 8: #endif ! 9: ! 10: /* lext -- extend line up to position if necessary */ ! 11: ! 12: lext(line,col) ! 13: /* Keywords: picture-mode movement insertion */ ! 14: { ! 15: mvc (line,col); ! 16: if (column<col) insertc(col-column,' '); ! 17: } ! 18: ! 19: dput(c) ! 20: /* Keywords: insertion modes:10 overwrite-mode */ ! 21: { ! 22: if (NODEL) insertc(1,c); ! 23: else put(c); ! 24: } ! 25: ! 26: /* move forward COUNT characters */ ! 27: /* Keywords: movement commands forwards character-at-a-time picture-mode:20 */ ! 28: forw(count) ! 29: ! 30: register int count; ! 31: { ! 32: register int retval; ! 33: ! 34: if (PICMODE) { ! 35: if (count>0) { ! 36: lext(curln,count+column); ! 37: return(1); ! 38: } else { ! 39: column += count; ! 40: if (column<0) { ! 41: beep(); ! 42: column=0; ! 43: return(0); ! 44: } else return(1); ! 45: } ! 46: } ! 47: if (count < 0) { ! 48: retval = findb(-count); ! 49: } else { ! 50: retval = findf(count); ! 51: } ! 52: if (retval == 0) beep(); /* couldn't go all the way */ ! 53: move(kline,kcol); ! 54: return(retval); ! 55: } ! 56: ! 57: /* backward COUNT characters */ ! 58: ! 59: back(count) ! 60: /* Keywords: movement commands forwards character-at-a-time */ ! 61: register int count; ! 62: ! 63: { ! 64: forw(-count); /* do it this way */ ! 65: } ! 66: ! 67: /* move to previous line, same collumn */ ! 68: ! 69: upl (count) ! 70: ! 71: /* Keywords: commands backwards:30 upward-movement movement text-lines */ ! 72: register int count; ! 73: ! 74: { ! 75: ! 76: if (curln-count < 1) { ! 77: if (count == 1) { ! 78: beep(); ! 79: return(0); ! 80: } else curln = 1; ! 81: } else curln -= count; ! 82: if (PICMODE) lext(curln,column); ! 83: else mvc(curln,column); ! 84: return(1); ! 85: } ! 86: /* move down one line, same column */ ! 87: ! 88: downl (count) ! 89: /* Keywords: commands forwards:30 downward-movement movement text-lines */ ! 90: register int count; ! 91: ! 92: { ! 93: register int retval; ! 94: ! 95: if (((curln += count) > nlines)&& (PICMODE == 0)) { ! 96: curln = nlines+NLRUN; ! 97: beep(); ! 98: retval = 0; ! 99: } else retval = 1; ! 100: if (PICMODE) lext(curln,column); ! 101: else mvc(curln,column); ! 102: return(retval); ! 103: } ! 104: ! 105: ! 106: /* abort EMACS */ ! 107: ! 108: int aborts = 0; ! 109: eabort(sig) ! 110: int sig; ! 111: { ! 112: /* Keywords: internal-errors unix-interface commands */ ! 113: if (sig){ ! 114: signal(sig,SIG_DFL); /* Prevent looping */ ! 115: } ! 116: signal (SIGIOT,SIG_DFL); ! 117: cook(); ! 118: if (aborts>3) exit(-1); ! 119: aborts++; ! 120: #ifdef MINFILES ! 121: rmtemp(); ! 122: #endif ! 123: #ifdef PC ! 124: rmtemp(); ! 125: exit(-1); ! 126: #else ! 127: #ifdef bsd ! 128: sigsetmask(0); /* ARGH, set mask to allow abort! */ ! 129: #endif ! 130: abort(); ! 131: exit(-1); ! 132: #endif PC ! 133: } ! 134: ! 135: ! 136: /* exit EMACS */ ! 137: ! 138: ! 139: quit() ! 140: ! 141: { ! 142: /* Keywords: commands exit-processing user-interface:20 unix-interface:30 */ ! 143: clear(); ! 144: cook(); ! 145: statout(); ! 146: #ifdef MINFILES ! 147: rmtemp(); /* flush temp files */ ! 148: #endif ! 149: #ifdef PC ! 150: rmtemp(); ! 151: #else ! 152: flushproc(); ! 153: #endif ! 154: exit(0); ! 155: } ! 156: ! 157: /* exit EMACS gracefully */ ! 158: ! 159: gquit() ! 160: /* Keywords: commands exit-processing user-interface:20 unix-interface:30 macro-hooks:10 */ ! 161: { ! 162: if (hooks[Exit_Emacs_Hook]) if (hook(Exit_Emacs_Hook) == 0) return; ! 163: if(bclean()== 0)quit(); ! 164: } ! 165: ! 166: /* kill line */ ! 167: ! 168: /* if the count is one, and if there is text on the line beyond column, ! 169: * only that text is killed ! 170: * if count is one, and column is at end of line, the end of line is killed */ ! 171: /* if count is greater than one, the next count lines (and their end of ! 172: * lines) are killed */ ! 173: ! 174: /* all killed text is put into the kill stack */ ! 175: ! 176: ! 177: ekill (count) ! 178: ! 179: register int count; ! 180: ! 181: /* Keywords: commands deletion killstack:10 text-lines */ ! 182: ! 183: { ! 184: register int l; ! 185: int opic,onodel; ! 186: ! 187: if (numarg == 0) { ! 188: if ((l=leng(curln)) > column) { ! 189: return(delc(l-column)); ! 190: } ! 191: } ! 192: opic = PICMODE; ! 193: onodel =NODEL; ! 194: PICMODE=NODEL=0; /* Allow line kills! */ ! 195: ! 196: kline = curln+count; ! 197: kcol = 0; ! 198: l= tkill(); ! 199: PICMODE=opic; ! 200: NODEL=onodel; ! 201: return(l); ! 202: } ! 203: ! 204: /* goto beginning of current line */ ! 205: ! 206: begin() ! 207: /* Keywords: text-lines commands movement backwards */ ! 208: { ! 209: move(curln,0); ! 210: } ! 211: ! 212: /* goto end of line */ ! 213: ! 214: endl() ! 215: /* Keywords: text-lines commands movement backwards */ ! 216: { ! 217: mvc (curln,10000); /* mvc will adjust line length */ ! 218: } ! 219: ! 220: mquote(arg) ! 221: int arg; ! 222: /* Keywords: quoting commands insertion */ ! 223: { ! 224: quote(arg,0200); ! 225: } ! 226: rquote(arg) ! 227: int arg; ! 228: /* Keywords: quoting commands insertion */ ! 229: { ! 230: quote(arg,0); ! 231: } ! 232: ! 233: /* insert the next character, whatever it is */ ! 234: ! 235: /* note that newlines inserted ths way act just like unquoted newlines */ ! 236: ! 237: quote(count,metf) ! 238: ! 239: register int metf; ! 240: register int count; ! 241: ! 242: { ! 243: /* Keywords: quoting commands insertion */ ! 244: register int c; ! 245: ! 246: while(count--) { ! 247: if ((VERBOSE)&& (MOREIN == 0)) prompt1("%d ^Q: ",count+1); ! 248: ! 249: c = getchar(); ! 250: c = c | metf; ! 251: insertc(1,c); ! 252: if (VERBOSE && (MOREIN == 0)) { ! 253: unprompt(); ! 254: } ! 255: disup(); ! 256: } ! 257: } ! 258: ! 259: /* numchar -- convert argument to a character to insert */ ! 260: ! 261: numchar(count) ! 262: /* Keywords: quoting commands insertion argument-processing */ ! 263: register int count; ! 264: { ! 265: insertc(1,count); /* insert the count */ ! 266: } ! 267: ! 268: ! 269: /* deletes count characters going forward */ ! 270: ! 271: fdel(count) ! 272: /* Keywords: commands deletion forwards character-at-a-time */ ! 273: { ! 274: IGNORE(findf(count)); ! 275: return(tkill()); ! 276: } ! 277: ! 278: /* deletes count characters going backward */ ! 279: ! 280: bdel(count) ! 281: ! 282: register int count; ! 283: /* Keywords: commands deletion backwards character-at-a-time */ ! 284: { ! 285: IGNORE(findb(count)); ! 286: return(tkill()); ! 287: } ! 288: ! 289: /* file write command */ ! 290: ! 291: ! 292: int fright(arg) ! 293: ! 294: int arg; ! 295: { ! 296: register char *np; ! 297: /* Keywords: files commands buffers:20 filenames:10 writing */ ! 298: if ((np = expenv(getname("Write file? "))) != NULL) { ! 299: return(wout(np,arg)); ! 300: } ! 301: return(0); ! 302: } ! 303: ! 304: /* fred -- read a file */ ! 305: ! 306: fred(arg) ! 307: ! 308: int arg; ! 309: { ! 310: /* Keywords: files commands buffers:20 filenames:10 reading */ ! 311: ! 312: register char *np; ! 313: ! 314: if ((np = expenv(getname("Read File? "))) != NULL) { ! 315: return(readin(np,arg)); ! 316: } else return(0); ! 317: } ! 318: ! 319: /* forward words -- leaves kline, kcol at spot that is count words ! 320: *forward */ ! 321: ! 322: ! 323: wordf(count) ! 324: ! 325: register int count; ! 326: ! 327: { ! 328: kmark(); ! 329: ! 330: /* Keywords: commands:10 forwards movement:50 deletion:50 word-oriented-commands */ ! 331: ! 332: while (count--) { ! 333: if (skipf(WRDSEP) || skipf(WRDCHR)) { ! 334: return; ! 335: } ! 336: } ! 337: } ! 338: ! 339: /* skips kline, kcol forward until a character without type bit on is ! 340: * found */ ! 341: ! 342: ! 343: skipf(bit) ! 344: ! 345: register int bit; ! 346: /* Keywords: forwards sentence-commands word-oriented-commands movement:20 commands:10 */ ! 347: { ! 348: while (bits[*klptr] & bit) { ! 349: if (mfk()) return(1); ! 350: } ! 351: return(0); ! 352: } ! 353: ! 354: ! 355: /* move forward count words */ ! 356: ! 357: mfwrd(count) ! 358: /* Keywords: commands forwards movement word-oriented-commands */ ! 359: register int count; ! 360: ! 361: { ! 362: ! 363: wordf(count); ! 364: move(kline,kcol); ! 365: } ! 366: ! 367: /* kill next count words */ ! 368: ! 369: ! 370: ! 371: kfwrd(count) ! 372: /* Keywords: commands forwards deletion word-oriented-commands */ ! 373: register int count; ! 374: ! 375: { ! 376: wordf(count); ! 377: return(tkill()); ! 378: } ! 379: ! 380: /* skip kline, kcol back until a character without type bit is found */ ! 381: ! 382: ! 383: ! 384: skipb(bit) ! 385: ! 386: register int bit; ! 387: /* Keywords: sentence-commands word-oriented-commands movement:20 backwards commands:10 */ ! 388: { ! 389: do { ! 390: if (mbk()) return(1); ! 391: } while (bits[*klptr] &bit); ! 392: return(0); ! 393: } ! 394: ! 395: /* backward count words, leaves pointer in kline, kcol */ ! 396: ! 397: wordb(count) ! 398: ! 399: register int count; ! 400: /* Keywords: commands:10 backwards movement:10 deletion:20 word-oriented-commands */ ! 401: { ! 402: kmark(); ! 403: while (count--) { ! 404: if ((skipb(WRDSEP) || skipb(WRDCHR))) { ! 405: return; ! 406: } ! 407: } ! 408: IGNORE(mfk()); ! 409: } ! 410: ! 411: /* move back count words */ ! 412: ! 413: mbwrd(count) ! 414: ! 415: register int count; ! 416: /* Keywords: commands backwards movement word-oriented-commands */ ! 417: { ! 418: wordb(count); ! 419: move(kline,kcol); ! 420: } ! 421: ! 422: /* kill back count words */ ! 423: ! 424: kbwrd(count) ! 425: ! 426: ! 427: register int count; ! 428: /* Keywords: commands backwards deletion word-oriented-commands */ ! 429: { ! 430: wordb(count); ! 431: return(tkill()); ! 432: } ! 433: ! 434: /* kmark -- set kline,kcol and klptr */ ! 435: ! 436: kmark() ! 437: ! 438: /* Keywords: commands:5 movement:50 deletion:50 character-at-a-time:20 word-oriented-commands:20 sentence-commands:20 */ ! 439: ! 440: { ! 441: kline = curln; ! 442: kcol = column; ! 443: klptr = mkline(kline)+kcol; ! 444: } ! 445: ! 446: ! 447: /* move kline,kcol forward one */ ! 448: ! 449: mfk() ! 450: /* Keywords: commands:5 movement:50 deletion:50 character-at-a-time:20 word-oriented-commands:20 sentence-commands:20 forwards */ ! 451: { ! 452: if ((*klptr++)!=EOL ) { ! 453: ++kcol; ! 454: return(0); ! 455: } ! 456: if (kline<nlines) { ! 457: ++kline; ! 458: klptr = mkline(kline); ! 459: kcol=0; ! 460: return(0); ! 461: } ! 462: return(1); ! 463: } ! 464: ! 465: /* move kline, kcol back one character */ ! 466: ! 467: mbk() ! 468: /* Keywords: commands:5 movement:50 deletion:50 character-at-a-time:20 word-oriented-commands:20 sentence-commands:20 backwards */ ! 469: { ! 470: if ((kcol--)>0) { ! 471: klptr--; ! 472: ! 473: return(0); ! 474: } ! 475: if (kline>1) { ! 476: --kline; ! 477: kcol = leng(kline); ! 478: klptr = mkline(kline) + kcol; ! 479: return(0); ! 480: } ! 481: kcol = 0; ! 482: return(1); ! 483: } ! 484: ! 485: /* forward to end of sentence */ ! 486: ! 487: /* leaves resulting pointer in kline, kcol */ ! 488: ! 489: fsent () ! 490: ! 491: /* Keywords: commands:10 forwards movement:40 sentence-commands */ ! 492: ! 493: { ! 494: kmark(); ! 495: ! 496: while (mfk() == 0) { ! 497: if ((bits[*klptr] & SENTE) && (bits[klptr[1]]&WHITE)) { ! 498: return(1); ! 499: } ! 500: } ! 501: return(0); ! 502: } ! 503: ! 504: /* back one sentence, leaves pointer in kline, kcol */ ! 505: ! 506: bsent() ! 507: ! 508: /* Keywords: commands:10 backwards movement:40 sentence-commands */ ! 509: ! 510: { ! 511: ! 512: kmark(); ! 513: ! 514: IGNORE(skipb(WRDSEP)); ! 515: while (mbk() == 0) { ! 516: if (kcol == 0) { ! 517: if (kline>1) { ! 518: if (bits[*mkline(kline-1)] & SENTE) return(1); ! 519: } ! 520: } ! 521: if ((bits[*klptr] & SENTE) && (bits[klptr[1]] & WHITE)) { ! 522: IGNORE(skipf(WRDCHR)); ! 523: IGNORE(skipf(WRDSEP)); ! 524: return(1); ! 525: } ! 526: } ! 527: return(0); ! 528: } ! 529: ! 530: /* move back count sentences */ ! 531: ! 532: ssent(count) ! 533: register int count; ! 534: ! 535: /* Keywords: commands backwards movement sentence-commands */ ! 536: ! 537: { ! 538: while (count--) { ! 539: if(bsent()) move(kline,kcol); ! 540: } ! 541: } ! 542: ! 543: /* move forward count sentences */ ! 544: ! 545: ! 546: esent(count) ! 547: register int count; ! 548: ! 549: /* Keywords: commands forwards movement sentence-commands */ ! 550: ! 551: { ! 552: while (count--) { ! 553: if (fsent() == 0) break; ! 554: move(kline,kcol+1); ! 555: } ! 556: } ! 557: ! 558: ! 559: /* move to top of file */ ! 560: ! 561: top() ! 562: /* Keywords: files:20 buffers:20 movement upward-movement commands */ ! 563: { ! 564: move(1,0); ! 565: } ! 566: ! 567: ! 568: /* move to end of file */ ! 569: ! 570: bot() ! 571: ! 572: /* Keywords: files:20 buffers:20 movement downward-movement commands */ ! 573: ! 574: { ! 575: mvc(nlines,10000); ! 576: } ! 577: ! 578: /* new line handler */ ! 579: ! 580: /* First, finishes off comment on the current line (if any) */ ! 581: ! 582: /* Next, if the current buffer has a sub-process, the line is sent to the sub-process */ ! 583: ! 584: /* Then, if the next line is non-empty, it creates an empty next line */ ! 585: /* next, the next line is tab adjusted (if in C mode ) */ ! 586: ! 587: /* now, any text on the current line beyond the current position, it is ! 588: * moved to the end of the next line */ ! 589: ! 590: /* finally, the pointer is moved to the (tab adjusted) start of the next ! 591: * line */ ! 592: ! 593: /* if count > 1, then count-1 blank lines will be inserted in between ! 594: * the current line and the 'next' line */ ! 595: ! 596: nl(count) ! 597: ! 598: /* Keywords: commands C-mode:30 insertion text-lines comments:50 shell-escape:10 */ ! 599: ! 600: ! 601: ! 602: register int count; ! 603: ! 604: { ! 605: ! 606: if (RARE == 0) { ! 607: if (comln == curln) putin(" */"); ! 608: #ifndef PC ! 609: if (curbf == procbuf){ ! 610: MARK *mp; ! 611: ! 612: mp = markptr(curbf); ! 613: if ((mp->markl == curln) && (mp->markc <= column)) { ! 614: ! 615: /* If this is the last line on which output was done from */ ! 616: /* the sub-process, then send from mark and re-mark */ ! 617: ! 618: sendproc (clptr+mp->markc, column+1-mp->markc); ! 619: mp->markl = curln+1; ! 620: mp->markc = 0; ! 621: } else { ! 622: sendproc(clptr,column+1); ! 623: } ! 624: } ! 625: #endif ! 626: } ! 627: comln = 0; ! 628: if ((count != 1) || (NLINS) || (isblank(curln+1)==0) || (clptr[column] != EOL)) { ! 629: openl(count); ! 630: } ! 631: if (TABMD&& (RARE == 0)) tabjust(curln+count); ! 632: else move(curln+count,0); ! 633: } ! 634: ! 635: /* sets mark at current position */ ! 636: ! 637: mark(mnumb) ! 638: ! 639: /* Keywords: marking regions commands */ ! 640: ! 641: { ! 642: MARK *markp; ! 643: markp = markptr(mnumb); ! 644: markp->markl = curln; ! 645: markp->markc = column; ! 646: } ! 647: ! 648: /* returns mark pointer */ ! 649: ! 650: MARK *markptr(mnumb) ! 651: ! 652: register int mnumb; ! 653: ! 654: /* Keywords: commands:10 marking:50 regions deletion:50 movement:50 */ ! 655: { ! 656: ! 657: if (mnumb >= NMARKS) { ! 658: error(WARN,44); ! 659: mnumb = curbf; ! 660: } ! 661: if ((mnumb == 1) && (numarg == 0)) mnumb = curbf; ! 662: return(&marks[mnumb]); ! 663: } ! 664: ! 665: ! 666: /* kills text between current position and mark position */ ! 667: ! 668: ! 669: mkill(mnumb) ! 670: int mnumb; ! 671: /* Keywords: commands deletion regions */ ! 672: { ! 673: register MARK *markp; ! 674: ! 675: markp = markptr(mnumb); ! 676: kline = markp->markl; ! 677: if (kline < 1) kline = 1; ! 678: if (kline > nlines) kline = nlines; ! 679: kcol = leng(kline); ! 680: if (markp->markc < kcol) kcol = markp->markc; ! 681: if (PICMODE) { ! 682: /* This pain is to get the ! 683: * mark to work in picture ! 684: * mode so that everything ! 685: * up to and including the ! 686: * marked position is killed */ ! 687: if (kcol > column) { ! 688: kcol++; ! 689: } else { ! 690: forw(1); ! 691: } ! 692: } ! 693: return(tkill()); ! 694: } ! 695: ! 696: /* retrieves text from the kill stack and inserts it (count times ) */ ! 697: ! 698: ! 699: int yline; ! 700: int ycol; ! 701: ! 702: yank(count) ! 703: ! 704: /* Keywords: regions commands insertion killstack retrieval popping:10 */ ! 705: ! 706: register int count; ! 707: { ! 708: register int result; ! 709: register int unp; ! 710: ! 711: unp = unstart(); ! 712: mark(curbf); ! 713: while (count--) { ! 714: result = retrv(); ! 715: } ! 716: unend(unp); ! 717: yline = curln; ! 718: ycol = column; /* Save, so we know when not to re-yank */ ! 719: ! 720: return(result); ! 721: } ! 722: ! 723: /* kills the marked region, removes the top item from the kill stack, ! 724: * and then inserts the next area from the kill stack */ ! 725: ! 726: ! 727: reyank(count) /* yank again */ ! 728: register int count; ! 729: /* Keywords: regions commands insertion killstack retrieval deletion popping:10 */ ! 730: { ! 731: register int unp; ! 732: ! 733: if ((curln != yline) || (column != ycol)) { ! 734: error (WARN,84); /* Prevent some nastyness */ ! 735: return; ! 736: } ! 737: kbapp = 0; ! 738: unp = unstart(); ! 739: mkill(curbf); /* flush last insertion */ ! 740: kpop(); /* first pop the mkill */ ! 741: kpop(); /* now pop that last insertion */ ! 742: yank(count); ! 743: unend(unp); ! 744: } ! 745: ! 746: /* search subroutine */ ! 747: ! 748: /* searches forward or backward for a string, starting at the ! 749: * given position. If the string is found, 1 is returned, and the start ! 750: * of the match is left in kline, kcol. Return of 0 indicates no match */ ! 751: ! 752: /* Keywords: searching */ ! 753: ! 754: srch(sline,scol,sp,direct) ! 755: ! 756: int sline; ! 757: int scol; ! 758: char *sp; ! 759: int direct; ! 760: ! 761: { ! 762: register char *lp; ! 763: register char *cp; ! 764: register int l; ! 765: int c; ! 766: ! 767: lp = sp; ! 768: while (c = *lp) *lp++ = casem[c&0177]; /* map string to allowed case */ ! 769: lp = mkline(sline)+scol; ! 770: while (1) { ! 771: cp = sp; ! 772: l = sline; ! 773: while (*cp) { ! 774: if ((c = casem[(*lp++)&0177]) != *cp++) goto again; ! 775: if (c == EOL) { ! 776: if (l == nlines) { ! 777: if (direct>0) return(0); ! 778: goto again; ! 779: } ! 780: ++l; ! 781: lp = mkline(l); ! 782: } ! 783: } ! 784: kline = sline; ! 785: kcol = scol; ! 786: return(1); ! 787: ! 788: again: if (brkflg) brkit(); ! 789: lp = mkline(sline)+scol; ! 790: if (direct>0) { ! 791: do { ! 792: if (*lp++ !=EOL) scol++; ! 793: else { ! 794: if (sline == nlines) return(0); ! 795: sline++; ! 796: scol = 0; ! 797: lp = mkline(sline); ! 798: } ! 799: } while (casem[*lp&0177] != *sp); ! 800: } else { ! 801: ! 802: do { ! 803: if (--scol<0) { ! 804: if (sline == 1) return(0); ! 805: scol = leng(--sline); ! 806: lp = mkline(sline)+scol; ! 807: } else lp--; ! 808: } while (casem[*lp&0177] != *sp); ! 809: } ! 810: } ! 811: } ! 812: ! 813: fisrch(arg) ! 814: int arg; ! 815: /* Keywords: searching commands forwards key-bindings:10 */ ! 816: { ! 817: return(isrch(1,arg)); ! 818: } ! 819: risrch(arg) ! 820: int arg; ! 821: /* Keywords: searching commands backwards key-bindings:10 */ ! 822: ! 823: { ! 824: return(isrch(-1,arg)); ! 825: } ! 826: /* incremental search command (either direction) */ ! 827: ! 828: ! 829: isrch(d,arg) ! 830: int d; ! 831: int arg; ! 832: ! 833: /* Keywords: commands:80 searching user-interface:60 key-bindings:50 */ ! 834: ! 835: ! 836: { ! 837: int oldln; ! 838: int oldcol; ! 839: register char *ilp; ! 840: register int c; ! 841: int lx; ! 842: int ly; ! 843: int nd; ! 844: int missed; ! 845: char sst[40]; ! 846: char *xp; ! 847: ! 848: ilp = sst; ! 849: missed = 0; ! 850: lx = oldln = curln; ! 851: ly = oldcol = column; ! 852: if (infrn < 0) { /* if in a macro */ ! 853: xp = getname(NULL); /* search argument */ ! 854: ilp = mstrcpy(ilp,xp); ! 855: } ! 856: while (1) { ! 857: *ilp = 0; ! 858: if (missed == 0) { ! 859: psrch(d,sst); /* prompt */ ! 860: if (infrn == 0) mflush(stdout); ! 861: if (srch(curln,column,sst,d) == NULL) { ! 862: move(lx,ly); ! 863: if (infrn >= 0) { ! 864: beep(); ! 865: prompt1("Failing Search: %s", sst); ! 866: } ! 867: missed = 1; ! 868: } else { ! 869: move(lx = kline,ly = kcol); ! 870: if (ilp!=sst)strcpy (presst,sst); ! 871: missed = 0; ! 872: } ! 873: } ! 874: if (infrn < 0) return(missed == 0); /* macro invocation */ ! 875: disup(); ! 876: if ((missed == 0) && (incnt == 0)) { ! 877: psrch(d,sst); /* restore prompt */ ! 878: mgo(nln,ncol); /* goback to display position */ ! 879: } ! 880: c = getchar(); ! 881: if ((c == CTRLH)||(c == RUBOUT)) { ! 882: if (ilp!=sst) ilp--; ! 883: missed=0; ! 884: move (oldln,oldcol); ! 885: continue; /* next loop */ ! 886: } ! 887: if (c == CTRLG) { ! 888: move (oldln,oldcol); ! 889: unprompt(); ! 890: beep(); ! 891: return(0); ! 892: } ! 893: if (srch_nl?((c == '\n') || (c == '\r')) : (c == ESC)) { ! 894: goout: unprompt(); ! 895: return(missed == 0); ! 896: } ! 897: if (nd=issrch(c)) { ! 898: if (nd == d) { ! 899: if (ilp == sst) { ! 900: ilp = mstrcpy(sst,presst); ! 901: continue; ! 902: } else { ! 903: if (missed) { ! 904: beep(); ! 905: continue; ! 906: } ! 907: forw(d); ! 908: } ! 909: } else { ! 910: missed=0; ! 911: d = nd; ! 912: } ! 913: continue; ! 914: } ! 915: if (isquote(c)) { ! 916: c = getchar(); /* skip all other processing */ ! 917: } else { ! 918: if (c == CTRLM) c = '\n'; ! 919: if ((c < 040) && (c != '\n')) { ! 920: ungetch(c); ! 921: goto goout; ! 922: } ! 923: } ! 924: if (missed) { ! 925: beep(); ! 926: continue; ! 927: } ! 928: *ilp++ = c; ! 929: } ! 930: } ! 931: ! 932: /* psrch -- print search prompt */ ! 933: ! 934: psrch(dir,sstp) ! 935: register int dir; ! 936: char *sstp; ! 937: ! 938: /* Keywords: mode-line prompting searching */ ! 939: ! 940: { ! 941: if (dir>0) prompt1("Search: %s",sstp); ! 942: else prompt1("Reverse Search: %s",sstp); ! 943: } ! 944: ! 945: /* handle a separator character in auto fill mode */ ! 946: ! 947: /* if fill mode is on, and the current position is beyond FILLCOL, a ! 948: * newline is inserted before the last word. Otherwise, just insert the ! 949: * character at the current position */ ! 950: ! 951: ! 952: afsep(count,chr) ! 953: ! 954: int count; ! 955: int chr; ! 956: ! 957: /* Keywords: commands:40 modes:30 text-filling comments:20 C-mode:10 */ ! 958: ! 959: { ! 960: register int cc; ! 961: int newcol; ! 962: int oldcol; ! 963: char lbuf[MAXEL]; /* KLUDGE! */ ! 964: register char *p1; ! 965: register char *p2; ! 966: ! 967: /* whitespace characters in a macro expansion must be quoted to be ! 968: * self-inserting. The following checks for non-zero character ! 969: * count, input from macro, and a whitespace character to be ! 970: * inserted. Under these conditions, no inserting is done. */ ! 971: ! 972: if (count && (infrn < 0)&& (WHITE&bits[chr])) return(1); ! 973: ! 974: ! 975: ! 976: if (FILLMD && (RARE == 0)) { ! 977: insertc(count,chr); ! 978: oldcol = column; ! 979: cc = leng(curln) - column; ! 980: mline=0; ! 981: findpos(clptr,column); ! 982: if (mline || (mcol>FILLCOL)|| (column > FILLCOL)) { ! 983: ! 984: again: newcol = column; ! 985: ! 986: do { ! 987: column--; ! 988: } while ((column) && ! 989: (((bits[clptr[column]] & WHITE) == 0) || ! 990: (clptr[column+1] == '.') || ! 991: (clptr[column+1] == '\''))); ! 992: mline=0; ! 993: findpos(clptr,column); ! 994: if (mline || (mcol>FILLCOL)|| (column > FILLCOL)) goto again; ! 995: ! 996: ! 997: ! 998: /* Now then, do the work. We are sitting at the right column to break the line */ ! 999: /* First, save the rest of the line. Then, kill it, then, do a newline, */ ! 1000: /* now, bring it back */ ! 1001: ! 1002: ! 1003: if (column == 0) column = newcol; /* 1 word line */ ! 1004: if (column == oldcol) return(1); /* Do absolutely nothing */ ! 1005: p1 = clptr+column+1; /* Eat the whitespace character */ ! 1006: ! 1007: p2 = lbuf; ! 1008: while ((*p2++= *p1++)!=EOL); /* copy line */ ! 1009: sputl(curln,column,curln); /* Flag line is bad! */ ! 1010: clptr[column]=EOL; /* truncate line */ ! 1011: if (comln == curln) { ! 1012: comln = -1; ! 1013: nl(1); ! 1014: cment(1); ! 1015: *(clptr+column-3)=' '; ! 1016: } else nl(1); ! 1017: p1 = lbuf; ! 1018: while (*p1 != EOL) put(*p1++); /* restore line */ ! 1019: forw(-cc); /* go back to right place. */ ! 1020: } ! 1021: return(1); ! 1022: } ! 1023: insertc(count,chr); ! 1024: return(1); ! 1025: } ! 1026: ! 1027: /* unix escape */ ! 1028: ! 1029: char *shell = "sh"; /* name of shell processor */ ! 1030: ! 1031: ux(arg) ! 1032: ! 1033: int arg; ! 1034: { ! 1035: /* Keywords: commands buffers:20 unix-interface shell-escape */ ! 1036: ! 1037: register char *sp; ! 1038: ! 1039: if (SAVEMD) fsave(0); ! 1040: do { ! 1041: sp = (getname("command line? ")); ! 1042: } while (sp && (unx(sp,(arg != 1))== 0)); ! 1043: return(cstatus); ! 1044: } ! 1045: ! 1046: #ifndef PC ! 1047: ! 1048: char * ! 1049: nvmatch(s1, s2) ! 1050: register char *s1, *s2; ! 1051: ! 1052: /* Keywords: unix-interface shell-escape environment-variables */ ! 1053: { ! 1054: while(*s1 == *s2++) ! 1055: if(*s1++ == '=') ! 1056: return(s2); ! 1057: if(*s1 == '\0' && *(s2-1) == '=') ! 1058: return(s2); ! 1059: return(NULL); ! 1060: } ! 1061: ! 1062: /* Environment fixer-upper, adds definition of filename to the ! 1063: * environment and returns a pointer to it. */ ! 1064: ! 1065: extern char **environ; ! 1066: ! 1067: char ** ! 1068: fixenv(defp) ! 1069: register char *defp; ! 1070: /* Keywords: unix-interface shell-escape environment-variables */ ! 1071: ! 1072: { ! 1073: register char **xp; ! 1074: register char **yp; ! 1075: int envd = 0; ! 1076: ! 1077: xp =((char **) &bbuf[0][0]); /* Overlay screen */ ! 1078: yp = environ; ! 1079: ! 1080: while (*xp = *yp++) { ! 1081: if (nvmatch(defp,*xp++)) { ! 1082: xp[-1] = defp; ! 1083: envd=1; ! 1084: } ! 1085: } ! 1086: if (envd==0) { ! 1087: *xp++ = defp; ! 1088: *xp = NULL; ! 1089: } ! 1090: xp =((char **) &bbuf[0][0]); /* Overlay screen */ ! 1091: return(xp); ! 1092: } ! 1093: #endif ! 1094: ! 1095: ! 1096: /* general unix escape -- */ ! 1097: ! 1098: /* flag = 0 means just run it */ ! 1099: /* flag = 1 means run and feed it the buffer */ ! 1100: /* flag = 2 means run and replace .exec with the result */ ! 1101: /* flag = 3 means run and append result to .exec */ ! 1102: /* flag = 4 means run and bring results back in fnbuf */ ! 1103: /* flag = 5 means run and hook up input and output pipes */ ! 1104: /* flag = 6 means run it and hook up output to splfile, leave input in splfile */ ! 1105: /* flag = 7 means run it and hook up input from splfile, leave output in splfile */ ! 1106: ! 1107: #define UNEEDSIN 1 ! 1108: #define UNEEDSOUT 2 ! 1109: #define UDOTEXEC 4 ! 1110: #define UNOSCREEN 8 ! 1111: #define URETBUF 16 ! 1112: #define UPROCESS 32 ! 1113: #define USENDBUF 64 ! 1114: #define UREADBUF 128 ! 1115: #define UINITBUF 256 ! 1116: #define USPLIN 512 ! 1117: #define USPLOUT 1024 ! 1118: ! 1119: int unxflags[8] = { ! 1120: 0, ! 1121: UNEEDSIN+USENDBUF, ! 1122: UNEEDSOUT+UDOTEXEC+UREADBUF+UINITBUF, ! 1123: UNEEDSOUT+UDOTEXEC+UREADBUF, ! 1124: UNEEDSOUT+UNOSCREEN+URETBUF, ! 1125: UNEEDSIN+UNEEDSOUT+UNOSCREEN+UPROCESS, ! 1126: UNEEDSIN+USPLOUT+UNOSCREEN, ! 1127: UNEEDSOUT+USPLIN+UNOSCREEN ! 1128: }; ! 1129: ! 1130: ! 1131: unx(cmd,flag) ! 1132: /* Keywords: commands:80 buffers:10 files:10 environment-variables:20 unix-interface shell-escape dired:10 sub-processes:40 encryption:20 */ ! 1133: register char *cmd; ! 1134: register int flag; ! 1135: ! 1136: { ! 1137: #ifdef PC ! 1138: return(1); /* Don't do this, just exit */ ! 1139: #else ! 1140: struct pipes { ! 1141: int rdpipe; ! 1142: int wrpipe; ! 1143: } piped1,piped2; ! 1144: FILE tinbuf[1]; ! 1145: FILE *infile; ! 1146: int (*istat)(); ! 1147: int (*qstat)(); ! 1148: register int i; ! 1149: int c; ! 1150: int obuf; ! 1151: int pid; ! 1152: char **evp; ! 1153: char *obname; ! 1154: char evbuf[256]; ! 1155: char *myshell; ! 1156: ! 1157: if (*cmd == 0) return(1); /* Don't even bother with null commands */ ! 1158: obname=fname(); ! 1159: cstatus = -1; /* start off bad */ ! 1160: flag = unxflags[flag]; /* Translate to bit-coded value */ ! 1161: ! 1162: if ((flag & UPROCESS) && procpid) flushproc(); /* Zap old process */ ! 1163: ! 1164: if (flag&UDOTEXEC) { /* if .exec in the business */ ! 1165: obuf = curbf; ! 1166: if (chgbuf(".exec") == 0) return(0); ! 1167: } ! 1168: ! 1169: if ((USILENT == 0) && ((flag&UNOSCREEN) == 0)) { ! 1170: clear(); ! 1171: putout("%s",cmd); ! 1172: istat = signal(SIGINT, SIG_IGN); ! 1173: qstat = signal(SIGQUIT, SIG_IGN); ! 1174: cook(); ! 1175: } ! 1176: if (flag & UNEEDSIN) { ! 1177: if (pipe(&piped1)) { ! 1178: error (WARN,errno,cmd); ! 1179: goto done; ! 1180: } ! 1181: } ! 1182: ! 1183: if (flag & UNEEDSOUT) { ! 1184: if (pipe (&piped2)) { ! 1185: error (WARN,errno,cmd); ! 1186: if (flag & UNEEDSIN) { ! 1187: close(piped1.rdpipe); ! 1188: close(piped1.wrpipe); ! 1189: } ! 1190: goto done; ! 1191: } ! 1192: } ! 1193: if ((pid = fork()) == 0) { /* child process */ ! 1194: ! 1195: if (flag &UNEEDSIN) { ! 1196: close(0); ! 1197: dup(piped1.rdpipe); ! 1198: } else if (flag & USPLIN) { ! 1199: close(0); ! 1200: dup(splfile); ! 1201: } else if ((USILENT)|| (flag & URETBUF)) { ! 1202: close(0); ! 1203: open("/dev/null",0); ! 1204: } ! 1205: if (flag &UNEEDSOUT) { /* if writing to .exec */ ! 1206: close(1); ! 1207: dup(piped2.wrpipe); ! 1208: } else if (flag & USPLOUT) { ! 1209: close(1); ! 1210: dup(splfile); ! 1211: ! 1212: } else if (USILENT) { /* silent, throw away output */ ! 1213: close(1); ! 1214: open("/dev/null",2); ! 1215: } ! 1216: signal(SIGINT, SIG_DFL); ! 1217: signal(SIGQUIT,SIG_DFL); ! 1218: xclose(2); /* close all irrelavent files */ ! 1219: dup(1); /* restore stderr */ ! 1220: ! 1221: myshell = getenv("SHELL"); ! 1222: if ((myshell == NULL)|| (*myshell == '\0')) myshell = "/bin/sh"; ! 1223: umask(mymask); /* Restore user's umask */ ! 1224: seprintf(evbuf,"filename=%s",obname); ! 1225: evp = fixenv(evbuf); /* Add filename definition */ ! 1226: ! 1227: if (streq(cmd,shell)) execl(myshell,shell,"-i",0,evp); ! 1228: execle(myshell, shell, "-c", cmd, 0,evp); ! 1229: execle("/bin/sh",shell, "-c", cmd, 0,evp); ! 1230: _exit(127); ! 1231: } ! 1232: ! 1233: /* parent process (the one that remains EMACS) */ ! 1234: ! 1235: if (pid== -1) { ! 1236: error(WARN,73,cmd); ! 1237: goto done; ! 1238: } ! 1239: if (flag &UPROCESS) { ! 1240: close (piped1.rdpipe); ! 1241: close (piped2.wrpipe); ! 1242: inproc = piped2.rdpipe; ! 1243: outproc = piped1.wrpipe; ! 1244: #ifdef ux3 ! 1245: fcntl(inproc,F_SETFL,O_NDELAY); /* Turn on non-blocking I/O */ ! 1246: ioset(1); /* Set timeout on terminal short */ ! 1247: #endif ! 1248: procbuf = curbf; ! 1249: procpid = pid; ! 1250: return(1); ! 1251: } ! 1252: if (flag & USPLIN) { ! 1253: close(splfile); ! 1254: splfile = piped2.rdpipe; ! 1255: close(piped2.wrpipe); ! 1256: return(1); ! 1257: } ! 1258: if (flag & USPLOUT) { ! 1259: close(splfile); ! 1260: splfile = piped1.wrpipe; ! 1261: close(piped1.rdpipe); ! 1262: return(1); ! 1263: } ! 1264: if (flag&USENDBUF) { /* if sending the buffer */ ! 1265: close(piped1.rdpipe); ! 1266: infile = fdopen(tinbuf,piped1.wrpipe,"w"); ! 1267: for (i = 1; i <=nlines; i++) { ! 1268: cmd = mkline(i); ! 1269: while ((c = *cmd++) != EOL) { ! 1270: putc(c,infile); ! 1271: } ! 1272: if (i != nlines) putc(EOL,infile); ! 1273: } ! 1274: mclose(infile); ! 1275: } ! 1276: if (flag&(UREADBUF|URETBUF)) { /* if writing */ ! 1277: close(piped2.wrpipe); ! 1278: infile = fdopen(tinbuf,piped2.rdpipe,"r"); ! 1279: if (flag&UINITBUF) bufinit(); ! 1280: else if (flag&UREADBUF) { ! 1281: bot(); /* append */ ! 1282: if (column != 0) nl(1); ! 1283: putin(cmd); ! 1284: nl(2); ! 1285: } ! 1286: if (flag&URETBUF) { ! 1287: cmd = fnbuf; ! 1288: i = 127; ! 1289: while (i--) { ! 1290: c = getc(infile); ! 1291: if ((c=='\0')||(c == '\n')||(c==' ')||(c=='\t')|| (c == EOF)) break; ! 1292: *cmd++ = c; ! 1293: } ! 1294: *cmd = 0; /* EOS */ ! 1295: mclose(infile); ! 1296: } else { ! 1297: i = ((flag & UINITBUF) != 0); ! 1298: readsub(infile,i,cmd,1-(USILENT|NOECHO)); ! 1299: chbuf(obuf); ! 1300: } ! 1301: } ! 1302: /* wait for child to finish */ ! 1303: ! 1304: /* must wait for child else it becomes a <defunct> process */ ! 1305: ! 1306: while ((i = wait(&cstatus)) != pid && i != -1); ! 1307: ! 1308: if (flag&URETBUF) return(cstatus); ! 1309: /* child is now done, go back to normal EMACS */ ! 1310: mailcnt = 0; ! 1311: ! 1312: done: if ((USILENT == 0) && ((flag&UNOSCREEN) == 0)) { ! 1313: uncook(); ! 1314: signal(SIGINT, istat); ! 1315: signal(SIGQUIT, qstat); ! 1316: junked++; ! 1317: } ! 1318: return(contin()); ! 1319: #endif ! 1320: } ! 1321: ! 1322: bux(arg) ! 1323: ! 1324: int arg; ! 1325: ! 1326: /* Keywords: commands buffers unix-interface shell-escape */ ! 1327: ! 1328: { ! 1329: register char *sp; ! 1330: register int flag; ! 1331: if (SAVEMD) fsave(0); ! 1332: if (arg == 0) flag = 5; ! 1333: else if (arg == 1) flag = 2; ! 1334: else flag = 3; ! 1335: ! 1336: do { ! 1337: sp = (getname("command line? ")); ! 1338: } while (sp && (unx(sp,flag)== 0)); ! 1339: return(cstatus); ! 1340: } ! 1341: ! 1342: /* query replace */ ! 1343: /* prompts for strings and does conditional replacement */ ! 1344: ! 1345: qrep(gflag) ! 1346: int gflag; ! 1347: /* Keywords: commands query-replace */ ! 1348: { ! 1349: iqrep(0,gflag); /* no regular expressions */ ! 1350: } ! 1351: ! 1352: rqrep(gflag) ! 1353: int gflag; ! 1354: /* Keywords: commands query-replace regular-expressions */ ! 1355: { ! 1356: iqrep(1,gflag); /* regular expression version */ ! 1357: } ! 1358: ! 1359: ! 1360: iqrep(regular,gflag) ! 1361: ! 1362: int regular; ! 1363: int gflag; ! 1364: ! 1365: /* Keywords: query-replace regular-expressions:20 user-interface key-bindings:20 commands:10 */ ! 1366: ! 1367: ! 1368: { ! 1369: ! 1370: char sstring[128]; ! 1371: int dir = 1; ! 1372: register char *sp; ! 1373: int bsflag = 0; ! 1374: int ask = 1; ! 1375: int show = 1; ! 1376: int l = 1; ! 1377: int stop = 0; ! 1378: int upt; ! 1379: register int c; ! 1380: int oldln; ! 1381: int oldcol; ! 1382: ! 1383: if((sp = getname("From? "))== NULL) return; ! 1384: if (*sp == NULL) sp = presst; ! 1385: strcpy(sstring,sp); ! 1386: if ((sp = getname("To? ")) == NULL) return; ! 1387: if (!streq(sp,"%")) strcpy(rstring,sp); /* Copy over return string unless it is a single % */ ! 1388: oldln = curln; ! 1389: oldcol = column; ! 1390: upt = unstart(); ! 1391: while (1) { ! 1392: if (regular) { ! 1393: if (rgsrch(curln,column,sstring,0,dir)== 0) break; ! 1394: } else { ! 1395: if (srch(curln,column,sstring,dir)== 0) break; ! 1396: } ! 1397: dir = 1; ! 1398: if ((l == 0) && (curln == kline) && (column == kcol)) { ! 1399: error(WARN,72,sstring,rstring); ! 1400: goto rdone; ! 1401: } ! 1402: ! 1403: prompt1("From %s To %s",sstring,rstring); ! 1404: strcpy(presst,sstring); /* save successful search */ ! 1405: move(kline,kcol); ! 1406: if (show) { ! 1407: disup(); ! 1408: } ! 1409: if (ask){ ! 1410: c = getchar(); ! 1411: donttime=0; ! 1412: } else c = 'y'; ! 1413: switch(c) { ! 1414: ! 1415: case '.': stop = 1; /* stop after this one */ ! 1416: goto rep_it; /* make this replacement. */ ! 1417: case ESC: sp = getname("Replace with: "); ! 1418: if (sp) { ! 1419: strcpy(rstring,sp); ! 1420: goto rep_it; ! 1421: } ! 1422: case CTRLG: beep(); ! 1423: done: unprompt(); /* wipe out help message */ ! 1424: unend(upt); ! 1425: return; ! 1426: ! 1427: case '<': ! 1428: move (oldln,oldcol); /* return to last replacement */ ! 1429: goto done; ! 1430: ! 1431: ! 1432: case 'R': show = 0; ! 1433: case 'r': ask = 0; /* do rest */ ! 1434: NOBEL++; /* Inhibit ding on zero length deletes */ ! 1435: /* fall through to do this one too */ ! 1436: case ' ': ! 1437: case 'y': ! 1438: case 'Y': ! 1439: rep_it: kbapp = 0; ! 1440: oldln = curln; ! 1441: oldcol = column; ! 1442: if (regular) { ! 1443: l = (loc2-column); ! 1444: } else { ! 1445: l = (lng(sstring)); ! 1446: } ! 1447: fdel(l); ! 1448: for (sp = rstring; *sp; sp++) { ! 1449: switch(*sp) { ! 1450: case '\\': ! 1451: if (!bsflag) { ! 1452: bsflag = 1; ! 1453: continue; ! 1454: } ! 1455: case '1': ! 1456: case '2': ! 1457: case '3': ! 1458: case '4': ! 1459: case '5': ! 1460: case '6': ! 1461: case '7': ! 1462: case '8': ! 1463: if (bsflag && regular && regrep(*sp-'1')) { ! 1464: bsflag = 0; ! 1465: continue; /* \number style replace */ ! 1466: } ! 1467: /* fall through to default treatment of numbers */ ! 1468: ! 1469: default: ! 1470: dput(*sp); ! 1471: bsflag = 0; ! 1472: break; ! 1473: case '&': ! 1474: if (bsflag) { ! 1475: dput(*sp); ! 1476: bsflag = 0; ! 1477: continue; ! 1478: } else { ! 1479: yank(1); ! 1480: unpop(1); ! 1481: } ! 1482: } ! 1483: } ! 1484: unins(oldln,oldcol); /* Make an undo entry */ ! 1485: kpop(); /* clean up our stack */ ! 1486: if (stop) goto done; ! 1487: if (show) { ! 1488: disup(); /* before next search */ ! 1489: mflush(stdout); ! 1490: } ! 1491: break; ! 1492: case CTRLH: ! 1493: case RUBOUT: ! 1494: case 'n': ! 1495: case 'N': ! 1496: forw(1); ! 1497: break; ! 1498: case 'p': ! 1499: case 'b': ! 1500: dir = -1; ! 1501: forw(-1); ! 1502: break; ! 1503: default: ! 1504: beep(); ! 1505: case '?': ! 1506: donttime=1; /* Avoid time mode */ ! 1507: prompt3("Query replace -- 'y' to replace, 'n' to skip, ^G to quit,'R' or 'r' for rest"); ! 1508: ! 1509: } ! 1510: if (gflag>1) move(kline+1,0); /* only do first one */ ! 1511: } ! 1512: rdone: prompt1("Replace Done"); ! 1513: if (ask==0) NOBEL--; /* Re-enable warning on 0 length deletes */ ! 1514: unend(upt); ! 1515: } ! 1516: /* length of a string */ ! 1517: ! 1518: lng(sp) ! 1519: ! 1520: char *sp; ! 1521: /* Keywords: string-handling length */ ! 1522: { ! 1523: register char *spo; ! 1524: ! 1525: spo = sp; ! 1526: while(*spo++); ! 1527: return(spo-sp-1); ! 1528: } ! 1529: ! 1530: /* capitalize next count characters */ ! 1531: ! 1532: capnxt(count) ! 1533: ! 1534: register int count; ! 1535: ! 1536: /* Keywords: commands character-at-a-time forwards capitalization */ ! 1537: { ! 1538: register int c; ! 1539: int oldover; ! 1540: while (count--) { ! 1541: c = (clptr[column]); ! 1542: if ((c >= 'a') && (c <= 'z')) { ! 1543: oldover=OVERW; ! 1544: OVERW=1; ! 1545: insertc(1,c-040); ! 1546: OVERW=oldover; ! 1547: } else if (forw(1)==0) break; /* check for EOF */ ! 1548: } ! 1549: } ! 1550: ! 1551: ! 1552: /* lowercase next count characters */ ! 1553: ! 1554: lownxt(count) ! 1555: ! 1556: register int count; ! 1557: ! 1558: /* Keywords: commands character-at-a-time forwards capitalization */ ! 1559: { ! 1560: register int c; ! 1561: int oldover; ! 1562: while (count--) { ! 1563: c = (clptr[column]); ! 1564: if ((c >= 'A') && (c <= 'Z')) { ! 1565: oldover=OVERW; ! 1566: OVERW=1; ! 1567: insertc(1,c+040); ! 1568: OVERW=oldover; ! 1569: } else if (forw(1)==0) break; /* check for EOF */ ! 1570: } ! 1571: } ! 1572: ! 1573: /* capitalize first character of the next word */ ! 1574: ! 1575: capwrd(count) ! 1576: ! 1577: register int count; ! 1578: ! 1579: /* Keywords: commands word-oriented-commands forwards capitalization */ ! 1580: { ! 1581: while (count--) { ! 1582: kmark(); ! 1583: IGNORE(skipf(WRDSEP)); ! 1584: move(kline,kcol); /* to next word */ ! 1585: capnxt(1); ! 1586: mfwrd(1); ! 1587: } ! 1588: } ! 1589: ! 1590: /* exchange current position and the marked position */ ! 1591: ! 1592: exch(mnumb) ! 1593: ! 1594: /* Keywords: commands regions marking movement */ ! 1595: { ! 1596: register int x; ! 1597: register int y; ! 1598: register MARK *markp; ! 1599: ! 1600: markp = markptr(mnumb); ! 1601: x = markp->markl; ! 1602: if (x < 1) x = 1; ! 1603: y = markp->markc; ! 1604: if ((x == curln) && (y == column)) { ! 1605: return(0); ! 1606: } ! 1607: if (x > nlines) x = nlines; ! 1608: mark(mnumb); ! 1609: mvc(x,y); ! 1610: return(1); ! 1611: } ! 1612: ! 1613: /* exchange next two chacters in the buffer and move forward one */ ! 1614: ! 1615: xpose(count) ! 1616: ! 1617: register int count; ! 1618: ! 1619: /* Keywords: commands forwards movement:10 transposition */ ! 1620: { ! 1621: int oldnodel,oldpic; ! 1622: ! 1623: register int undp; ! 1624: ! 1625: oldnodel=NODEL; ! 1626: oldpic=PICMODE; ! 1627: NODEL=0; ! 1628: PICMODE=0; ! 1629: kbapp = 0; ! 1630: undp = unstart(); ! 1631: fdel(1); ! 1632: forw(count); ! 1633: yank(1); ! 1634: unend(undp); ! 1635: kpop(); ! 1636: forw(-1); ! 1637: NODEL=oldnodel; ! 1638: PICMODE=oldpic; ! 1639: } ! 1640: ! 1641: /* changes a mode parameter. Mode parameters are of three types, ! 1642: * string, boolean, or integer. ! 1643: ! 1644: * Integer modes set from the count argument, boolean modes turn on if ! 1645: * count is one, off otherwise, and string modes prompt for new value ! 1646: ! 1647: * chmode returns the previous value of the mode set */ ! 1648: ! 1649: ! 1650: chmode(count) ! 1651: register int count; ! 1652: ! 1653: /* Keywords: modes commands assignment */ ! 1654: { ! 1655: register char *mp; ! 1656: ! 1657: if ((mp=getname("Mode? ")) != NULL) { ! 1658: if (*mp == '\0') { ! 1659: modisp(numarg); ! 1660: return(0); ! 1661: } ! 1662: return(setmode(mp,count,1)); ! 1663: } ! 1664: return(0); ! 1665: } ! 1666: ! 1667: char *MDHEAD = "EMACS_MODES:"; ! 1668: ! 1669: bfmodes() /* set modes from buffer */ ! 1670: /* Keywords: modes buffers file-modes assignment:10 */ ! 1671: { ! 1672: register char *cp; ! 1673: register char *cp1; ! 1674: char mdbuf[20]; ! 1675: int onoff; ! 1676: ! 1677: kline = 11; ! 1678: if (kline > nlines) kline = nlines; ! 1679: while ((kline > 0) && srch(kline,leng(kline),MDHEAD,-1)) { ! 1680: /* if modes set */ ! 1681: ! 1682: for (cp = mkline(kline)+kcol+12; *cp != EOL;) { ! 1683: cp1 = mdbuf; ! 1684: while ((*cp != EOL) && (*cp != '!') && ((bits[*cp] & WRDCHR) == 0)) cp++; ! 1685: if (*cp == '!') { ! 1686: onoff = 0; ! 1687: cp++; ! 1688: } else onoff = 1; ! 1689: ! 1690: while (bits[*cp] & WRDCHR) { ! 1691: *cp1++ = *cp++; ! 1692: } ! 1693: if (*cp == '=') { ! 1694: cp++; ! 1695: cp = nscan(cp,&onoff); ! 1696: } ! 1697: ! 1698: *cp1 = 0; ! 1699: if (mdbuf[0]) setmode(mdbuf,onoff,0); /* Set up mode */ ! 1700: } ! 1701: kline--; ! 1702: } ! 1703: } ! 1704: ! 1705: ! 1706: setmode(mp,count,fudge) ! 1707: register char *mp; ! 1708: int count; ! 1709: int fudge; ! 1710: /* Keywords: modes macro-programming:10 assignment time-handling:20 display-format:10 */ ! 1711: { ! 1712: register int i; ! 1713: extern char cbuf[]; ! 1714: int retval; ! 1715: int mfield; ! 1716: ! 1717: for (i = 0; i < NMODES; i++) { ! 1718: if (streq(mdata[i].modename,mp)) { ! 1719: retval = *mdata[i].modeloc; /* old value */ ! 1720: switch(mdata[i].modetype) { ! 1721: case ONOFF: ! 1722: if (fudge && (count != 1)) count = 0; ! 1723: *mdata[i].modeloc = count; ! 1724: break; ! 1725: case INT: ! 1726: *mdata[i].modeloc = count; ! 1727: break; ! 1728: } ! 1729: if ((mfield = mdata[i].moderset)&DSIZE) { ! 1730: SCRNLIN = SCRLINES+4; ! 1731: setsize(); ! 1732: } ! 1733: /* customize the behavior of ^H in word commands */ ! 1734: ! 1735: if (mfield|CTYPE) { ! 1736: if (BACKP) { ! 1737: bits[CTRLH] = bits['_'] = WRDCHR; ! 1738: ctype[CTRLH] = BACKSP; ! 1739: } else { ! 1740: bits[CTRLH] = bits['_'] = WRDSEP; ! 1741: ctype[CTRLH] = CONTRL; ! 1742: } ! 1743: if (NOTABS) ctype[CTRLI] = CONTRL; ! 1744: else ctype[CTRLI] = TAB; ! 1745: if (bit8) metal = 0; ! 1746: else metal = 2; ! 1747: } ! 1748: if (mfield & CSE) { ! 1749: if (NOCASE) count = 'a'-'A'; ! 1750: else count = 0; ! 1751: for (i = 'A'; i <= 'Z'; i++) { ! 1752: casem[i] = i+count; ! 1753: } ! 1754: } ! 1755: if (timemd == 0) *cbuf = 0; /* Nullify current time */ ! 1756: if (mfield&DISPLAY) { ! 1757: fclear(); /* force re-display */ ! 1758: if (PICMODE==0) hcol=0; ! 1759: } ! 1760: return(retval); ! 1761: } ! 1762: } ! 1763: IGNORE(error (WARN,45,mp)); ! 1764: return(0); ! 1765: } ! 1766: ! 1767: ! 1768: modval(mp) ! 1769: char *mp; ! 1770: /* Keywords: commands macro-programming modes */ ! 1771: { ! 1772: register int i; ! 1773: ! 1774: ! 1775: for (i = 0; i < NMODES; i++) if (streq(mdata[i].modename,mp)) return(*mdata[i].modeloc); ! 1776: return(0); ! 1777: } ! 1778: ! 1779: ! 1780: /* display all active modes. Values displayed for integer and string ! 1781: * modes, all on boolean modes are displayed */ ! 1782: ! 1783: modisp(arg) ! 1784: register int arg; ! 1785: /* Keywords: informational-displays modes commands user-interface */ ! 1786: { ! 1787: register int i; ! 1788: char *mp; ! 1789: ! 1790: if ((arg < 0) && (mp = getname("Mode? "))) return(modval(mp)); ! 1791: ! 1792: mtop(); ! 1793: for (i = 0; i < NMODES; i++) { ! 1794: switch(mdata[i].modetype) { ! 1795: ! 1796: case ONOFF: ! 1797: if (*mdata[i].modeloc) putout("%s mode is on",mdata[i].modename); ! 1798: else if (arg) putout ("%s mode is off",mdata[i].modename); ! 1799: break; ! 1800: case INT: ! 1801: putout("%s = %d",mdata[i].modename,*mdata[i].modeloc); ! 1802: break; ! 1803: } ! 1804: } ! 1805: putout (endput); ! 1806: return(contin()); ! 1807: } ! 1808: ! 1809: /* compare two strings */ ! 1810: ! 1811: streq(cp,cp1) ! 1812: ! 1813: register char *cp; ! 1814: register char *cp1; ! 1815: ! 1816: /* Keywords: string-handling comparison */ ! 1817: { ! 1818: while (*cp) if (*cp++ != *cp1++) return(0); ! 1819: if (*cp1) return(0); ! 1820: return(1); ! 1821: } ! 1822: ! 1823: char * ! 1824: mstrcpy(cp,cp1) ! 1825: ! 1826: /* Keywords: assignment string-handling */ ! 1827: register char *cp; ! 1828: register char *cp1; ! 1829: { ! 1830: while (*cp++ = *cp1++); ! 1831: return(cp-1); ! 1832: } ! 1833: ! 1834: /* push the marked region onto the kill stack without killing it */ ! 1835: ! 1836: ! 1837: pickup(mnumb) ! 1838: ! 1839: /* Keywords: regions commands killstack stacking */ ! 1840: ! 1841: ! 1842: { ! 1843: register MARK *markp; ! 1844: ! 1845: ! 1846: markp = markptr(mnumb); ! 1847: ! 1848: if ((markp->markl < curln) || ((markp->markl == curln) && (markp->markc < column))) { ! 1849: killstk(markp->markl,markp->markc,curln,column); ! 1850: } else { ! 1851: killstk(curln,column,markp->markl,markp->markc); ! 1852: } ! 1853: } ! 1854: ! 1855: /* go to beginning of count line */ ! 1856: ! 1857: absgoto(count) ! 1858: register int count; ! 1859: /* Keywords: commands movement text-lines */ ! 1860: ! 1861: { ! 1862: move((count<nlines)?count:nlines, 0); ! 1863: } ! 1864: ! 1865: /* begin a C coment. comment begins in COMCOL, if current position is ! 1866: * not column 0, otherwise begins in column 0. the next newline will end ! 1867: * the coment */ ! 1868: ! 1869: cment() ! 1870: ! 1871: /* Keywords: C-mode commands comments */ ! 1872: ! 1873: { ! 1874: ! 1875: if (column) { ! 1876: disup(); ! 1877: if (mcol<comcol) { ! 1878: while (mcol<comcol) { ! 1879: put(' '); ! 1880: disup(); ! 1881: } ! 1882: } else { ! 1883: put (' '); ! 1884: } ! 1885: } ! 1886: putin ("\057* "); /* it's a slash, for stupid compilers! */ ! 1887: comln = curln; ! 1888: } ! 1889: ! 1890: /* adjust the indentation of the current line to be consistent with that ! 1891: * in the last line. */ ! 1892: ! 1893: tabjust(lno) ! 1894: register int lno; ! 1895: /* Keywords: insertion C-mode commands:10 */ ! 1896: { ! 1897: register int lln; ! 1898: register int tabno; ! 1899: char *llp; ! 1900: int c; ! 1901: ! 1902: tabno = 0; ! 1903: for (lln = lno-1; lln > 0; lln--) { ! 1904: llp = mkline(lln); ! 1905: while (llp[tabno] == ' ') ++tabno; ! 1906: if ((llp[tabno]!= EOL) && (llp[tabno+1] != '*')) { ! 1907: while ((c = llp[tabno])!=EOL) { ! 1908: switch(c) { ! 1909: case '{': ! 1910: ++tabno; ! 1911: break; ! 1912: default: ! 1913: ++llp; ! 1914: } ! 1915: } ! 1916: goto tabout; ! 1917: } ! 1918: tabno = 0; ! 1919: } ! 1920: tabout: ! 1921: move(lno,0); ! 1922: while ((c = clptr[column]) == ' ') { ! 1923: tabno--; ! 1924: column++; ! 1925: } ! 1926: if ((c == '}') && tabno) tabno--; ! 1927: if (tabno) { ! 1928: if (tabno>0) tabc(tabno,' '); ! 1929: else { ! 1930: bdel(-tabno); ! 1931: kpop(); ! 1932: unpop(1); ! 1933: } ! 1934: } else { ! 1935: sputl(curln,column,curln); ! 1936: move(curln,column); ! 1937: } ! 1938: } ! 1939: ! 1940: /* } handler, re-sets the indentation back one level */ ! 1941: ! 1942: cbrak(count,brace) ! 1943: ! 1944: register int count; ! 1945: register int brace; ! 1946: /* Keywords: C-mode insertion commands */ ! 1947: { ! 1948: if (TABMD &&(RARE == 0) && column && (*(clptr+column-1) == ' ')){ ! 1949: bdel(1); ! 1950: kpop(); ! 1951: unpop(1); ! 1952: }; ! 1953: insertc(count,brace); ! 1954: } ! 1955: ! 1956: ! 1957: /* returns 1 if next line contains no non blank (or tab) characters */ ! 1958: ! 1959: isblank(line) ! 1960: ! 1961: register int line; ! 1962: /* Keywords: commands:10 line-representation:50 */ ! 1963: { ! 1964: register char *lp; ! 1965: ! 1966: if ((line <= nlines) && (ptrs[line] == 0)) return(1); ! 1967: lp = mkline(line); ! 1968: while (*lp!=EOL) { ! 1969: if ((bits[*lp++] & WHITE) == 0) return(0); ! 1970: } ! 1971: return(1); ! 1972: } ! 1973: ! 1974: /* change working dir */ ! 1975: ! 1976: cwd() ! 1977: ! 1978: /* Keywords: commands directories unix-interface */ ! 1979: { ! 1980: #ifndef PC ! 1981: char *np; ! 1982: np = expenv(getname("Directory? ")); ! 1983: if (np) { ! 1984: if (SAVEMD) fsave(0); ! 1985: if (*np == 0) np = getenv("HOME"); /* null means home */ ! 1986: if(chdir(np)) { ! 1987: IGNORE(error(WARN,errno,np)); ! 1988: return(0); ! 1989: } ! 1990: return(1); ! 1991: } ! 1992: return(0); ! 1993: #endif PC ! 1994: } ! 1995: ! 1996: stats() ! 1997: { ! 1998: /* Keywords: commands informational-displays statistics */ ! 1999: ! 2000: #ifdef COMPRESS ! 2001: extern long coutc; ! 2002: #endif ! 2003: mtop(); ! 2004: putout ("%d chars from terminal",ninch); ! 2005: putout ("%D calls to mputc",nmput); ! 2006: putout ("%D chars written by mputc",noutc); ! 2007: #ifdef COMPRESS ! 2008: putout ("%D chars after compression",coutc); ! 2009: #endif ! 2010: putout ("%d terminal writes", ntwrite); ! 2011: putout ("%d calls to makeline",nmkline); ! 2012: putout ("%d buffer reads",nbread); ! 2013: putout ("%d file writes",nbwrite); ! 2014: putout ("%d file seeks", nbseek); ! 2015: putout ("%d characters of buffer left", (NBLOCK*BLEN)-macptr); ! 2016: IGNORE(contin()); ! 2017: } ! 2018: ! 2019: uline(count) ! 2020: ! 2021: /* Keywords: word-oriented-commands commands underlining */ ! 2022: register int count; ! 2023: ! 2024: { ! 2025: while (count--) { ! 2026: kmark(); ! 2027: IGNORE(skipf(WRDSEP)); /* skip to begginning of word */ ! 2028: move(kline,kcol); ! 2029: while (bits[*klptr] & WRDCHR) { ! 2030: put('_'); ! 2031: put(CTRLH); ! 2032: forw(1); ! 2033: } ! 2034: } ! 2035: } ! 2036: ! 2037: infile(fn) ! 2038: ! 2039: /* Keywords: commands:40 files keyboard-macros:10 command-line-processing:10 command-files */ ! 2040: register char *fn; ! 2041: { ! 2042: if (pushin(expenv(fn))) { ! 2043: edit(1); ! 2044: inpop(); ! 2045: return(1); ! 2046: } else return(0); ! 2047: } ! 2048: ! 2049: ! 2050: inpsh(arg) ! 2051: int arg; ! 2052: { ! 2053: register char *fp; ! 2054: /* Keywords: commands files keyboard-macros:10 command-files */ ! 2055: ! 2056: if (fp=getname("Input file? ")) { ! 2057: if (infile(fp)==0 ) { ! 2058: if (arg > 0) IGNORE(error(WARN,errno,fp)); ! 2059: return(0); ! 2060: } ! 2061: } ! 2062: return(1); ! 2063: } ! 2064: ! 2065: /* send the contents of the buffer as mail */ ! 2066: ! 2067: /* mtch -- see if current line matches header */ ! 2068: ! 2069: mtch(cp) ! 2070: register char *cp; ! 2071: /* Keywords: mail-processing string-handling:20 comparison:40 */ ! 2072: ! 2073: { ! 2074: register char *cl; ! 2075: cl = clptr; ! 2076: while (*cp) if (*cp++ != *cl++) return(0); ! 2077: return(1); ! 2078: } ! 2079: ! 2080: mailit() ! 2081: ! 2082: /* Keywords: mail-processing unix-interface commands */ ! 2083: ! 2084: ! 2085: { ! 2086: char cmdbuf[256]; ! 2087: register char *mp; ! 2088: register char *mp1; ! 2089: int mailstat; ! 2090: char *mailcom; ! 2091: #ifdef POSTHACK ! 2092: char *s; ! 2093: register int c; ! 2094: extern char *strrchr(); ! 2095: #endif ! 2096: mailstat = 0; ! 2097: #ifndef PC ! 2098: #ifdef bsd ! 2099: #define DEFMAIL "/usr/lib/sendmail -t" ! 2100: #else ! 2101: #define DEFMAIL "mail" ! 2102: #endif ! 2103: if ((mailcom=getenv("MAILER"))==NULL) mailcom=DEFMAIL; ! 2104: ! 2105: mp = mstrcpy(cmdbuf,mailcom); ! 2106: ! 2107: #ifdef POSTHACK ! 2108: /* find the start of the mail command name */ ! 2109: if ((s = strrchr(mailcom, '/')) != NULL) { ! 2110: ++s; ! 2111: } ! 2112: else { ! 2113: s = mailcom; ! 2114: } ! 2115: /* if this is post or Berkeley mail */ ! 2116: if (streq(s, "post") || streq(s, "Mail")) { ! 2117: top(); ! 2118: while (curln < 10 && *clptr != EOL) { ! 2119: ! 2120: /* if there is a subject line in the message */ ! 2121: if (mtch("Subject: ")) { ! 2122: ! 2123: /* add -s 'subject' to the mail command */ ! 2124: strcpy(mp, " -s '"); ! 2125: mp += 5; ! 2126: mp1 = clptr + 9; /* skip "Subject: " */ ! 2127: while ((c = *mp1) != EOL) { ! 2128: if (c == '\'') { /* ' becomes '\'' */ ! 2129: *mp++ = '\''; ! 2130: *mp++ = '\\'; ! 2131: *mp++ = '\''; ! 2132: *mp++ = '\''; ! 2133: } ! 2134: else { ! 2135: *mp++ = c; ! 2136: } ! 2137: ++mp1; ! 2138: } ! 2139: *mp++ = '\''; ! 2140: *mp = 0; ! 2141: break; ! 2142: } ! 2143: move(curln+1,0); ! 2144: } ! 2145: } ! 2146: /* get the list of addressees */ ! 2147: #endif ! 2148: top(); ! 2149: while (curln < 10 && *clptr != EOL) { ! 2150: if (mtch("TO: ") || mtch("To: ") || mtch("CC: ") || mtch("Cc: ")) { ! 2151: if (clptr[1] == 'O') clptr[1] = 'o'; ! 2152: if (clptr[1] == 'C') clptr[1] = 'c'; ! 2153: column = 3; ! 2154: if (((mp-cmdbuf)+leng(curln)-column) > 250) { ! 2155: mailstat += unx(cmdbuf,1); /* partial list */ ! 2156: mp = mstrcpy(cmdbuf,mailcom); ! 2157: move(curln,column); ! 2158: } ! 2159: mp1 = clptr+column; ! 2160: while (*mp1 != EOL) *mp++ = *mp1++; /* copy mailing list */ ! 2161: *mp = 0; ! 2162: } ! 2163: move(curln+1,0); ! 2164: } ! 2165: mp1 = cmdbuf+4; ! 2166: while (*mp1) if (*mp1++ != ' ') { /* Check for non-null destination list */ ! 2167: ! 2168: mailstat += unx(cmdbuf,1); /* send to mail command */ ! 2169: return(mailstat == 0); ! 2170: } ! 2171: IGNORE(error (WARN,46)); ! 2172: #endif ! 2173: return(0); ! 2174: } ! 2175: ! 2176: /* contin -- ask user to continue */ ! 2177: ! 2178: ! 2179: contin() ! 2180: { ! 2181: /* Keywords: informational-displays:20 user-interface:10 prompting:40 */ ! 2182: register int c; ! 2183: if (infrn < 0) return(1); /* continue always in a macro */ ! 2184: prompt1("Continue?"); ! 2185: c = getchar(); ! 2186: prompt1(""); ! 2187: if ((c == 'y') || (c == ' ') || (c == '\n') || (c == '\015')) return(1); ! 2188: if ('n' == c) return(0); ! 2189: if (c == CTRLZ) { ! 2190: gquit(); ! 2191: return(1); ! 2192: } ! 2193: ungetch(c); ! 2194: return(0); ! 2195: } ! 2196: ! 2197: /* buffer length and current position */ ! 2198: ! 2199: ! 2200: /* If invoked from tty, prints buffer status info on the terminal. If */ ! 2201: /* invoked from a macro, returns a value dependent on its argument */ ! 2202: ! 2203: #define VLIN 0 /* return line number */ ! 2204: #define VCOL 1 /* return column number */ ! 2205: #define VDLIN 2 /* display line */ ! 2206: #define VDCOL 3 /* display column */ ! 2207: #define VMINLN 4 /* First file line on screen */ ! 2208: #define VMAXLN 5 /* ditto last */ ! 2209: #define VWTOP 6 /* First screen line of window */ ! 2210: #define VWBOT 7 /* ditto last */ ! 2211: ! 2212: buflng(arg) ! 2213: ! 2214: int arg; ! 2215: { ! 2216: /* Keywords: commands macro-programming:40 buffers statistics */ ! 2217: ! 2218: long flng; ! 2219: long fpos; ! 2220: char xbuf[128]; ! 2221: extern int minln; ! 2222: extern int maxln; ! 2223: register int i; ! 2224: if (infrn < 0) { ! 2225: /* If from macro, return useful info */ ! 2226: switch(arg) { ! 2227: ! 2228: case VCOL: return(column); ! 2229: case VLIN: return(curln); ! 2230: case VDCOL: ! 2231: case VDLIN: ! 2232: if (findline(curln) == 0) return(-1); ! 2233: mline=nln; ! 2234: if (findpos(clptr,column) == 0) return(-1); ! 2235: if (arg == VDLIN) return(nln-wbase); ! 2236: else return(mcol); ! 2237: case VMINLN: return(minln); ! 2238: case VMAXLN: return(maxln); ! 2239: case VWTOP: return(wbase); ! 2240: case VWBOT: return(SCRLINES-1); ! 2241: } ! 2242: } ! 2243: flng = 0L; ! 2244: for (i = 1; i <= nlines; i++) { ! 2245: if (i != 1) flng++; /* linefeed from last line */ ! 2246: if (i == curln) fpos = flng + column; ! 2247: flng += leng(i); ! 2248: } ! 2249: clptr=mkline(curln); ! 2250: seprintf(xbuf,"next char: %o, line: %d/%d: pos: %D/%D column: %d", ! 2251: clptr[column],curln,nlines-1,fpos,flng,column); ! 2252: prompt1(xbuf); ! 2253: return(0); ! 2254: } ! 2255: ! 2256: filler(arg) ! 2257: /* Keywords: regions:50 text-filling commands */ ! 2258: int arg; ! 2259: { ! 2260: register int i; ! 2261: register char *cp; ! 2262: register int j; ! 2263: int unp; ! 2264: ! 2265: unp = unstart(); ! 2266: if (arg != 1) { ! 2267: /* fill region only */ ! 2268: register MARK *markp; ! 2269: markp = markptr(curbf); ! 2270: if ((i = markp->markl) > curln) fillreg(curln,i,1); ! 2271: else fillreg(i,curln,1); ! 2272: } else { ! 2273: undel(); ! 2274: killstk(1,0,nlines,0); ! 2275: kpop(); ! 2276: for (i = 1; i < nlines;i++ ) { ! 2277: cp = mkline(i); ! 2278: if ((*cp != '.') && (*cp != '\'') && (*cp != EOL)) { ! 2279: j = i; ! 2280: while (i < nlines) { ! 2281: cp = mkline(i); ! 2282: if ((*cp == '.') || (*cp == '\'') || (*cp == EOL)) break; ! 2283: i++; ! 2284: } ! 2285: fillreg(j,i,0); ! 2286: i = curln+1; ! 2287: } ! 2288: } ! 2289: unins(1,0); ! 2290: } ! 2291: unend(unp); ! 2292: } ! 2293: ! 2294: fillreg(i,j,u) ! 2295: register int i; ! 2296: register int j; ! 2297: int u; ! 2298: { ! 2299: /* Keywords: commands:10 text-filling regions:20 undo:10 */ ! 2300: ! 2301: int onlin,ofill; ! 2302: onlin = NLINS; ! 2303: ofill = FILLMD; ! 2304: FILLMD = NLINS = 1; /* Turn on "rigid_newline" mode */ ! 2305: move(i,0); ! 2306: if (u) { ! 2307: ! 2308: /* Make an undo record for this region */ ! 2309: ! 2310: undel(); ! 2311: killstk(i,0,j,0); ! 2312: kpop(); ! 2313: } ! 2314: while (curln < j) { ! 2315: endl(); ! 2316: do { ! 2317: i = curln; ! 2318: afsep(0,0);/* Note that we don't really put anything in */ ! 2319: if (i != curln) j++; ! 2320: } while (i != curln); ! 2321: if (curln < j-1) { ! 2322: fdel(1); ! 2323: kpop(); ! 2324: unpop(1); ! 2325: while ((clptr[column] == ' ') || (clptr[column] == ' ')) { ! 2326: fdel(1); ! 2327: kpop(); ! 2328: unpop(1); ! 2329: } ! 2330: put(' '); ! 2331: j--; ! 2332: } else break; ! 2333: } ! 2334: if (u) { ! 2335: move(j,0); ! 2336: unins(i,0); /* Make a second undo record */ ! 2337: } ! 2338: NLINS = onlin; ! 2339: FILLMD = ofill; ! 2340: } ! 2341: ! 2342: /* macro the region */ ! 2343: ! 2344: macro(arg) ! 2345: int arg; ! 2346: { ! 2347: /* Keywords: key-bindings memory-allocation:10 parsing symbol-handling commands macro-hooks:20 */ ! 2348: ! 2349: register int mychar; ! 2350: register int balance; ! 2351: register int machr; ! 2352: int oldpic; ! 2353: int compos; ! 2354: int hookp; ! 2355: int hash,ename; ! 2356: #ifdef u370 ! 2357: int beepbeep(); ! 2358: #else ! 2359: extern int beep(); ! 2360: #endif ! 2361: ! 2362: oldpic=PICMODE; ! 2363: PICMODE=0; ! 2364: bot(); ! 2365: back(2); ! 2366: if (clptr[column] != CTRLZ) { ! 2367: ! 2368: /* File does not end in ^Z, Try to catch a potential disaster */ ! 2369: ! 2370: error(WARN,80,fname()); ! 2371: PICMODE=oldpic; ! 2372: return(0); ! 2373: } ! 2374: if (arg != 1) { ! 2375: for (mychar = 0; mychar < NCHARS; mychar++) { ! 2376: if (map_it[mychar] > ISIZE) { ! 2377: map_it[mychar] = 0; ! 2378: } ! 2379: if (mychar < NMAC) machash[mychar] = 0; ! 2380: if (mychar < NHOOKS) hooks[mychar] = 0; ! 2381: ! 2382: } ! 2383: macptr = 0; ! 2384: fbkno = 0; ! 2385: } ! 2386: top(); ! 2387: ! 2388: while (curln<nlines) { ! 2389: ! 2390: balance = 0; ! 2391: machr = clptr[column]&0377; ! 2392: if (machr == ESC) machr = (clptr[++column]&0377)+0200; ! 2393: if (machr == CTRLX) { ! 2394: machr = (clptr[++column]&0377)+0400; ! 2395: } ! 2396: if (machr == CTRLZ) { ! 2397: hookp = (clptr[++column]&0377); ! 2398: if (hookp > NHOOKS) { ! 2399: hookp = 0; /* Just ignore the bad ones */ ! 2400: --column; ! 2401: } ! 2402: } ! 2403: forw(1); ! 2404: if (macptr == 0) pshchr(0); /* Can't use the first location! */ ! 2405: compos = macptr; ! 2406: pshchr(0); /* Leave room for linkage chain */ ! 2407: pshchr(0); ! 2408: hash = 0; ! 2409: ename = 1; ! 2410: if (clptr[column] == CTRLBACK) { /* if comment */ ! 2411: pshchr(0); ! 2412: ++column; ! 2413: while (clptr[column] != EOL) { ! 2414: if ((clptr[column] == ' ')||(clptr[column] == ' ')) ename = 0; ! 2415: if (ename) hash += clptr[column]; ! 2416: pshchr(clptr[column++]); ! 2417: } ! 2418: pshchr(0); ! 2419: forw(1); /* skip newline */ ! 2420: } ! 2421: hash %= NMAC; ! 2422: bbuf[0][compos] = machash[hash]; ! 2423: bbuf[0][compos+1] = machash[hash]>>8; ! 2424: machash[hash] = compos; ! 2425: if (machr == CTRLZ) hooks[hookp] = macptr; /* Define hook */ ! 2426: else { ! 2427: /* Define character command */ ! 2428: ! 2429: map_it[machr] = macptr+ISIZE; ! 2430: } ! 2431: while (curln < nlines) { ! 2432: mychar = clptr[column]&0377; ! 2433: if (column == 0) { ! 2434: while ((mychar==' ') || (mychar==' ')) { ! 2435: column++; ! 2436: mychar = clptr[column]&0377; ! 2437: } ! 2438: } ! 2439: if (mychar != CTRLBACK) { ! 2440: if (mychar == MTA({)) balance++; ! 2441: else if (mychar == MTA(})) balance--; ! 2442: pshchr(mychar); ! 2443: forw(1); ! 2444: if ((mychar == CTRLZ) && (clptr[column] == EOL)) { ! 2445: if (balance) { ! 2446: error(WARN,47,curln); ! 2447: } ! 2448: goto macdone; /* end of macro definition */ ! 2449: } ! 2450: } else { ! 2451: move(curln+1,0); /* skip comment */ ! 2452: } ! 2453: } ! 2454: error (WARN,48); ! 2455: pshchr(CTRLG); /* escape from bad macro */ ! 2456: ! 2457: macdone: forw(1); /* on to next macro */ ! 2458: } ! 2459: PICMODE=oldpic; ! 2460: if (hooks[Load_Macro_Hook]) { ! 2461: hook(Load_Macro_Hook); ! 2462: hooks[Load_Macro_Hook] = 0; ! 2463: } ! 2464: return(1); ! 2465: } ! 2466: ! 2467: ldmac(arg) ! 2468: int arg; ! 2469: /* Keywords: commands files reading macro-programming:20 */ ! 2470: { ! 2471: register int oldbuf; ! 2472: register int tmpbuf; ! 2473: char *obname; ! 2474: int oldbin; ! 2475: int err; ! 2476: ! 2477: if (arg>0) err = 1; ! 2478: else { ! 2479: err = 0; ! 2480: arg = 1; ! 2481: } ! 2482: obname = fname(); /* Old file name */ ! 2483: oldbuf = curbf; ! 2484: chgbuf("..."); /* temporary buffer */ ! 2485: strcpy(fname(),obname); /* Restore file name */ ! 2486: #ifdef PC ! 2487: oldbin = BINMODE; ! 2488: BINMODE = 1; ! 2489: #endif PC ! 2490: if (fred(err)) { /* read file */ ! 2491: macro(arg); ! 2492: err = 1; ! 2493: } else { ! 2494: err = 0; ! 2495: } ! 2496: #ifdef PC ! 2497: BINMODE=oldbin; ! 2498: #endif PC ! 2499: tmpbuf = curbf; ! 2500: chbuf(oldbuf); ! 2501: klbfr(tmpbuf); /* kill temp buffer */ ! 2502: return(err); ! 2503: } ! 2504: /* macro programming commands */ ! 2505: ! 2506: /* these commands perform various utility functions for macro commands */ ! 2507: ! 2508: bfchr() /* get a character from the buffer */ ! 2509: { ! 2510: /* Keywords: macro-programming quoting character-at-a-time buffers:40 */ ! 2511: return(clptr[column]&0377); /* Trim sign bits! */ ! 2512: } ! 2513: ! 2514: litchr() /* literal character */ ! 2515: ! 2516: { ! 2517: /* Keywords: macro-programming quoting */ ! 2518: return(getchar()); ! 2519: } ! 2520: ! 2521: compar(ctype) /* general comparison */ ! 2522: ! 2523: /* comparison type definitions (pecular arangement for convenient */ ! 2524: /* specification via ^U */ ! 2525: ! 2526: ! 2527: #define CLE 0 /* <= */ ! 2528: #define CEQ 1 /* = */ ! 2529: #define CLS 2 /* < */ ! 2530: #define CGT 3 /* > */ ! 2531: #define CNE 4 /* != */ ! 2532: #define CGE 5 /* >= */ ! 2533: #define COR 6 /* OR */ ! 2534: #define CAND 7 /* AND */ ! 2535: #define CNOT 8 /* NOT */ ! 2536: #define CFALSE 9 /* FALSE */ ! 2537: #define CTRUE 10 /* TRUE */ ! 2538: #define CPLUS 11 /* arg1 + arg2 */ ! 2539: #define CMINUS 12 /* arg1 - arg2 */ ! 2540: #define CTIMES 13 /* arg1 * arg2 */ ! 2541: #define CDIV 14 /* arg1 / arg2 */ ! 2542: #define CREM 15 /* arg1 % arg2 */ ! 2543: #define CDTOS 16 /* arg1 convert to string on kill stack */ ! 2544: #define CSTOD 17 /* convert ks to decimal and return */ ! 2545: #define CBAND 18 /* Bitwise and */ ! 2546: #define CBOR 19 /* Bitwise or */ ! 2547: #define CXOR 20 /* Bitwise xor */ ! 2548: #define CUNGET 21 /* Unget character */ ! 2549: #define CPENDING 22 /* number of characters pending */ ! 2550: ! 2551: /* Keywords: macro-programming arithmetic:50 comparison:50 */ ! 2552: ! 2553: register int ctype; ! 2554: { ! 2555: register int r1; ! 2556: register int r2; ! 2557: char *sp; ! 2558: char sbuf[20]; ! 2559: int res; ! 2560: ! 2561: if (ctype == CFALSE) return(0); ! 2562: if (ctype == CTRUE) return(1); ! 2563: if (ctype == CSTOD) { ! 2564: sp = getname("Number?"); ! 2565: nscan(sp,&res); ! 2566: return(res); ! 2567: } ! 2568: if (ctype == CPENDING) { ! 2569: ttfill(); /* Read any pending tty input */ ! 2570: return(ttcnt); ! 2571: } ! 2572: r1 = edit(0); /* first arg */ ! 2573: ! 2574: if (ctype == CNOT) return(r1 == 0); ! 2575: if (ctype == CDTOS) { ! 2576: seprintf(sbuf,"%d",r1); ! 2577: stkstr(sbuf); ! 2578: return(r1); ! 2579: } ! 2580: if (ctype == CUNGET) { ! 2581: pushin(0); /* Force to tty */ ! 2582: ungetch(r1); ! 2583: inpop(); ! 2584: return(1); ! 2585: } ! 2586: r2 = edit(0); /* second arg */ ! 2587: ! 2588: switch(ctype) { ! 2589: ! 2590: case CLE: return(r1<=r2); ! 2591: case CEQ: return(r1==r2); ! 2592: case CLS: return(r1<r2); ! 2593: case CGT: return(r1>r2); ! 2594: case CNE: return(r1!=r2); ! 2595: case CGE: return(r1>=r2); ! 2596: case CAND: return(r1 && r2); ! 2597: case COR: return(r1 || r2); ! 2598: case CPLUS: return(r1+r2); ! 2599: case CMINUS: return(r1-r2); ! 2600: case CTIMES: return (r1*r2); ! 2601: case CDIV: if (r2) return(r1/r2); ! 2602: else return(0); ! 2603: case CREM: if (r2) return(r1%r2); ! 2604: else return(0); ! 2605: case CBAND: return(r1&r2); ! 2606: case CBOR: return(r1|r2); ! 2607: case CXOR: return (r1^r2); ! 2608: default:return(0); ! 2609: } ! 2610: } ! 2611: ! 2612: ! 2613: pscan(lev) /* parenthesis scan */ ! 2614: /* Keywords: macro-programming parsing control-flow:50 */ ! 2615: register int lev; /* returns when lev+paren level = 0 */ ! 2616: { ! 2617: register int c; ! 2618: register int ctlx; ! 2619: ctlx = 0; ! 2620: while (lev) { ! 2621: c = Mgetchar(); ! 2622: if (c == CTRLX) { ! 2623: ctlx++; ! 2624: continue; ! 2625: } ! 2626: if (!ctlx && ((c == (CTRLQ)) || (c == MTA(q)) || (c == (CTRLQ+META)))) { ! 2627: c = Mgetchar(); ! 2628: continue; ! 2629: } ! 2630: ctlx = 0; ! 2631: if (c == MTA({)) lev++; ! 2632: else if (c == MTA(})) lev--; ! 2633: } ! 2634: } ! 2635: ! 2636: ! 2637: cond() /* conditional execute */ ! 2638: /* Keywords: control-flow parsing :5 conditionals macro-programming */ ! 2639: { ! 2640: register int c; ! 2641: ! 2642: MACEXIT; /* Only in a macro */ ! 2643: ! 2644: if ((c = Mgetchar()) != MTA({)) { ! 2645: /* must be M-{ */ ! 2646: return(error(NORM,49)); ! 2647: } ! 2648: while ((c = Mgetchar()) != MTA(})) { ! 2649: while ((c != MTA({)) && (c !=MTA(}))) c = Mgetchar(); ! 2650: if (c == MTA(})) return(0); /* failed */ ! 2651: if (edit(0)) { ! 2652: c = edit(1); /* scan command */ ! 2653: pscan(1); /* skip to end of cond */ ! 2654: return(c); ! 2655: } else pscan(1); /* skip to end of block */ ! 2656: } ! 2657: return(0); /* cond failed */ ! 2658: } ! 2659: ! 2660: /* macro case statement: syntax is ^x!M-{<expr> ! 2661: * M-{<char><sequence>M-} ! 2662: * ... ! 2663: * M-} ! 2664: */ ! 2665: ! 2666: ! 2667: mcase() ! 2668: ! 2669: ! 2670: ! 2671: /* Keywords: cases parsing:5 control-flow macro-programming */ ! 2672: { ! 2673: register int cchar; ! 2674: register int c; ! 2675: ! 2676: MACEXIT; ! 2677: ! 2678: while ((cchar =Mgetchar()) != MTA({)); ! 2679: cchar = edit(0); /* match expression */ ! 2680: ! 2681: while ((c = Mgetchar()) != MTA(})) { ! 2682: while ((c != MTA({)) && (c !=MTA(}))) c = Mgetchar(); ! 2683: if (c == MTA(})) return(0); /* failed */ ! 2684: c = Mgetchar(); ! 2685: if ((c == cchar) || (c == 0377)) { ! 2686: c = edit(1); /* scan command */ ! 2687: pscan(1); /* skip to end of case */ ! 2688: return(c); ! 2689: } else pscan(1); /* skip to end of block */ ! 2690: } ! 2691: return(0); /* case failed */ ! 2692: } ! 2693: ! 2694: /* mbegin -- begin block in macro */ ! 2695: ! 2696: mbegin() ! 2697: ! 2698: ! 2699: /* Keywords: macro-programming parsing:20 control-flow */ ! 2700: ! 2701: { ! 2702: return(edit(1)); /* push command */ ! 2703: } ! 2704: ! 2705: /* iteration handler */ ! 2706: ! 2707: iter() ! 2708: { ! 2709: /* Keywords: macro-programming control-flow parsing:10 loops */ ! 2710: ! 2711: register int c; ! 2712: register char *savptr; ! 2713: ! 2714: MACEXIT; ! 2715: ! 2716: while ((c =Mgetchar()) != MTA({)) { ! 2717: if ((c != ' ') && (c != ' ') && (c != EOL)) { ! 2718: return(error (NORM,50)); ! 2719: } ! 2720: } ! 2721: savptr = inget(); ! 2722: while (edit(0)) { /* test condition */ ! 2723: ! 2724: c = edit(1); /* execute body */ ! 2725: ! 2726: inset(savptr); /* backup */ ! 2727: ! 2728: } ! 2729: pscan(1); /* skip body */ ! 2730: return(c); ! 2731: } ! 2732: ! 2733: /* gparam -- get a parameter and push into the kill stack */ ! 2734: ! 2735: /* with an argument of 1, it takes the parameter in line, with */ ! 2736: /* other arguments, it takes the parameter from the tty, prompting with */ ! 2737: /* the in line parameter4 */ ! 2738: ! 2739: ! 2740: gparam(arg) /* get a parameter */ ! 2741: ! 2742: int arg; /* with 1 arg, from macro text, else from tty */ ! 2743: ! 2744: ! 2745: /* Keywords: macro-programming string-handling:20 string-variables:50 filenames:10 prompting:40 reading:20 killstack:20 */ ! 2746: { ! 2747: char pbuf[128]; ! 2748: register char *pb; ! 2749: register int pbch; ! 2750: ! 2751: MACEXIT; ! 2752: for (pb = pbuf;;) { ! 2753: *pb++ = pbch = Mgetchar(); ! 2754: if (pbch == CTRLQ){ ! 2755: --pb; ! 2756: *pb++ = Mgetchar(); ! 2757: } ! 2758: if ((pbch == EOL)|| (pbch==CTRLZ)) break; ! 2759: if (pb>=(pbuf+128)) pb--; /* Truncate pb */ ! 2760: } ! 2761: *(--pb) = 0; /* pickup prompt message */ ! 2762: return(gpm(arg,pbuf)); /* pickup up parameter */ ! 2763: } ! 2764: ! 2765: /* gkarm -- like gparm, except input is from the kill stack. */ ! 2766: ! 2767: ! 2768: gkarm(arg) ! 2769: ! 2770: /* Keywords: macro-programming string-handling:20 string-variables:50 filenames:10 prompting:40 reading:20 killstack:20 */ ! 2771: int arg; ! 2772: { ! 2773: char *pb; ! 2774: ! 2775: pb = getname(""); /* pick up parameter */ ! 2776: ! 2777: return(gpm(arg,pb)); ! 2778: } ! 2779: ! 2780: ! 2781: gpm(arg,pbuf) ! 2782: register int arg; ! 2783: register char *pbuf; ! 2784: ! 2785: /* Keywords: macro-programming string-handling:20 string-variables:50 filenames:10 prompting:40 reading:20 killstack:20 */ ! 2786: { ! 2787: register char *pb; ! 2788: char pmpt[128]; ! 2789: int pbch; ! 2790: ! 2791: if (arg == 3) { ! 2792: eprintf("%s",pbuf); /* Raw print, shouldn't mung screen */ ! 2793: ! 2794: return(1); ! 2795: } ! 2796: if (arg != 1) { ! 2797: pushin(NULL); ! 2798: if (arg <= 0) { ! 2799: /* single character */ ! 2800: prompt1("%s",pbuf); ! 2801: if (arg < 0) { ! 2802: mgo(nln,ncol); ! 2803: pbch = getchar(); ! 2804: unprompt(); ! 2805: } ! 2806: inpop(); ! 2807: return(pbch); ! 2808: } ! 2809: strcpy(pmpt,pbuf); /* In case prompt is in pbuf already */ ! 2810: pb = getname(pmpt); ! 2811: if (pb == NULL) pb = ""; ! 2812: inpop(); ! 2813: } else pb = pbuf; ! 2814: stkstr(pb); ! 2815: return(lng(pb)); ! 2816: } ! 2817: ! 2818: ! 2819: char * ! 2820: maclook(mp) ! 2821: char *mp; ! 2822: ! 2823: /* Keywords: macro-programming:20 symbol-handling macro-invocation global-variables:50 */ ! 2824: { ! 2825: int hash,ohash; ! 2826: register char *mp1,*mp2; ! 2827: ! 2828: /* now look up macro name */ ! 2829: ! 2830: mp1 = mp; ! 2831: hash = 0; ! 2832: while (*mp1) hash += *mp1++; ! 2833: hash = hash %NMAC; ! 2834: ohash = hash; ! 2835: hash = machash[hash]; ! 2836: while (hash) { ! 2837: for (mp1=mp,mp2= &bbuf[0][hash+3]; *mp1++ == *mp2++; ) { ! 2838: if ((*mp1 == 0) && ((*mp2 == 0)||(*mp2 == ' ')|| (*mp2 == ' '))) { ! 2839: while (*mp2++); ! 2840: return(mp2); ! 2841: } ! 2842: } ! 2843: hash = (bbuf[0][hash]&0377) + (bbuf[0][hash+1] <<8); ! 2844: } ! 2845: return(NULL); ! 2846: } ! 2847: ! 2848: /* macro call by name */ ! 2849: ! 2850: ! 2851: macex(arg,ivchar) ! 2852: ! 2853: int arg; ! 2854: int ivchar; ! 2855: ! 2856: /* Keywords: macro-invocation macro-programming modes:10 reading:40 */ ! 2857: { ! 2858: char mbuf[100]; ! 2859: register char *mp1; ! 2860: register char *mp3; ! 2861: register int c; ! 2862: ! 2863: mp1 = mbuf; ! 2864: if (infrn < 0) { ! 2865: while ((c = Mgetchar()) != EOL) *mp1++ = c; ! 2866: *mp1 = 0; ! 2867: mp3 = mbuf; ! 2868: } else { ! 2869: mp3 = getname ("Macro name? "); ! 2870: } ! 2871: if (mp3 == NULL) return(0); /* aborted */ ! 2872: if (mp1 = maclook(mp3)) { ! 2873: run: return(xmac(mp1-bbuf[0],arg,ivchar)); ! 2874: } else { ! 2875: if (AUTOLOAD && (infrn < 0)) { ! 2876: ! 2877: /* Autoload mode, If an undefined macro is called from a macro, it */ ! 2878: /* tries to load it from a standard library */ ! 2879: ! 2880: char buf[128]; ! 2881: #ifdef PC ! 2882: seprintf (buf,"%s",mp3); ! 2883: #else ! 2884: seprintf(buf,"~EMACS/macros/%s",mp3); ! 2885: #endif ! 2886: stkstr(buf); ! 2887: if (ldmac(-1) &&(mp1 = maclook(mp3))) { ! 2888: loaded: prompt(ECHOL,"Autoloaded %s",buf); ! 2889: goto run; ! 2890: } ! 2891: #ifdef PC ! 2892: seprintf(buf,"c:%s",mp3); ! 2893: #else ! 2894: seprintf(buf,"$EMACS_LIB/%s",mp3); ! 2895: #endif ! 2896: stkstr(buf); ! 2897: if (ldmac(-1) && (mp1 = maclook(mp3))) goto loaded; ! 2898: } ! 2899: error (WARN,51,mp3); ! 2900: return(NULL); ! 2901: } ! 2902: } ! 2903: hook(hookp) ! 2904: int hookp; ! 2905: ! 2906: /* Keywords: macro-programming macro-invoction:50 macro-hooks */ ! 2907: { ! 2908: register int oldhook; ! 2909: int result; ! 2910: char xfnbuf[FNLEN]; ! 2911: ! 2912: strcpy(xfnbuf,fnbuf); /* Preserve temp buffer, in case it's wiped by the macro */ ! 2913: ! 2914: oldhook = hooks[hookp]; ! 2915: hooks[hookp] = 0; /* Prevent recursion */ ! 2916: result = xmac (oldhook,0,0); ! 2917: hooks[hookp] = oldhook; ! 2918: strcpy(fnbuf,xfnbuf); ! 2919: return(result); ! 2920: } ! 2921: /* xmac -- execute a macro */ ! 2922: ! 2923: ! 2924: xmac(macp,arg,ivchar) ! 2925: ! 2926: register int macp; ! 2927: register int arg; ! 2928: int ivchar; ! 2929: { ! 2930: /* Keywords: macro-programming macro-invocation local-variables:60 argument-processing:20 */ ! 2931: ! 2932: int mvars[NMVAR]; /* macro variables */ ! 2933: int *omarg; /* old pointer to mvars */ ! 2934: ! 2935: omarg = marg; ! 2936: marg = mvars; ! 2937: mvars[1]=arg; /* record macro argument */ ! 2938: mvars[0] = ivchar; /* invoking character */ ! 2939: pshmac(macp); ! 2940: if (etrace) putout("Entering macro: %s",hmap(macp)); ! 2941: ! 2942: arg = edit(1); ! 2943: ! 2944: if (etrace) putout ("Exiting macro: %s",hmap(macp)); ! 2945: marg = omarg; ! 2946: inpop(); ! 2947: return(arg); ! 2948: } ! 2949: ! 2950: /* setvar -- set a local variable */ ! 2951: ! 2952: setvar(arg) ! 2953: register int arg; ! 2954: { ! 2955: /* Keywords: assignment macro-programming local-variables */ ! 2956: register int oldvar; ! 2957: ! 2958: if ((arg <NMVAR) && (arg >=0)) { ! 2959: oldvar = marg[arg]; ! 2960: marg[arg] = edit(0); /* set new value */ ! 2961: return(oldvar); ! 2962: } else { ! 2963: beep(); ! 2964: return(0); ! 2965: } ! 2966: } ! 2967: ! 2968: /* getsharg -- get argument from shell command line */ ! 2969: ! 2970: /* with argument of 1, gets one argument and pops. */ ! 2971: /* with other argument, returns argument but does not pop */ ! 2972: ! 2973: /* Value returned is 1 unless there are no more command line options. */ ! 2974: ! 2975: ! 2976: getsharg(arg) ! 2977: int arg; ! 2978: { ! 2979: /* Keywords: argument-processing:10 command-line-processing macro-programming */ ! 2980: extern char **sharg; ! 2981: extern int nsharg; ! 2982: ! 2983: if (nsharg) { ! 2984: ! 2985: stkstr(*sharg); ! 2986: if (arg==1) { ! 2987: nsharg--; ! 2988: sharg++; ! 2989: } ! 2990: return(1); ! 2991: } ! 2992: return(0); ! 2993: } ! 2994: ! 2995: ! 2996: ! 2997: /* string operations */ ! 2998: ! 2999: /* compares same argument conventions as other comparisons */ ! 3000: ! 3001: #define CAPP 7 /* Arg 2 appended to arg1 */ ! 3002: #define CINDEX 8 /* index of arg 2 in arg1 */ ! 3003: #define SBINARY 8 ! 3004: #define CSUBSTR 9 /* string indexed by next 2 commands */ ! 3005: #define CLENGTH 10 /* String length */ ! 3006: #define SUNARY 10 ! 3007: #define CPTR 11 ! 3008: #define CSTRING 12 ! 3009: #define CPRINTF 13 /* formatted I/O */ ! 3010: ! 3011: cmpst(arg) ! 3012: ! 3013: register int arg; ! 3014: ! 3015: /* Keywords: macro-programming comparison string-variables string-handling:30 conversions:20 */ ! 3016: { ! 3017: char buf[256]; ! 3018: ! 3019: register char *bp1; ! 3020: register char *bp2; ! 3021: char *bp3; ! 3022: int i,j; ! 3023: ! 3024: if (arg <= SUNARY)bp1 = getname(""); /* get first string */ ! 3025: ! 3026: if (arg <= SBINARY) { ! 3027: strcpy(buf,bp1); ! 3028: bp1 = buf; ! 3029: bp2 = getname(""); ! 3030: } ! 3031: ! 3032: if (arg <= CGE) { ! 3033: while ((*bp1 == *bp2) && *bp1) { ! 3034: bp1++; ! 3035: bp2++; ! 3036: } ! 3037: } ! 3038: switch (arg) { ! 3039: ! 3040: case CLE: return(*bp1<=*bp2); ! 3041: case CEQ: return(*bp1==*bp2); ! 3042: case CLS: return(*bp1<*bp2); ! 3043: case CGT: return(*bp1>*bp2); ! 3044: case CNE: return(*bp1!=*bp2); ! 3045: case CGE: return(*bp1>=*bp2); ! 3046: case CAPP: ! 3047: strcpy(bp2+lng(bp2),bp1); ! 3048: stkstr(bp2); ! 3049: return(1); ! 3050: case CINDEX: ! 3051: i = 0; ! 3052: bp3 = bp2; ! 3053: while (*(bp2=bp3+i)) { ! 3054: bp1 = buf; ! 3055: while (*bp1++ == *bp2++) { ! 3056: if (*bp1 == 0) return(i); ! 3057: } ! 3058: i++; ! 3059: } ! 3060: return(-1); ! 3061: case CSUBSTR: ! 3062: i = edit(0); ! 3063: j = edit(0); ! 3064: bp1[j]=0; ! 3065: stkstr(bp1+i); ! 3066: return(1); ! 3067: case CLENGTH: return(lng(bp1)); ! 3068: case CPTR: return(kgptr()); ! 3069: case CSTRING: ! 3070: i = edit(0); ! 3071: kput(i); ! 3072: return(1); ! 3073: case CPRINTF: ! 3074: /* Printf like formatting. */ ! 3075: { ! 3076: int pts[20],len; ! 3077: char buf2[256]; ! 3078: bp1=bp2=getname(""); /* Format string */ ! 3079: ! 3080: /* First, collect all of the parameters */ ! 3081: ! 3082: i = 0; ! 3083: while(*bp1) { ! 3084: if (bp1[0] == '%') { ! 3085: if (bp1[1] == '%') bp1++; ! 3086: else pts[i++] = kgptr(); /* Collect one */ ! 3087: } ! 3088: bp1++; ! 3089: } ! 3090: strcpy(buf2,bp2); ! 3091: bp2 = buf2; ! 3092: bp1 = buf; ! 3093: while (*bp2) { ! 3094: if (*bp2 == '%') { ! 3095: bp2 = nscan(bp2+1,&j); ! 3096: if (*bp2 == '%') { ! 3097: *bp1++ = *bp2++; ! 3098: continue; ! 3099: } ! 3100: kput(pts[--i]); ! 3101: bp3 = getname(""); /* get the param */ ! 3102: len = lng(bp3); ! 3103: ! 3104: switch(*bp2++) { ! 3105: ! 3106: case 'l': bp1 = mstrcpy(bp1,bp3); ! 3107: j = j-len; ! 3108: if (j>0) while (j--) *bp1++ = ' '; ! 3109: break; ! 3110: case 'r': ! 3111: j = j-len; ! 3112: if (j>0) while (j--) *bp1++ = ' '; ! 3113: bp1 = mstrcpy(bp1,bp3); ! 3114: break; ! 3115: case 'c': ! 3116: len = (j-len); ! 3117: if (len>= 0) { ! 3118: j = len/2; ! 3119: len = len-j; ! 3120: while (j--) *bp1++ = ' '; ! 3121: } ! 3122: bp1 = mstrcpy(bp1,bp3); ! 3123: if (len> 0) while (len--) *bp1++ = ' '; ! 3124: break; ! 3125: } ! 3126: } else *bp1++ = *bp2++; ! 3127: } ! 3128: *bp1 = 0; ! 3129: stkstr(buf); ! 3130: return(1); ! 3131: } ! 3132: default: return(0); ! 3133: } ! 3134: } ! 3135: ! 3136: ! 3137: /* Global variable -- global variables are dynamically bound by ! 3138: * names. They are 2 or 4 bytes long and always stored in order of ! 3139: * lsB first. */ ! 3140: ! 3141: glob(arg) ! 3142: int arg; ! 3143: { ! 3144: /* Keywords: global-variables assignment:50 macro-programming */ ! 3145: int size; ! 3146: char *name; ! 3147: char *where; ! 3148: int hash; ! 3149: ! 3150: ! 3151: if (name= getname ("Global variable name? ")) { ! 3152: if ((where = maclook(name)) == NULL) { ! 3153: if (arg == 0) return(0); ! 3154: where = name; ! 3155: hash = 0; ! 3156: while (*where) hash += *where++; ! 3157: hash = hash %NMAC; ! 3158: pshchr(machash[hash]); ! 3159: pshchr(machash[hash]>>8); ! 3160: machash[hash] = macptr-2; ! 3161: where = name; ! 3162: pshchr(0); ! 3163: while (*where) pshchr(*where++); ! 3164: pshchr(0); ! 3165: for (size=0; size<sizeof(size); size++) pshchr(0); ! 3166: where = maclook(name); ! 3167: } ! 3168: switch(arg) { ! 3169: ! 3170: case 0: ! 3171: return(1); ! 3172: break; ! 3173: case 1: ! 3174: hash = 0; ! 3175: for (size=0; size<sizeof(size); size++) { ! 3176: hash+= ((*where++)&0377) << (size*8); ! 3177: } ! 3178: return(hash); ! 3179: case 2: ! 3180: hash = edit(0); ! 3181: for (size=0; size<sizeof(size); size++) { ! 3182: *where++ = hash; ! 3183: hash = hash >>8; ! 3184: } ! 3185: break; ! 3186: } ! 3187: } ! 3188: return(0); ! 3189: } ! 3190: /* envexp -- expand environment variables in a string */ ! 3191: ! 3192: /* expansion takes place in the caller's string buffer */ ! 3193: /* pointer is returned for convenience only */ ! 3194: ! 3195: char *pwpath = "/etc/passwd"; ! 3196: ! 3197: char * ! 3198: expenv(str) ! 3199: register char *str; ! 3200: /* Keywords: environment-variables unix-interface user-interface:20 shell-escape:10 */ ! 3201: { ! 3202: char strtemp[128]; ! 3203: char vartemp [64]; ! 3204: register char *cp1; ! 3205: char *cp2; ! 3206: register int c; ! 3207: int oc; ! 3208: ! 3209: if (str == NULL) return(NULL); ! 3210: ! 3211: cp1 = strtemp; ! 3212: cp2 = str; ! 3213: while (*cp1++ = *str) { ! 3214: if ((*str== '`')||(*str=='*')||(*str=='{')||(*str=='[')||((*str++)=='?')) { ! 3215: seprintf(strtemp,"exec echo %s",cp2); ! 3216: unx(strtemp,4); /* expand through the shell */ ! 3217: return(fnbuf); ! 3218: } ! 3219: } ! 3220: cp1 = strtemp; ! 3221: str = fnbuf; /* always copy back into file name */ ! 3222: while (c = *cp1++) { ! 3223: if ((c == '$') || (c == '~')) { ! 3224: ! 3225: /* Environment variable or `logdir` */ ! 3226: ! 3227: oc = c; ! 3228: cp2 = vartemp; ! 3229: while (bits[c=((*cp1++)&0377)]&WRDCHR) { ! 3230: *cp2++ = c; ! 3231: } ! 3232: cp1--; /* backspace pointer */ ! 3233: *cp2 = 0; ! 3234: if (oc == '$') { ! 3235: cp2 = getenv(vartemp); /* environment variable */ ! 3236: } else { ! 3237: #ifndef PC ! 3238: /* Home Directory */ ! 3239: ! 3240: if (*vartemp == 0) { ! 3241: cp2 = getenv("HOME"); /* Bare ~ means home */ ! 3242: } else if (streq(vartemp,"EMACS")) { ! 3243: cp2 = em_dir; ! 3244: } else if (streq(vartemp,"exptools") && ! 3245: (cp2 = getenv("TOOLS")) && *cp2) { ! 3246: ; ! 3247: } else { ! 3248: FILE pwfile[1]; ! 3249: FILE *pwptr; ! 3250: char *vp; ! 3251: ! 3252: cp2 = NULL; ! 3253: pwptr = xopen(pwfile,pwpath,"r"); ! 3254: if (pwptr) { ! 3255: while ((c = getc(pwptr))!= EOF) { ! 3256: if (c == '\n') { ! 3257: vp = vartemp; ! 3258: /* Try to match the specified user ID */ ! 3259: while (*vp++ == (c = getc(pwptr))); ! 3260: if ((vp[-1] == 0) && (c == ':')) { ! 3261: /* Found it, now skip 4 colons, and copy next field into vartemp; */ ! 3262: c = 0; ! 3263: while (c < 4) if (getc(pwptr) == ':') c++; ! 3264: cp2 = vartemp; ! 3265: while ((c = getc(pwptr)) != ':') *cp2++=c; ! 3266: *cp2++=0; ! 3267: cp2=vartemp; ! 3268: break; /* Break out of password scan */ ! 3269: } ! 3270: } ! 3271: } ! 3272: mclose(pwptr); ! 3273: } else error(WARN,errno,pwpath); ! 3274: } ! 3275: #endif PC ! 3276: } ! 3277: if (cp2 != NULL) { ! 3278: str = mstrcpy(str,cp2); ! 3279: } else { ! 3280: *str++ = oc; ! 3281: str = mstrcpy(str,vartemp); ! 3282: } ! 3283: } else { ! 3284: *str++ = c; ! 3285: } ! 3286: } ! 3287: *str++ = 0; ! 3288: return(fnbuf); ! 3289: } ! 3290: /* ! 3291: * envget takes a string and expands it into the string ! 3292: * stored in the shell variable by the same name. ! 3293: * If the shell variable did not exist, then envget ! 3294: * returns NULL. ! 3295: */ ! 3296: ! 3297: envget() ! 3298: /* Keywords: commands environment-variables */ ! 3299: ! 3300: { ! 3301: char * ptr; ! 3302: ! 3303: if (ptr = getenv(getname("Environment variable: "))) { ! 3304: stkstr(ptr); ! 3305: return(1); ! 3306: } ! 3307: else { ! 3308: stkstr(""); ! 3309: return(0); ! 3310: } ! 3311: } ! 3312: ! 3313: stopjob () ! 3314: { ! 3315: char x; ! 3316: clear(); ! 3317: cook(); ! 3318: #if (defined (bsd) || defined (v8)) ! 3319: kill(mypid,SIGSTOP); ! 3320: #else ! 3321: eprintf ("Type ^Z to suspend emacs and <return> to continue"); ! 3322: read(0,&x,1); ! 3323: #endif ! 3324: uncook(); ! 3325: clear(); ! 3326: } ! 3327: ! 3328: #ifdef u370 ! 3329: beepbeep() ! 3330: { ! 3331: extern int beep(); ! 3332: } ! 3333: #endif ! 3334:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.