Annotation of researchv9/cmd/emacs/emacs_cmds.c, revision 1.1

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: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.