Annotation of researchv9/cmd/sh/macro.c, revision 1.1.1.1

1.1       root        1: /*     @(#)macro.c     1.5     */
                      2: /*
                      3:  * UNIX shell
                      4:  *
                      5:  * Bell Telephone Laboratories
                      6:  *
                      7:  */
                      8: 
                      9: #include       "defs.h"
                     10: #include       "sym.h"
                     11: 
                     12: static char    quote;  /* used locally */
                     13: static char    quoted; /* used locally */
                     14: 
                     15: static int     getch();
                     16: static int     flush();
                     17: static int     comsubst();
                     18: 
                     19: static char *
                     20: copyto(endch)
                     21: register char  endch;
                     22: {
                     23:        register char   c;
                     24: 
                     25:        while ((c = getch(endch)) != endch && c)
                     26:                pushstak(c | quote);
                     27:        zerostak();
                     28:        if (c != endch)
                     29:                error(badsub);
                     30: }
                     31: 
                     32: static
                     33: skipto(endch)
                     34: register char  endch;
                     35: {
                     36:        /*
                     37:         * skip chars up to }
                     38:         */
                     39:        register char   c;
                     40: 
                     41:        while ((c = readc()) && c != endch)
                     42:        {
                     43:                switch (c)
                     44:                {
                     45:                case SQUOTE:
                     46:                        skipto(SQUOTE);
                     47:                        break;
                     48: 
                     49:                case DQUOTE:
                     50:                        skipto(DQUOTE);
                     51:                        break;
                     52: 
                     53:                case DOLLAR:
                     54:                        if (readc() == BRACE)
                     55:                                skipto('}');
                     56:                }
                     57:        }
                     58:        if (c != endch)
                     59:                error(badsub);
                     60: }
                     61: 
                     62: static
                     63: getch(endch)
                     64: char   endch;
                     65: {
                     66:        register char   d;
                     67: 
                     68: retry:
                     69:        d = readc();
                     70:        if (!subchar(d))
                     71:                return(d);
                     72:        if (d == DOLLAR)
                     73:        {
                     74:                register int    c;
                     75: 
                     76:                if ((c = readc(), dolchar(c)))
                     77:                {
                     78:                        struct namnod *n = (struct namnod *)NIL;
                     79:                        int             dolg = 0;
                     80:                        BOOL            bra;
                     81:                        BOOL            nulflg;
                     82:                        register char   *argp, *v;
                     83:                        char            idb[2];
                     84:                        char            *id = idb;
                     85: 
                     86:                        if (bra = (c == BRACE))
                     87:                                c = readc();
                     88:                        if (letter(c))
                     89:                        {
                     90:                                argp = (char *)relstak();
                     91:                                while (alphanum(c))
                     92:                                {
                     93:                                        pushstak(c);
                     94:                                        c = readc();
                     95:                                }
                     96:                                zerostak();
                     97:                                n = lookup(absstak(argp));
                     98:                                setstak(argp);
                     99:                                if (n->namval.flg & N_FUNCTN)
                    100:                                        error(badsub);
                    101:                                v = n->namval.val;
                    102:                                id = n->namid;
                    103:                                peekc = c | MARK;
                    104:                        }
                    105:                        else if (digchar(c))
                    106:                        {
                    107:                                *id = c;
                    108:                                idb[1] = 0;
                    109:                                if (astchar(c))
                    110:                                {
                    111:                                        dolg = 1;
                    112:                                        c = '1';
                    113:                                }
                    114:                                c -= '0';
                    115:                                v = ((c == 0) ? cmdadr : (c <= dolc) ? dolv[c] : (char *)(dolg = 0));
                    116:                        }
                    117:                        else if (c == '$')
                    118:                                v = pidadr;
                    119:                        else if (c == '!')
                    120:                                v = pcsadr;
                    121:                        else if (c == '#')
                    122:                        {
                    123:                                itos(dolc);
                    124:                                v = numbuf;
                    125:                        }
                    126:                        else if (c == '?')
                    127:                        {
                    128:                                itos(retval);
                    129:                                v = numbuf;
                    130:                        }
                    131:                        else if (c == '-')
                    132:                                v = flagadr;
                    133:                        else if (bra)
                    134:                                error(badsub);
                    135:                        else
                    136:                                goto retry;
                    137:                        c = readc();
                    138:                        if (c == ':' && bra)    /* null and unset fix */
                    139:                        {
                    140:                                nulflg = 1;
                    141:                                c = readc();
                    142:                        }
                    143:                        else
                    144:                                nulflg = 0;
                    145:                        if (!defchar(c) && bra)
                    146:                                error(badsub);
                    147:                        argp = 0;
                    148:                        if (bra)
                    149:                        {
                    150:                                if (c != '}')
                    151:                                {
                    152:                                        argp = (char *)relstak();
                    153:                                        if ((v == 0 || (nulflg && *v == 0)) ^ (setchar(c)))
                    154:                                                copyto('}');
                    155:                                        else
                    156:                                                skipto('}');
                    157:                                        argp = absstak(argp);
                    158:                                }
                    159:                        }
                    160:                        else
                    161:                        {
                    162:                                peekc = c | MARK;
                    163:                                c = 0;
                    164:                        }
                    165:                        if (v && (!nulflg || *v))
                    166:                        {
                    167:                                char tmp = (*id == '*' ? SP | quote : SP);
                    168: 
                    169:                                if (c != '+')
                    170:                                {
                    171:                                        for (;;)
                    172:                                        {
                    173:                                                if (*v == 0 && quote)
                    174:                                                        pushstak(QUOTE);
                    175:                                                else
                    176:                                                {
                    177:                                                        while (c = *v++)
                    178:                                                                pushstak(c | quote);
                    179:                                                }
                    180: 
                    181:                                                if (dolg == 0 || (++dolg > dolc))
                    182:                                                        break;
                    183:                                                else
                    184:                                                {
                    185:                                                        v = dolv[dolg];
                    186:                                                        pushstak(tmp);
                    187:                                                }
                    188:                                        }
                    189:                                }
                    190:                        }
                    191:                        else if (*id == '@' && quoted)
                    192:                                quoted = -1;    /* swallow the quote later */
                    193:                        else if (argp)
                    194:                        {
                    195:                                if (c == '?')
                    196:                                        failed(id, *argp ? argp : badparam);
                    197:                                else if (c == '=')
                    198:                                {
                    199:                                        if (n)
                    200:                                        {
                    201:                                                trim(argp);
                    202:                                                assign(n, argp);
                    203:                                        }
                    204:                                        else
                    205:                                                error(badsub);
                    206:                                }
                    207:                        }
                    208:                        else if (flags & setflg)
                    209:                                failed(id, unset);
                    210:                        goto retry;
                    211:                }
                    212:                else
                    213:                        peekc = c | MARK;
                    214:        }
                    215:        else if (d == endch)
                    216:                return(d);
                    217:        else if (d == SQUOTE)
                    218:        {
                    219:                comsubst();
                    220:                goto retry;
                    221:        }
                    222:        else if (d == DQUOTE)
                    223:        {
                    224:                quoted++;
                    225:                quote ^= QUOTE;
                    226:                goto retry;
                    227:        }
                    228:        return(d);
                    229: }
                    230: 
                    231: char *
                    232: macro(as)
                    233: char   *as;
                    234: {
                    235:        /*
                    236:         * Strip "" and do $ substitution
                    237:         * Leaves result on top of stack
                    238:         */
                    239:        register BOOL   savqu = quoted;
                    240:        register char   savq = quote;
                    241:        struct filehdr  fb;
                    242: 
                    243:        push(&fb);
                    244:        estabf(as);
                    245:        usestak();
                    246:        quote = 0;
                    247:        quoted = 0;
                    248:        copyto(0);
                    249:        pop();
                    250:        if (quoted && (stakbot == staktop))
                    251:                pushstak(QUOTE);
                    252: /*
                    253:  * above is the fix for *'.c' bug
                    254:  */
                    255:        quote = savq;
                    256:        quoted = savqu;
                    257:        return(fixstak());
                    258: }
                    259: 
                    260: static
                    261: comsubst()
                    262: {
                    263:        /*
                    264:         * command substn
                    265:         */
                    266:        struct fileblk  cb;
                    267:        register char   d;
                    268:        register char *savptr = fixstak();
                    269:        register struct ionod *saviopend;
                    270: 
                    271:        usestak();
                    272:        while ((d = readc()) != SQUOTE && d)
                    273:                pushstak(d);
                    274:        {
                    275:                register char   *argc;
                    276: 
                    277:                trim(argc = fixstak());
                    278:                push(&cb);
                    279:                estabf(argc);
                    280:        }
                    281: 
                    282:        saviopend = iopend;
                    283:        iopend = (struct ionod *)0;
                    284:        {
                    285:                register struct trenod *t = makefork(FPOU, cmd(EOFSYM, MTFLG | NLFLG));
                    286:                int             pv[2];
                    287: 
                    288:                /*
                    289:                 * this is done like this so that the pipe
                    290:                 * is open only when needed
                    291:                 */
                    292:                chkpipe(pv);
                    293:                initf(pv[INPIPE]);
                    294:                execute(t, 0, (int)(flags & errflg), 0, pv);
                    295:                close(pv[OTPIPE]);
                    296:        }
                    297:        iopend = saviopend;
                    298: 
                    299:        tdystak(savptr);
                    300:        staktop = movstr(savptr, stakbot);
                    301:        while (d = readc())
                    302:                pushstak(d | quote);
                    303:        await(0, 0);
                    304:        while (stakbot != staktop)
                    305:        {
                    306:                if ((*--staktop & STRIP) != NL)
                    307:                {
                    308:                        ++staktop;
                    309:                        break;
                    310:                }
                    311:        }
                    312:        pop();
                    313: }
                    314: 
                    315: #define CPYSIZ 512
                    316: 
                    317: subst(in, ot)
                    318: int    in, ot;
                    319: {
                    320:        register char   c;
                    321:        struct fileblk  fb;
                    322:        register int    count = CPYSIZ;
                    323: 
                    324:        push(&fb);
                    325:        initf(in);
                    326:        /*
                    327:         * DQUOTE used to stop it from quoting
                    328:         */
                    329:        while (c = (getch(DQUOTE) & STRIP))
                    330:        {
                    331:                pushstak(c);
                    332:                if (--count == 0)
                    333:                {
                    334:                        flush(ot);
                    335:                        count = CPYSIZ;
                    336:                }
                    337:        }
                    338:        flush(ot);
                    339:        pop();
                    340: }
                    341: 
                    342: static
                    343: flush(ot)
                    344: {
                    345:        write(ot, stakbot, staktop - stakbot);
                    346:        if (flags & execpr)
                    347:                write(output, stakbot, staktop - stakbot);
                    348:        staktop = stakbot;
                    349: }

unix.superglobalmegacorp.com

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