Annotation of researchv10no/cmd/equal/=.c-1, 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: main(argc, argv)
                    151: char *argv[];
                    152: {
                    153:        register FILE *f; FILE *getline();
                    154:        register nsubst, i;
                    155:        char *strchr();
                    156:        int edit=0;
                    157:        int print=0;
                    158:        cmd=argv[0];
                    159:        if(cmd[0]!='\0'){
                    160:                if(cmd[1]==cmd[0])
                    161:                        edit++;
                    162:                if(cmd[1]=='p' || cmd[1]!='\0' && cmd[2]=='p')
                    163:                        print++;
                    164:        }
                    165:        for(nsubst=0;argc>1 && strchr(argv[argc-1], cmd[0])!=NULL;nsubst++){
                    166:                --argc;
                    167:                edit=0;
                    168:        }
                    169:        histname=getenv("HISTORY");
                    170:        f = getline(argc, argv);
                    171:        for(i=0;i!=nsubst;i++)
                    172:                alter(argv[argc+i]);
                    173:        if(edit){
                    174:                if((tty=fopen("/dev/tty", "r"))==0)
                    175:                        tty=stdin;
                    176:                xform(f);
                    177:        }
                    178:        fclose(f);
                    179:        if((f=fopen(histname, "a"))!=NULL){
                    180:                fprintf(f, "%s\n", linebuf);
                    181:                fclose(f);
                    182:        }
                    183:        if(print)
                    184:                dumpline(1);
                    185:        else{
                    186:                if(!edit)
                    187:                        dumpline(2);
                    188:                execl("/bin/sh", "sh", "-c", linebuf, (char *)0);
                    189:                error("No shell!\n");
                    190:        }
                    191: }
                    192: dumpline(fd){
                    193:        /* write on fd directly for speed */
                    194:        write(fd, linebuf, strlen(linebuf));
                    195:        write(2, "\n", 1);
                    196: }
                    197: /*
                    198:  * Look at $HISTORY.  If argc==1 get the last non-blank line in the file.
                    199:  * Otherwise, argv[1] is a pattern to match against the lines of the history
                    200:  * file.  The last matching line wins.
                    201:  */
                    202: FILE *
                    203: getline(argc, argv)
                    204: char *argv[];
                    205: {
                    206:        char history[LBSIZE];
                    207:        char pat[LBSIZE];
                    208:        register char *hp;
                    209:        register FILE *f;
                    210:        register i;
                    211:        int nmatch=0, ntell;
                    212:        if(histname==NULL)
                    213:                error("Environment lacks HISTORY\n");
                    214:        if((f=fopen(histname, "r"))==NULL){
                    215:                perror(histname);
                    216:                exit(1);
                    217:        }
                    218:        pat[0]='\0';
                    219:        for(i=1;i!=argc && argv[i][0]!=cmd[0];i++){
                    220:                strcat(pat, argv[i]);
                    221:                strcat(pat, " ");
                    222:        }
                    223:        pat[strlen(pat)-1]='\0';        /* annul the extra space */
                    224:        while(ntell=ftell(f), fgets(history, LBSIZE, f)){
                    225:                /*
                    226:                 * Skip leading blanks or tabs
                    227:                 */
                    228:                for(hp=history;*hp==' '||*hp=='\t';hp++)
                    229:                        ;
                    230:                if(anyequals(hp))
                    231:                        continue;
                    232:                /*
                    233:                 * Welcome to the land of snakey logic
                    234:                 */
                    235:                if(pat[0]=='\0'?!empty(hp):match(hp, pat)){
                    236:                        linesave(ntell, nmatch++);
                    237:                        strncpy(linebuf, hp, LBSIZE);
                    238:                }
                    239:        }
                    240:        if(nmatch==0)
                    241:                error("Can't find a line to redo");
                    242:        linebuf[strlen(linebuf)-1]='\0';        /* delete a newline */
                    243:        return f;
                    244: }
                    245: 
                    246: #define VECSIZE        512
                    247: int *matchvec, *matchend, *lastmatch, *lastuniq, vecsize;
                    248: 
                    249: linesave(adr, i)
                    250: {
                    251:        if (matchvec == 0)
                    252:                matchend = matchvec = Malloc(int, vecsize = VECSIZE);
                    253:        if (i >= vecsize)
                    254:                matchvec = Realloc(int, matchvec, vecsize += VECSIZE);
                    255:        if (matchvec == 0)
                    256:                return;
                    257:        *matchend++ = adr;
                    258: }
                    259: 
                    260: prevline(f)
                    261: FILE *f;
                    262: {
                    263:        char history[LBSIZE]; char *strchr(), *savestr();
                    264:        register char *hp; register int *ip;
                    265:        if (matchvec == 0)
                    266:                return;
                    267:        if (lastmatch == 0)
                    268:                lastuniq = matchend, lastmatch = --matchend;
                    269:        *--lastuniq = (int)savestr(linebuf);
                    270:        do {
                    271:                if (--lastmatch < matchvec) {
                    272:                        matchvec = 0;
                    273:                        return;
                    274:                }
                    275:                fseek(f, *lastmatch, 0);
                    276:                fgets(history, LBSIZE, f);
                    277:                for(hp=history;*hp==' '||*hp=='\t';hp++)
                    278:                        ;
                    279:                *strchr(hp,'\n') = '\0';
                    280:                for (ip=lastuniq; ip <= matchend; ip++)
                    281:                        if (strcmp((char *)(*ip), hp) == 0) break;
                    282:        } while (ip <= matchend);
                    283:        strncpy(linebuf, hp, LBSIZE);
                    284: }
                    285: 
                    286: char *
                    287: savestr(str)   /* Place string into permanent storage. */
                    288: register char *str;
                    289: {
                    290:        static int nchleft; static char *strpt;
                    291:        register int len; char *strcpy();
                    292: 
                    293:        if ((len = strlen(str)+1) > nchleft) {
                    294:                strpt = malloc(nchleft = 2*LBSIZE);
                    295:        }
                    296:        if (strpt == 0)
                    297:                return 0;
                    298:        str = strcpy(strpt, str);
                    299:        strpt += len; nchleft -= len;
                    300:        return str;
                    301: }
                    302: 
                    303: /*
                    304:  * Throw away any command with an = or == word
                    305:  */
                    306: anyequals(line)
                    307:        register char *line;
                    308: {
                    309:        register char *p, *q;
                    310:        for(p=line; *p; p++)
                    311:                if(*p=='=' && (p==line || p[-1]==' ' || p[-1]=='\t')){
                    312:                        if(p[1]=='=')
                    313:                                p++;
                    314:                        if(p[1]=='\n' || p[1]==' ' || p[1]=='\t')
                    315:                                return 1;
                    316:                }
                    317:        return 0;
                    318: }
                    319: match(s, p)
                    320: register char *s, *p;
                    321: {
                    322:        register char *h;
                    323:        for(h=s;*s!='\n' && *s!=' ' && *s!='\t' && *s!='\0';s++)
                    324:                if(*s=='/')
                    325:                        h=s+1;
                    326:        return(startis(h, p));
                    327: }
                    328: startis(s, p)
                    329: register char *s, *p;
                    330: {
                    331:        while(*p!='\0')
                    332:                if(*p==' '){
                    333:                        if(*s!=' ' && *s!='\t')
                    334:                                return(0);
                    335:                        while(*s==' ' || *s=='\t')
                    336:                                s++;
                    337:                        p++;
                    338:                }
                    339:                else if(*s++ != *p++)
                    340:                        return(0);
                    341:        return(1);
                    342: }
                    343: empty(s)
                    344: register char *s;
                    345: {
                    346:        if(*s==cmd[0])
                    347:                return(1);
                    348:        while(*s!='\0'){
                    349:                if(*s!=' ' && *s!='\t' && *s!='\n')
                    350:                        return(0);
                    351:                s++;
                    352:        }
                    353:        return(1);
                    354: }
                    355: alter(pat)
                    356: register char *pat;
                    357: {
                    358:        register char *sub, *s=linebuf, *t=genbuf;
                    359:        int patlen, sublen, matched=0;
                    360:        for(sub=pat;*sub!=cmd[0] && *sub!='\0';sub++);
                    361:        if(*sub!=cmd[0])
                    362:                error("Bad Substitution");
                    363:        patlen=sub-pat;
                    364:        if(*sub==cmd[0])
                    365:                *sub++='\0';
                    366:        sublen=strlen(sub);
                    367:        while(*s)
                    368:                if(!matched && startis(s, pat)){
                    369:                        matched++;
                    370:                        s+=patlen;
                    371:                        strcpy(t, sub);
                    372:                        t+=sublen;
                    373:                }
                    374:                else
                    375:                        *t++ = *s++;
                    376:        if(!matched)
                    377:                error("No pattern match");
                    378:        *t='\0';
                    379:        strcpy(linebuf, genbuf);
                    380: }

unix.superglobalmegacorp.com

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