Annotation of 40BSD/cmd/sh/macro.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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