Annotation of 42BSD/bin/sh/macro.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)macro.c    4.3 8/11/83";
                      3: #endif
                      4: 
                      5: #
                      6: /*
                      7:  * UNIX shell
                      8:  *
                      9:  * S. R. Bourne
                     10:  * Bell Telephone Laboratories
                     11:  *
                     12:  */
                     13: 
                     14: #include       "defs.h"
                     15: #include       "sym.h"
                     16: 
                     17: LOCAL CHAR     quote;  /* used locally */
                     18: LOCAL CHAR     quoted; /* used locally */
                     19: 
                     20: 
                     21: 
                     22: LOCAL STRING   copyto(endch)
                     23:        REG CHAR        endch;
                     24: {
                     25:        REG CHAR        c;
                     26: 
                     27:        WHILE (c=getch(endch))!=endch ANDF c
                     28:        DO pushstak(c|quote) OD
                     29:        zerostak();
                     30:        IF c!=endch THEN error(badsub) FI
                     31: }
                     32: 
                     33: LOCAL  skipto(endch)
                     34:        REG CHAR        endch;
                     35: {
                     36:        /* skip chars up to } */
                     37:        REG CHAR        c;
                     38:        WHILE (c=readc()) ANDF c!=endch
                     39:        DO      SWITCH c IN
                     40: 
                     41:                case SQUOTE:    skipto(SQUOTE); break;
                     42: 
                     43:                case DQUOTE:    skipto(DQUOTE); break;
                     44: 
                     45:                case DOLLAR:    IF readc()==BRACE
                     46:                                THEN    skipto('}');
                     47:                                FI
                     48:                ENDSW
                     49:        OD
                     50:        IF c!=endch THEN error(badsub) FI
                     51: }
                     52: 
                     53: LOCAL  getch(endch)
                     54:        CHAR            endch;
                     55: {
                     56:        REG CHAR        d;
                     57: 
                     58: retry:
                     59:        d=readc();
                     60:        IF !subchar(d)
                     61:        THEN    return(d);
                     62:        FI
                     63:        IF d==DOLLAR
                     64:        THEN    REG INT c;
                     65:                IF (c=readc(), dolchar(c))
                     66:                THEN    NAMPTR          n=NIL;
                     67:                        INT             dolg=0;
                     68:                        BOOL            bra;
                     69:                        REG STRING      argp, v;
                     70:                        CHAR            idb[2];
                     71:                        STRING          id=idb;
                     72: 
                     73:                        IF bra=(c==BRACE) THEN c=readc() FI
                     74:                        IF letter(c)
                     75:                        THEN    argp=relstak();
                     76:                                WHILE alphanum(c) DO pushstak(c); c=readc() OD
                     77:                                zerostak();
                     78:                                n=lookup(absstak(argp)); setstak(argp);
                     79:                                v = n->namval; id = n->namid;
                     80:                                peekc = c|MARK;;
                     81:                        ELIF digchar(c)
                     82:                        THEN    *id=c; idb[1]=0;
                     83:                                IF astchar(c)
                     84:                                THEN    dolg=1; c='1';
                     85:                                FI
                     86:                                c -= '0';
                     87:                                v=((c==0) ? cmdadr : (c<=dolc) ? dolv[c] : (dolg=0));
                     88:                        ELIF c=='$'
                     89:                        THEN    v=pidadr;
                     90:                        ELIF c=='!'
                     91:                        THEN    v=pcsadr;
                     92:                        ELIF c=='#'
                     93:                        THEN    v=dolladr;
                     94:                        ELIF c=='?'
                     95:                        THEN    v=exitadr;
                     96:                        ELIF c=='-'
                     97:                        THEN    v=flagadr;
                     98:                        ELIF bra THEN error(badsub);
                     99:                        ELSE    goto retry;
                    100:                        FI
                    101:                        c = readc();
                    102:                        IF !defchar(c) ANDF bra
                    103:                        THEN    error(badsub);
                    104:                        FI
                    105:                        argp=0;
                    106:                        IF bra
                    107:                        THEN    IF c!='}'
                    108:                                THEN    argp=relstak();
                    109:                                        IF (v==0)NEQ(setchar(c))
                    110:                                        THEN    copyto('}');
                    111:                                        ELSE    skipto('}');
                    112:                                        FI
                    113:                                        argp=absstak(argp);
                    114:                                FI
                    115:                        ELSE    peekc = c|MARK; c = 0;
                    116:                        FI
                    117:                        IF v
                    118:                        THEN    IF c!='+'
                    119:                                THEN    LOOP WHILE c = *v++
                    120:                                             DO pushstak(c|quote); OD
                    121:                                             IF dolg==0 ORF (++dolg>dolc)
                    122:                                             THEN break;
                    123:                                             ELSE v=dolv[dolg]; pushstak(SP|(*id=='*' ? quote : 0));
                    124:                                             FI
                    125:                                        POOL
                    126:                                FI
                    127:                        ELIF argp
                    128:                        THEN    IF c=='?'
                    129:                                THEN    failed(id,*argp?argp:badparam);
                    130:                                ELIF c=='='
                    131:                                THEN    IF n
                    132:                                        THEN    assign(n,argp);
                    133:                                        ELSE    error(badsub);
                    134:                                        FI
                    135:                                FI
                    136:                        ELIF flags&setflg
                    137:                        THEN    failed(id,badparam);
                    138:                        FI
                    139:                        goto retry;
                    140:                ELSE    peekc=c|MARK;
                    141:                FI
                    142:        ELIF d==endch
                    143:        THEN    return(d);
                    144:        ELIF d==SQUOTE
                    145:        THEN    comsubst(); goto retry;
                    146:        ELIF d==DQUOTE
                    147:        THEN    quoted++; quote^=QUOTE; goto retry;
                    148:        FI
                    149:        return(d);
                    150: }
                    151: 
                    152: STRING macro(as)
                    153:        STRING          as;
                    154: {
                    155:        /* Strip "" and do $ substitution
                    156:         * Leaves result on top of stack
                    157:         */
                    158:        REG BOOL        savqu =quoted;
                    159:        REG CHAR        savq = quote;
                    160:        FILEHDR         fb;
                    161: 
                    162:        push(&fb); estabf(as);
                    163:        usestak();
                    164:        quote=0; quoted=0;
                    165:        copyto(0);
                    166:        pop();
                    167:        IF quoted ANDF (stakbot==staktop) THEN pushstak(QUOTE) FI
                    168:        quote=savq; quoted=savqu;
                    169:        return(fixstak());
                    170: }
                    171: 
                    172: LOCAL  comsubst()
                    173: {
                    174:        /* command substn */
                    175:        FILEBLK         cb;
                    176:        REG CHAR        d;
                    177:        REG STKPTR      savptr = fixstak();
                    178: 
                    179:        usestak();
                    180:        WHILE (d=readc())!=SQUOTE ANDF d
                    181:        DO pushstak(d) OD
                    182: 
                    183:        BEGIN
                    184:           REG STRING   argc;
                    185:           trim(argc=fixstak());
                    186:           push(&cb); estabf(argc);
                    187:        END
                    188:        BEGIN
                    189:           REG TREPTR   t = makefork(FPOU,cmd(EOFSYM,MTFLG|NLFLG));
                    190:           INT          pv[2];
                    191: 
                    192:           /* this is done like this so that the pipe
                    193:            * is open only when needed
                    194:            */
                    195:           chkpipe(pv);
                    196:           initf(pv[INPIPE]);
                    197:           execute(t, 0, 0, pv);
                    198:           close(pv[OTPIPE]);
                    199:        END
                    200:        tdystak(savptr); staktop=movstr(savptr,stakbot);
                    201:        WHILE d=readc() DO locstak(); pushstak(d|quote) OD
                    202:        await(0);
                    203:        WHILE stakbot!=staktop
                    204:        DO      IF (*--staktop&STRIP)!=NL
                    205:                THEN    ++staktop; break;
                    206:                FI
                    207:        OD
                    208:        pop();
                    209: }
                    210: 
                    211: #define CPYSIZ 512
                    212: 
                    213: subst(in,ot)
                    214:        INT             in, ot;
                    215: {
                    216:        REG CHAR        c;
                    217:        FILEBLK         fb;
                    218:        REG INT         count=CPYSIZ;
                    219: 
                    220:        push(&fb); initf(in);
                    221:        /* DQUOTE used to stop it from quoting */
                    222:        WHILE c=(getch(DQUOTE)&STRIP)
                    223:        DO pushstak(c);
                    224:           IF --count == 0
                    225:           THEN flush(ot); count=CPYSIZ;
                    226:           FI
                    227:        OD
                    228:        flush(ot);
                    229:        pop();
                    230: }
                    231: 
                    232: LOCAL  flush(ot)
                    233: {
                    234:        write(ot,stakbot,staktop-stakbot);
                    235:        IF flags&execpr THEN write(output,stakbot,staktop-stakbot) FI
                    236:        staktop=stakbot;
                    237: }

unix.superglobalmegacorp.com

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