Annotation of coherent/a/usr/bob/korn/history.c, revision 1.1.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.