Annotation of researchv9/cmd/sh/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: #ifndef BSD4_2
                     13: #include       <ndir.h>
                     14: #else
                     15: #include       <sys/dir.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:        BOOL    dir = 0;
                     48:        char    *rescan = 0;
                     49:        register char   *s, *cs;
                     50:        struct argnod   *schain = gchain;
                     51:        BOOL    slash;
                     52: 
                     53:        if (trapnote & SIGSET)
                     54:                return(0);
                     55:        s = cs = as;
                     56:        /*
                     57:         * check for meta chars
                     58:         */
                     59:        {
                     60:                register BOOL open;
                     61: 
                     62:                slash = 0;
                     63:                open = 0;
                     64:                do
                     65:                {
                     66:                        switch (*cs++)
                     67:                        {
                     68:                        case 0:
                     69:                                if (rcnt && slash)
                     70:                                        break;
                     71:                                else
                     72:                                        return(0);
                     73: 
                     74:                        case '/':
                     75:                                slash++;
                     76:                                open = 0;
                     77:                                continue;
                     78: 
                     79:                        case '[':
                     80:                                open++;
                     81:                                continue;
                     82: 
                     83:                        case ']':
                     84:                                if (open == 0)
                     85:                                        continue;
                     86: 
                     87:                        case '?':
                     88:                        case '*':
                     89:                                if (rcnt > slash)
                     90:                                        continue;
                     91:                                else
                     92:                                        cs--;
                     93:                                break;
                     94: 
                     95: 
                     96:                        default:
                     97:                                continue;
                     98:                        }
                     99:                        break;
                    100:                } while (TRUE);
                    101:        }
                    102: 
                    103:        for (;;)
                    104:        {
                    105:                if (cs == s)
                    106:                {
                    107:                        s = nullstr;
                    108:                        break;
                    109:                }
                    110:                else if (*--cs == '/')
                    111:                {
                    112:                        *cs = 0;
                    113:                        if (s == cs)
                    114:                                s = "/";
                    115:                        break;
                    116:                }
                    117:        }
                    118: 
                    119:        if ((dirf = opendir(*s ? s : ".")) != 0)
                    120:                dir = TRUE;
                    121:        
                    122:        count = 0;
                    123:        if (*cs == 0)
                    124:                *cs++ = 0200;
                    125: 
                    126:        if(dir)
                    127:        {
                    128:                register char *rs;
                    129:                struct direct *e;
                    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: 
                    146:                        if (entry[0] == '.' && *cs != '.')
                    147:                        {
                    148:                                if (entry[1] == 0)
                    149:                                        continue;
                    150:                                if (entry[1] == '.' && entry[2] == 0)
                    151:                                        continue;
                    152:                        }
                    153: 
                    154:                        if (gmatch(entry, cs))
                    155:                        {
                    156:                                addg(s, entry, rescan);
                    157:                                count++;
                    158:                        }
                    159:                }
                    160:                closedir(dirf);
                    161: 
                    162:                if (rescan)
                    163:                {
                    164:                        register struct argnod  *rchain;
                    165: 
                    166:                        rchain = gchain;
                    167:                        gchain = schain;
                    168:                        if (count)
                    169:                        {
                    170:                                count = 0;
                    171:                                while (rchain)
                    172:                                {
                    173:                                        count += expand(rchain->argval, slash + 1);
                    174:                                        rchain = rchain->argnxt;
                    175:                                }
                    176:                        }
                    177:                        *rescan = '/';
                    178:                }
                    179:        }
                    180: 
                    181:        {
                    182:                register char   c;
                    183: 
                    184:                s = as;
                    185:                while (c = *s)
                    186:                        *s++ = (c & STRIP ? c : '/');
                    187:        }
                    188:        return(count);
                    189: }
                    190: 
                    191: 
                    192: 
                    193: gmatch(s, p)
                    194: register char  *s, *p;
                    195: {
                    196:        register int    scc;
                    197:        char            c;
                    198: 
                    199:        if (scc = *s++)
                    200:        {
                    201:                if ((scc &= STRIP) == 0)
                    202:                        scc=0200;
                    203:        }
                    204:        switch (c = *p++)
                    205:        {
                    206:        case '[':
                    207:                {
                    208:                        BOOL ok;
                    209:                        int lc;
                    210:                        int notflag = 0;
                    211: 
                    212:                        ok = 0;
                    213:                        lc = 077777;
                    214:                        if (*p == '^')
                    215:                        {
                    216:                                notflag = 1;
                    217:                                p++;
                    218:                        }
                    219:                        while (c = *p++)
                    220:                        {
                    221:                                if (c == ']')
                    222:                                        return(ok ? gmatch(s, p) : 0);
                    223:                                else if (c == MINUS)
                    224:                                {
                    225:                                        if (notflag)
                    226:                                        {
                    227:                                                if (scc < lc || scc > *(p++))
                    228:                                                        ok++;
                    229:                                                else
                    230:                                                        return(0);
                    231:                                        }
                    232:                                        else
                    233:                                        {
                    234:                                                if (lc <= scc && scc <= (*p++))
                    235:                                                        ok++;
                    236:                                        }
                    237:                                }
                    238:                                else
                    239:                                {
                    240:                                        lc = c & STRIP;
                    241:                                        if (notflag)
                    242:                                        {
                    243:                                                if (scc && scc != lc)
                    244:                                                        ok++;
                    245:                                                else
                    246:                                                        return(0);
                    247:                                        }
                    248:                                        else
                    249:                                        {
                    250:                                                if (scc == lc)
                    251:                                                        ok++;
                    252:                                        }
                    253:                                }
                    254:                        }
                    255:                        return(0);
                    256:                }
                    257: 
                    258:        default:
                    259:                if ((c & STRIP) != scc)
                    260:                        return(0);
                    261: 
                    262:        case '?':
                    263:                return(scc ? gmatch(s, p) : 0);
                    264: 
                    265:        case '*':
                    266:                while (*p == '*')
                    267:                        p++;
                    268: 
                    269:                if (*p == 0)
                    270:                        return(1);
                    271:                --s;
                    272:                while (*s)
                    273:                {
                    274:                        if (gmatch(s++, p))
                    275:                                return(1);
                    276:                }
                    277:                return(0);
                    278: 
                    279:        case 0:
                    280:                return(scc == 0);
                    281:        }
                    282: }
                    283: 
                    284: static
                    285: addg(as1, as2, as3)
                    286: char   *as1, *as2, *as3;
                    287: {
                    288:        register char   *s1;
                    289:        register int    c;
                    290: 
                    291:        staktop = locstak() + BYTESPERWORD;
                    292:        s1 = as1;
                    293:        while (c = *s1++)
                    294:        {
                    295:                if ((c &= STRIP) == 0)
                    296:                {
                    297:                        pushstak('/');
                    298:                        break;
                    299:                }
                    300:                pushstak(c);
                    301:        }
                    302:        s1 = as2;
                    303:        while (c = *s1++)
                    304:                pushstak(c);
                    305:        if (s1 = as3)
                    306:        {
                    307:                pushstak('/');
                    308:                do
                    309:                        pushstak(*++s1);
                    310:                while(*s1);
                    311:        }
                    312:        makearg(fixstak());
                    313: }
                    314: 
                    315: makearg(args)
                    316:        register struct argnod *args;
                    317: {
                    318:        args->argnxt = gchain;
                    319:        gchain = args;
                    320: }
                    321: 
                    322: 
                    323: DIR *
                    324: opendir(name)
                    325: register char *name;
                    326: {
                    327:        DIR dirbuf, *dirp;
                    328:        struct stat statb;
                    329:        char buf[MAXNAMELEN+1];
                    330:        register char *s;
                    331: 
                    332:        *(movstrn(name, buf, MAXNAMELEN)) = 0;
                    333:        for (s=buf; *s; s++)
                    334:                *s &= STRIP;
                    335:        if ((dirbuf.dd_fd = open(buf, 0)) < 0)
                    336:                return(NULL);
                    337:        if (fstat(dirbuf.dd_fd, &statb)!=0 || (statb.st_mode & S_IFMT)!=S_IFDIR){
                    338:                close(dirbuf.dd_fd);
                    339:                return(NULL);
                    340:        }
                    341:        dirbuf.dd_loc = 0;
                    342:        dirp = (DIR *)shalloc(sizeof(DIR));
                    343:        *dirp = dirbuf;
                    344:        return(dirp);
                    345: }
                    346: 
                    347: void
                    348: closedir(dirp)
                    349: DIR *dirp;
                    350: {
                    351:        close(dirp->dd_fd);
                    352:        shfree((char *)dirp);
                    353: }

unix.superglobalmegacorp.com

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