|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.