Annotation of 43BSD/contrib/B/src/bed/demo.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
                      2: static char rcsid[] = "$Header: demo.c,v 2.6 85/08/22 16:01:21 timo Exp $";
                      3: 
                      4: /*
                      5:  * B editor -- Editor command processor.
                      6:  */
                      7: 
                      8: #include <ctype.h>
                      9: 
                     10: #include "b.h"
                     11: #include "feat.h"
                     12: #include "erro.h"
                     13: #include "bobj.h"
                     14: #include "node.h"
                     15: #include "gram.h"
                     16: #include "keys.h"
                     17: #include "supr.h"
                     18: 
                     19: #ifdef BTOP
                     20: #include <setjmp.h>
                     21: 
                     22: #ifndef CMDPROMPT
                     23: #define CMDPROMPT ">>> " /* Prompt user for immediate command */
                     24: #endif CMDPROMPT
                     25: #endif BTOP
                     26: 
                     27: 
                     28: value editqueue();
                     29: 
                     30: /* Command line flags */
                     31: extern bool dflag;
                     32: extern bool slowterminal;
                     33: 
                     34: #ifdef SAVEBUF
                     35: extern char copysavefile[];
                     36: #endif SAVEBUF
                     37: 
                     38: 
                     39: Visible bool lefttorite;
                     40:        /* Saves some time in nosuggtoqueue() for read from file */
                     41: 
                     42: #define MAXHIST 101 /* One more than the number of UNDO's allowed. */
                     43: 
                     44: #define Mod(k) (((k)+MAXHIST) % MAXHIST)
                     45: #define Succ(k) (((k)+1) % MAXHIST)
                     46: #define Pred(k) (((k)+MAXHIST-1) % MAXHIST)
                     47: 
                     48: Hidden environ *tobesaved;
                     49: Hidden string savewhere;
                     50: 
                     51: 
                     52: #ifdef BTOP
                     53: 
                     54: extern jmp_buf jumpback;
                     55: extern bool interrupted;
                     56: extern bool canjump;
                     57: 
                     58: /*
                     59:  * Main loop, called from main program if -t option present.
                     60:  */
                     61: 
                     62: Visible Procedure
                     63: mainloop()
                     64: {
                     65:        environ env;
                     66:        environ *ep = &env;
                     67:        FILE *pdown;
                     68:        FILE *pup;
                     69:        int cmdchar;
                     70: 
                     71:        savewhere = (string)NULL;
                     72:        tobesaved = (environ*)NULL;
                     73:        start_b(&pdown, &pup);
                     74:        clrenv(ep);
                     75: #ifdef SAVEBUF
                     76:        ep->copybuffer = editqueue(copysavefile);
                     77:        if (ep->copybuffer)
                     78:                ep->copyflag = Yes;
                     79: #endif SAVEBUF
                     80: 
                     81:        for (;;) {
                     82:                cmdchar = sleur();
                     83:                if (cmdchar == EOF)
                     84:                        break;
                     85:                getinput(ep, cmdchar, pdown, pup);
                     86:        }
                     87: #ifdef SAVEBUF
                     88:        if (ep->copyflag)
                     89:                savequeue(ep->copybuffer, copysavefile);
                     90:        else
                     91:                savequeue(Vnil, copysavefile);
                     92: #endif SAVEBUF
                     93:        Erelease(*ep);
                     94: }
                     95: 
                     96: 
                     97: /*
                     98:  * Provide input for the interpreter.
                     99:  */
                    100: 
                    101: Hidden Procedure
                    102: getinput(ep, cmdchar, pdown, pup)
                    103:        environ *ep;
                    104:        int cmdchar;
                    105:        FILE *pdown;
                    106:        FILE *pup;
                    107: {
                    108:        int n;
                    109:        char buffer[100];
                    110:        char filename[100];
                    111:        int lineno;
                    112: 
                    113: 
                    114:        switch (cmdchar) {
                    115: 
                    116:        case '>': /* Immediate command */
                    117:        case 'E': /* Expression */
                    118:        case 'R': /* Raw input */
                    119:        case 'Y': /* Yes/No */
                    120:                if (cmdchar == '>')
                    121:                        setroot("Imm_cmd");
                    122:                else if (cmdchar == 'E')
                    123:                        setroot("Expression");
                    124:                else
                    125:                        setroot("Raw_input");
                    126:                delfocus(&ep->focus);
                    127:                initshow();
                    128:                if (cmdchar == '>')
                    129:                        cmdprompt(CMDPROMPT);
                    130:                editdocument(ep);
                    131:                endshow();
                    132:                top(&ep->focus);
                    133:                ep->mode = WHOLE;
                    134:                if (!interrupted)
                    135:                        send(ep->focus, pdown);
                    136:                delete(ep);
                    137:                break;
                    138: 
                    139:        case ':':
                    140:        case '=':
                    141:                fgets(buffer, sizeof buffer, pup);
                    142:                if (index(buffer, '+'))
                    143:                        n = sscanf(buffer, " +%d %s", &lineno, filename) - 1;
                    144:                else {
                    145:                        n = sscanf(buffer, " %s", filename);
                    146:                        lineno = 0;
                    147:                }
                    148:                if (n == 1) {
                    149:                        initshow();
                    150:                        dofile(ep, filename, lineno);
                    151:                        endshow();
                    152:                        top(&ep->focus);
                    153:                        ep->mode = WHOLE;
                    154:                        delete(ep);
                    155:                        if (!ep->copyflag) {
                    156:                                release(ep->copybuffer);
                    157:                                ep->copybuffer = Vnil;
                    158:                        }
                    159:                }
                    160:                putc('\n', pdown);
                    161:                interrupted = No; /* Interrupts handled locally in editdocument! */
                    162:                break;
                    163: 
                    164:        default:
                    165:                printf("[Unrecognized command character '%c' (0%o)]\n",
                    166:                        cmdchar&0177, cmdchar);
                    167: 
                    168:        }
                    169: }
                    170: 
                    171: #endif BTOP
                    172: 
                    173: 
                    174: #ifdef FILEARGS
                    175: 
                    176: /*
                    177:  * Edit a single unit or target, called from main program if file name
                    178:  * arguments are present.
                    179:  */
                    180: 
                    181: Visible Procedure
                    182: demo(filename, linenumber)
                    183:        string filename;
                    184:        int linenumber;
                    185: {
                    186:        environ env;
                    187:        environ *ep = &env;
                    188:        bool ok;
                    189: 
                    190:        clrenv(ep);
                    191: #ifdef SAVEBUF
                    192:        ep->copybuffer = editqueue(copysavefile);
                    193:        if (ep->copybuffer)
                    194:                ep->copyflag = Yes;
                    195: #endif SAVEBUF
                    196:        initshow();
                    197:        ok = dofile(ep, filename, linenumber);
                    198:        endshow();
                    199:        if (!ok)
                    200:                return No;
                    201: #ifdef SAVEBUF
                    202:        if (ep->copyflag)
                    203:                savequeue(ep->copybuffer, copysavefile);
                    204:        else
                    205:                savequeue(Vnil, copysavefile);
                    206: #endif SAVEBUF
                    207:        Erelease(*ep);
                    208:        return Yes;
                    209: }
                    210: 
                    211: #endif !FILEARGS
                    212: 
                    213: 
                    214: /*
                    215:  * Edit a unit or target, using the environment offered as a parameter.
                    216:  */
                    217: 
                    218: Hidden bool
                    219: dofile(ep, filename, linenumber)
                    220:        environ *ep;
                    221:        string filename;
                    222:        int linenumber;
                    223: {
                    224: #ifdef HELPFUL
                    225:        static bool didmessage;
                    226: 
                    227:        if (!didmessage) {
                    228:                didmessage = Yes;
                    229:                message("[Press ? or ESC-? for help]");
                    230:        }
                    231: #endif HELPFUL
                    232: #ifdef SAVEPOS
                    233:        if (linenumber <= 0)
                    234:                linenumber = getpos(filename);
                    235: #endif SAVEPOS
                    236:        setroot(filename[0] == '=' ? "Target_edit" : "Unit_edit");
                    237:        savewhere = filename;
                    238:        tobesaved = (environ*)NULL;
                    239: 
                    240:        lefttorite = Yes;
                    241:        edit(ep, filename, linenumber);
                    242: #ifdef USERSUGG
                    243:        readsugg(ep->focus);
                    244: #endif USERSUGG
                    245:        lefttorite = No;
                    246: 
                    247:        ep->generation = 0;
                    248:        if (!editdocument(ep))
                    249:                return No;
                    250:        if (ep->generation > 0) {
                    251:                if (!save(ep->focus, filename))
                    252:                        error("Cannot save unit: %s", unixerror(filename));
                    253: #ifdef USERSUGG
                    254:                writesugg(ep->focus);
                    255: #endif USERSUGG
                    256:        }
                    257: #ifdef SAVEPOS
                    258:        savepos(filename, lineno(ep)+1);
                    259: #endif SAVEPOS
                    260:        savewhere = (char*)NULL;
                    261:        tobesaved = (environ*)NULL;
                    262:        return Yes;
                    263: }
                    264: 
                    265: 
                    266: /*
                    267:  * Call the editor for a given document.
                    268:  */
                    269: 
                    270: Hidden bool
                    271: editdocument(ep)
                    272:        environ *ep;
                    273: {
                    274:        int k;
                    275:        int first = 0;
                    276:        int last = 0;
                    277:        int current = 0;
                    278:        int onscreen = -1;
                    279:        bool reverse = No;
                    280:        environ newenv;
                    281:        int cmd;
                    282:        bool errors = No;
                    283:        int undoage = 0;
                    284:        bool done = No;
                    285:        environ history[MAXHIST];
                    286: 
                    287:        Ecopy(*ep, history[0]);
                    288: 
                    289:        for (;;) { /* Command interpretation loop */
                    290:                if (onscreen != current)
                    291:                        virtupdate(onscreen < 0 ? (environ*)NULL : &history[onscreen],
                    292:                                &history[current],
                    293:                                reverse && onscreen >= 0 ?
                    294:                                        history[onscreen].highest : history[current].highest);
                    295:                onscreen = current;
                    296:                if (done)
                    297:                        break;
                    298: #ifdef BTOP
                    299:                if (!interrupted && !moreinput())
                    300: #else BTOP
                    301:                if (!moreinput())
                    302: #endif BTOP
                    303:                                actupdate(history[current].copyflag ?
                    304:                                                history[current].copybuffer : Vnil,
                    305: #ifdef RECORDING
                    306:                                        history[current].newmacro != Vnil,
                    307: #else !RECORDING
                    308:                                        No,
                    309: #endif !RECORDING
                    310:                                        No);
                    311: #ifdef BTOP
                    312:                if (interrupted || setjmp(jumpback))
                    313:                        break;
                    314:                canjump = Yes;
                    315: #endif BTOP
                    316:                cmd = inchar();
                    317: #ifdef BTOP
                    318:                canjump = No;
                    319: #endif BTOP
                    320:                errors = No;
                    321: 
                    322:                switch (cmd) {
                    323: 
                    324: #ifndef NDEBUG
                    325:                case Ctl(@): /* Debug exit with variable dump */
                    326:                        tobesaved = (environ*)NULL;
                    327:                        return No;
                    328: #endif NDEBUG
                    329: 
                    330: #ifndef SMALLSYS
                    331:                case Ctl(^): /* Debug status message */
                    332:                        dbmess(&history[current]);
                    333:                        errors = Yes; /* Causes clear after new keystroke seen */
                    334:                        continue;
                    335: #endif !SMALLSYS
                    336: 
                    337:                case UNDO:
                    338:                        if (current == first)
                    339:                                errors = Yes;
                    340:                        else {
                    341:                                if (onscreen == current)
                    342:                                        reverse = Yes;
                    343:                                current = Pred(current);
                    344:                                undoage = Mod(last-current);
                    345:                        }
                    346:                        break;
                    347: 
                    348:                case REDO:
                    349:                        if (current == last)
                    350:                                errors = Yes;
                    351:                        else {
                    352:                                if (current == onscreen)
                    353:                                        reverse = No;
                    354:                                if (history[Succ(current)].generation <
                    355:                                                history[current].generation)
                    356:                                        error(REDO_OLD); /***** Should refuse altogether??? *****/
                    357:                                current = Succ(current);
                    358:                                undoage = Mod(last-current);
                    359:                        }
                    360:                        break;
                    361: 
                    362: #ifdef HELPFUL
                    363:                case HELP:
                    364:                        if (help())
                    365:                                onscreen = -1;
                    366:                        break;
                    367: #endif HELPFUL
                    368: 
                    369:                case REDRAW:
                    370:                        onscreen = -1;
                    371:                        trmundefined();
                    372:                        break;
                    373: 
                    374:                case EOF:
                    375:                        done = Yes;
                    376:                        break;
                    377: 
                    378:                default:
                    379:                        Ecopy(history[current], newenv);
                    380:                        newenv.highest = Maxintlet;
                    381:                        newenv.changed = No;
                    382:                        if (cmd != EXIT)
                    383:                                errors = !execute(&newenv, cmd) || !checkep(&newenv);
                    384:                        else
                    385:                                done = Yes;
                    386:                        if (errors) {
                    387:                                switch (cmd) {
                    388:                                case '\r':
                    389:                                case '\n':
                    390:                                        if (newenv.mode == ATEND && !parent(newenv.focus)) {
                    391:                                                errors = !checkep(&newenv);
                    392:                                                if (!errors)
                    393:                                                        done = Yes;
                    394:                                        }
                    395:                                        break;
                    396: #ifdef HELPFUL
                    397:                                case '?':
                    398:                                        if (help())
                    399:                                                onscreen = -1;
                    400: #endif HELPFUL
                    401:                                }
                    402:                        }
                    403:                        if (errors)
                    404:                                Erelease(newenv);
                    405:                        else {
                    406: #ifndef SMALLSYS
                    407:                                if (done)
                    408:                                        done = canexit(&newenv);
                    409: #endif SMALLSYS
                    410:                                if (newenv.changed)
                    411:                                        ++newenv.generation;
                    412:                                last = Succ(last);
                    413:                                current = Succ(current);
                    414:                                if (last == first) {
                    415:                                        /* Array full (always after a while). Discard "oldest". */
                    416:                                        if (current == last
                    417:                                                || undoage < Mod(current-first)) {
                    418:                                                Erelease(history[first]);
                    419:                                                first = Succ(first);
                    420:                                                if (undoage < MAXHIST)
                    421:                                                        ++undoage;
                    422:                                        }
                    423:                                        else {
                    424:                                                last = Pred(last);
                    425:                                                Erelease(history[last]);
                    426:                                        }
                    427:                                }
                    428:                                if (current != last
                    429:                                        && newenv.highest < history[current].highest)
                    430:                                        history[current].highest = newenv.highest;
                    431:                                /* Move entries beyond current one up. */
                    432:                                for (k = last; k != current; k = Pred(k)) {
                    433:                                        if (Pred(k) == onscreen)
                    434:                                                onscreen = k;
                    435:                                        Emove(history[Pred(k)], history[k]);
                    436:                                }
                    437:                                Ecopy(newenv, history[current]);
                    438:                                Erelease(history[current]);
                    439:                        }
                    440:                        break; /* default */
                    441: 
                    442:                } /* switch */
                    443: 
                    444:                if (errors && cmd != '?') {
                    445:                        if (!slowterminal && isascii(cmd)
                    446:                                && (isprint(cmd) || cmd == ' '))
                    447:                                error(INS_BAD, cmd);
                    448:                        else
                    449:                                error((char*)NULL);
                    450:                }
                    451:                if (savewhere)
                    452:                        tobesaved = &history[current];
                    453:        } /* for (;;) */
                    454: 
                    455:        actupdate(Vnil, No, Yes);
                    456:        Erelease(*ep);
                    457:        Ecopy(history[current], *ep);
                    458:        if (savewhere)
                    459:                tobesaved = ep;
                    460:        for (current = first; current != last; current = Succ(current))
                    461:                Erelease(history[current]);
                    462:        Erelease(history[last]);
                    463:        /* endshow(); */
                    464:        return Yes;
                    465: }
                    466: 
                    467: 
                    468: /*
                    469:  * Execute a command, return success or failure.
                    470:  */
                    471: 
                    472: Hidden bool
                    473: execute(ep, cmd)
                    474:        register environ *ep;
                    475:        register int cmd;
                    476: {
                    477:        register bool spflag = ep->spflag;
                    478:        register int i;
                    479:        environ env;
                    480:        char buf[2];
                    481:        register char *cp;
                    482: #ifdef USERSUGG
                    483:        bool sugg = symbol(tree(ep->focus)) == Suggestion;
                    484: #define ACCSUGG(ep) if (sugg) accsugg(ep)
                    485: #define KILLSUGG(ep) if (sugg) killsugg(ep)
                    486: #else !USERSUGG
                    487: #define ACCSUGG(ep) /* NULL */
                    488: #define KILLSUGG(ep) /* NULL */
                    489: #endif !USERSUGG
                    490: 
                    491: #ifdef RECORDING
                    492:        if (ep->newmacro && cmd != USEMACRO && cmd != SAVEMACRO) {
                    493:                buf[0] = cmd;
                    494:                buf[1] = 0;
                    495:                concato(&ep->newmacro, buf);
                    496:        }
                    497: #endif RECORDING
                    498:        ep->spflag = No;
                    499: 
                    500:        switch (cmd) {
                    501: 
                    502: #ifdef RECORDING
                    503:        case SAVEMACRO:
                    504:                ep->spflag = spflag;
                    505:                if (ep->newmacro) { /* End definition */
                    506:                        release(ep->oldmacro);
                    507:                        if (ep->newmacro && Length(ep->newmacro) > 0) {
                    508:                                ep->oldmacro = ep->newmacro;
                    509:                                message(REC_OK);
                    510:                        }
                    511:                        else {
                    512:                                release(ep->newmacro);
                    513:                                ep->oldmacro = Vnil;
                    514:                        }
                    515:                        ep->newmacro = Vnil;
                    516:                }
                    517:                else /* Start definition */
                    518:                        ep->newmacro = mk_text("");
                    519:                return Yes;
                    520: 
                    521:        case USEMACRO:
                    522:                if (!ep->oldmacro || Length(ep->oldmacro) <= 0) {
                    523:                        error(PLB_NOK);
                    524:                        return No;
                    525:                }
                    526:                ep->spflag = spflag;
                    527:                cp = Str(ep->oldmacro);
                    528:                for (i = 0; i < Length(ep->oldmacro); ++i) {
                    529:                        Ecopy(*ep, env);
                    530:                        if (execute(ep, cp[i]&0377) && checkep(ep))
                    531:                                Erelease(env);
                    532:                        else {
                    533:                                Erelease(*ep);
                    534:                                Emove(env, *ep);
                    535:                                if (!i)
                    536:                                        return No;
                    537:                                error((char*)NULL); /* Just a bell */
                    538:                                /* The error must be signalled here, because the overall
                    539:                                   command (USEMACRO) succeeds, so the main loop
                    540:                                   doesn't ring the bell; but we want to inform the
                    541:                                   that not everything was done either. */
                    542:                                return Yes;
                    543:                        }
                    544:                }
                    545:                return Yes;
                    546: #endif RECORDING
                    547: 
                    548: #ifndef SMALLSYS
                    549:        case Ctl(_): /* 'Touch', i.e. set modified flag */
                    550:                ep->changed = Yes;
                    551:                return Yes;
                    552: #endif SMALLSYS
                    553: 
                    554:        case GOTO:
                    555:                ACCSUGG(ep);
                    556: #ifdef RECORDING
                    557:                if (ep->newmacro) {
                    558:                        error(GOTO_REC);
                    559:                        return No;
                    560:                }
                    561: #endif RECORDING
                    562:                return gotocursor(ep);
                    563: 
                    564:        case NEXT:
                    565:                ACCSUGG(ep);
                    566:                return next(ep);
                    567: 
                    568:        case PREVIOUS:
                    569:                ACCSUGG(ep);
                    570:                return previous(ep);
                    571: 
                    572:        case LEFTARROW:
                    573:                ACCSUGG(ep);
                    574:                return leftarrow(ep);
                    575: 
                    576:        case RITEARROW:
                    577:                ACCSUGG(ep);
                    578:                return ritearrow(ep);
                    579: 
                    580:        case WIDEN:
                    581:                ACCSUGG(ep);
                    582:                return widen(ep);
                    583: 
                    584:        case EXTEND:
                    585:                ACCSUGG(ep);
                    586:                return extend(ep);
                    587: 
                    588:        case NARROW:
                    589:                ACCSUGG(ep);
                    590:                return narrow(ep);
                    591: 
                    592:        case RNARROW:
                    593:                ACCSUGG(ep);
                    594:                return rnarrow(ep);
                    595: 
                    596:        case UPARROW:
                    597:                ACCSUGG(ep);
                    598:                return uparrow(ep);
                    599: 
                    600:        case DOWNARROW:
                    601:                ACCSUGG(ep);
                    602:                return downarrow(ep);
                    603: 
                    604:        case UPLINE:
                    605:                ACCSUGG(ep);
                    606:                return upline(ep);
                    607: 
                    608:        case DOWNLINE:
                    609:                ACCSUGG(ep);
                    610:                return downline(ep);
                    611: 
                    612:        case COPY:
                    613:                ACCSUGG(ep);
                    614:                ep->spflag = spflag;
                    615:                return copyinout(ep);
                    616: 
                    617:        case DELETE:
                    618:                ACCSUGG(ep);
                    619:                return delete(ep);
                    620: 
                    621:        case ACCEPT:
                    622:                ACCSUGG(ep);
                    623:                return accept(ep);
                    624: 
                    625:        default:
                    626:                if (!isascii(cmd) || !isprint(cmd))
                    627:                        return No;
                    628:                ep->spflag = spflag;
                    629:                return ins_char(ep, cmd, islower(cmd) ? toupper(cmd) : -1);
                    630: 
                    631:        case ' ':
                    632:                ep->spflag = spflag;
                    633:                return ins_char(ep, ' ', -1);
                    634: 
                    635:        case RETURN:
                    636:        case NEWLINE:
                    637:                KILLSUGG(ep);
                    638:                return ins_newline(ep);
                    639:        }
                    640: }
                    641: 
                    642: 
                    643: /*
                    644:  * Initialize an environment variable.  Most things are set to 0 or NULL.
                    645:  */
                    646: 
                    647: Hidden Procedure
                    648: clrenv(ep)
                    649:        environ *ep;
                    650: {
                    651:        ep->focus = newpath(Pnil, gram(Optional), 1);
                    652:        ep->mode = WHOLE;
                    653:        ep->copyflag = ep->spflag = ep->changed = No;
                    654:        ep->s1 = ep->s2 = ep->s3 = 0;
                    655:        ep->highest = Maxintlet;
                    656:        ep->copybuffer = Vnil;
                    657: #ifdef RECORDING
                    658:        ep->oldmacro = ep->newmacro = Vnil;
                    659: #endif RECORDING
                    660:        ep->generation = 0;
                    661:        ep->changed = No;
                    662: }
                    663: 
                    664: 
                    665: /*
                    666:  * Save parse tree and copy buffer.
                    667:  */
                    668: 
                    669: Visible Procedure
                    670: enddemo()
                    671: {
                    672:        register environ *ep = tobesaved;
                    673: 
                    674:        tobesaved = (environ*)NULL;
                    675:                /* To avoid loops if saving is interrupted. */
                    676:        if (savewhere && ep) {
                    677:                if (ep->generation > 0) {
                    678:                        save(ep->focus, savewhere);
                    679: #ifdef USERSUGG
                    680:                        writesugg(ep->focus);
                    681: #endif USERSUGG
                    682:                }
                    683: #ifdef SAVEBUF
                    684:                if (ep->copyflag)
                    685:                        savequeue(ep->copybuffer, copysavefile);
                    686:                else
                    687:                        savequeue(Vnil, copysavefile);
                    688: #endif SAVEBUF
                    689: #ifdef SAVEPOS
                    690:                savepos(savewhere, lineno(ep)+1);
                    691: #endif SAVEPOS
                    692:        }
                    693: #ifdef BTOP
                    694:        waitchild();
                    695: #endif BTOP
                    696: }
                    697: 
                    698: 
                    699: /*
                    700:  * Find out if the current position is higher in the tree
                    701:  * than `ever' before (as remembered in ep->highest).
                    702:  * The algorithm of pathlength() is repeated here to gain
                    703:  * some efficiency by stopping as soon as it is clear
                    704:  * no change can occur.
                    705:  * (Higher() is called VERY often, so this pays).
                    706:  */
                    707: 
                    708: Visible Procedure
                    709: higher(ep)
                    710:        register environ *ep;
                    711: {
                    712:        register path p = ep->focus;
                    713:        register int pl = 0;
                    714:        register int max = ep->highest;
                    715: 
                    716:        while (p) {
                    717:                ++pl;
                    718:                if (pl >= max)
                    719:                        return;
                    720:                p = parent(p);
                    721:        }
                    722:        ep->highest = pl;
                    723: }
                    724: 
                    725: 
                    726: /*
                    727:  * Issue debug status message.
                    728:  */
                    729: 
                    730: Visible Procedure
                    731: dbmess(ep)
                    732:        register environ *ep;
                    733: {
                    734: #ifndef SMALLSYS
                    735:        char stuff[80];
                    736:        register string str = stuff;
                    737: 
                    738:        switch (ep->mode) {
                    739:        case VHOLE:
                    740:                sprintf(stuff, "VHOLE:%d.%d", ep->s1, ep->s2);
                    741:                break;
                    742:        case FHOLE:
                    743:                sprintf(stuff, "FHOLE:%d.%d", ep->s1, ep->s2);
                    744:                break;
                    745:        case ATBEGIN:
                    746:                str = "ATBEGIN";
                    747:                break;
                    748:        case ATEND:
                    749:                str = "ATEND";
                    750:                break;
                    751:        case WHOLE:
                    752:                str = "WHOLE";
                    753:                break;
                    754:        case SUBRANGE:
                    755:                sprintf(stuff, "SUBRANGE:%d.%d-%d", ep->s1, ep->s2, ep->s3);
                    756:                break;
                    757:        case SUBSET:
                    758:                sprintf(stuff, "SUBSET:%d-%d", ep->s1, ep->s2);
                    759:                break;
                    760:        case SUBLIST:
                    761:                sprintf(stuff, "SUBLIST...%d", ep->s3);
                    762:                break;
                    763:        default:
                    764:                sprintf(stuff, "UNKNOWN:%d,%d,%d,%d",
                    765:                        ep->mode, ep->s1, ep->s2, ep->s3);
                    766:        }
                    767:        message(
                    768: #ifdef SAVEBUF
                    769:                "%s, %s, wi=%d, hi=%d, (y,x,l)=(%d,%d,%d) %s",
                    770:                symname(symbol(tree(ep->focus))),
                    771: #else !SAVEBUF
                    772:                "%d, %s, wi=%d, hi=%d, (y,x,l)=(%d,%d,%d) %s",
                    773:                symbol(tree(ep->focus)),
                    774: #endif SAVEBUF
                    775:                str, width(tree(ep->focus)), ep->highest,
                    776:                Ycoord(ep->focus), Xcoord(ep->focus), Level(ep->focus),
                    777:                        ep->spflag ? "spflag on" : "");
                    778: #endif !SMALLSYS
                    779: }
                    780: 
                    781: #ifndef SMALLSYS
                    782: 
                    783: Hidden bool
                    784: canexit(ep)
                    785:        environ *ep;
                    786: {
                    787:        environ env;
                    788: 
                    789:        shrink(ep);
                    790:        if (ishole(ep))
                    791:                delete(ep);
                    792:        Ecopy(*ep, env);
                    793:        top(&ep->focus);
                    794:        higher(ep);
                    795:        ep->mode = WHOLE;
                    796:        if (findhole(&ep->focus)) {
                    797:                Erelease(env);
                    798:                error(EXIT_HOLES); /* There are holes left */
                    799:                return No;
                    800:        }
                    801:        Erelease(*ep);
                    802:        Emove(env, *ep);
                    803:        return Yes;
                    804: }
                    805: 
                    806: 
                    807: Hidden bool
                    808: findhole(pp)
                    809:        register path *pp;
                    810: {
                    811:        register node n = tree(*pp);
                    812: 
                    813:        if (Type(n) == Tex)
                    814:                return No;
                    815:        if (symbol(n) == Hole)
                    816:                return Yes;
                    817:        if (!down(pp))
                    818:                return No;
                    819:        for (;;) {
                    820:                if (findhole(pp))
                    821:                        return Yes;
                    822:                if (!rite(pp))
                    823:                        break;
                    824: 
                    825:        }
                    826:        up(pp) || Abort();
                    827:        return No;
                    828: }
                    829: 
                    830: #endif !SMALLSYS

unix.superglobalmegacorp.com

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