Annotation of 43BSD/bin/sh/expand.c, revision 1.1

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

unix.superglobalmegacorp.com

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