]> git.ipfire.org Git - thirdparty/bash.git/blame - braces.c
Bash-4.4 patch 4
[thirdparty/bash.git] / braces.c
CommitLineData
726f6388
JA
1/* braces.c -- code for doing word expansion in curly braces. */
2
ac50fbac 3/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
726f6388
JA
4
5 This file is part of GNU Bash, the Bourne Again SHell.
6
3185942a
JA
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
726f6388 11
3185942a
JA
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
726f6388
JA
16
17 You should have received a copy of the GNU General Public License
3185942a
JA
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
726f6388 20
ccc6cda3 21/* Stuff in curly braces gets expanded before all other shell expansions. */
726f6388 22
ccc6cda3
JA
23#include "config.h"
24
25#if defined (BRACE_EXPANSION)
26
27#if defined (HAVE_UNISTD_H)
cce855bc
JA
28# ifdef _MINIX
29# include <sys/types.h>
30# endif
ccc6cda3
JA
31# include <unistd.h>
32#endif
726f6388 33
ac50fbac
CR
34#include <errno.h>
35
d166f048 36#include "bashansi.h"
ac50fbac 37#include "bashintl.h"
726f6388
JA
38
39#if defined (SHELL)
ccc6cda3 40# include "shell.h"
a0c0a00f
CR
41#else
42# if defined (TEST)
43typedef char *WORD_DESC;
44typedef char **WORD_LIST;
45#define _(X) X
46# endif /* TEST */
726f6388
JA
47#endif /* SHELL */
48
ac50fbac 49#include "typemax.h" /* INTMAX_MIN, INTMAX_MAX */
726f6388 50#include "general.h"
7117c2d2 51#include "shmbutil.h"
b80f6443 52#include "chartypes.h"
7117c2d2 53
ac50fbac
CR
54#ifndef errno
55extern int errno;
56#endif
57
726f6388
JA
58#define brace_whitespace(c) (!(c) || (c) == ' ' || (c) == '\t' || (c) == '\n')
59
b80f6443
JA
60#define BRACE_SEQ_SPECIFIER ".."
61
3185942a
JA
62extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
63
ac50fbac
CR
64extern int last_command_exit_value;
65
726f6388
JA
66/* Basic idea:
67
68 Segregate the text into 3 sections: preamble (stuff before an open brace),
69 postamble (stuff after the matching close brace) and amble (stuff after
70 preamble, and before postamble). Expand amble, and then tack on the
71 expansions to preamble. Expand postamble, and tack on the expansions to
72 the result so far.
73 */
74
75/* The character which is used to separate arguments. */
3185942a 76static const int brace_arg_separator = ',';
726f6388 77
f73dda09 78#if defined (__P)
7117c2d2 79static int brace_gobbler __P((char *, size_t, int *, int));
b80f6443
JA
80static char **expand_amble __P((char *, size_t, int));
81static char **expand_seqterm __P((char *, size_t));
ac50fbac 82static char **mkseq __P((intmax_t, intmax_t, intmax_t, int, int));
f73dda09
JA
83static char **array_concat __P((char **, char **));
84#else
726f6388 85static int brace_gobbler ();
f73dda09 86static char **expand_amble ();
b80f6443
JA
87static char **expand_seqterm ();
88static char **mkseq();
f73dda09
JA
89static char **array_concat ();
90#endif
726f6388 91
0628567a
JA
92#if 0
93static void
94dump_result (a)
95 char **a;
96{
97 int i;
98
99 for (i = 0; a[i]; i++)
100 printf ("dump_result: a[%d] = -%s-\n", i, a[i]);
101}
102#endif
103
726f6388
JA
104/* Return an array of strings; the brace expansion of TEXT. */
105char **
106brace_expand (text)
107 char *text;
108{
109 register int start;
7117c2d2 110 size_t tlen;
726f6388 111 char *preamble, *postamble, *amble;
7117c2d2 112 size_t alen;
726f6388 113 char **tack, **result;
0628567a 114 int i, j, c, c1;
726f6388 115
7117c2d2
JA
116 DECLARE_MBSTATE;
117
726f6388 118 /* Find the text of the preamble. */
7117c2d2 119 tlen = strlen (text);
726f6388 120 i = 0;
0628567a
JA
121#if defined (CSH_BRACE_COMPAT)
122 c = brace_gobbler (text, tlen, &i, '{'); /* } */
123#else
124 /* Make sure that when we exit this loop, c == 0 or text[i] begins a
125 valid brace expansion sequence. */
126 do
127 {
128 c = brace_gobbler (text, tlen, &i, '{'); /* } */
129 c1 = c;
130 /* Verify that c begins a valid brace expansion word. If it doesn't, we
131 go on. Loop stops when there are no more open braces in the word. */
132 if (c)
133 {
134 start = j = i + 1; /* { */
135 c = brace_gobbler (text, tlen, &j, '}');
136 if (c == 0) /* it's not */
137 {
138 i++;
139 c = c1;
140 continue;
141 }
142 else /* it is */
143 {
144 c = c1;
145 break;
146 }
147 }
148 else
149 break;
150 }
151 while (c);
152#endif /* !CSH_BRACE_COMPAT */
726f6388
JA
153
154 preamble = (char *)xmalloc (i + 1);
ac50fbac
CR
155 if (i > 0)
156 strncpy (preamble, text, i);
726f6388
JA
157 preamble[i] = '\0';
158
159 result = (char **)xmalloc (2 * sizeof (char *));
160 result[0] = preamble;
161 result[1] = (char *)NULL;
ccc6cda3 162
726f6388
JA
163 /* Special case. If we never found an exciting character, then
164 the preamble is all of the text, so just return that. */
165 if (c != '{')
166 return (result);
167
168 /* Find the amble. This is the stuff inside this set of braces. */
169 start = ++i;
7117c2d2 170 c = brace_gobbler (text, tlen, &i, '}');
726f6388
JA
171
172 /* What if there isn't a matching close brace? */
ccc6cda3 173 if (c == 0)
726f6388
JA
174 {
175#if defined (NOTDEF)
726f6388
JA
176 /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
177 and I, then this should be an error. Otherwise, it isn't. */
7117c2d2
JA
178 j = start;
179 while (j < i)
726f6388
JA
180 {
181 if (text[j] == '\\')
182 {
183 j++;
7117c2d2 184 ADVANCE_CHAR (text, tlen, j);
726f6388
JA
185 continue;
186 }
187
188 if (text[j] == brace_arg_separator)
b80f6443 189 { /* { */
7117c2d2 190 strvec_dispose (result);
ac50fbac 191 last_command_exit_value = 1;
b80f6443 192 report_error ("no closing `%c' in %s", '}', text);
726f6388
JA
193 throw_to_top_level ();
194 }
7117c2d2 195 ADVANCE_CHAR (text, tlen, j);
726f6388
JA
196 }
197#endif
198 free (preamble); /* Same as result[0]; see initialization. */
199 result[0] = savestring (text);
200 return (result);
201 }
202
bb70624e
JA
203#if defined (SHELL)
204 amble = substring (text, start, i);
7117c2d2 205 alen = i - start;
bb70624e 206#else
726f6388
JA
207 amble = (char *)xmalloc (1 + (i - start));
208 strncpy (amble, &text[start], (i - start));
7117c2d2
JA
209 alen = i - start;
210 amble[alen] = '\0';
bb70624e 211#endif
726f6388
JA
212
213#if defined (SHELL)
7117c2d2
JA
214 INITIALIZE_MBSTATE;
215
726f6388
JA
216 /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
217 just return without doing any expansion. */
7117c2d2
JA
218 j = 0;
219 while (amble[j])
ccc6cda3
JA
220 {
221 if (amble[j] == '\\')
222 {
223 j++;
7117c2d2 224 ADVANCE_CHAR (amble, alen, j);
ccc6cda3
JA
225 continue;
226 }
7117c2d2 227
ccc6cda3
JA
228 if (amble[j] == brace_arg_separator)
229 break;
7117c2d2
JA
230
231 ADVANCE_CHAR (amble, alen, j);
ccc6cda3
JA
232 }
233
b80f6443 234 if (amble[j] == 0)
ccc6cda3 235 {
b80f6443
JA
236 tack = expand_seqterm (amble, alen);
237 if (tack)
238 goto add_tack;
ac50fbac
CR
239 else if (text[i + 1])
240 {
241 /* If the sequence expansion fails (e.g., because the integers
242 overflow), but there is more in the string, try and process
243 the rest of the string, which may contain additional brace
244 expansions. Treat the unexpanded sequence term as a simple
245 string (including the braces). */
246 tack = strvec_create (2);
247 tack[0] = savestring (text+start-1);
248 tack[0][i-start+2] = '\0';
249 tack[1] = (char *)0;
250 goto add_tack;
251 }
b80f6443
JA
252 else
253 {
254 free (amble);
255 free (preamble);
256 result[0] = savestring (text);
257 return (result);
258 }
ccc6cda3 259 }
726f6388
JA
260#endif /* SHELL */
261
b80f6443
JA
262 tack = expand_amble (amble, alen, 0);
263add_tack:
726f6388
JA
264 result = array_concat (result, tack);
265 free (amble);
ac50fbac
CR
266 if (tack != result)
267 strvec_dispose (tack);
726f6388 268
b80f6443
JA
269 postamble = text + i + 1;
270
ac50fbac
CR
271 if (postamble && *postamble)
272 {
273 tack = brace_expand (postamble);
274 result = array_concat (result, tack);
275 if (tack != result)
276 strvec_dispose (tack);
277 }
726f6388
JA
278
279 return (result);
280}
281
282/* Expand the text found inside of braces. We simply try to split the
283 text at BRACE_ARG_SEPARATORs into separate strings. We then brace
284 expand each slot which needs it, until there are no more slots which
285 need it. */
286static char **
b80f6443 287expand_amble (text, tlen, flags)
726f6388 288 char *text;
7117c2d2 289 size_t tlen;
b80f6443 290 int flags;
726f6388 291{
ac50fbac 292 char **result, **partial, **tresult;
726f6388
JA
293 char *tem;
294 int start, i, c;
295
a0c0a00f 296#if defined (SHELL)
7117c2d2 297 DECLARE_MBSTATE;
a0c0a00f 298#endif
7117c2d2 299
726f6388
JA
300 result = (char **)NULL;
301
7117c2d2
JA
302 start = i = 0;
303 c = 1;
304 while (c)
726f6388 305 {
7117c2d2 306 c = brace_gobbler (text, tlen, &i, brace_arg_separator);
bb70624e
JA
307#if defined (SHELL)
308 tem = substring (text, start, i);
309#else
726f6388
JA
310 tem = (char *)xmalloc (1 + (i - start));
311 strncpy (tem, &text[start], (i - start));
a0c0a00f 312 tem[i - start] = '\0';
bb70624e 313#endif
726f6388
JA
314
315 partial = brace_expand (tem);
316
317 if (!result)
318 result = partial;
319 else
320 {
b80f6443
JA
321 register int lr, lp, j;
322
323 lr = strvec_len (result);
324 lp = strvec_len (partial);
726f6388 325
ac50fbac
CR
326 tresult = strvec_mresize (result, lp + lr + 1);
327 if (tresult == 0)
328 {
329 internal_error (_("brace expansion: cannot allocate memory for %s"), tem);
a0c0a00f
CR
330 free (tem);
331 strvec_dispose (partial);
ac50fbac
CR
332 strvec_dispose (result);
333 result = (char **)NULL;
334 return result;
335 }
336 else
337 result = tresult;
726f6388
JA
338
339 for (j = 0; j < lp; j++)
340 result[lr + j] = partial[j];
341
342 result[lr + j] = (char *)NULL;
343 free (partial);
344 }
345 free (tem);
a0c0a00f 346#if defined (SHELL)
7117c2d2 347 ADVANCE_CHAR (text, tlen, i);
a0c0a00f
CR
348#else
349 i++;
350#endif
7117c2d2 351 start = i;
726f6388
JA
352 }
353 return (result);
354}
355
b80f6443
JA
356#define ST_BAD 0
357#define ST_INT 1
358#define ST_CHAR 2
3185942a 359#define ST_ZINT 3
b80f6443 360
ac50fbac
CR
361#ifndef sh_imaxabs
362# define sh_imaxabs(x) (((x) >= 0) ? (x) : -(x))
363#endif
364
365/* Handle signed arithmetic overflow and underflow. Have to do it this way
366 to avoid compilers optimizing out simpler overflow checks. */
367
368/* Make sure that a+b does not exceed MAXV or is smaller than MINV (if b < 0).
369 Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
370#define ADDOVERFLOW(a,b,minv,maxv) \
371 ((((a) > 0) && ((b) > ((maxv) - (a)))) || \
372 (((a) < 0) && ((b) < ((minv) - (a)))))
373
374/* Make sure that a-b is not smaller than MINV or exceeds MAXV (if b < 0).
375 Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
376#define SUBOVERFLOW(a,b,minv,maxv) \
377 ((((b) > 0) && ((a) < ((minv) + (b)))) || \
378 (((b) < 0) && ((a) > ((maxv) + (b)))))
379
b80f6443 380static char **
3185942a 381mkseq (start, end, incr, type, width)
ac50fbac
CR
382 intmax_t start, end, incr;
383 int type, width;
b80f6443 384{
ac50fbac
CR
385 intmax_t n, prevn;
386 int i, j, nelem;
b80f6443
JA
387 char **result, *t;
388
0628567a
JA
389 if (incr == 0)
390 incr = 1;
ac50fbac 391
0628567a
JA
392 if (start > end && incr > 0)
393 incr = -incr;
394 else if (start < end && incr < 0)
ac50fbac
CR
395 {
396 if (incr == INTMAX_MIN) /* Don't use -INTMAX_MIN */
397 return ((char **)NULL);
398 incr = -incr;
399 }
400
401 /* Check that end-start will not overflow INTMAX_MIN, INTMAX_MAX. The +3
402 and -2, not strictly necessary, are there because of the way the number
403 of elements and value passed to strvec_create() are calculated below. */
404 if (SUBOVERFLOW (end, start, INTMAX_MIN+3, INTMAX_MAX-2))
405 return ((char **)NULL);
406
407 prevn = sh_imaxabs (end - start);
408 /* Need to check this way in case INT_MAX == INTMAX_MAX */
409 if (INT_MAX == INTMAX_MAX && (ADDOVERFLOW (prevn, 2, INT_MIN, INT_MAX)))
410 return ((char **)NULL);
411 /* Make sure the assignment to nelem below doesn't end up <= 0 due to
412 intmax_t overflow */
413 else if (ADDOVERFLOW ((prevn/sh_imaxabs(incr)), 1, INTMAX_MIN, INTMAX_MAX))
414 return ((char **)NULL);
415
416 /* XXX - TOFIX: potentially allocating a lot of extra memory if
417 imaxabs(incr) != 1 */
418 /* Instead of a simple nelem = prevn + 1, something like:
419 nelem = (prevn / imaxabs(incr)) + 1;
420 would work */
421 nelem = (prevn / sh_imaxabs(incr)) + 1;
422 if (nelem > INT_MAX - 2) /* Don't overflow int */
423 return ((char **)NULL);
424 result = strvec_mcreate (nelem + 1);
425 if (result == 0)
426 {
427 internal_error (_("brace expansion: failed to allocate memory for %d elements"), nelem);
428 return ((char **)NULL);
429 }
b80f6443
JA
430
431 /* Make sure we go through the loop at least once, so {3..3} prints `3' */
432 i = 0;
433 n = start;
434 do
435 {
0628567a 436#if defined (SHELL)
a0c0a00f
CR
437 if (ISINTERRUPT)
438 {
439 strvec_dispose (result);
440 result = (char **)NULL;
441 }
442 QUIT;
0628567a 443#endif
b80f6443 444 if (type == ST_INT)
ac50fbac 445 result[i++] = t = itos (n);
3185942a
JA
446 else if (type == ST_ZINT)
447 {
495aee44
CR
448 int len, arg;
449 arg = n;
450 len = asprintf (&t, "%0*d", width, arg);
3185942a
JA
451 result[i++] = t;
452 }
b80f6443
JA
453 else
454 {
ac50fbac
CR
455 if (t = (char *)malloc (2))
456 {
457 t[0] = n;
458 t[1] = '\0';
459 }
b80f6443
JA
460 result[i++] = t;
461 }
ac50fbac
CR
462
463 /* We failed to allocate memory for this number, so we bail. */
464 if (t == 0)
465 {
466 char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1];
467
468 /* Easier to do this than mess around with various intmax_t printf
469 formats (%ld? %lld? %jd?) and PRIdMAX. */
470 p = inttostr (n, lbuf, sizeof (lbuf));
471 internal_error (_("brace expansion: failed to allocate memory for `%s'"), p);
472 strvec_dispose (result);
473 return ((char **)NULL);
474 }
475
476 /* Handle overflow and underflow of n+incr */
477 if (ADDOVERFLOW (n, incr, INTMAX_MIN, INTMAX_MAX))
478 break;
479
b80f6443 480 n += incr;
ac50fbac 481
3185942a
JA
482 if ((incr < 0 && n < end) || (incr > 0 && n > end))
483 break;
b80f6443
JA
484 }
485 while (1);
486
487 result[i] = (char *)0;
488 return (result);
489}
490
491static char **
492expand_seqterm (text, tlen)
493 char *text;
494 size_t tlen;
495{
496 char *t, *lhs, *rhs;
ac50fbac
CR
497 int i, lhs_t, rhs_t, lhs_l, rhs_l, width;
498 intmax_t lhs_v, rhs_v, incr;
b80f6443 499 intmax_t tl, tr;
0001803f 500 char **result, *ep, *oep;
b80f6443
JA
501
502 t = strstr (text, BRACE_SEQ_SPECIFIER);
503 if (t == 0)
504 return ((char **)NULL);
505
3185942a
JA
506 lhs_l = t - text; /* index of start of BRACE_SEQ_SPECIFIER */
507 lhs = substring (text, 0, lhs_l);
508 rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
b80f6443
JA
509
510 if (lhs[0] == 0 || rhs[0] == 0)
511 {
512 free (lhs);
513 free (rhs);
514 return ((char **)NULL);
515 }
516
517 /* Now figure out whether LHS and RHS are integers or letters. Both
518 sides have to match. */
519 lhs_t = (legal_number (lhs, &tl)) ? ST_INT :
520 ((ISALPHA (lhs[0]) && lhs[1] == 0) ? ST_CHAR : ST_BAD);
3185942a
JA
521
522 /* Decide on rhs and whether or not it looks like the user specified
523 an increment */
524 ep = 0;
525 if (ISDIGIT (rhs[0]) || ((rhs[0] == '+' || rhs[0] == '-') && ISDIGIT (rhs[1])))
526 {
527 rhs_t = ST_INT;
ac50fbac 528 errno = 0;
3185942a 529 tr = strtoimax (rhs, &ep, 10);
ac50fbac 530 if (errno == ERANGE || (ep && *ep != 0 && *ep != '.'))
3185942a
JA
531 rhs_t = ST_BAD; /* invalid */
532 }
533 else if (ISALPHA (rhs[0]) && (rhs[1] == 0 || rhs[1] == '.'))
534 {
535 rhs_t = ST_CHAR;
536 ep = rhs + 1;
537 }
538 else
539 {
540 rhs_t = ST_BAD;
541 ep = 0;
542 }
543
544 incr = 1;
545 if (rhs_t != ST_BAD)
546 {
0001803f 547 oep = ep;
ac50fbac 548 errno = 0;
3185942a
JA
549 if (ep && *ep == '.' && ep[1] == '.' && ep[2])
550 incr = strtoimax (ep + 2, &ep, 10);
ac50fbac
CR
551 if (*ep != 0 || errno == ERANGE)
552 rhs_t = ST_BAD; /* invalid incr or overflow */
0001803f 553 tlen -= ep - oep;
3185942a 554 }
b80f6443
JA
555
556 if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
557 {
558 free (lhs);
559 free (rhs);
560 return ((char **)NULL);
561 }
562
563 /* OK, we have something. It's either a sequence of integers, ascending
564 or descending, or a sequence or letters, ditto. Generate the sequence,
565 put it into a string vector, and return it. */
566
567 if (lhs_t == ST_CHAR)
568 {
eb873671
JA
569 lhs_v = (unsigned char)lhs[0];
570 rhs_v = (unsigned char)rhs[0];
3185942a 571 width = 1;
b80f6443
JA
572 }
573 else
574 {
575 lhs_v = tl; /* integer truncation */
576 rhs_v = tr;
3185942a
JA
577
578 /* Decide whether or not the terms need zero-padding */
579 rhs_l = tlen - lhs_l - sizeof (BRACE_SEQ_SPECIFIER) + 1;
580 width = 0;
581 if (lhs_l > 1 && lhs[0] == '0')
582 width = lhs_l, lhs_t = ST_ZINT;
583 if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
584 width = lhs_l, lhs_t = ST_ZINT;
585 if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
586 width = rhs_l, lhs_t = ST_ZINT;
587 if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l)
588 width = rhs_l, lhs_t = ST_ZINT;
0001803f
CR
589
590 if (width < lhs_l && lhs_t == ST_ZINT)
591 width = lhs_l;
592 if (width < rhs_l && lhs_t == ST_ZINT)
593 width = rhs_l;
b80f6443
JA
594 }
595
3185942a 596 result = mkseq (lhs_v, rhs_v, incr, lhs_t, width);
b80f6443
JA
597
598 free (lhs);
599 free (rhs);
600
601 return (result);
602}
603
726f6388
JA
604/* Start at INDEX, and skip characters in TEXT. Set INDEX to the
605 index of the character matching SATISFY. This understands about
606 quoting. Return the character that caused us to stop searching;
607 this is either the same as SATISFY, or 0. */
0628567a
JA
608/* If SATISFY is `}', we are looking for a brace expression, so we
609 should enforce the rules that govern valid brace expansions:
610 1) to count as an arg separator, a comma or `..' has to be outside
611 an inner set of braces.
612*/
726f6388 613static int
7117c2d2 614brace_gobbler (text, tlen, indx, satisfy)
726f6388 615 char *text;
7117c2d2 616 size_t tlen;
726f6388
JA
617 int *indx;
618 int satisfy;
619{
0628567a 620 register int i, c, quoted, level, commas, pass_next;
d166f048
JA
621#if defined (SHELL)
622 int si;
623 char *t;
624#endif
7117c2d2 625 DECLARE_MBSTATE;
726f6388
JA
626
627 level = quoted = pass_next = 0;
0628567a
JA
628#if defined (CSH_BRACE_COMPAT)
629 commas = 1;
630#else
631 commas = (satisfy == '}') ? 0 : 1;
632#endif
726f6388 633
7117c2d2
JA
634 i = *indx;
635 while (c = text[i])
726f6388
JA
636 {
637 if (pass_next)
638 {
639 pass_next = 0;
a0c0a00f 640#if defined (SHELL)
7117c2d2 641 ADVANCE_CHAR (text, tlen, i);
a0c0a00f
CR
642#else
643 i++;
644#endif
726f6388
JA
645 continue;
646 }
647
648 /* A backslash escapes the next character. This allows backslash to
649 escape the quote character in a double-quoted string. */
650 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
28ef6c31
JA
651 {
652 pass_next = 1;
7117c2d2 653 i++;
28ef6c31
JA
654 continue;
655 }
726f6388 656
b80f6443
JA
657#if defined (SHELL)
658 /* If compiling for the shell, treat ${...} like \{...} */
659 if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */
660 {
661 pass_next = 1;
662 i++;
eb873671
JA
663 if (quoted == 0)
664 level++;
b80f6443
JA
665 continue;
666 }
667#endif
668
726f6388
JA
669 if (quoted)
670 {
671 if (c == quoted)
672 quoted = 0;
ac50fbac
CR
673#if defined (SHELL)
674 /* The shell allows quoted command substitutions */
675 if (quoted == '"' && c == '$' && text[i+1] == '(') /*)*/
676 goto comsub;
677#endif
a0c0a00f 678#if defined (SHELL)
7117c2d2 679 ADVANCE_CHAR (text, tlen, i);
a0c0a00f
CR
680#else
681 i++;
682#endif
726f6388
JA
683 continue;
684 }
685
686 if (c == '"' || c == '\'' || c == '`')
687 {
688 quoted = c;
7117c2d2 689 i++;
726f6388
JA
690 continue;
691 }
ccc6cda3 692
d166f048 693#if defined (SHELL)
3185942a
JA
694 /* Pass new-style command and process substitutions through unchanged. */
695 if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */
d166f048 696 {
ac50fbac 697comsub:
d166f048 698 si = i + 2;
3185942a 699 t = extract_command_subst (text, &si, 0);
d166f048
JA
700 i = si;
701 free (t);
7117c2d2 702 i++;
d166f048
JA
703 continue;
704 }
705#endif
706
0628567a 707 if (c == satisfy && level == 0 && quoted == 0 && commas > 0)
726f6388
JA
708 {
709 /* We ignore an open brace surrounded by whitespace, and also
ccc6cda3
JA
710 an open brace followed immediately by a close brace preceded
711 by whitespace. */
726f6388
JA
712 if (c == '{' &&
713 ((!i || brace_whitespace (text[i - 1])) &&
714 (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
7117c2d2
JA
715 {
716 i++;
717 continue;
718 }
b80f6443 719
726f6388
JA
720 break;
721 }
722
723 if (c == '{')
724 level++;
725 else if (c == '}' && level)
726 level--;
0628567a
JA
727#if !defined (CSH_BRACE_COMPAT)
728 else if (satisfy == '}' && c == brace_arg_separator && level == 0)
729 commas++;
730 else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) &&
731 text[i+2] != satisfy && level == 0)
732 commas++;
733#endif
7117c2d2 734
a0c0a00f 735#if defined (SHELL)
7117c2d2 736 ADVANCE_CHAR (text, tlen, i);
a0c0a00f
CR
737#else
738 i++;
739#endif
726f6388
JA
740 }
741
742 *indx = i;
743 return (c);
744}
745
ac50fbac
CR
746/* Return 1 if ARR has any non-empty-string members. Used to short-circuit
747 in array_concat() below. */
748static int
749degenerate_array (arr)
750 char **arr;
751{
752 register int i;
753
754 for (i = 0; arr[i]; i++)
755 if (arr[i][0] != '\0')
756 return 0;
757 return 1;
758}
759
726f6388
JA
760/* Return a new array of strings which is the result of appending each
761 string in ARR2 to each string in ARR1. The resultant array is
762 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
763 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
764 is returned. */
765static char **
766array_concat (arr1, arr2)
767 char **arr1, **arr2;
768{
769 register int i, j, len, len1, len2;
770 register char **result;
771
ccc6cda3 772 if (arr1 == 0)
ac50fbac 773 return (arr2); /* XXX - see if we can get away without copying? */
726f6388 774
ccc6cda3 775 if (arr2 == 0)
ac50fbac
CR
776 return (arr1); /* XXX - caller expects us to free arr1 */
777
778 /* We can only short-circuit if the array consists of a single null element;
779 otherwise we need to replicate the contents of the other array and
780 prefix (or append, below) an empty element to each one. */
781 if (arr1[0] && arr1[0][0] == 0 && arr1[1] == 0)
782 {
783 strvec_dispose (arr1);
784 return (arr2); /* XXX - use flags to see if we can avoid copying here */
785 }
786
787 if (arr2[0] && arr2[0][0] == 0 && arr2[1] == 0)
788 return (arr1); /* XXX - rather than copying and freeing it */
726f6388 789
7117c2d2
JA
790 len1 = strvec_len (arr1);
791 len2 = strvec_len (arr2);
726f6388
JA
792
793 result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
794
795 len = 0;
796 for (i = 0; i < len1; i++)
797 {
798 int strlen_1 = strlen (arr1[i]);
799
800 for (j = 0; j < len2; j++)
801 {
b80f6443 802 result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
726f6388
JA
803 strcpy (result[len], arr1[i]);
804 strcpy (result[len] + strlen_1, arr2[j]);
805 len++;
806 }
807 free (arr1[i]);
808 }
809 free (arr1);
810
811 result[len] = (char *)NULL;
812 return (result);
813}
814
815#if defined (TEST)
816#include <stdio.h>
817
a0c0a00f
CR
818void *
819xmalloc(n)
820 size_t n;
726f6388 821{
a0c0a00f 822 return (malloc (n));
726f6388
JA
823}
824
a0c0a00f
CR
825void *
826xrealloc(p, n)
827 void *p;
828 size_t n;
829{
830 return (realloc (p, n));
831}
832
833int
834internal_error (format, arg1, arg2)
726f6388
JA
835 char *format, *arg1, *arg2;
836{
837 fprintf (stderr, format, arg1, arg2);
838 fprintf (stderr, "\n");
839}
a0c0a00f 840
726f6388
JA
841main ()
842{
843 char example[256];
844
845 for (;;)
846 {
847 char **result;
848 int i;
849
850 fprintf (stderr, "brace_expand> ");
851
852 if ((!fgets (example, 256, stdin)) ||
853 (strncmp (example, "quit", 4) == 0))
854 break;
855
856 if (strlen (example))
857 example[strlen (example) - 1] = '\0';
858
859 result = brace_expand (example);
860
861 for (i = 0; result[i]; i++)
862 printf ("%s\n", result[i]);
863
a0c0a00f 864 strvec_dispose (result);
726f6388
JA
865 }
866}
867\f
868/*
869 * Local variables:
870 * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
871 * end:
872 */
873
874#endif /* TEST */
ccc6cda3 875#endif /* BRACE_EXPANSION */