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