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

unix.superglobalmegacorp.com

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