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
Defined variables
sccsid
defined in line
2;
never used