Annotation of 41BSD/cmd/sh/expand.c, revision 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       <sys/types.h>
        !            12: #define DIRSIZ 15
        !            13: #include       <sys/stat.h>
        !            14: #include       <sys/dir.h>
        !            15: 
        !            16: 
        !            17: 
        !            18: /* globals (file name generation)
        !            19:  *
        !            20:  * "*" in params matches r.e ".*"
        !            21:  * "?" in params matches r.e. "."
        !            22:  * "[...]" in params matches character class
        !            23:  * "[...a-z...]" in params matches a through z.
        !            24:  *
        !            25:  */
        !            26: 
        !            27: PROC VOID      addg();
        !            28: 
        !            29: 
        !            30: INT    expand(as,rflg)
        !            31:        STRING          as;
        !            32: {
        !            33:        INT             count, dirf;
        !            34:        BOOL            dir=0;
        !            35:        STRING          rescan = 0;
        !            36:        REG STRING      s, cs;
        !            37:        ARGPTR          schain = gchain;
        !            38:        struct direct   entry;
        !            39:        STATBUF         statb;
        !            40: 
        !            41:        IF trapnote&SIGSET THEN return(0); FI
        !            42: 
        !            43:        s=cs=as; entry.d_name[DIRSIZ-1]=0; /* to end the string */
        !            44: 
        !            45:        /* check for meta chars */
        !            46:        BEGIN
        !            47:           REG BOOL slash; slash=0;
        !            48:           WHILE !fngchar(*cs)
        !            49:           DO   IF *cs++==0
        !            50:                THEN    IF rflg ANDF slash THEN break; ELSE return(0) FI
        !            51:                ELIF *cs=='/'
        !            52:                THEN    slash++;
        !            53:                FI
        !            54:           OD
        !            55:        END
        !            56: 
        !            57:        LOOP    IF cs==s
        !            58:                THEN    s=nullstr;
        !            59:                        break;
        !            60:                ELIF *--cs == '/'
        !            61:                THEN    *cs=0;
        !            62:                        IF s==cs THEN s="/" FI
        !            63:                        break;
        !            64:                FI
        !            65:        POOL
        !            66:        IF stat(s,&statb)>=0
        !            67:            ANDF (statb.st_mode&S_IFMT)==S_IFDIR
        !            68:            ANDF (dirf=open(s,0))>0
        !            69:        THEN    dir++;
        !            70:        FI
        !            71:        count=0;
        !            72:        IF *cs==0 THEN *cs++=0200 FI
        !            73:        IF dir
        !            74:        THEN    /* check for rescan */
        !            75:                REG STRING rs; rs=cs;
        !            76: 
        !            77:                REP     IF *rs=='/' THEN rescan=rs; *rs=0; gchain=0 FI
        !            78:                PER     *rs++ DONE
        !            79: 
        !            80:                WHILE read(dirf, &entry, 16) == 16 ANDF (trapnote&SIGSET) == 0
        !            81:                DO      IF entry.d_ino==0 ORF
        !            82:                            (*entry.d_name=='.' ANDF *cs!='.')
        !            83:                        THEN    continue;
        !            84:                        FI
        !            85:                        IF gmatch(entry.d_name, cs)
        !            86:                        THEN    addg(s,entry.d_name,rescan); count++;
        !            87:                        FI
        !            88:                OD
        !            89:                close(dirf);
        !            90: 
        !            91:                IF rescan
        !            92:                THEN    REG ARGPTR      rchain;
        !            93:                        rchain=gchain; gchain=schain;
        !            94:                        IF count
        !            95:                        THEN    count=0;
        !            96:                                WHILE rchain
        !            97:                                DO      count += expand(rchain->argval,1);
        !            98:                                        rchain=rchain->argnxt;
        !            99:                                OD
        !           100:                        FI
        !           101:                        *rescan='/';
        !           102:                FI
        !           103:        FI
        !           104: 
        !           105:        BEGIN
        !           106:           REG CHAR     c;
        !           107:           s=as;
        !           108:           WHILE c = *s
        !           109:           DO   *s++=(c&STRIP?c:'/') OD
        !           110:        END
        !           111:        return(count);
        !           112: }
        !           113: 
        !           114: gmatch(s, p)
        !           115:        REG STRING      s, p;
        !           116: {
        !           117:        REG INT         scc;
        !           118:        CHAR            c;
        !           119: 
        !           120:        IF scc = *s++
        !           121:        THEN    IF (scc &= STRIP)==0
        !           122:                THEN    scc=0200;
        !           123:                FI
        !           124:        FI
        !           125:        SWITCH c = *p++ IN
        !           126: 
        !           127:            case '[':
        !           128:                {BOOL ok; INT lc;
        !           129:                ok=0; lc=077777;
        !           130:                WHILE c = *p++
        !           131:                DO      IF c==']'
        !           132:                        THEN    return(ok?gmatch(s,p):0);
        !           133:                        ELIF c==MINUS
        !           134:                        THEN    IF lc<=scc ANDF scc<=(*p++) THEN ok++ FI
        !           135:                        ELSE    IF scc==(lc=(c&STRIP)) THEN ok++ FI
        !           136:                        FI
        !           137:                OD
        !           138:                return(0);
        !           139:                }
        !           140: 
        !           141:            default:
        !           142:                IF (c&STRIP)!=scc THEN return(0) FI
        !           143: 
        !           144:            case '?':
        !           145:                return(scc?gmatch(s,p):0);
        !           146: 
        !           147:            case '*':
        !           148:                IF *p==0 THEN return(1) FI
        !           149:                --s;
        !           150:                WHILE *s
        !           151:                DO  IF gmatch(s++,p) THEN return(1) FI OD
        !           152:                return(0);
        !           153: 
        !           154:            case 0:
        !           155:                return(scc==0);
        !           156:        ENDSW
        !           157: }
        !           158: 
        !           159: LOCAL VOID     addg(as1,as2,as3)
        !           160:        STRING          as1, as2, as3;
        !           161: {
        !           162:        REG STRING      s1, s2;
        !           163:        REG INT         c;
        !           164: 
        !           165:        s2 = locstak()+BYTESPERWORD;
        !           166: 
        !           167:        s1=as1;
        !           168:        WHILE c = *s1++
        !           169:        DO      IF (c &= STRIP)==0
        !           170:                THEN    *s2++='/';
        !           171:                        break;
        !           172:                FI
        !           173:                *s2++=c;
        !           174:        OD
        !           175:        s1=as2;
        !           176:        WHILE *s2 = *s1++ DO s2++ OD
        !           177:        IF s1=as3
        !           178:        THEN    *s2++='/';
        !           179:                WHILE *s2++ = *++s1 DONE
        !           180:        FI
        !           181:        makearg(endstak(s2));
        !           182: }
        !           183: 
        !           184: makearg(args)
        !           185:        REG STRING      args;
        !           186: {
        !           187:        args->argnxt=gchain;
        !           188:        gchain=args;
        !           189: }
        !           190: 

unix.superglobalmegacorp.com

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