Annotation of 43BSDTahoe/new/B/src/bed/demo.c, revision 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.