Annotation of researchv10no/cmd/equal/=.c-2, revision 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.