Annotation of coherent/a/usr/bob/korn/history.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * command history
        !             3:  *
        !             4:  * only implements in-memory history.
        !             5:  */
        !             6: 
        !             7: static char *RCSid = "$Header: history.c,v 3.1 88/11/03 09:16:05 egisin Exp $";
        !             8: 
        !             9: #include <stddef.h>
        !            10: #include <stdio.h>
        !            11: #include <string.h>
        !            12: #include <errno.h>
        !            13: #include <setjmp.h>
        !            14: #include "sh.h"
        !            15: #include "lex.h"
        !            16: 
        !            17: char  **histget();
        !            18: char   *histrpl();
        !            19: 
        !            20: c_fc(wp)
        !            21:        register char **wp;
        !            22: {
        !            23:        register char *id;
        !            24:        FILE *f;
        !            25:        struct temp *tf;
        !            26:        register char **hp;
        !            27:        char **hbeg, **hend;
        !            28:        int lflag = 0, nflag = 0, sflag = 0;
        !            29: 
        !            30:        for (wp++; (id = *wp) != NULL && *id == '-' && !sflag; wp++)
        !            31:                switch (id[1]) {
        !            32:                  case 'l':
        !            33:                        lflag++;
        !            34:                        break;
        !            35:                  case 'n':
        !            36:                        nflag++;
        !            37:                        break;
        !            38:                  case 's':
        !            39:                        sflag++;
        !            40:                        break;
        !            41:                }
        !            42: 
        !            43:        /* fc -s [pat=rep] [cmd], equivalent to Korn's fc -e - [pat=rep] */
        !            44:        if (sflag) {
        !            45:                char *pat = NULL, *rep = NULL;
        !            46: 
        !            47:                hp = histptr - 1;
        !            48:                while ((id = *wp++) != NULL)
        !            49:                        /* todo: multiple substitutions */
        !            50:                        if ((rep = strchr(id, '=')) != NULL) {
        !            51:                                pat = id;
        !            52:                                *rep++ = '\0';
        !            53:                        } else
        !            54:                                hp = histget(id);
        !            55: 
        !            56:                if (hp == NULL || hp < history)
        !            57:                        errorf("cannot find history\n");
        !            58:                if (pat == NULL)
        !            59:                        strcpy(line, *hp);
        !            60:                else
        !            61:                        histrpl(*hp, pat, rep);
        !            62:                histsave(line);
        !            63:                histpush--;
        !            64:                line[0] = '\0';
        !            65:                return 0;
        !            66:        }
        !            67: 
        !            68:        if (*wp != NULL) {
        !            69:                hbeg = histget(*wp++); /* first */
        !            70:                if (*wp != NULL)
        !            71:                        hend = histget(*wp++); /* last */
        !            72:                else
        !            73:                        hend = hbeg;
        !            74:        } else {
        !            75:                if (lflag)
        !            76:                        hbeg = histptr - 12, hend = histptr;
        !            77:                else
        !            78:                        hbeg = hend = histptr - 1;
        !            79:                if (hbeg < history)
        !            80:                        hbeg = history;
        !            81:        }
        !            82:        if (hbeg == NULL || hend == NULL)
        !            83:                errorf("can't find history\n");
        !            84: 
        !            85:        if (lflag)
        !            86:                f = stdout;
        !            87:        else {
        !            88:                nflag++;
        !            89:                tf = maketemp(ATEMP);
        !            90:                tf->next = e.temps; e.temps = tf;
        !            91:                f = fopen(tf->name, "w");
        !            92:                if (f == NULL)
        !            93:                        errorf("cannot create temp file %s", tf->name);
        !            94:                setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
        !            95:        }
        !            96: 
        !            97:        for (hp = hbeg; hp <= hend; hp++) {
        !            98:                if (!nflag)
        !            99:                        fprintf(f, "%3d: ", source->line - (int)(histptr-hp));
        !           100:                fprintf(f, "%s\n", *hp);
        !           101:        }
        !           102: 
        !           103:        if (lflag)
        !           104:                return 0;
        !           105:        else
        !           106:                fclose(f);
        !           107: 
        !           108:        setstr(local("_"), tf->name);
        !           109:        command("${FCEDIT:-/bin/ed} $_"); /* edit temp file */
        !           110: 
        !           111:        f = fopen(tf->name, "r");
        !           112:        if (f == NULL)
        !           113:                errorf("cannot open temp file %s\n", tf->name);
        !           114:        setvbuf(f, (char *)NULL, _IOFBF, BUFSIZ);
        !           115:        /* we push the editted lines onto the history list */
        !           116:        while (fgets(line, sizeof(line), f) != NULL) {
        !           117:                histsave(line);
        !           118:                histpush--;
        !           119:        }
        !           120:        line[0] = '\0';
        !           121:        fclose(f);
        !           122: 
        !           123:        return 0;
        !           124: }
        !           125: 
        !           126: /*
        !           127:  * save command in history
        !           128:  */
        !           129: void
        !           130: histsave(cmd)
        !           131:        char *cmd;
        !           132: {
        !           133:        register char **hp = histptr;
        !           134:        char *cp;
        !           135: 
        !           136:        if (++hp >= history + HISTORY) { /* remove oldest command */
        !           137:                afree((Void*)*history, APERM);
        !           138:                for (hp = history; hp < history + HISTORY - 1; hp++)
        !           139:                        hp[0] = hp[1];
        !           140:        }
        !           141:        *hp = strsave(cmd, APERM);
        !           142:        if ((cp = strchr(*hp, '\n')) != NULL)
        !           143:                *cp = '\0';
        !           144:        histptr = hp;
        !           145: }
        !           146: 
        !           147: /*
        !           148:  * get pointer to history given pattern
        !           149:  * pattern is a number or string
        !           150:  */
        !           151: char **
        !           152: histget(str)
        !           153:        char *str;
        !           154: {
        !           155:        register char **hp = NULL;
        !           156: 
        !           157:        if (*str == '-')
        !           158:                hp = histptr + getn(str);
        !           159:        else
        !           160:        if (digit(*str))
        !           161:                hp = histptr + (getn(str) - source->line);
        !           162:        else 
        !           163:        if (*str == '?')        /* unanchored match */
        !           164:                for (hp = histptr-1; hp >= history; hp--)
        !           165:                        if (strstr(*hp, str+1) != NULL)
        !           166:                                break;
        !           167:        else                    /* anchored match */
        !           168:                for (hp = histptr; hp >= history; hp--)
        !           169:                        if (strncmp(*hp, str, strlen(str)) == 0)
        !           170:                                break;
        !           171: 
        !           172:        return (history <= hp && hp <= histptr) ? hp : NULL;
        !           173: }
        !           174: 
        !           175: char *
        !           176: histrpl(s, pat, rep)
        !           177:        char *s;
        !           178:        char *pat, *rep;
        !           179: {
        !           180:        char *s1;
        !           181: 
        !           182:        if (strlen(s) - strlen(pat) + strlen(rep) >= LINE)
        !           183:                errorf("substitution too long\n");
        !           184:        s1 = strstr(s, pat);
        !           185:        if (s1 == NULL)
        !           186:                errorf("substitution failed\n");
        !           187:        *s1 = '\0';
        !           188:        strcpy(line, s);        /* first part */
        !           189:        strcat(line, rep);      /* replacement */
        !           190:        strcat(line, s1 + strlen(pat)); /* last part */
        !           191:        return line;
        !           192: }
        !           193: 
        !           194: #if 0
        !           195: 
        !           196: /* History file management routines (by DPK@BRL) */
        !           197: 
        !           198: void
        !           199: hist_init()
        !           200: {
        !           201:        register struct namnod *n;
        !           202:        int fd;
        !           203: 
        !           204:        if (hist_fd >= 0 || (flags&oneflg))
        !           205:                return;
        !           206:        if ((n = findnam(histname)) == (struct namnod *)0
        !           207:         || n->namval == (char *)0)
        !           208:                return;
        !           209:        if ((fd = open(n->namval, O_RDWR)) >= 0) {
        !           210:                hist_load(fd);
        !           211:                (void)fcntl(fd, F_SETFL, O_APPEND);
        !           212:        }
        !           213:        hist_fd = fd;
        !           214: }
        !           215: 
        !           216: void
        !           217: hist_finish()
        !           218: {
        !           219:        if (hist_fd >= 0)
        !           220:                (void)close(hist_fd);
        !           221:        hist_fd = -1;
        !           222: }
        !           223: 
        !           224: void
        !           225: hist_record(buf, len)
        !           226: char   *buf;
        !           227: int    len;
        !           228: {
        !           229:        if (hist_fd >= 0)
        !           230:                (void)write(hist_fd, buf, (unsigned)len);
        !           231: }
        !           232: 
        !           233: void
        !           234: hist_load(fd)
        !           235: int    fd;
        !           236: {
        !           237:        extern long     lseek();
        !           238:        struct stat sb;
        !           239:        char *x;
        !           240:        register char *cmdp, *end;
        !           241:        register int    len;
        !           242:        register int    i;
        !           243: 
        !           244:        if (fstat(fd, &sb) < 0 || sb.st_size <= 0)
        !           245:                return;
        !           246:        if (x = alloc((unsigned)(sb.st_size+1))) {
        !           247:                (void)lseek(fd, 0L, 0);
        !           248:                if ((len = read(fd, x, (unsigned)sb.st_size)) <= 0) {
        !           249:                        free((struct blk *)x);
        !           250:                        return;
        !           251:                }
        !           252:                x[len] = 0;
        !           253:                end = x;
        !           254:                for (;;) {
        !           255:                        while(*end == NL)
        !           256:                                end++;          /* Skip NL */
        !           257:                        if (*end == 0)
        !           258:                                break;
        !           259:                        cmdp = end;
        !           260:                        while(*end && *end != NL)
        !           261:                                end++;  /* Goto NL */
        !           262:                        if (*end == 0)
        !           263:                                break;
        !           264:                        if ((len = (end - cmdp)) < 2)
        !           265:                                continue;
        !           266:                        if (len >= BUFSIZ)
        !           267:                                len = BUFSIZ - 1;               /* Protection */
        !           268:                        i = curhist % NHISTORY;
        !           269:                        if(histbuf[i])
        !           270:                                free((struct blk *)histbuf[i]);
        !           271:                        histbuf[i] = alloc((unsigned)(len+1));
        !           272:                        (void)strncpy(histbuf[i], cmdp, len);
        !           273:                        histbuf[i][len] = 0;
        !           274:                        curhist++;
        !           275:                        histpc=curhist;
        !           276:                }
        !           277:                free((struct blk *)x);
        !           278:        }
        !           279:        return;
        !           280: }
        !           281: 
        !           282: #endif
        !           283: 

unix.superglobalmegacorp.com

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