Annotation of researchv9/cmd/equal/=.c, 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: 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.