Annotation of 43BSDTahoe/new/jove/extend.c, revision 1.1

1.1     ! root        1: /***************************************************************************
        !             2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
        !             3:  * is provided to you without charge, and with no warranty.  You may give  *
        !             4:  * away copies of JOVE, including sources, provided that this notice is    *
        !             5:  * included in all the files.                                              *
        !             6:  ***************************************************************************/
        !             7: 
        !             8: #include "jove.h"
        !             9: #include "io.h"
        !            10: #include "termcap.h"
        !            11: #include "ctype.h"
        !            12: #ifdef JOB_CONTROL
        !            13: #      include <signal.h>
        !            14: #endif
        !            15: 
        !            16: #ifdef MAC
        !            17: #      include "mac.h"
        !            18: #else
        !            19: #      include <varargs.h>
        !            20: #endif
        !            21: 
        !            22: #ifdef MSDOS
        !            23: #include <process.h>
        !            24: #endif
        !            25: 
        !            26: #ifdef MAC
        !            27: #      undef private
        !            28: #      define private
        !            29: #endif
        !            30: 
        !            31: #ifdef LINT_ARGS
        !            32: private        void
        !            33:        fb_aux(data_obj *, data_obj **, char *, char *),
        !            34:        find_binds(data_obj *, char *),
        !            35:        vpr_aux(struct variable *, char *);
        !            36: #else
        !            37: private        void
        !            38:        fb_aux(),
        !            39:        find_binds(),
        !            40:        vpr_aux();
        !            41: #endif /* LINT_ARGS */
        !            42: 
        !            43: #ifdef MAC
        !            44: #      undef private
        !            45: #      define private static
        !            46: #endif
        !            47: 
        !            48: 
        !            49: int    InJoverc = 0;
        !            50: 
        !            51: extern int     getch(),
        !            52:                getchar();
        !            53: 
        !            54: /* Auto execute code */
        !            55: 
        !            56: #define NEXECS 20
        !            57: 
        !            58: private struct {
        !            59:        char    *a_pattern;
        !            60:        data_obj        *a_cmd;
        !            61: } AutoExecs[NEXECS] = {0};
        !            62: 
        !            63: private int    ExecIndex = 0;
        !            64: 
        !            65: /* Command auto-execute. */
        !            66: 
        !            67: void
        !            68: CAutoExec()
        !            69: {
        !            70:        DefAutoExec(findcom);
        !            71: }
        !            72: 
        !            73: /* Macro auto-execute. */
        !            74: 
        !            75: void
        !            76: MAutoExec()
        !            77: {
        !            78:        DefAutoExec(findmac);
        !            79: }
        !            80: 
        !            81: /* VARARGS0 */
        !            82: 
        !            83: void
        !            84: DefAutoExec(proc)
        !            85: #ifdef LINT_ARGS
        !            86: data_obj       *(*proc)(char *);
        !            87: #else
        !            88: data_obj       *(*proc)();
        !            89: #endif
        !            90: {
        !            91:        data_obj        *d;
        !            92:        char    *pattern;
        !            93:        int     i;
        !            94: 
        !            95:        if (ExecIndex >= NEXECS)
        !            96:                complain("Too many auto-executes, max %d.", NEXECS);
        !            97:        if ((d = (*proc)(ProcFmt)) == 0)
        !            98:                return;
        !            99:        pattern = do_ask("\r\n", (int (*)()) 0, (char *) 0, ": %f %s ", d->Name);
        !           100:        if (pattern != 0)
        !           101:            for (i = 0; i < ExecIndex; i++)
        !           102:                if ((AutoExecs[i].a_cmd == d) &&
        !           103:                    (strcmp(pattern, AutoExecs[i].a_pattern) == 0))
        !           104:                        return;         /* eliminate duplicates */
        !           105:        AutoExecs[ExecIndex].a_pattern = copystr(pattern);
        !           106:        AutoExecs[ExecIndex].a_cmd = d;
        !           107:        ExecIndex += 1;
        !           108: }
        !           109: 
        !           110: /* DoAutoExec: NEW and OLD are file names, and if NEW and OLD aren't the
        !           111:    same kind of file (i.e., match the same pattern) or OLD is 0 and it
        !           112:    matches, OR if the pattern is 0 (none was specified) then, we execute
        !           113:    the command associated with that kind of file. */
        !           114: 
        !           115: void
        !           116: DoAutoExec(new, old)
        !           117: register char  *new,
        !           118:                *old;
        !           119: {
        !           120:        register int    i;
        !           121: 
        !           122:        set_arg_value(1);
        !           123:        for (i = 0; i < ExecIndex; i++)
        !           124:                if ((AutoExecs[i].a_pattern == 0) ||
        !           125:                    ((new != 0 && LookingAt(AutoExecs[i].a_pattern, new, 0)) &&
        !           126:                     (old == 0 || !LookingAt(AutoExecs[i].a_pattern, old, 0))))
        !           127:                        ExecCmd(AutoExecs[i].a_cmd);
        !           128: }
        !           129: 
        !           130: void
        !           131: BindAKey()
        !           132: {
        !           133:        BindSomething(findcom);
        !           134: }
        !           135: 
        !           136: void
        !           137: BindMac()
        !           138: {
        !           139:        BindSomething(findmac);
        !           140: }
        !           141: 
        !           142: extern void    EscPrefix(),
        !           143:                CtlxPrefix(),
        !           144:                MiscPrefix();
        !           145: 
        !           146: data_obj **
        !           147: IsPrefix(cp)
        !           148: data_obj       *cp;
        !           149: {
        !           150: #ifdef MAC
        !           151:        void (*proc)();
        !           152: #else
        !           153:        int     (*proc)();
        !           154: #endif
        !           155:        
        !           156:        if (cp == 0 || (cp->Type & TYPEMASK) != FUNCTION)
        !           157:                return 0;
        !           158:        proc = ((struct cmd *) cp)->c_proc;
        !           159:        if (proc == EscPrefix)
        !           160:                return pref1map;
        !           161:        if (proc == CtlxPrefix)
        !           162:                return pref2map;
        !           163:        if (proc == MiscPrefix)
        !           164:                return miscmap;
        !           165:        return 0;
        !           166: }
        !           167: 
        !           168: void
        !           169: UnbindC()
        !           170: {
        !           171:        char    *keys;
        !           172:        data_obj        **map = mainmap;
        !           173: 
        !           174:        keys = ask((char *) 0, ProcFmt);
        !           175:        for (;;) {
        !           176:                if (keys[1] == '\0')
        !           177:                        break;
        !           178:                if ((map = IsPrefix(map[*keys])) == 0)
        !           179:                        break;
        !           180:                keys += 1;
        !           181:        }
        !           182:        if (keys[1] != 0)
        !           183:                complain("That's not a legitimate key sequence.");
        !           184:        map[keys[0]] = 0;
        !           185: }
        !           186:                
        !           187: int
        !           188: addgetc()
        !           189: {
        !           190:        int     c;
        !           191: 
        !           192:        if (!InJoverc) {
        !           193:                Asking = strlen(mesgbuf);
        !           194:                c = getch();
        !           195:                Asking = 0;
        !           196:                add_mess("%p ", c);
        !           197:        } else {
        !           198:                c = getch();
        !           199:                if (c == '\n')
        !           200:                        return EOF;     /* this isn't part of the sequence */
        !           201:                else if (c == '\\') {
        !           202:                        if ((c = getch()) == LF)
        !           203:                                complain("[Premature end of line]");
        !           204:                } else if (c == '^') {
        !           205:                        if ((c = getch()) == '?')
        !           206:                                c = RUBOUT;
        !           207:                        else if (isalpha(c) || index("@[\\]^_", c))
        !           208:                                c = CTL(c);
        !           209:                        else
        !           210:                                complain("[Unknown control character]");
        !           211:                }
        !           212:        }
        !           213:        return c;
        !           214: }
        !           215: 
        !           216: void
        !           217: BindWMap(map, lastkey, cmd)
        !           218: data_obj       **map,
        !           219:                *cmd;
        !           220: {
        !           221:        data_obj        **nextmap;
        !           222:        int     c;
        !           223: 
        !           224:        c = addgetc();
        !           225:        if (c == EOF) {
        !           226:                if (lastkey == EOF)
        !           227:                        complain("[Empty key sequence]");
        !           228:                complain("[Premature end of key sequence]");
        !           229:        } else {
        !           230:                if (nextmap = IsPrefix(map[c]))
        !           231:                        BindWMap(nextmap, c, cmd);
        !           232:                else {
        !           233:                        map[c] = cmd;
        !           234: #ifdef MAC
        !           235:                        ((struct cmd *) cmd)->c_key = c;        /* see about_j() in mac.c */
        !           236:                        if(map == mainmap) ((struct cmd *) cmd)->c_map = F_MAINMAP;
        !           237:                        else if(map == pref1map) ((struct cmd *) cmd)->c_map = F_PREF1MAP;
        !           238:                        else if(map == pref2map) ((struct cmd *) cmd)->c_map = F_PREF2MAP;
        !           239: #endif
        !           240:                }
        !           241:        }
        !           242: }
        !           243: 
        !           244: /* VARARGS0 */
        !           245: 
        !           246: void
        !           247: BindSomething(proc)
        !           248: #ifdef LINT_ARGS
        !           249: data_obj       *(*proc)(char *);
        !           250: #else
        !           251: data_obj       *(*proc)();
        !           252: #endif
        !           253: {
        !           254:        data_obj        *d;
        !           255: 
        !           256:        if ((d = (*proc)(ProcFmt)) == 0)
        !           257:                return;
        !           258:        s_mess(": %f %s ", d->Name);
        !           259:        BindWMap(mainmap, EOF, d);
        !           260: }
        !           261: 
        !           262: /* Describe key */
        !           263: 
        !           264: void
        !           265: DescWMap(map, key)
        !           266: data_obj       **map;
        !           267: {
        !           268:        data_obj        *cp = map[key],
        !           269:                        **prefp;
        !           270: 
        !           271:        if (cp == 0)
        !           272:                add_mess("is unbound.");
        !           273:        else if (prefp = IsPrefix(cp))
        !           274:                DescWMap(prefp, addgetc());
        !           275:        else
        !           276:                add_mess("is bound to %s.", cp->Name);
        !           277: }
        !           278: 
        !           279: void
        !           280: KeyDesc()
        !           281: {
        !           282:        s_mess(ProcFmt);
        !           283:        DescWMap(mainmap, addgetc());
        !           284: }
        !           285: 
        !           286: void
        !           287: DescCom()
        !           288: {
        !           289:        data_obj        *dp;
        !           290:        char    pattern[100],
        !           291:                doc_type[40],
        !           292:                *the_type,
        !           293:                *file = CmdDb;
        !           294:        File    *fp;
        !           295:        int     is_var;
        !           296: 
        !           297:        if (!strcmp(LastCmd->Name, "describe-variable")) {
        !           298:                dp = (data_obj *) findvar(ProcFmt);
        !           299:                the_type = "Variable";
        !           300:                is_var = YES;
        !           301:        } else {
        !           302:                dp = (data_obj *) findcom(ProcFmt);
        !           303:                the_type = "Command";
        !           304:                is_var = NO;
        !           305:        }
        !           306:        if (dp == 0)
        !           307:                return;
        !           308:        fp = open_file(file, iobuff, F_READ, COMPLAIN, QUIET);
        !           309:        Placur(ILI, 0);
        !           310:        flusho();
        !           311:        sprintf(pattern, "^:entry \"%s\" \"\\([^\"]*\\)\"", dp->Name);
        !           312:        TOstart("Help", TRUE);
        !           313:        for (;;) {
        !           314:                if (f_gets(fp, genbuf, LBSIZE) == EOF) {
        !           315:                        Typeout("There is no documentation for \"%s\".", dp->Name);
        !           316:                        goto outahere;
        !           317:                }
        !           318:                if ((strncmp(genbuf, ":entry", 6) == 0) &&
        !           319:                    (LookingAt(pattern, genbuf, 0))) {
        !           320:                        char    type[64];
        !           321: 
        !           322:                        putmatch(1, type, sizeof type);
        !           323:                        if (strcmp(type, the_type) == 0)
        !           324:                                break;
        !           325:                }
        !           326:        }
        !           327:        /* found it ... let's print it */
        !           328:        putmatch(1, doc_type, sizeof doc_type);
        !           329:        if (is_var == YES)
        !           330:                Typeout(dp->Name);
        !           331:        else {
        !           332:                char    binding[128];
        !           333: 
        !           334:                find_binds(dp, binding);
        !           335:                if (blnkp(binding))
        !           336:                        Typeout("To invoke %s, type \"ESC X %s<cr>\".",
        !           337:                                dp->Name,
        !           338:                                dp->Name);
        !           339:                else
        !           340:                        Typeout("Type \"%s\" to invoke %s.", binding, dp->Name);
        !           341:        }
        !           342:        Typeout("");
        !           343:        while (f_gets(fp, genbuf, LBSIZE) != EOF)
        !           344:                if (strncmp(genbuf, ":entry", 6) == 0)
        !           345:                        goto outahere;
        !           346:                else
        !           347:                        Typeout("%s", genbuf);
        !           348: outahere:
        !           349:        f_close(fp);
        !           350:        TOstop();
        !           351: }
        !           352: 
        !           353: void
        !           354: DescBindings()
        !           355: {
        !           356:        extern void     Typeout();
        !           357: 
        !           358:        TOstart("Key Bindings", TRUE);
        !           359:        DescMap(mainmap, NullStr);
        !           360:        TOstop();
        !           361: }
        !           362: 
        !           363: extern int specialmap;
        !           364: 
        !           365: void
        !           366: DescMap(map, pref)
        !           367: data_obj       **map;
        !           368: char   *pref;
        !           369: {
        !           370:        int     c1,
        !           371:                c2 = 0,
        !           372:                numbetween;
        !           373:        char    keydescbuf[40];
        !           374:        data_obj        **prefp;
        !           375: 
        !           376: #ifdef IBMPC
        !           377:        specialmap = (map == miscmap);
        !           378: #endif
        !           379: 
        !           380:        for (c1 = 0; c1 < NCHARS && c2 < NCHARS; c1 = c2 + 1) {
        !           381:                c2 = c1;
        !           382:                if (map[c1] == 0)
        !           383:                        continue;
        !           384:                while (++c2 < NCHARS && map[c1] == map[c2])
        !           385:                        ;
        !           386:                c2 -= 1;
        !           387:                numbetween = c2 - c1;
        !           388:                if (numbetween == 1)
        !           389:                        sprintf(keydescbuf, "%s {%p,%p}", pref, c1, c2);
        !           390:                else if (numbetween == 0)
        !           391:                        sprintf(keydescbuf, "%s %p", pref, c1);
        !           392:                else
        !           393:                        sprintf(keydescbuf, "%s [%p-%p]", pref, c1, c2);
        !           394:                if ((prefp = IsPrefix(map[c1])) && (prefp != map))
        !           395:                        DescMap(prefp, keydescbuf);
        !           396:                else
        !           397:                        Typeout("%-18s%s", keydescbuf, map[c1]->Name);
        !           398:        }
        !           399: }
        !           400: 
        !           401: private void
        !           402: find_binds(dp, buf)
        !           403: data_obj       *dp;
        !           404: char   *buf;
        !           405: {
        !           406:        char    *endp;
        !           407: 
        !           408:        buf[0] = '\0';
        !           409:        fb_aux(dp, mainmap, (char *) 0, buf);
        !           410:        endp = buf + strlen(buf) - 2;
        !           411:        if ((endp > buf) && (strcmp(endp, ", ") == 0))
        !           412:                *endp = '\0';
        !           413: }
        !           414: 
        !           415: private void
        !           416: fb_aux(cp, map, prefix, buf)
        !           417: register data_obj      *cp,
        !           418:                        **map;
        !           419: char   *buf,
        !           420:        *prefix;
        !           421: {
        !           422:        int     c1,
        !           423:                c2;
        !           424:        char    *bufp = buf + strlen(buf),
        !           425:                prefbuf[20];
        !           426:        data_obj        **prefp;
        !           427: 
        !           428: #ifdef IBMPC
        !           429:        specialmap = (map == miscmap);
        !           430: #endif 
        !           431: 
        !           432:        for (c1 = c2 = 0; c1 < NCHARS && c2 < NCHARS; c1 = c2 + 1) {
        !           433:                c2 = c1;
        !           434:                if (map[c1] == cp) {
        !           435:                        while (++c2 < NCHARS && map[c1] == map[c2])
        !           436:                                ;
        !           437:                        c2 -= 1;
        !           438:                        if (prefix)
        !           439:                                sprintf(bufp, "%s ", prefix);
        !           440:                        bufp += strlen(bufp);
        !           441:                        switch (c2 - c1) {
        !           442:                        case 0:
        !           443:                                sprintf(bufp, "%p, ", c1);
        !           444:                                break;
        !           445:        
        !           446:                        case 1:
        !           447:                                sprintf(bufp, "{%p,%p}, ", c1, c2);
        !           448:                                break;
        !           449:        
        !           450:                        default:
        !           451:                                sprintf(bufp, "[%p-%p], ", c1, c2);
        !           452:                                break;
        !           453:                        }
        !           454:                }
        !           455:                if ((prefp = IsPrefix(map[c1])) && (prefp != map))  {
        !           456:                        sprintf(prefbuf, "%p", c1);
        !           457:                        fb_aux(cp, prefp, prefbuf, bufp);
        !           458:                }
        !           459:                bufp += strlen(bufp);
        !           460:        }
        !           461: }
        !           462: 
        !           463: void
        !           464: Apropos()
        !           465: {
        !           466:        register struct cmd     *cp;
        !           467:        register struct macro   *m;
        !           468:        register struct variable        *v;
        !           469:        char    *ans;
        !           470:        int     anyfs = NO,
        !           471:                anyvs = NO,
        !           472:                anyms = NO;
        !           473:        char    buf[256];
        !           474: 
        !           475:        ans = ask((char *) 0, ": %f (keyword) ");
        !           476:        TOstart("Help", TRUE);
        !           477:        for (cp = commands; cp->Name != 0; cp++)
        !           478:                if (sindex(ans, cp->Name)) {
        !           479:                        if (anyfs == 0) {
        !           480:                                Typeout("Commands");
        !           481:                                Typeout("--------");
        !           482:                        }
        !           483:                        find_binds((data_obj *) cp, buf);
        !           484:                        if (buf[0])
        !           485:                                Typeout(": %-35s(%s)", cp->Name, buf);
        !           486:                        else
        !           487:                                Typeout(": %s", cp->Name);
        !           488:                        anyfs = YES;
        !           489:                }
        !           490:        if (anyfs)
        !           491:                Typeout(NullStr);
        !           492:        for (v = variables; v->Name != 0; v++)
        !           493:                if (sindex(ans, v->Name)) {
        !           494:                        if (anyvs == 0) {
        !           495:                                Typeout("Variables");
        !           496:                                Typeout("---------");
        !           497:                        }
        !           498:                        anyvs = YES;
        !           499:                        vpr_aux(v, buf);
        !           500:                        Typeout(": set %-26s%s", v->Name, buf);
        !           501:                }
        !           502:        if (anyvs)
        !           503:                Typeout(NullStr);
        !           504:        for (m = macros; m != 0; m = m->m_nextm)
        !           505:                if (sindex(ans, m->Name)) {
        !           506:                        if (anyms == 0) {
        !           507:                                Typeout("Macros");
        !           508:                                Typeout("------");
        !           509:                        }
        !           510:                        anyms = YES;
        !           511:                        find_binds((data_obj *) m, buf);
        !           512:                        if (buf[0])
        !           513:                                Typeout(": %-35s(%s)", m->Name, buf);
        !           514:                        else
        !           515:                                Typeout(": %-35s%s", "execute-macro", m->Name);
        !           516:                }
        !           517:        TOstop();
        !           518: }
        !           519: 
        !           520: void
        !           521: Extend()
        !           522: {
        !           523:        data_obj        *d;
        !           524: 
        !           525:        if (d = findcom(": "))
        !           526:                ExecCmd(d);
        !           527: }
        !           528: 
        !           529: /* Read a positive integer from CP.  It must be in base BASE, and
        !           530:    complains if it isn't.  If allints is nonzero, all the characters
        !           531:    in the string must be integers or we return -1; otherwise we stop
        !           532:    reading at the first nondigit. */
        !           533: 
        !           534: int
        !           535: chr_to_int(cp, base, allints, result)
        !           536: register char  *cp;
        !           537: register int   *result;
        !           538: {
        !           539:        register int    c;
        !           540:        int     value = 0,
        !           541:                sign;
        !           542: 
        !           543:        if ((c = *cp) == '-') {
        !           544:                sign = -1;
        !           545:                cp += 1;
        !           546:        } else
        !           547:                sign = 1;
        !           548:        while (c = *cp++) {
        !           549:                if (!isdigit(c)) {
        !           550:                        if (allints == YES)
        !           551:                                return INT_BAD;
        !           552:                        break;
        !           553:                }
        !           554:                c = c - '0';
        !           555:                if (c >= base)
        !           556:                        complain("You must specify in base %d.", base);
        !           557:                value = value * base + c;
        !           558:        }
        !           559:        *result = value * sign;
        !           560:        return INT_OKAY;
        !           561: }
        !           562: 
        !           563: int
        !           564: ask_int(prompt, base)
        !           565: char   *prompt;
        !           566: int    base;
        !           567: {
        !           568:        char    *val = ask((char *) 0, prompt);
        !           569:        int     value;
        !           570: 
        !           571:        if (chr_to_int(val, base, YES, &value) == INT_BAD)
        !           572:                complain("That's not a number!");
        !           573:        return value;
        !           574: }
        !           575: 
        !           576: private void
        !           577: vpr_aux(vp, buf)
        !           578: register struct variable       *vp;
        !           579: char   *buf;
        !           580: {
        !           581:        switch (vp->v_flags & V_TYPEMASK) {
        !           582:        case V_BASE10:
        !           583:                sprintf(buf, "%d", *(vp->v_value));
        !           584:                break;
        !           585: 
        !           586:        case V_BASE8:
        !           587:                sprintf(buf, "%o", *(vp->v_value));
        !           588:                break;
        !           589: 
        !           590:        case V_BOOL:
        !           591:                sprintf(buf, (*(vp->v_value)) ? "on" : "off");
        !           592:                break;
        !           593: 
        !           594:        case V_STRING:
        !           595:        case V_FILENAME:
        !           596:                sprintf(buf, "%s", (char *) vp->v_value);
        !           597:                break;
        !           598: 
        !           599:        case V_CHAR:
        !           600:                sprintf(buf, "%p", *(vp->v_value));
        !           601:                break;
        !           602:        }
        !           603: }
        !           604: 
        !           605: void
        !           606: PrVar()
        !           607: {
        !           608:        struct variable *vp;
        !           609:        char    prbuf[256];
        !           610: 
        !           611:        if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
        !           612:                return;
        !           613:        vpr_aux(vp, prbuf);
        !           614:        s_mess(": %f %s => %s", vp->Name, prbuf);
        !           615: }
        !           616: 
        !           617: void
        !           618: SetVar()
        !           619: {
        !           620:        struct variable *vp;
        !           621:        char    *prompt;
        !           622: 
        !           623:        if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
        !           624:                return;
        !           625:        prompt = sprint(": %f %s ", vp->Name);
        !           626: 
        !           627:        switch (vp->v_flags & V_TYPEMASK) {
        !           628:        case V_BASE10:
        !           629:        case V_BASE8:
        !           630:            {
        !           631:                int     value;
        !           632: 
        !           633:                value = ask_int(prompt, ((vp->v_flags & V_TYPEMASK) == V_BASE10)
        !           634:                                          ? 10 : 8);
        !           635:                *(vp->v_value) = value;
        !           636:                break;
        !           637:            }
        !           638: 
        !           639:        case V_BOOL:
        !           640:            {
        !           641:                char    *def = *(vp->v_value) ? "off" : "on",
        !           642:                        *on_off;
        !           643:                int     value;
        !           644: 
        !           645:                on_off = ask(def, prompt);
        !           646:                if (casecmp(on_off, "on") == 0)
        !           647:                        value = ON;
        !           648:                else if (casecmp(on_off, "off") == 0)
        !           649:                        value = OFF;
        !           650:                else
        !           651:                        complain("Boolean variables must be ON or OFF.");
        !           652:                *(vp->v_value) = value;
        !           653: #ifdef MAC
        !           654:                MarkVar(vp,-1,0);       /* mark the menu item */
        !           655: #endif
        !           656:                s_mess("%s%s", prompt, value ? "on" : "off");
        !           657:                break;
        !           658:            }
        !           659: 
        !           660:        case V_FILENAME:
        !           661:            {
        !           662:                char    fbuf[FILESIZE];
        !           663: 
        !           664:                sprintf(&prompt[strlen(prompt)], "(default %s) ", vp->v_value);
        !           665:                (void) ask_file(prompt, (char *) vp->v_value, fbuf);
        !           666:                strcpy((char *) vp->v_value, fbuf);
        !           667:                break;
        !           668:            }
        !           669: 
        !           670:        case V_STRING:
        !           671:            {
        !           672:                char    *str;
        !           673: 
        !           674:                /* Do_ask() so you can set string to "" if you so desire. */
        !           675:                str = do_ask("\r\n", (int (*)()) 0, (char *) vp->v_value, prompt);
        !           676:                if (str == 0)
        !           677:                        str = NullStr;
        !           678:                strcpy((char *) vp->v_value, str);
        !           679:                /* ... and hope there is enough room. */
        !           680:                break;
        !           681:            }
        !           682:        case V_CHAR:
        !           683:                f_mess(prompt);
        !           684:                *(vp->v_value) = addgetc();
        !           685:                break;          
        !           686: 
        !           687:        }
        !           688:        if (vp->v_flags & V_MODELINE)
        !           689:                UpdModLine = YES;
        !           690:        if (vp->v_flags & V_CLRSCREEN) {
        !           691: #ifdef IBMPC
        !           692:                setcolor(Fgcolor, Bgcolor);
        !           693: #endif /* IBMPC */
        !           694:                ClAndRedraw();
        !           695:        }
        !           696:        if (vp->v_flags & V_TTY_RESET)
        !           697:                tty_reset();
        !           698: }
        !           699:                        
        !           700: /* Command completion - possible is an array of strings, prompt is
        !           701:    the prompt to use, and flags are ... well read jove.h.
        !           702: 
        !           703:    If flags are RET_STATE, and the user hits <return> what they typed
        !           704:    so far is in the Minibuf string. */
        !           705: 
        !           706: private char   **Possible;
        !           707: private int    comp_value,
        !           708:                comp_flags;
        !           709: 
        !           710: int
        !           711: aux_complete(c)
        !           712: {
        !           713:        int     command,
        !           714:                length,
        !           715:                i;
        !           716: 
        !           717:        if (comp_flags & CASEIND) {
        !           718:                char    *lp;
        !           719: 
        !           720:                for (lp = linebuf; *lp != '\0'; lp++)
        !           721: #if (defined(IBMPC) || defined(MAC))
        !           722:                        lower(lp);
        !           723: #else                  
        !           724:                        if (isupper(*lp))
        !           725:                                *lp = tolower(*lp);
        !           726: #endif
        !           727:        }
        !           728:        switch (c) {
        !           729:        case EOF:
        !           730:                comp_value = -1;
        !           731:                return 0;
        !           732: 
        !           733:        case '\r':
        !           734:        case '\n':
        !           735:                command = match(Possible, linebuf);
        !           736:                if (command >= 0) {
        !           737:                        comp_value = command;
        !           738:                        return 0;       /* tells ask to stop */
        !           739:                }
        !           740:                if (eolp() && bolp()) {
        !           741:                        comp_value = NULLSTRING;
        !           742:                        return 0;
        !           743:                }
        !           744:                if (comp_flags & RET_STATE) {
        !           745:                        comp_value = command;
        !           746:                        return 0;
        !           747:                }
        !           748:                if (InJoverc)
        !           749:                        complain("[\"%s\" unknown]", linebuf);
        !           750:                rbell();
        !           751:                break;
        !           752: 
        !           753:        case '\t':
        !           754:        case ' ':
        !           755:            {
        !           756:                int     minmatch = 1000,
        !           757:                        maxmatch = 0,
        !           758:                        numfound = 0,
        !           759:                        lastmatch = -1,
        !           760:                        length = strlen(linebuf);
        !           761: 
        !           762:                for (i = 0; Possible[i] != 0; i++) {
        !           763:                        int     this_len;
        !           764: 
        !           765:                        this_len = numcomp(Possible[i], linebuf);
        !           766:                        maxmatch = max(maxmatch, this_len);
        !           767:                        if (this_len >= length) {
        !           768:                                if (numfound)
        !           769:                                        minmatch = min(minmatch, numcomp(Possible[lastmatch], Possible[i]));
        !           770:                                else
        !           771:                                        minmatch = strlen(Possible[i]);
        !           772:                                numfound += 1;
        !           773:                                lastmatch = i;
        !           774:                                if (strcmp(linebuf, Possible[i]) == 0)
        !           775:                                        break;
        !           776:                        }
        !           777:                }
        !           778: 
        !           779:                if (numfound == 0) {
        !           780:                        rbell();
        !           781:                        if (InJoverc)
        !           782:                                complain("[\"%s\" unknown]", linebuf);
        !           783:                        /* If we're not in the .joverc then
        !           784:                           let's do something helpful for the
        !           785:                           user. */
        !           786:                        if (maxmatch < length) {
        !           787:                                char    *cp;
        !           788: 
        !           789:                                cp = linebuf + maxmatch;
        !           790:                                *cp = 0;
        !           791:                                Eol();
        !           792:                        }
        !           793:                        break;
        !           794:                }
        !           795:                if (c != '\t' && numfound == 1) {
        !           796:                        comp_value = lastmatch;
        !           797:                        return 0;
        !           798:                }
        !           799:                null_ncpy(linebuf, Possible[lastmatch], minmatch);
        !           800:                Eol();
        !           801:                if (minmatch == length) /* No difference */
        !           802:                        rbell();
        !           803:                break;
        !           804:            }
        !           805: 
        !           806:        case '?':
        !           807:                if (InJoverc)
        !           808:                        complain((char *) 0);
        !           809:                /* kludge: in case we're using UseBuffers, in which case
        !           810:                   linebuf gets written all over */
        !           811:                strcpy(Minibuf, linebuf);
        !           812:                length = strlen(Minibuf);
        !           813:                TOstart("Completion", TRUE);    /* for now ... */
        !           814:                for (i = 0; Possible[i]; i++)
        !           815:                        if (numcomp(Possible[i], Minibuf) >= length) {
        !           816:                                Typeout(Possible[i]);
        !           817:                                if (TOabort != 0)
        !           818:                                        break;
        !           819:                        }
        !           820: 
        !           821:                TOstop();
        !           822:                break;
        !           823:        }
        !           824:        return !FALSE;
        !           825: }
        !           826: 
        !           827: int
        !           828: complete(possible, prompt, flags)
        !           829: register char  *possible[];
        !           830: char   *prompt;
        !           831: {
        !           832:        Possible = possible;
        !           833:        comp_flags = flags;
        !           834:        (void) do_ask("\r\n \t?", aux_complete, NullStr, prompt);
        !           835:        return comp_value;
        !           836: }
        !           837: 
        !           838: int
        !           839: match(choices, what)
        !           840: register char  **choices,
        !           841:                *what;
        !           842: {
        !           843:        register int    len;
        !           844:        int     i,
        !           845:                found = 0,
        !           846:                save,
        !           847:                exactmatch = -1;
        !           848: 
        !           849:        len = strlen(what);
        !           850:        if (len == 0)
        !           851:                return NULLSTRING;
        !           852:        for (i = 0; choices[i]; i++) {
        !           853:                if (strncmp(what, choices[i], len) == 0) {
        !           854:                        if (strcmp(what, choices[i]) == 0)
        !           855:                                exactmatch = i;
        !           856:                        save = i;
        !           857:                        found += 1;     /* found one */
        !           858:                }
        !           859:        }
        !           860: 
        !           861:        if (found == 0)
        !           862:                save = ORIGINAL;
        !           863:        else if (found > 1) {
        !           864:                if (exactmatch != -1)
        !           865:                        save = exactmatch;
        !           866:                else
        !           867:                        save = AMBIGUOUS;
        !           868:        }
        !           869: 
        !           870:        return save;
        !           871: }
        !           872: 
        !           873: void
        !           874: Source()
        !           875: {
        !           876:        char    *com, *getenv(),
        !           877:                buf[FILESIZE];
        !           878: 
        !           879: #ifndef MSDOS
        !           880:        sprintf(buf, "%s/.joverc", getenv("HOME"));
        !           881: #else /* MSDOS */
        !           882:        if (com = getenv("JOVERC"))
        !           883:                strcpy(buf, com);
        !           884:        else
        !           885:                strcpy(buf, Joverc);
        !           886: #endif /* MSDOS */
        !           887:        com = ask_file((char *) 0, buf, buf);
        !           888:        if (joverc(buf) == 0)
        !           889:                complain(IOerr("read", com));
        !           890: }
        !           891: 
        !           892: void
        !           893: BufPos()
        !           894: {
        !           895:        register Line   *lp = curbuf->b_first;
        !           896:        register int    i,
        !           897:                        dotline;
        !           898:        long    dotchar,
        !           899:                nchars;
        !           900: 
        !           901:        for (i = nchars = 0; lp != 0; i++, lp = lp->l_next) {
        !           902:                if (lp == curline) {
        !           903:                        dotchar = nchars + curchar;
        !           904:                        dotline = i + 1;
        !           905:                }
        !           906:                nchars += length(lp) + (lp->l_next != 0); /* include the NL */
        !           907:        }
        !           908: 
        !           909:        s_mess("[\"%s\" line %d/%d, char %D/%D (%d%%), cursor = %d/%d]",
        !           910:               filename(curbuf), dotline, i, dotchar, nchars,
        !           911:               (nchars == 0) ? 100 : (int) (((long) dotchar * 100) / nchars),
        !           912:               calc_pos(linebuf, curchar),
        !           913:               calc_pos(linebuf, strlen(linebuf)));
        !           914: }
        !           915: 
        !           916: #define IF_UNBOUND     -1
        !           917: #define IF_TRUE                1
        !           918: #define IF_FALSE       !IF_TRUE
        !           919: 
        !           920: #ifndef MAC
        !           921: int
        !           922: do_if(cmd)
        !           923: char   *cmd;
        !           924: {
        !           925: #ifdef MSDOS
        !           926:        int status;
        !           927: #else  
        !           928:        int     pid,
        !           929:                status;
        !           930: #endif /* MSDOS */
        !           931: #ifndef MSDOS
        !           932: 
        !           933:        switch (pid = fork()) {
        !           934:        case -1:
        !           935:                complain("[Fork failed: if]");
        !           936: 
        !           937:        case 0:
        !           938:            {
        !           939: #endif /* MSDOS */
        !           940:                char    *args[12],
        !           941:                        *cp = cmd,
        !           942:                        **ap = args;
        !           943: 
        !           944:                *ap++ = cmd;
        !           945:                for (;;) {
        !           946:                        if ((cp = index(cp, ' ')) == 0)
        !           947:                                break;
        !           948:                        *cp++ = '\0';
        !           949:                        *ap++ = cp;
        !           950:                }
        !           951:                *ap = 0;
        !           952: 
        !           953: #ifndef MSDOS
        !           954:                close(0);       /*      we want reads to fail */
        !           955:                /* close(1);     but not writes or ioctl's
        !           956:                close(2);    */
        !           957: #else /* MSDOS */
        !           958:        if ((status = spawnvp(0, args[0], args)) < 0)
        !           959:                complain("[Spawn failed: if]");
        !           960: #endif /* MSDOS */
        !           961: 
        !           962: #ifndef MSDOS
        !           963:                (void) execvp(args[0], args);
        !           964:                _exit(-10);     /* signals exec error (see below) */
        !           965:            }
        !           966:        }
        !           967: #ifdef IPROCS
        !           968:        sighold(SIGCHLD);
        !           969: #endif
        !           970:        dowait(pid, &status);
        !           971: #ifdef IPROCS
        !           972:        sigrelse(SIGCHLD);
        !           973: #endif
        !           974:        if (status == -10)
        !           975:                complain("[Exec failed]");
        !           976:        if (status < 0)
        !           977:                complain("[Exit %d]", status);
        !           978: #endif /* MSDOS */
        !           979:        return (status == 0);   /* 0 means successful */
        !           980: }
        !           981: #endif /* MAC */
        !           982: 
        !           983: int
        !           984: joverc(file)
        !           985: char   *file;
        !           986: {
        !           987:        char    buf[LBSIZE],
        !           988:                lbuf[LBSIZE];
        !           989:        int     lnum = 0,
        !           990:                eof = FALSE;
        !           991:        jmp_buf savejmp;
        !           992:        int     IfStatus = IF_UNBOUND;
        !           993:        File    *fp;
        !           994: 
        !           995:        fp = open_file(file, buf, F_READ, !COMPLAIN, QUIET);
        !           996:        if (fp == NIL)
        !           997:                return NO;      /* joverc returns an integer */
        !           998: 
        !           999:        /* Catch any errors, here, and do the right thing with them,
        !          1000:           and then restore the error handle to whoever did a setjmp
        !          1001:           last. */
        !          1002: 
        !          1003:        InJoverc += 1;
        !          1004:        push_env(savejmp);
        !          1005:        if (setjmp(mainjmp)) {
        !          1006:                Buffer  *savebuf = curbuf;
        !          1007: 
        !          1008:                SetBuf(do_select((Window *) 0, "RC errors"));
        !          1009:                ins_str(sprint("%s:%d:%s\t%s\n", pr_name(file, YES), lnum, lbuf, mesgbuf), NO);
        !          1010:                unmodify();
        !          1011:                SetBuf(savebuf);
        !          1012:                Asking = 0;
        !          1013:        }
        !          1014:        if (!eof) do {
        !          1015:                eof = (f_gets(fp, lbuf, sizeof lbuf) == EOF);
        !          1016:                lnum += 1;
        !          1017:                if (lbuf[0] == '#')             /* a comment */
        !          1018:                        continue;
        !          1019: #ifndef MAC
        !          1020:                if (casencmp(lbuf, "if", 2) == 0) {
        !          1021:                        char    cmd[128];
        !          1022: 
        !          1023:                        if (IfStatus != IF_UNBOUND)
        !          1024:                                complain("[Cannot have nested if's]");
        !          1025:                        if (LookingAt("if[ \t]*\\(.*\\)$", lbuf, 0) == 0)
        !          1026:                                complain("[If syntax error]");
        !          1027:                        putmatch(1, cmd, sizeof cmd);
        !          1028:                        IfStatus = do_if(cmd) ? IF_TRUE : IF_FALSE;
        !          1029:                        continue;
        !          1030:                } else if (casencmp(lbuf, "else", 4) == 0) {
        !          1031:                        if (IfStatus == IF_UNBOUND)
        !          1032:                                complain("[Unexpected `else']");
        !          1033:                        IfStatus = !IfStatus;
        !          1034:                        continue;
        !          1035:                } else if (casencmp(lbuf, "endif", 5) == 0) {
        !          1036:                        if (IfStatus == IF_UNBOUND)
        !          1037:                                complain("[Unexpected `endif']");
        !          1038:                        IfStatus = IF_UNBOUND;
        !          1039:                        continue;
        !          1040:                }
        !          1041: #endif
        !          1042:                if (IfStatus == IF_FALSE)
        !          1043:                        continue;
        !          1044:                (void) strcat(lbuf, "\n");
        !          1045:                Inputp = lbuf;
        !          1046:                while (*Inputp == ' ' || *Inputp == '\t')
        !          1047:                        Inputp += 1;    /* skip white space */
        !          1048:                Extend();
        !          1049:        } while (!eof);
        !          1050: 
        !          1051:        f_close(fp);
        !          1052:        pop_env(savejmp);
        !          1053:        Inputp = 0;
        !          1054:        Asking = 0;
        !          1055:        InJoverc -= 1;
        !          1056:        if (IfStatus != IF_UNBOUND)
        !          1057:                complain("[Missing endif]");
        !          1058:        return 1;
        !          1059: }

unix.superglobalmegacorp.com

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