Blame


1 f08fdedc 2003-11-23 devnull #include "rc.h"
2 f08fdedc 2003-11-23 devnull #include "exec.h"
3 f08fdedc 2003-11-23 devnull #include "fns.h"
4 f08fdedc 2003-11-23 devnull char *globname;
5 f08fdedc 2003-11-23 devnull struct word *globv;
6 f08fdedc 2003-11-23 devnull /*
7 f08fdedc 2003-11-23 devnull * delete all the GLOB marks from s, in place
8 f08fdedc 2003-11-23 devnull */
9 c8f53842 2007-03-26 devnull
10 c8f53842 2007-03-26 devnull void
11 c8f53842 2007-03-26 devnull deglob(char *s)
12 f08fdedc 2003-11-23 devnull {
13 c8f53842 2007-03-26 devnull char *t = s;
14 f08fdedc 2003-11-23 devnull do{
15 c8f53842 2007-03-26 devnull if(*t==GLOB)
16 c8f53842 2007-03-26 devnull t++;
17 f08fdedc 2003-11-23 devnull *s++=*t;
18 f08fdedc 2003-11-23 devnull }while(*t++);
19 f08fdedc 2003-11-23 devnull }
20 c8f53842 2007-03-26 devnull
21 c8f53842 2007-03-26 devnull int
22 c8f53842 2007-03-26 devnull globcmp(const void *s, const void *t)
23 f08fdedc 2003-11-23 devnull {
24 f08fdedc 2003-11-23 devnull return strcmp(*(char**)s, *(char**)t);
25 f08fdedc 2003-11-23 devnull }
26 c8f53842 2007-03-26 devnull
27 c8f53842 2007-03-26 devnull void
28 c8f53842 2007-03-26 devnull globsort(word *left, word *right)
29 f08fdedc 2003-11-23 devnull {
30 f08fdedc 2003-11-23 devnull char **list;
31 f08fdedc 2003-11-23 devnull word *a;
32 c8f53842 2007-03-26 devnull int n = 0;
33 c8f53842 2007-03-26 devnull for(a = left;a!=right;a = a->next) n++;
34 c8f53842 2007-03-26 devnull list = (char **)emalloc(n*sizeof(char *));
35 c8f53842 2007-03-26 devnull for(a = left,n = 0;a!=right;a = a->next,n++) list[n] = a->word;
36 c8f53842 2007-03-26 devnull qsort((void *)list, n, sizeof(void *), globcmp);
37 c8f53842 2007-03-26 devnull for(a = left,n = 0;a!=right;a = a->next,n++) a->word = list[n];
38 f08fdedc 2003-11-23 devnull efree((char *)list);
39 f08fdedc 2003-11-23 devnull }
40 f08fdedc 2003-11-23 devnull /*
41 f08fdedc 2003-11-23 devnull * Push names prefixed by globname and suffixed by a match of p onto the astack.
42 f08fdedc 2003-11-23 devnull * namep points to the end of the prefix in globname.
43 f08fdedc 2003-11-23 devnull */
44 c8f53842 2007-03-26 devnull
45 c8f53842 2007-03-26 devnull void
46 c8f53842 2007-03-26 devnull globdir(char *p, char *namep)
47 f08fdedc 2003-11-23 devnull {
48 f08fdedc 2003-11-23 devnull char *t, *newp;
49 f08fdedc 2003-11-23 devnull int f;
50 f08fdedc 2003-11-23 devnull /* scan the pattern looking for a component with a metacharacter in it */
51 f08fdedc 2003-11-23 devnull if(*p=='\0'){
52 c8f53842 2007-03-26 devnull globv = newword(globname, globv);
53 f08fdedc 2003-11-23 devnull return;
54 f08fdedc 2003-11-23 devnull }
55 c8f53842 2007-03-26 devnull t = namep;
56 c8f53842 2007-03-26 devnull newp = p;
57 f08fdedc 2003-11-23 devnull while(*newp){
58 f08fdedc 2003-11-23 devnull if(*newp==GLOB)
59 f08fdedc 2003-11-23 devnull break;
60 f08fdedc 2003-11-23 devnull *t=*newp++;
61 f08fdedc 2003-11-23 devnull if(*t++=='/'){
62 c8f53842 2007-03-26 devnull namep = t;
63 c8f53842 2007-03-26 devnull p = newp;
64 f08fdedc 2003-11-23 devnull }
65 f08fdedc 2003-11-23 devnull }
66 f08fdedc 2003-11-23 devnull /* If we ran out of pattern, append the name if accessible */
67 f08fdedc 2003-11-23 devnull if(*newp=='\0'){
68 f08fdedc 2003-11-23 devnull *t='\0';
69 f08fdedc 2003-11-23 devnull if(access(globname, 0)==0)
70 c8f53842 2007-03-26 devnull globv = newword(globname, globv);
71 f08fdedc 2003-11-23 devnull return;
72 f08fdedc 2003-11-23 devnull }
73 f08fdedc 2003-11-23 devnull /* read the directory and recur for any entry that matches */
74 f08fdedc 2003-11-23 devnull *namep='\0';
75 c8f53842 2007-03-26 devnull if((f = Opendir(globname[0]?globname:"."))<0) return;
76 f08fdedc 2003-11-23 devnull while(*newp!='/' && *newp!='\0') newp++;
77 c8f53842 2007-03-26 devnull while(Readdir(f, namep, *newp=='/')){
78 f08fdedc 2003-11-23 devnull if(matchfn(namep, p)){
79 c8f53842 2007-03-26 devnull for(t = namep;*t;t++);
80 f08fdedc 2003-11-23 devnull globdir(newp, t);
81 f08fdedc 2003-11-23 devnull }
82 f08fdedc 2003-11-23 devnull }
83 f08fdedc 2003-11-23 devnull Closedir(f);
84 f08fdedc 2003-11-23 devnull }
85 f08fdedc 2003-11-23 devnull /*
86 f08fdedc 2003-11-23 devnull * Push all file names matched by p on the current thread's stack.
87 f08fdedc 2003-11-23 devnull * If there are no matches, the list consists of p.
88 f08fdedc 2003-11-23 devnull */
89 c8f53842 2007-03-26 devnull
90 c8f53842 2007-03-26 devnull void
91 c8f53842 2007-03-26 devnull glob(char *p)
92 f08fdedc 2003-11-23 devnull {
93 c8f53842 2007-03-26 devnull word *svglobv = globv;
94 c8f53842 2007-03-26 devnull int globlen = Globsize(p);
95 f08fdedc 2003-11-23 devnull if(!globlen){
96 f08fdedc 2003-11-23 devnull deglob(p);
97 c8f53842 2007-03-26 devnull globv = newword(p, globv);
98 f08fdedc 2003-11-23 devnull return;
99 f08fdedc 2003-11-23 devnull }
100 c8f53842 2007-03-26 devnull globname = emalloc(globlen);
101 f08fdedc 2003-11-23 devnull globname[0]='\0';
102 f08fdedc 2003-11-23 devnull globdir(p, globname);
103 f08fdedc 2003-11-23 devnull efree(globname);
104 f08fdedc 2003-11-23 devnull if(svglobv==globv){
105 f08fdedc 2003-11-23 devnull deglob(p);
106 c8f53842 2007-03-26 devnull globv = newword(p, globv);
107 f08fdedc 2003-11-23 devnull }
108 f08fdedc 2003-11-23 devnull else
109 f08fdedc 2003-11-23 devnull globsort(globv, svglobv);
110 f08fdedc 2003-11-23 devnull }
111 f08fdedc 2003-11-23 devnull /*
112 f08fdedc 2003-11-23 devnull * Do p and q point at equal utf codes
113 f08fdedc 2003-11-23 devnull */
114 c8f53842 2007-03-26 devnull
115 c8f53842 2007-03-26 devnull int
116 c8f53842 2007-03-26 devnull equtf(char *p, char *q)
117 c8f53842 2007-03-26 devnull {
118 c8f53842 2007-03-26 devnull if(*p!=*q)
119 c8f53842 2007-03-26 devnull return 0;
120 f08fdedc 2003-11-23 devnull if(twobyte(*p)) return p[1]==q[1];
121 f08fdedc 2003-11-23 devnull if(threebyte(*p)){
122 c8f53842 2007-03-26 devnull if(p[1]!=q[1])
123 c8f53842 2007-03-26 devnull return 0;
124 c8f53842 2007-03-26 devnull if(p[1]=='\0')
125 c8f53842 2007-03-26 devnull return 1; /* broken code at end of string! */
126 f08fdedc 2003-11-23 devnull return p[2]==q[2];
127 f08fdedc 2003-11-23 devnull }
128 f08fdedc 2003-11-23 devnull return 1;
129 f08fdedc 2003-11-23 devnull }
130 f08fdedc 2003-11-23 devnull /*
131 f08fdedc 2003-11-23 devnull * Return a pointer to the next utf code in the string,
132 f08fdedc 2003-11-23 devnull * not jumping past nuls in broken utf codes!
133 f08fdedc 2003-11-23 devnull */
134 c8f53842 2007-03-26 devnull
135 c8f53842 2007-03-26 devnull char*
136 c8f53842 2007-03-26 devnull nextutf(char *p)
137 c8f53842 2007-03-26 devnull {
138 f08fdedc 2003-11-23 devnull if(twobyte(*p)) return p[1]=='\0'?p+1:p+2;
139 f08fdedc 2003-11-23 devnull if(threebyte(*p)) return p[1]=='\0'?p+1:p[2]=='\0'?p+2:p+3;
140 f08fdedc 2003-11-23 devnull return p+1;
141 f08fdedc 2003-11-23 devnull }
142 f08fdedc 2003-11-23 devnull /*
143 f08fdedc 2003-11-23 devnull * Convert the utf code at *p to a unicode value
144 f08fdedc 2003-11-23 devnull */
145 c8f53842 2007-03-26 devnull
146 c8f53842 2007-03-26 devnull int
147 c8f53842 2007-03-26 devnull unicode(char *p)
148 c8f53842 2007-03-26 devnull {
149 f08fdedc 2003-11-23 devnull int u=*p&0xff;
150 f08fdedc 2003-11-23 devnull if(twobyte(u)) return ((u&0x1f)<<6)|(p[1]&0x3f);
151 f08fdedc 2003-11-23 devnull if(threebyte(u)) return (u<<12)|((p[1]&0x3f)<<6)|(p[2]&0x3f);
152 f08fdedc 2003-11-23 devnull return u;
153 f08fdedc 2003-11-23 devnull }
154 f08fdedc 2003-11-23 devnull /*
155 f08fdedc 2003-11-23 devnull * Does the string s match the pattern p
156 f08fdedc 2003-11-23 devnull * . and .. are only matched by patterns starting with .
157 f08fdedc 2003-11-23 devnull * * matches any sequence of characters
158 f08fdedc 2003-11-23 devnull * ? matches any single character
159 f08fdedc 2003-11-23 devnull * [...] matches the enclosed list of characters
160 f08fdedc 2003-11-23 devnull */
161 c8f53842 2007-03-26 devnull
162 c8f53842 2007-03-26 devnull int
163 c8f53842 2007-03-26 devnull matchfn(char *s, char *p)
164 f08fdedc 2003-11-23 devnull {
165 f08fdedc 2003-11-23 devnull if(s[0]=='.' && (s[1]=='\0' || s[1]=='.' && s[2]=='\0') && p[0]!='.')
166 f08fdedc 2003-11-23 devnull return 0;
167 f08fdedc 2003-11-23 devnull return match(s, p, '/');
168 f08fdedc 2003-11-23 devnull }
169 c8f53842 2007-03-26 devnull
170 c8f53842 2007-03-26 devnull int
171 c8f53842 2007-03-26 devnull match(char *s, char *p, int stop)
172 f08fdedc 2003-11-23 devnull {
173 f08fdedc 2003-11-23 devnull int compl, hit, lo, hi, t, c;
174 c8f53842 2007-03-26 devnull for(;*p!=stop && *p!='\0';s = nextutf(s),p = nextutf(p)){
175 f08fdedc 2003-11-23 devnull if(*p!=GLOB){
176 f08fdedc 2003-11-23 devnull if(!equtf(p, s)) return 0;
177 f08fdedc 2003-11-23 devnull }
178 f08fdedc 2003-11-23 devnull else switch(*++p){
179 f08fdedc 2003-11-23 devnull case GLOB:
180 c8f53842 2007-03-26 devnull if(*s!=GLOB)
181 c8f53842 2007-03-26 devnull return 0;
182 f08fdedc 2003-11-23 devnull break;
183 f08fdedc 2003-11-23 devnull case '*':
184 f08fdedc 2003-11-23 devnull for(;;){
185 f08fdedc 2003-11-23 devnull if(match(s, nextutf(p), stop)) return 1;
186 c8f53842 2007-03-26 devnull if(!*s)
187 c8f53842 2007-03-26 devnull break;
188 c8f53842 2007-03-26 devnull s = nextutf(s);
189 f08fdedc 2003-11-23 devnull }
190 f08fdedc 2003-11-23 devnull return 0;
191 f08fdedc 2003-11-23 devnull case '?':
192 c8f53842 2007-03-26 devnull if(*s=='\0')
193 c8f53842 2007-03-26 devnull return 0;
194 f08fdedc 2003-11-23 devnull break;
195 f08fdedc 2003-11-23 devnull case '[':
196 c8f53842 2007-03-26 devnull if(*s=='\0')
197 c8f53842 2007-03-26 devnull return 0;
198 c8f53842 2007-03-26 devnull c = unicode(s);
199 f08fdedc 2003-11-23 devnull p++;
200 f08fdedc 2003-11-23 devnull compl=*p=='~';
201 c8f53842 2007-03-26 devnull if(compl)
202 c8f53842 2007-03-26 devnull p++;
203 c8f53842 2007-03-26 devnull hit = 0;
204 f08fdedc 2003-11-23 devnull while(*p!=']'){
205 c8f53842 2007-03-26 devnull if(*p=='\0')
206 c8f53842 2007-03-26 devnull return 0; /* syntax error */
207 c8f53842 2007-03-26 devnull lo = unicode(p);
208 c8f53842 2007-03-26 devnull p = nextutf(p);
209 c8f53842 2007-03-26 devnull if(*p!='-')
210 c8f53842 2007-03-26 devnull hi = lo;
211 f08fdedc 2003-11-23 devnull else{
212 f08fdedc 2003-11-23 devnull p++;
213 c8f53842 2007-03-26 devnull if(*p=='\0')
214 c8f53842 2007-03-26 devnull return 0; /* syntax error */
215 c8f53842 2007-03-26 devnull hi = unicode(p);
216 c8f53842 2007-03-26 devnull p = nextutf(p);
217 c8f53842 2007-03-26 devnull if(hi<lo){ t = lo; lo = hi; hi = t; }
218 f08fdedc 2003-11-23 devnull }
219 c8f53842 2007-03-26 devnull if(lo<=c && c<=hi)
220 c8f53842 2007-03-26 devnull hit = 1;
221 f08fdedc 2003-11-23 devnull }
222 c8f53842 2007-03-26 devnull if(compl)
223 c8f53842 2007-03-26 devnull hit=!hit;
224 c8f53842 2007-03-26 devnull if(!hit)
225 c8f53842 2007-03-26 devnull return 0;
226 f08fdedc 2003-11-23 devnull break;
227 f08fdedc 2003-11-23 devnull }
228 f08fdedc 2003-11-23 devnull }
229 f08fdedc 2003-11-23 devnull return *s=='\0';
230 f08fdedc 2003-11-23 devnull }
231 c8f53842 2007-03-26 devnull
232 c8f53842 2007-03-26 devnull void
233 c8f53842 2007-03-26 devnull globlist1(word *gl)
234 f08fdedc 2003-11-23 devnull {
235 f08fdedc 2003-11-23 devnull if(gl){
236 f08fdedc 2003-11-23 devnull globlist1(gl->next);
237 f08fdedc 2003-11-23 devnull glob(gl->word);
238 f08fdedc 2003-11-23 devnull }
239 f08fdedc 2003-11-23 devnull }
240 c8f53842 2007-03-26 devnull
241 c8f53842 2007-03-26 devnull void
242 c8f53842 2007-03-26 devnull globlist(void)
243 c8f53842 2007-03-26 devnull {
244 f08fdedc 2003-11-23 devnull word *a;
245 c8f53842 2007-03-26 devnull globv = 0;
246 f08fdedc 2003-11-23 devnull globlist1(runq->argv->words);
247 f08fdedc 2003-11-23 devnull poplist();
248 f08fdedc 2003-11-23 devnull pushlist();
249 f08fdedc 2003-11-23 devnull if(globv){
250 c8f53842 2007-03-26 devnull for(a = globv;a->next;a = a->next);
251 c8f53842 2007-03-26 devnull a->next = runq->argv->words;
252 c8f53842 2007-03-26 devnull runq->argv->words = globv;
253 f08fdedc 2003-11-23 devnull }
254 f08fdedc 2003-11-23 devnull }