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

Defined functions

addg defined in line 159; used 2 times
expand defined in line 30; used 2 times
gmatch defined in line 114; used 5 times
makearg defined in line 184; used 2 times

Defined macros

DIRSIZ defined in line 12; used 1 times
  • in line 43
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 844
Valid CSS Valid XHTML 1.0 Strict