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
Defined macros