]>
Commit | Line | Data |
---|---|---|
cf7098dd MM |
1 | diff -urN netbsd-sh/expand.c ash-0.3.7.orig/expand.c |
2 | --- netbsd-sh/expand.c Tue Mar 14 13:03:45 2000 | |
3 | +++ ash-0.3.7.orig/expand.c Mon Apr 23 22:16:46 2001 | |
4 | @@ -54,6 +54,10 @@ | |
5 | #include <pwd.h> | |
6 | #include <stdlib.h> | |
7 | #include <stdio.h> | |
8 | +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) | |
9 | +#include <fnmatch.h> | |
10 | +#include <glob.h> | |
11 | +#endif | |
12 | ||
13 | /* | |
14 | * Routines to expand arguments to commands. We have to deal with | |
15 | @@ -102,17 +106,30 @@ | |
16 | STATIC int subevalvar __P((char *, char *, int, int, int, int)); | |
17 | STATIC char *evalvar __P((char *, int)); | |
18 | STATIC int varisset __P((char *, int)); | |
19 | +STATIC char *strtodest __P((char *, int, int)); | |
20 | STATIC void varvalue __P((char *, int, int)); | |
21 | STATIC void recordregion __P((int, int, int)); | |
22 | STATIC void removerecordregions __P((int)); | |
23 | STATIC void ifsbreakup __P((char *, struct arglist *)); | |
24 | STATIC void ifsfree __P((void)); | |
25 | STATIC void expandmeta __P((struct strlist *, int)); | |
26 | +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) | |
27 | +STATIC const char *preglob __P((const char *)); | |
28 | +STATIC void addglob __P((const glob_t *)); | |
29 | +#else | |
30 | STATIC void expmeta __P((char *, char *)); | |
31 | +#endif | |
32 | STATIC void addfname __P((char *)); | |
33 | +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) | |
34 | +STATIC int patmatch __P((char *, char *, int)); | |
35 | +STATIC int patmatch2 __P((char *, char *, int)); | |
36 | +STATIC char * _rmescapes __P((char *, int)); | |
37 | +#else | |
38 | STATIC struct strlist *expsort __P((struct strlist *)); | |
39 | STATIC struct strlist *msort __P((struct strlist *, int)); | |
40 | STATIC int pmatch __P((char *, char *, int)); | |
41 | +#define patmatch2 patmatch | |
42 | +#endif | |
43 | STATIC char *cvtnum __P((int, char *)); | |
44 | ||
45 | /* | |
46 | @@ -371,7 +388,7 @@ | |
47 | * have to rescan starting from the beginning since CTLESC | |
48 | * characters have to be processed left to right. | |
49 | */ | |
50 | - CHECKSTRSPACE(8, expdest); | |
51 | + CHECKSTRSPACE(10, expdest); | |
52 | USTPUTC('\0', expdest); | |
53 | start = stackblock(); | |
54 | p = expdest - 1; | |
55 | @@ -393,7 +410,7 @@ | |
56 | if (quotes) | |
57 | rmescapes(p+2); | |
58 | result = arith(p+2); | |
59 | - fmtstr(p, 10, "%d", result); | |
60 | + fmtstr(p, 12, "%d", result); | |
61 | ||
62 | while (*p++) | |
63 | ; | |
64 | @@ -503,7 +520,7 @@ | |
65 | int amount; | |
66 | ||
67 | herefd = -1; | |
68 | - argstr(p, 0); | |
69 | + argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0); | |
70 | STACKSTRNUL(expdest); | |
71 | herefd = saveherefd; | |
72 | argbackq = saveargbackq; | |
73 | @@ -535,7 +552,7 @@ | |
74 | for (loc = startp; loc < str; loc++) { | |
75 | c = *loc; | |
76 | *loc = '\0'; | |
77 | - if (patmatch(str, startp, varflags & VSQUOTE)) | |
78 | + if (patmatch2(str, startp, varflags & VSQUOTE)) | |
79 | goto recordleft; | |
80 | *loc = c; | |
81 | if ((varflags & VSQUOTE) && *loc == CTLESC) | |
82 | @@ -547,7 +564,7 @@ | |
83 | for (loc = str - 1; loc >= startp;) { | |
84 | c = *loc; | |
85 | *loc = '\0'; | |
86 | - if (patmatch(str, startp, varflags & VSQUOTE)) | |
87 | + if (patmatch2(str, startp, varflags & VSQUOTE)) | |
88 | goto recordleft; | |
89 | *loc = c; | |
90 | loc--; | |
91 | @@ -564,7 +581,7 @@ | |
92 | ||
93 | case VSTRIMRIGHT: | |
94 | for (loc = str - 1; loc >= startp;) { | |
95 | - if (patmatch(str, loc, varflags & VSQUOTE)) | |
96 | + if (patmatch2(str, loc, varflags & VSQUOTE)) | |
97 | goto recordright; | |
98 | loc--; | |
99 | if ((varflags & VSQUOTE) && loc > startp && | |
100 | @@ -580,7 +597,7 @@ | |
101 | ||
102 | case VSTRIMRIGHTMAX: | |
103 | for (loc = startp; loc < str - 1; loc++) { | |
104 | - if (patmatch(str, loc, varflags & VSQUOTE)) | |
105 | + if (patmatch2(str, loc, varflags & VSQUOTE)) | |
106 | goto recordright; | |
107 | if ((varflags & VSQUOTE) && *loc == CTLESC) | |
108 | loc++; | |
109 | @@ -819,6 +836,34 @@ | |
110 | ||
111 | ||
112 | /* | |
113 | + * Put a string on the stack. | |
114 | + */ | |
115 | + | |
116 | +STATIC char * | |
117 | +strtodest(p, quoted, allow_split) | |
118 | + char *p; | |
119 | + int quoted; | |
120 | + int allow_split; | |
121 | +{ | |
122 | + char const *syntax; | |
123 | + | |
124 | + if (allow_split) { | |
125 | + syntax = quoted ? DQSYNTAX : BASESYNTAX; | |
126 | + while (*p) { | |
127 | + if (syntax[(int) *p] == CCTL) | |
128 | + STPUTC(CTLESC, expdest); | |
129 | + STPUTC(*p++, expdest); | |
130 | + } | |
131 | + } else | |
132 | + while (*p) | |
133 | + STPUTC(*p++, expdest); | |
134 | + | |
135 | + return p; | |
136 | +} | |
137 | + | |
138 | + | |
139 | + | |
140 | +/* | |
141 | * Add the value of a specialized variable to the stack string. | |
142 | */ | |
143 | ||
144 | @@ -834,22 +879,6 @@ | |
145 | extern int oexitstatus; | |
146 | char sep; | |
147 | char **ap; | |
148 | - char const *syntax; | |
149 | - | |
150 | -#define STRTODEST(p) \ | |
151 | - do {\ | |
152 | - if (allow_split) { \ | |
153 | - syntax = quoted? DQSYNTAX : BASESYNTAX; \ | |
154 | - while (*p) { \ | |
155 | - if (syntax[(int)*p] == CCTL) \ | |
156 | - STPUTC(CTLESC, expdest); \ | |
157 | - STPUTC(*p++, expdest); \ | |
158 | - } \ | |
159 | - } else \ | |
160 | - while (*p) \ | |
161 | - STPUTC(*p++, expdest); \ | |
162 | - } while (0) | |
163 | - | |
164 | ||
165 | switch (*name) { | |
166 | case '$': | |
167 | @@ -875,7 +904,7 @@ | |
168 | case '@': | |
169 | if (allow_split && quoted) { | |
170 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { | |
171 | - STRTODEST(p); | |
172 | + p = strtodest(p, quoted, allow_split); | |
173 | if (*ap) | |
174 | STPUTC('\0', expdest); | |
175 | } | |
176 | @@ -888,21 +917,20 @@ | |
177 | else | |
178 | sep = ' '; | |
179 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { | |
180 | - STRTODEST(p); | |
181 | + p = strtodest(p, quoted, allow_split); | |
182 | if (*ap && sep) | |
183 | STPUTC(sep, expdest); | |
184 | } | |
185 | break; | |
186 | case '0': | |
187 | - p = arg0; | |
188 | - STRTODEST(p); | |
189 | + p = strtodest(arg0, quoted, allow_split); | |
190 | break; | |
191 | default: | |
192 | if (is_digit(*name)) { | |
193 | num = atoi(name); | |
194 | if (num > 0 && num <= shellparam.nparam) { | |
195 | - p = shellparam.p[num - 1]; | |
196 | - STRTODEST(p); | |
197 | + p = strtodest(shellparam.p[num - 1], quoted, | |
198 | + allow_split); | |
199 | } | |
200 | } | |
201 | break; | |
202 | @@ -1054,6 +1082,98 @@ | |
203 | * should be escapes. The results are stored in the list exparg. | |
204 | */ | |
205 | ||
206 | +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) | |
207 | +STATIC void | |
208 | +expandmeta(str, flag) | |
209 | + struct strlist *str; | |
210 | + int flag; | |
211 | +{ | |
212 | + const char *p; | |
213 | + glob_t pglob; | |
214 | + /* TODO - EXP_REDIR */ | |
215 | + | |
216 | + while (str) { | |
217 | + if (fflag) | |
218 | + goto nometa; | |
219 | + p = preglob(str->text); | |
220 | + INTOFF; | |
221 | + switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) { | |
222 | + case 0: | |
223 | + if (!(pglob.gl_flags & GLOB_MAGCHAR)) | |
224 | + goto nometa2; | |
225 | + addglob(&pglob); | |
226 | + globfree(&pglob); | |
227 | + INTON; | |
228 | + break; | |
229 | + case GLOB_NOMATCH: | |
230 | +nometa2: | |
231 | + globfree(&pglob); | |
232 | + INTON; | |
233 | +nometa: | |
234 | + *exparg.lastp = str; | |
235 | + rmescapes(str->text); | |
236 | + exparg.lastp = &str->next; | |
237 | + break; | |
238 | + default: /* GLOB_NOSPACE */ | |
239 | + error("Out of space"); | |
240 | + } | |
241 | + str = str->next; | |
242 | + } | |
243 | +} | |
244 | + | |
245 | + | |
246 | +/* | |
247 | + * Prepare the string for glob(3). | |
248 | + */ | |
249 | + | |
250 | +STATIC const char * | |
251 | +preglob(str) | |
252 | + const char *str; | |
253 | +{ | |
254 | + const char *p; | |
255 | + char *q, *r; | |
256 | + size_t len; | |
257 | + | |
258 | + p = str; | |
259 | + while (*p != CTLQUOTEMARK && *p != CTLESC) { | |
260 | + if (*p++ == '\0') | |
261 | + return str; | |
262 | + } | |
263 | + len = p - str; | |
264 | + q = r = stalloc(strlen(str) + 1); | |
265 | + if (len > 0) { | |
266 | + memcpy(q, str, len); | |
267 | + q += len; | |
268 | + } | |
269 | + do { | |
270 | + if (*p == CTLQUOTEMARK) | |
271 | + continue; | |
272 | + if (*p == CTLESC) { | |
273 | + if (*++p != '/') | |
274 | + *q++ = '\\'; | |
275 | + } | |
276 | + *q++ = *p; | |
277 | + } while (*++p); | |
278 | + *q = '\0'; | |
279 | + return r; | |
280 | +} | |
281 | + | |
282 | + | |
283 | +/* | |
284 | + * Add the result of glob(3) to the list. | |
285 | + */ | |
286 | + | |
287 | +STATIC void | |
288 | +addglob(pglob) | |
289 | + const glob_t *pglob; | |
290 | +{ | |
291 | + char **p = pglob->gl_pathv; | |
292 | + | |
293 | + do { | |
294 | + addfname(*p); | |
295 | + } while (*++p); | |
296 | +} | |
297 | +#else | |
298 | char *expdir; | |
299 | ||
300 | ||
301 | @@ -1238,6 +1358,7 @@ | |
302 | if (! atend) | |
303 | endname[-1] = '/'; | |
304 | } | |
305 | +#endif | |
306 | ||
307 | ||
308 | /* | |
309 | @@ -1260,6 +1381,7 @@ | |
310 | } | |
311 | ||
312 | ||
313 | +#if !(defined(__GLIBC__) && !defined(GLOB_BROKEN)) | |
314 | /* | |
315 | * Sort the results of file name expansion. It calculates the number of | |
316 | * strings to sort and then calls msort (short for merge sort) to do the | |
317 | @@ -1321,6 +1443,7 @@ | |
318 | } | |
319 | return list; | |
320 | } | |
321 | +#endif | |
322 | ||
323 | ||
324 | ||
325 | @@ -1328,6 +1451,39 @@ | |
326 | * Returns true if the pattern matches the string. | |
327 | */ | |
328 | ||
329 | +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) | |
330 | +STATIC int | |
331 | +patmatch(pattern, string, squoted) | |
332 | + char *pattern; | |
333 | + char *string; | |
334 | + int squoted; /* string might have quote chars */ | |
335 | + { | |
336 | + const char *p; | |
337 | + char *q; | |
338 | + | |
339 | + p = preglob(pattern); | |
340 | + q = squoted ? _rmescapes(string, 1) : string; | |
341 | + | |
342 | + return !fnmatch(p, q, 0); | |
343 | +} | |
344 | + | |
345 | + | |
346 | +STATIC int | |
347 | +patmatch2(pattern, string, squoted) | |
348 | + char *pattern; | |
349 | + char *string; | |
350 | + int squoted; /* string might have quote chars */ | |
351 | + { | |
352 | + char *p; | |
353 | + int res; | |
354 | + | |
355 | + sstrnleft--; | |
356 | + p = grabstackstr(expdest); | |
357 | + res = patmatch(pattern, string, squoted); | |
358 | + ungrabstackstr(p, expdest); | |
359 | + return res; | |
360 | +} | |
361 | +#else | |
362 | int | |
363 | patmatch(pattern, string, squoted) | |
364 | char *pattern; | |
365 | @@ -1462,6 +1618,7 @@ | |
366 | return 0; | |
367 | return 1; | |
368 | } | |
369 | +#endif | |
370 | ||
371 | ||
372 | ||
373 | @@ -1469,6 +1626,50 @@ | |
374 | * Remove any CTLESC characters from a string. | |
375 | */ | |
376 | ||
377 | +#if defined(__GLIBC__) && !defined(GLOB_BROKEN) | |
378 | +void | |
379 | +rmescapes(str) | |
380 | + char *str; | |
381 | +{ | |
382 | + _rmescapes(str, 0); | |
383 | +} | |
384 | + | |
385 | + | |
386 | +STATIC char * | |
387 | +_rmescapes(str, flag) | |
388 | + char *str; | |
389 | + int flag; | |
390 | +{ | |
391 | + char *p, *q, *r; | |
392 | + | |
393 | + p = str; | |
394 | + while (*p != CTLESC && *p != CTLQUOTEMARK) { | |
395 | + if (*p++ == '\0') | |
396 | + return str; | |
397 | + } | |
398 | + q = p; | |
399 | + r = str; | |
400 | + if (flag) { | |
401 | + size_t len = p - str; | |
402 | + q = r = stalloc(strlen(p) + len + 1); | |
403 | + if (len > 0) { | |
404 | + memcpy(q, str, len); | |
405 | + q += len; | |
406 | + } | |
407 | + } | |
408 | + while (*p) { | |
409 | + if (*p == CTLQUOTEMARK) { | |
410 | + p++; | |
411 | + continue; | |
412 | + } | |
413 | + if (*p == CTLESC) | |
414 | + p++; | |
415 | + *q++ = *p++; | |
416 | + } | |
417 | + *q = '\0'; | |
418 | + return r; | |
419 | +} | |
420 | +#else | |
421 | void | |
422 | rmescapes(str) | |
423 | char *str; | |
424 | @@ -1492,6 +1693,7 @@ | |
425 | } | |
426 | *q = '\0'; | |
427 | } | |
428 | +#endif | |
429 | ||
430 | ||
431 | ||
432 | ||
433 | diff -urN netbsd-sh/expand.h ash-0.3.7.orig/expand.h | |
434 | --- netbsd-sh/expand.h Fri Jul 9 13:02:06 1999 | |
435 | +++ ash-0.3.7.orig/expand.h Mon Apr 23 22:16:46 2001 | |
436 | @@ -64,7 +64,9 @@ | |
437 | void expandhere __P((union node *, int)); | |
438 | void expandarg __P((union node *, struct arglist *, int)); | |
439 | void expari __P((int)); | |
440 | +#if !(defined(__GLIBC__) && !defined(GLOB_BROKEN)) | |
441 | int patmatch __P((char *, char *, int)); | |
442 | +#endif | |
443 | void rmescapes __P((char *)); | |
444 | int casematch __P((union node *, char *)); | |
445 |