Annotation of researchv10dc/cmd/osh/expand.c, revision 1.1.1.1

1.1       root        1: /*     @(#)expand.c    1.4     */
                      2: /*
                      3:  *     UNIX shell
                      4:  *
                      5:  *     Bell Telephone Laboratories
                      6:  *
                      7:  */
                      8: 
                      9: #include       "defs.h"
                     10: #include       <sys/types.h>
                     11: #include       <sys/stat.h>
                     12: #ifdef BSD4_2
                     13: #include       <sys/dir.h>
                     14: #else
                     15: #include       <ndir.h>
                     16: #endif
                     17: 
                     18: #ifdef BSD4_2
                     19: #define                DIRSIZE MAXNAMELEN
                     20: #else
                     21: #define                DIRSIZE 14
                     22: #endif
                     23: #ifndef        MAXNAMELEN
                     24: #define        MAXNAMELEN      255
                     25: #endif
                     26: 
                     27: 
                     28: static char            entry[DIRSIZE+1];
                     29: 
                     30: /*
                     31:  * globals (file name generation)
                     32:  *
                     33:  * "*" in params matches r.e ".*"
                     34:  * "?" in params matches r.e. "."
                     35:  * "[...]" in params matches character class
                     36:  * "[...a-z...]" in params matches a through z.
                     37:  *
                     38:  */
                     39: 
                     40: static addg();
                     41: 
                     42: expand(as, rcnt)
                     43:        char    *as;
                     44: {
                     45:        int     count;
                     46:        DIR     *dirf;
                     47:        struct direct   *e;
                     48:        BOOL    dir = 0;
                     49:        char    *rescan = 0;
                     50:        register char   *s, *cs;
                     51:        struct argnod   *schain = gchain;
                     52:        BOOL    slash;
                     53: 
                     54:        if (trapnote & SIGSET)
                     55:                return(0);
                     56:        s = cs = as;
                     57:        /*
                     58:         * check for meta chars
                     59:         */
                     60:        {
                     61:                register BOOL open;
                     62: 
                     63:                slash = 0;
                     64:                open = 0;
                     65:                do
                     66:                {
                     67:                        switch (*cs++)
                     68:                        {
                     69:                        case 0:
                     70:                                if (rcnt && slash)
                     71:                                        break;
                     72:                                else
                     73:                                        return(0);
                     74: 
                     75:                        case '/':
                     76:                                slash++;
                     77:                                open = 0;
                     78:                                continue;
                     79: 
                     80:                        case '[':
                     81:                                open++;
                     82:                                continue;
                     83: 
                     84:                        case ']':
                     85:                                if (open == 0)
                     86:                                        continue;
                     87: 
                     88:                        case '?':
                     89:                        case '*':
                     90:                                if (rcnt > slash)
                     91:                                        continue;
                     92:                                else
                     93:                                        cs--;
                     94:                                break;
                     95: 
                     96: 
                     97:                        default:
                     98:                                continue;
                     99:                        }
                    100:                        break;
                    101:                } while (TRUE);
                    102:        }
                    103: 
                    104:        for (;;)
                    105:        {
                    106:                if (cs == s)
                    107:                {
                    108:                        s = nullstr;
                    109:                        break;
                    110:                }
                    111:                else if (*--cs == '/')
                    112:                {
                    113:                        *cs = 0;
                    114:                        if (s == cs)
                    115:                                s = "/";
                    116:                        break;
                    117:                }
                    118:        }
                    119: 
                    120:        if ((dirf = opendir(*s ? s : ".")) != 0)
                    121:                dir = TRUE;
                    122:        
                    123:        count = 0;
                    124:        if (*cs == 0)
                    125:                *cs++ = 0200;
                    126: 
                    127:        if(dir)
                    128:        {
                    129:                register char *rs;
                    130: 
                    131:                rs = cs;
                    132:                do
                    133:                {
                    134:                        if (*rs == '/')
                    135:                        {
                    136:                                rescan = rs;
                    137:                                *rs = 0;
                    138:                                gchain = 0;
                    139:                        }
                    140:                } while (*rs++);
                    141: 
                    142:                while ((e = readdir(dirf)) && (trapnote & SIGSET) == 0)
                    143:                {
                    144:                        *(movstrn(e->d_name, entry, DIRSIZE)) = 0;
                    145:                        if (entry[0] == '.' && *cs != '.')
                    146:                        {
                    147:                                if (entry[1] == 0)
                    148:                                        continue;
                    149:                                if (entry[1] == '.' && entry[2] == 0)
                    150:                                        continue;
                    151:                        }
                    152: 
                    153:                        if (gmatch(entry, cs))
                    154:                        {
                    155:                                addg(s, entry, rescan);
                    156:                                count++;
                    157:                        }
                    158:                }
                    159:                closedir(dirf);
                    160: 
                    161:                if (rescan)
                    162:                {
                    163:                        register struct argnod  *rchain;
                    164: 
                    165:                        rchain = gchain;
                    166:                        gchain = schain;
                    167:                        if (count)
                    168:                        {
                    169:                                count = 0;
                    170:                                while (rchain)
                    171:                                {
                    172:                                        count += expand(rchain->argval, slash + 1);
                    173:                                        rchain = rchain->argnxt;
                    174:                                }
                    175:                        }
                    176:                        *rescan = '/';
                    177:                }
                    178:        }
                    179: 
                    180:        {
                    181:                register char   c;
                    182: 
                    183:                s = as;
                    184:                while (c = *s)
                    185:                        *s++ = (c & STRIP ? c : '/');
                    186:        }
                    187:        return(count);
                    188: }
                    189: 
                    190: 
                    191: 
                    192: gmatch(s, p)
                    193: register char  *s, *p;
                    194: {
                    195:        register int    scc;
                    196:        char            c;
                    197: 
                    198:        if (scc = *s++)
                    199:        {
                    200:                if ((scc &= STRIP) == 0)
                    201:                        scc=0200;
                    202:        }
                    203:        switch (c = *p++)
                    204:        {
                    205:        case '[':
                    206:                {
                    207:                        BOOL ok;
                    208:                        int lc;
                    209:                        int notflag = 0;
                    210: 
                    211:                        ok = 0;
                    212:                        lc = 077777;
                    213:                        if (*p == '^')
                    214:                        {
                    215:                                notflag = 1;
                    216:                                p++;
                    217:                        }
                    218:                        while (c = *p++)
                    219:                        {
                    220:                                if (c == ']')
                    221:                                        return(ok ? gmatch(s, p) : 0);
                    222:                                else if (c == MINUS)
                    223:                                {
                    224:                                        if (notflag)
                    225:                                        {
                    226:                                                if (scc < lc || scc > *(p++))
                    227:                                                        ok++;
                    228:                                                else
                    229:                                                        return(0);
                    230:                                        }
                    231:                                        else
                    232:                                        {
                    233:                                                if (lc <= scc && scc <= (*p++))
                    234:                                                        ok++;
                    235:                                        }
                    236:                                }
                    237:                                else
                    238:                                {
                    239:                                        lc = c & STRIP;
                    240:                                        if (notflag)
                    241:                                        {
                    242:                                                if (scc && scc != lc)
                    243:                                                        ok++;
                    244:                                                else
                    245:                                                        return(0);
                    246:                                        }
                    247:                                        else
                    248:                                        {
                    249:                                                if (scc == lc)
                    250:                                                        ok++;
                    251:                                        }
                    252:                                }
                    253:                        }
                    254:                        return(0);
                    255:                }
                    256: 
                    257:        default:
                    258:                if ((c & STRIP) != scc)
                    259:                        return(0);
                    260: 
                    261:        case '?':
                    262:                return(scc ? gmatch(s, p) : 0);
                    263: 
                    264:        case '*':
                    265:                while (*p == '*')
                    266:                        p++;
                    267: 
                    268:                if (*p == 0)
                    269:                        return(1);
                    270:                --s;
                    271:                while (*s)
                    272:                {
                    273:                        if (gmatch(s++, p))
                    274:                                return(1);
                    275:                }
                    276:                return(0);
                    277: 
                    278:        case 0:
                    279:                return(scc == 0);
                    280:        }
                    281: }
                    282: 
                    283: static
                    284: addg(as1, as2, as3)
                    285: char   *as1, *as2, *as3;
                    286: {
                    287:        register char   *s1;
                    288:        register int    c;
                    289: 
                    290:        staktop = locstak() + BYTESPERWORD;
                    291:        s1 = as1;
                    292:        while (c = *s1++)
                    293:        {
                    294:                if ((c &= STRIP) == 0)
                    295:                {
                    296:                        pushstak('/');
                    297:                        break;
                    298:                }
                    299:                pushstak(c);
                    300:        }
                    301:        s1 = as2;
                    302:        while (c = *s1++)
                    303:                pushstak(c);
                    304:        if (s1 = as3)
                    305:        {
                    306:                pushstak('/');
                    307:                do
                    308:                        pushstak(*++s1);
                    309:                while(*s1);
                    310:        }
                    311:        makearg((struct argnod *)fixstak());
                    312: }
                    313: 
                    314: makearg(args)
                    315:        register struct argnod *args;
                    316: {
                    317:        args->argnxt = gchain;
                    318:        gchain = args;
                    319: }

unix.superglobalmegacorp.com

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