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

unix.superglobalmegacorp.com

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