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: }

Defined functions

addg defined in line 163; used 2 times
expand defined in line 33; used 2 times
gmatch defined in line 118; used 5 times
makearg defined in line 188; used 2 times

Defined variables

sccsid defined in line 2; never used
Last modified: 1983-08-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2664
Valid CSS Valid XHTML 1.0 Strict