syntax error (from casey)
[unix-history] / usr / src / old / sh / expand.c
CommitLineData
f6227721
SL
1#ifndef lint
2static char sccsid[] = "@(#)expand.c 4.5 %G%";
3#endif
c62d0dbc
KM
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>
657820b8 17#include <sys/dir.h>
c62d0dbc
KM
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
30PROC VOID addg();
31
32
33INT 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
443e9382 72 ANDF (dirf=opendir(s)) != NULL
c62d0dbc
KM
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
22674779
SL
84 IF setjmp(INTbuf) == 0 THEN trapjmp[INTR] = 1; FI
85 WHILE (trapnote&SIGSET) == 0 ANDF (dp = readdir(dirf)) != NULL
c62d0dbc
KM
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
22674779 93 closedir(dirf); trapjmp[INTR] = 0;
c62d0dbc
KM
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
118gmatch(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
163LOCAL 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
188makearg(args)
189 REG STRING args;
190{
191 args->argnxt=gchain;
192 gchain=args;
193}
194