Patch-ID: bash40-006
[bash.git] / braces.c
blob4e0c08a795d9f13d0e853bc1a4f499a16324af76
1 /* braces.c -- code for doing word expansion in curly braces. */
3 /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
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.
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.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
21 /* Stuff in curly braces gets expanded before all other shell expansions. */
23 #include "config.h"
25 #if defined (BRACE_EXPANSION)
27 #if defined (HAVE_UNISTD_H)
28 # ifdef _MINIX
29 # include <sys/types.h>
30 # endif
31 # include <unistd.h>
32 #endif
34 #include "bashansi.h"
36 #if defined (SHELL)
37 # include "shell.h"
38 #endif /* SHELL */
40 #include "general.h"
41 #include "shmbutil.h"
42 #include "chartypes.h"
44 #define brace_whitespace(c) (!(c) || (c) == ' ' || (c) == '\t' || (c) == '\n')
46 #define BRACE_SEQ_SPECIFIER ".."
48 extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
50 /* Basic idea:
52 Segregate the text into 3 sections: preamble (stuff before an open brace),
53 postamble (stuff after the matching close brace) and amble (stuff after
54 preamble, and before postamble). Expand amble, and then tack on the
55 expansions to preamble. Expand postamble, and tack on the expansions to
56 the result so far.
59 /* The character which is used to separate arguments. */
60 static const int brace_arg_separator = ',';
62 #if defined (__P)
63 static int brace_gobbler __P((char *, size_t, int *, int));
64 static char **expand_amble __P((char *, size_t, int));
65 static char **expand_seqterm __P((char *, size_t));
66 static char **mkseq __P((int, int, int, int, int));
67 static char **array_concat __P((char **, char **));
68 #else
69 static int brace_gobbler ();
70 static char **expand_amble ();
71 static char **expand_seqterm ();
72 static char **mkseq();
73 static char **array_concat ();
74 #endif
76 #if 0
77 static void
78 dump_result (a)
79 char **a;
81 int i;
83 for (i = 0; a[i]; i++)
84 printf ("dump_result: a[%d] = -%s-\n", i, a[i]);
86 #endif
88 /* Return an array of strings; the brace expansion of TEXT. */
89 char **
90 brace_expand (text)
91 char *text;
93 register int start;
94 size_t tlen;
95 char *preamble, *postamble, *amble;
96 size_t alen;
97 char **tack, **result;
98 int i, j, c, c1;
100 DECLARE_MBSTATE;
102 /* Find the text of the preamble. */
103 tlen = strlen (text);
104 i = 0;
105 #if defined (CSH_BRACE_COMPAT)
106 c = brace_gobbler (text, tlen, &i, '{'); /* } */
107 #else
108 /* Make sure that when we exit this loop, c == 0 or text[i] begins a
109 valid brace expansion sequence. */
112 c = brace_gobbler (text, tlen, &i, '{'); /* } */
113 c1 = c;
114 /* Verify that c begins a valid brace expansion word. If it doesn't, we
115 go on. Loop stops when there are no more open braces in the word. */
116 if (c)
118 start = j = i + 1; /* { */
119 c = brace_gobbler (text, tlen, &j, '}');
120 if (c == 0) /* it's not */
122 i++;
123 c = c1;
124 continue;
126 else /* it is */
128 c = c1;
129 break;
132 else
133 break;
135 while (c);
136 #endif /* !CSH_BRACE_COMPAT */
138 preamble = (char *)xmalloc (i + 1);
139 strncpy (preamble, text, i);
140 preamble[i] = '\0';
142 result = (char **)xmalloc (2 * sizeof (char *));
143 result[0] = preamble;
144 result[1] = (char *)NULL;
146 /* Special case. If we never found an exciting character, then
147 the preamble is all of the text, so just return that. */
148 if (c != '{')
149 return (result);
151 /* Find the amble. This is the stuff inside this set of braces. */
152 start = ++i;
153 c = brace_gobbler (text, tlen, &i, '}');
155 /* What if there isn't a matching close brace? */
156 if (c == 0)
158 #if defined (NOTDEF)
159 /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
160 and I, then this should be an error. Otherwise, it isn't. */
161 j = start;
162 while (j < i)
164 if (text[j] == '\\')
166 j++;
167 ADVANCE_CHAR (text, tlen, j);
168 continue;
171 if (text[j] == brace_arg_separator)
172 { /* { */
173 strvec_dispose (result);
174 report_error ("no closing `%c' in %s", '}', text);
175 throw_to_top_level ();
177 ADVANCE_CHAR (text, tlen, j);
179 #endif
180 free (preamble); /* Same as result[0]; see initialization. */
181 result[0] = savestring (text);
182 return (result);
185 #if defined (SHELL)
186 amble = substring (text, start, i);
187 alen = i - start;
188 #else
189 amble = (char *)xmalloc (1 + (i - start));
190 strncpy (amble, &text[start], (i - start));
191 alen = i - start;
192 amble[alen] = '\0';
193 #endif
195 #if defined (SHELL)
196 INITIALIZE_MBSTATE;
198 /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
199 just return without doing any expansion. */
200 j = 0;
201 while (amble[j])
203 if (amble[j] == '\\')
205 j++;
206 ADVANCE_CHAR (amble, alen, j);
207 continue;
210 if (amble[j] == brace_arg_separator)
211 break;
213 ADVANCE_CHAR (amble, alen, j);
216 if (amble[j] == 0)
218 tack = expand_seqterm (amble, alen);
219 if (tack)
220 goto add_tack;
221 else
223 free (amble);
224 free (preamble);
225 result[0] = savestring (text);
226 return (result);
229 #endif /* SHELL */
231 tack = expand_amble (amble, alen, 0);
232 add_tack:
233 result = array_concat (result, tack);
234 free (amble);
235 strvec_dispose (tack);
237 postamble = text + i + 1;
239 tack = brace_expand (postamble);
240 result = array_concat (result, tack);
241 strvec_dispose (tack);
243 return (result);
246 /* Expand the text found inside of braces. We simply try to split the
247 text at BRACE_ARG_SEPARATORs into separate strings. We then brace
248 expand each slot which needs it, until there are no more slots which
249 need it. */
250 static char **
251 expand_amble (text, tlen, flags)
252 char *text;
253 size_t tlen;
254 int flags;
256 char **result, **partial;
257 char *tem;
258 int start, i, c;
260 DECLARE_MBSTATE;
262 result = (char **)NULL;
264 start = i = 0;
265 c = 1;
266 while (c)
268 c = brace_gobbler (text, tlen, &i, brace_arg_separator);
269 #if defined (SHELL)
270 tem = substring (text, start, i);
271 #else
272 tem = (char *)xmalloc (1 + (i - start));
273 strncpy (tem, &text[start], (i - start));
274 tem[i- start] = '\0';
275 #endif
277 partial = brace_expand (tem);
279 if (!result)
280 result = partial;
281 else
283 register int lr, lp, j;
285 lr = strvec_len (result);
286 lp = strvec_len (partial);
288 result = strvec_resize (result, lp + lr + 1);
290 for (j = 0; j < lp; j++)
291 result[lr + j] = partial[j];
293 result[lr + j] = (char *)NULL;
294 free (partial);
296 free (tem);
297 ADVANCE_CHAR (text, tlen, i);
298 start = i;
300 return (result);
303 #define ST_BAD 0
304 #define ST_INT 1
305 #define ST_CHAR 2
306 #define ST_ZINT 3
308 static char **
309 mkseq (start, end, incr, type, width)
310 int start, end, incr, type, width;
312 int n, i;
313 char **result, *t;
315 n = abs (end - start) + 1;
316 result = strvec_create (n + 1);
318 if (incr == 0)
319 incr = 1;
321 if (start > end && incr > 0)
322 incr = -incr;
323 else if (start < end && incr < 0)
324 incr = -incr;
326 /* Make sure we go through the loop at least once, so {3..3} prints `3' */
327 i = 0;
328 n = start;
331 #if defined (SHELL)
332 QUIT; /* XXX - memory leak here */
333 #endif
334 if (type == ST_INT)
335 result[i++] = itos (n);
336 else if (type == ST_ZINT)
338 int len;
339 len = asprintf (&t, "%0*d", width, n);
340 result[i++] = t;
342 else
344 t = (char *)xmalloc (2);
345 t[0] = n;
346 t[1] = '\0';
347 result[i++] = t;
349 n += incr;
350 if ((incr < 0 && n < end) || (incr > 0 && n > end))
351 break;
353 while (1);
355 result[i] = (char *)0;
356 return (result);
359 static char **
360 expand_seqterm (text, tlen)
361 char *text;
362 size_t tlen;
364 char *t, *lhs, *rhs;
365 int i, lhs_t, rhs_t, lhs_v, rhs_v, incr, lhs_l, rhs_l, width;
366 intmax_t tl, tr;
367 char **result, *ep;
369 t = strstr (text, BRACE_SEQ_SPECIFIER);
370 if (t == 0)
371 return ((char **)NULL);
373 lhs_l = t - text; /* index of start of BRACE_SEQ_SPECIFIER */
374 lhs = substring (text, 0, lhs_l);
375 rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
377 if (lhs[0] == 0 || rhs[0] == 0)
379 free (lhs);
380 free (rhs);
381 return ((char **)NULL);
384 /* Now figure out whether LHS and RHS are integers or letters. Both
385 sides have to match. */
386 lhs_t = (legal_number (lhs, &tl)) ? ST_INT :
387 ((ISALPHA (lhs[0]) && lhs[1] == 0) ? ST_CHAR : ST_BAD);
389 /* Decide on rhs and whether or not it looks like the user specified
390 an increment */
391 ep = 0;
392 if (ISDIGIT (rhs[0]) || ((rhs[0] == '+' || rhs[0] == '-') && ISDIGIT (rhs[1])))
394 rhs_t = ST_INT;
395 tr = strtoimax (rhs, &ep, 10);
396 if (ep && *ep != 0 && *ep != '.')
397 rhs_t = ST_BAD; /* invalid */
399 else if (ISALPHA (rhs[0]) && (rhs[1] == 0 || rhs[1] == '.'))
401 rhs_t = ST_CHAR;
402 ep = rhs + 1;
404 else
406 rhs_t = ST_BAD;
407 ep = 0;
410 incr = 1;
411 if (rhs_t != ST_BAD)
413 if (ep && *ep == '.' && ep[1] == '.' && ep[2])
414 incr = strtoimax (ep + 2, &ep, 10);
415 if (*ep != 0)
416 rhs_t = ST_BAD; /* invalid incr */
419 if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
421 free (lhs);
422 free (rhs);
423 return ((char **)NULL);
426 /* OK, we have something. It's either a sequence of integers, ascending
427 or descending, or a sequence or letters, ditto. Generate the sequence,
428 put it into a string vector, and return it. */
430 if (lhs_t == ST_CHAR)
432 lhs_v = (unsigned char)lhs[0];
433 rhs_v = (unsigned char)rhs[0];
434 width = 1;
436 else
438 lhs_v = tl; /* integer truncation */
439 rhs_v = tr;
441 /* Decide whether or not the terms need zero-padding */
442 rhs_l = tlen - lhs_l - sizeof (BRACE_SEQ_SPECIFIER) + 1;
443 width = 0;
444 if (lhs_l > 1 && lhs[0] == '0')
445 width = lhs_l, lhs_t = ST_ZINT;
446 if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
447 width = lhs_l, lhs_t = ST_ZINT;
448 if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
449 width = rhs_l, lhs_t = ST_ZINT;
450 if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l)
451 width = rhs_l, lhs_t = ST_ZINT;
454 result = mkseq (lhs_v, rhs_v, incr, lhs_t, width);
456 free (lhs);
457 free (rhs);
459 return (result);
462 /* Start at INDEX, and skip characters in TEXT. Set INDEX to the
463 index of the character matching SATISFY. This understands about
464 quoting. Return the character that caused us to stop searching;
465 this is either the same as SATISFY, or 0. */
466 /* If SATISFY is `}', we are looking for a brace expression, so we
467 should enforce the rules that govern valid brace expansions:
468 1) to count as an arg separator, a comma or `..' has to be outside
469 an inner set of braces.
471 static int
472 brace_gobbler (text, tlen, indx, satisfy)
473 char *text;
474 size_t tlen;
475 int *indx;
476 int satisfy;
478 register int i, c, quoted, level, commas, pass_next;
479 #if defined (SHELL)
480 int si;
481 char *t;
482 #endif
483 DECLARE_MBSTATE;
485 level = quoted = pass_next = 0;
486 #if defined (CSH_BRACE_COMPAT)
487 commas = 1;
488 #else
489 commas = (satisfy == '}') ? 0 : 1;
490 #endif
492 i = *indx;
493 while (c = text[i])
495 if (pass_next)
497 pass_next = 0;
498 ADVANCE_CHAR (text, tlen, i);
499 continue;
502 /* A backslash escapes the next character. This allows backslash to
503 escape the quote character in a double-quoted string. */
504 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
506 pass_next = 1;
507 i++;
508 continue;
511 #if defined (SHELL)
512 /* If compiling for the shell, treat ${...} like \{...} */
513 if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */
515 pass_next = 1;
516 i++;
517 if (quoted == 0)
518 level++;
519 continue;
521 #endif
523 if (quoted)
525 if (c == quoted)
526 quoted = 0;
527 ADVANCE_CHAR (text, tlen, i);
528 continue;
531 if (c == '"' || c == '\'' || c == '`')
533 quoted = c;
534 i++;
535 continue;
538 #if defined (SHELL)
539 /* Pass new-style command and process substitutions through unchanged. */
540 if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */
542 si = i + 2;
543 t = extract_command_subst (text, &si, 0);
544 i = si;
545 free (t);
546 i++;
547 continue;
549 #endif
551 if (c == satisfy && level == 0 && quoted == 0 && commas > 0)
553 /* We ignore an open brace surrounded by whitespace, and also
554 an open brace followed immediately by a close brace preceded
555 by whitespace. */
556 if (c == '{' &&
557 ((!i || brace_whitespace (text[i - 1])) &&
558 (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
560 i++;
561 continue;
564 break;
567 if (c == '{')
568 level++;
569 else if (c == '}' && level)
570 level--;
571 #if !defined (CSH_BRACE_COMPAT)
572 else if (satisfy == '}' && c == brace_arg_separator && level == 0)
573 commas++;
574 else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) &&
575 text[i+2] != satisfy && level == 0)
576 commas++;
577 #endif
579 ADVANCE_CHAR (text, tlen, i);
582 *indx = i;
583 return (c);
586 /* Return a new array of strings which is the result of appending each
587 string in ARR2 to each string in ARR1. The resultant array is
588 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
589 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
590 is returned. */
591 static char **
592 array_concat (arr1, arr2)
593 char **arr1, **arr2;
595 register int i, j, len, len1, len2;
596 register char **result;
598 if (arr1 == 0)
599 return (strvec_copy (arr2));
601 if (arr2 == 0)
602 return (strvec_copy (arr1));
604 len1 = strvec_len (arr1);
605 len2 = strvec_len (arr2);
607 result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
609 len = 0;
610 for (i = 0; i < len1; i++)
612 int strlen_1 = strlen (arr1[i]);
614 for (j = 0; j < len2; j++)
616 result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
617 strcpy (result[len], arr1[i]);
618 strcpy (result[len] + strlen_1, arr2[j]);
619 len++;
621 free (arr1[i]);
623 free (arr1);
625 result[len] = (char *)NULL;
626 return (result);
629 #if defined (TEST)
630 #include <stdio.h>
632 fatal_error (format, arg1, arg2)
633 char *format, *arg1, *arg2;
635 report_error (format, arg1, arg2);
636 exit (1);
639 report_error (format, arg1, arg2)
640 char *format, *arg1, *arg2;
642 fprintf (stderr, format, arg1, arg2);
643 fprintf (stderr, "\n");
646 main ()
648 char example[256];
650 for (;;)
652 char **result;
653 int i;
655 fprintf (stderr, "brace_expand> ");
657 if ((!fgets (example, 256, stdin)) ||
658 (strncmp (example, "quit", 4) == 0))
659 break;
661 if (strlen (example))
662 example[strlen (example) - 1] = '\0';
664 result = brace_expand (example);
666 for (i = 0; result[i]; i++)
667 printf ("%s\n", result[i]);
669 free_array (result);
674 * Local variables:
675 * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
676 * end:
679 #endif /* TEST */
680 #endif /* BRACE_EXPANSION */