Annotation of researchv10no/cmd/equal/=.c, revision 1.1.1.1

1.1       root        1: /*% cc -O %
                      2:  * =, == -- redo commands from history
                      3:  */
                      4: #include <stdio.h>
                      5: #define        TRUE    1
                      6: #define        FALSE   0
                      7: #define LBSIZE 512
                      8: 
                      9: char *malloc(), *realloc();
                     10: 
                     11: #define Malloc(type,size)      ((type *)malloc((size)*sizeof(type)))
                     12: #define Realloc(type,ptr,size) ((type *)realloc(ptr,(size)*sizeof(type)))
                     13: 
                     14: char linebuf[LBSIZE];
                     15: char *linebp;
                     16: char *getenv();
                     17: char *cmd;
                     18: char genbuf[LBSIZE];
                     19: #define        RHSIZE  512
                     20: char rhsbuf[RHSIZE];
                     21: FILE *tty;
                     22: int nextcol(col,cp,input)
                     23: register col;
                     24: register char *cp;
                     25: int input;
                     26: {
                     27:        register char c;
                     28:        c = *cp;
                     29:        if (c=='\t')
                     30:                col |= 07;
                     31:        else if (c<' ' || c=='\177')
                     32:                error("Invalid character in command");
                     33:        return (++col);
                     34: }
                     35: xform(hfile)
                     36: FILE *hfile;
                     37: {
                     38:        register char *i, *m, *o;
                     39:        int *line, insert, ic, mc, c;
                     40:        char *tf, *tl;
                     41:        for(;;){
                     42:                dumpline(2);
                     43:                m=rhsbuf;
                     44:                while ((c = getc(tty))!='\n') {
                     45:                        if (c == EOF)
                     46:                                exit(0);
                     47:                        *m++ = c;
                     48:                        if (m==rhsbuf+RHSIZE-1)
                     49:                                error("Out of space");
                     50:                }
                     51:                *m='\0';
                     52:                if (m==rhsbuf)
                     53:                        break;
                     54:                if (rhsbuf[0] == '=' && rhsbuf[1] == 0) {
                     55:                        prevline(hfile);
                     56:                        continue;
                     57:                }
                     58:                i=linebuf;
                     59:                o=genbuf;
                     60:                do ; while (*o++ = *i++);
                     61:                if (i+(m-rhsbuf) > linebuf+LBSIZE)
                     62:                        error("Out of space");
                     63:                i=genbuf;
                     64:                o=linebuf;
                     65:                m=rhsbuf;
                     66:                insert=FALSE;
                     67:                ic=0;
                     68:                mc=0;
                     69:                while (*i && *m && !insert) {
                     70:                        if(*i=='\t' && *m!='#' && *m!='^' && *m!='$') {
                     71:                                ic=nextcol(ic,i,FALSE);
                     72:                                tf=m;
                     73:                                tl=m;
                     74:                                do {
                     75:                                        if (*m!=' ' && *m!='\t') {
                     76:                                                if(*m=='%')
                     77:                                                        *m=' ';
                     78:                                                tl=m+1;
                     79:                                        }
                     80:                                        mc=nextcol(mc,m++,TRUE);
                     81:                                } while (ic>mc && *m && *m!='#' &&
                     82:                                         *m!='^' && *m!='$');
                     83:                                if (ic>mc) {
                     84:                                        ic=mc;
                     85:                                        if (*m)
                     86:                                                tl=m;
                     87:                                } else {
                     88:                                        if (tl==m)
                     89:                                                i++;
                     90:                                        else
                     91:                                                ic--;
                     92:                                }
                     93:                                while (tf!=tl)
                     94:                                        *o++ = *tf++;
                     95:                        } else {
                     96:                                mc=nextcol(mc,m,TRUE);
                     97:                                *o = *m;
                     98:                                switch (*m++) {
                     99:                                case ' ':
                    100:                                case '\t':
                    101:                                        break;
                    102:                                case '^':
                    103:                                        mc=ic;
                    104:                                        insert++;
                    105:                                        break;
                    106:                                case '$':
                    107:                                        i="";
                    108:                                        break;
                    109:                                case '#':
                    110:                                        ic=nextcol(ic,i++,FALSE);
                    111:                                        while(*m=='#' && ic>mc)
                    112:                                              mc=nextcol(mc,m++,TRUE);
                    113:                                        if (ic!=mc)
                    114:                                                error("Partly deleted tab");
                    115:                                        break;
                    116:                                case '%':
                    117:                                        *o = ' ';
                    118:                                        /* fall through */
                    119:                                default:
                    120:                                        o++;
                    121:                                        ic=nextcol(ic,i++,FALSE);
                    122:                                }
                    123:                        }
                    124:                        for (;;) {
                    125:                                if (ic>mc && *m) {
                    126:                                        if (*m!=' ' && *m!='\t')
                    127:                                                error("Skipped non-blank");
                    128:                                        mc=nextcol(mc,m++,TRUE);
                    129:                                } else if (mc>ic && *i) {
                    130:                                        ic=nextcol(ic,i,FALSE);
                    131:                                        *o++ = *i++;
                    132:                                } else
                    133:                                        break;
                    134:                        }
                    135:                }
                    136:                if (mc>ic && m[-1]=='\t')
                    137:                        *o++ = '\t';
                    138:                while (*m)
                    139:                        *o++ = *m++;
                    140:                do ; while (*o++ = *i++);
                    141:        }
                    142: }
                    143: error(s)
                    144: char *s;
                    145: {
                    146:        fprintf(stderr, "%s: %s\n", cmd, s);
                    147:        exit(1);
                    148: }
                    149: char *histname;
                    150: char *shellname;
                    151: main(argc, argv)
                    152: char *argv[];
                    153: {
                    154:        register FILE *f; FILE *getline();
                    155:        register nsubst, i;
                    156:        char *strchr();
                    157:        int edit=0;
                    158:        int print=0;
                    159:        cmd=argv[0];
                    160:        if(cmd[0]!='\0'){
                    161:                if(cmd[1]==cmd[0])
                    162:                        edit++;
                    163:                if(cmd[1]=='p' || cmd[1]!='\0' && cmd[2]=='p')
                    164:                        print++;
                    165:        }
                    166:        for(nsubst=0;argc>1 && strchr(argv[argc-1], cmd[0])!=NULL;nsubst++)
                    167:                --argc;
                    168:        histname=getenv("HISTORY");
                    169:        shellname=getenv("SHELL");
                    170:        if (shellname == 0 || *shellname == 0)
                    171:                shellname = "/bin/sh";
                    172:        f = getline(argc, argv);
                    173:        for(i=0;i!=nsubst;i++)
                    174:                alter(argv[argc+i]);
                    175:        if(edit){
                    176:                if((tty=fopen("/dev/tty", "r"))==0)
                    177:                        tty=stdin;
                    178:                xform(f);
                    179:        }
                    180:        fclose(f);
                    181:        if((f=fopen(histname, "a"))!=NULL){
                    182:                fprintf(f, "%s\n", linebuf);
                    183:                fclose(f);
                    184:        }
                    185:        if(print)
                    186:                dumpline(1);
                    187:        else{
                    188:                if(!edit)
                    189:                        dumpline(2);
                    190:                execl(shellname, "sh", "-c", linebuf, (char *)0);
                    191:                error("No shell!\n");
                    192:        }
                    193: }
                    194: dumpline(fd){
                    195:        /* write on fd directly for speed */
                    196:        write(fd, linebuf, strlen(linebuf));
                    197:        write(2, "\n", 1);
                    198: }
                    199: /*
                    200:  * Look at $HISTORY.  If argc==1 get the last non-blank line in the file.
                    201:  * Otherwise, argv[1] is a pattern to match against the lines of the history
                    202:  * file.  The last matching line wins.
                    203:  */
                    204: FILE *
                    205: getline(argc, argv)
                    206: char *argv[];
                    207: {
                    208:        char history[LBSIZE];
                    209:        char pat[LBSIZE];
                    210:        register char *hp;
                    211:        register FILE *f;
                    212:        register i;
                    213:        int nmatch=0, ntell;
                    214:        if(histname==NULL)
                    215:                error("Environment lacks HISTORY\n");
                    216:        if((f=fopen(histname, "r"))==NULL){
                    217:                perror(histname);
                    218:                exit(1);
                    219:        }
                    220:        pat[0]='\0';
                    221:        for(i=1;i!=argc && argv[i][0]!=cmd[0];i++){
                    222:                strcat(pat, argv[i]);
                    223:                strcat(pat, " ");
                    224:        }
                    225:        pat[strlen(pat)-1]='\0';        /* annul the extra space */
                    226:        while(ntell=ftell(f), fgets(history, LBSIZE, f)){
                    227:                /*
                    228:                 * Skip leading blanks or tabs
                    229:                 */
                    230:                for(hp=history;*hp==' '||*hp=='\t';hp++)
                    231:                        ;
                    232:                if(anyequals(hp))
                    233:                        continue;
                    234:                /*
                    235:                 * Welcome to the land of snakey logic
                    236:                 */
                    237:                if(pat[0]=='\0'?!empty(hp):match(hp, pat)){
                    238:                        linesave(ntell, nmatch++);
                    239:                        strncpy(linebuf, hp, LBSIZE);
                    240:                }
                    241:        }
                    242:        if(nmatch==0)
                    243:                error("Can't find a line to redo");
                    244:        linebuf[strlen(linebuf)-1]='\0';        /* delete a newline */
                    245:        return f;
                    246: }
                    247: 
                    248: #define VECSIZE        512
                    249: int *matchvec, *matchend, *lastmatch, *lastuniq, vecsize;
                    250: 
                    251: linesave(adr, i)
                    252: {
                    253:        if (matchvec == 0)
                    254:                matchend = matchvec = Malloc(int, vecsize = VECSIZE);
                    255:        if (i >= vecsize)
                    256:                matchvec = Realloc(int, matchvec, vecsize += VECSIZE);
                    257:        if (matchvec == 0)
                    258:                return;
                    259:        *matchend++ = adr;
                    260: }
                    261: 
                    262: prevline(f)
                    263: FILE *f;
                    264: {
                    265:        char history[LBSIZE]; char *strchr(), *savestr();
                    266:        register char *hp; register int *ip;
                    267:        if (matchvec == 0)
                    268:                return;
                    269:        if (lastmatch == 0)
                    270:                lastuniq = matchend, lastmatch = --matchend;
                    271:        *--lastuniq = (int)savestr(linebuf);
                    272:        do {
                    273:                if (--lastmatch < matchvec) {
                    274:                        matchvec = 0;
                    275:                        return;
                    276:                }
                    277:                fseek(f, *lastmatch, 0);
                    278:                fgets(history, LBSIZE, f);
                    279:                for(hp=history;*hp==' '||*hp=='\t';hp++)
                    280:                        ;
                    281:                *strchr(hp,'\n') = '\0';
                    282:                for (ip=lastuniq; ip <= matchend; ip++)
                    283:                        if (strcmp((char *)(*ip), hp) == 0) break;
                    284:        } while (ip <= matchend);
                    285:        strncpy(linebuf, hp, LBSIZE);
                    286: }
                    287: 
                    288: char *
                    289: savestr(str)   /* Place string into permanent storage. */
                    290: register char *str;
                    291: {
                    292:        static int nchleft; static char *strpt;
                    293:        register int len; char *strcpy();
                    294: 
                    295:        if ((len = strlen(str)+1) > nchleft) {
                    296:                strpt = malloc(nchleft = 2*LBSIZE);
                    297:        }
                    298:        if (strpt == 0)
                    299:                return 0;
                    300:        str = strcpy(strpt, str);
                    301:        strpt += len; nchleft -= len;
                    302:        return str;
                    303: }
                    304: 
                    305: /*
                    306:  * Throw away any command with an = or == word
                    307:  */
                    308: anyequals(line)
                    309:        register char *line;
                    310: {
                    311:        register char *p, *q;
                    312:        for(p=line; *p; p++)
                    313:                if(*p=='=' && (p==line || p[-1]==' ' || p[-1]=='\t')){
                    314:                        if(p[1]=='=')
                    315:                                p++;
                    316:                        if(p[1]=='\n' || p[1]==' ' || p[1]=='\t')
                    317:                                return 1;
                    318:                }
                    319:        return 0;
                    320: }
                    321: match(s, p)
                    322: register char *s, *p;
                    323: {
                    324:        register char *h;
                    325:        for(h=s;*s!='\n' && *s!=' ' && *s!='\t' && *s!='\0';s++)
                    326:                if(*s=='/')
                    327:                        h=s+1;
                    328:        return(startis(h, p));
                    329: }
                    330: startis(s, p)
                    331: register char *s, *p;
                    332: {
                    333:        while(*p!='\0')
                    334:                if(*p==' '){
                    335:                        if(*s!=' ' && *s!='\t')
                    336:                                return(0);
                    337:                        while(*s==' ' || *s=='\t')
                    338:                                s++;
                    339:                        p++;
                    340:                }
                    341:                else if(*s++ != *p++)
                    342:                        return(0);
                    343:        return(1);
                    344: }
                    345: empty(s)
                    346: register char *s;
                    347: {
                    348:        if(*s==cmd[0])
                    349:                return(1);
                    350:        while(*s!='\0'){
                    351:                if(*s!=' ' && *s!='\t' && *s!='\n')
                    352:                        return(0);
                    353:                s++;
                    354:        }
                    355:        return(1);
                    356: }
                    357: alter(pat)
                    358: register char *pat;
                    359: {
                    360:        register char *sub, *s=linebuf, *t=genbuf;
                    361:        int patlen, sublen, matched=0;
                    362:        for(sub=pat;*sub!=cmd[0] && *sub!='\0';sub++);
                    363:        if(*sub!=cmd[0])
                    364:                error("Bad Substitution");
                    365:        patlen=sub-pat;
                    366:        if(*sub==cmd[0])
                    367:                *sub++='\0';
                    368:        sublen=strlen(sub);
                    369:        while(*s)
                    370:                if(!matched && startis(s, pat)){
                    371:                        matched++;
                    372:                        s+=patlen;
                    373:                        strcpy(t, sub);
                    374:                        t+=sublen;
                    375:                }
                    376:                else
                    377:                        *t++ = *s++;
                    378:        if(!matched)
                    379:                error("No pattern match");
                    380:        *t='\0';
                    381:        strcpy(linebuf, genbuf);
                    382: }

unix.superglobalmegacorp.com

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