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. */
25 #if defined (BRACE_EXPANSION)
27 #if defined (HAVE_UNISTD_H)
29 # include <sys/types.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)));
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
59 /* The character which is used to separate arguments. */
60 static const int brace_arg_separator = ',';
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((intmax_t, intmax_t, int, int, int));
67 static char **array_concat __P((char **, char **));
69 static int brace_gobbler ();
70 static char **expand_amble ();
71 static char **expand_seqterm ();
72 static char **mkseq();
73 static char **array_concat ();
83 for (i = 0; a[i]; i++)
84 printf ("dump_result: a[%d] = -%s-\n", i, a[i]);
88 /* Return an array of strings; the brace expansion of TEXT. */
95 char *preamble, *postamble, *amble;
97 char **tack, **result;
102 /* Find the text of the preamble. */
103 tlen = strlen (text);
105 #if defined (CSH_BRACE_COMPAT)
106 c = brace_gobbler (text, tlen, &i, '{'); /* } */
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, '{'); /* } */
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. */
118 start = j = i + 1; /* { */
119 c = brace_gobbler (text, tlen, &j, '}');
120 if (c == 0) /* it's not */
136 #endif /* !CSH_BRACE_COMPAT */
138 preamble = (char *)xmalloc (i + 1);
139 strncpy (preamble, text, i);
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. */
151 /* Find the amble. This is the stuff inside this set of braces. */
153 c = brace_gobbler (text, tlen, &i, '}');
155 /* What if there isn't a matching close brace? */
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. */
167 ADVANCE_CHAR (text, tlen, j);
171 if (text[j] == brace_arg_separator)
173 strvec_dispose (result);
174 report_error ("no closing `%c' in %s", '}', text);
175 throw_to_top_level ();
177 ADVANCE_CHAR (text, tlen, j);
180 free (preamble); /* Same as result[0]; see initialization. */
181 result[0] = savestring (text);
186 amble = substring (text, start, i);
189 amble = (char *)xmalloc (1 + (i - start));
190 strncpy (amble, &text[start], (i - start));
198 /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
199 just return without doing any expansion. */
203 if (amble[j] == '\\')
206 ADVANCE_CHAR (amble, alen, j);
210 if (amble[j] == brace_arg_separator)
213 ADVANCE_CHAR (amble, alen, j);
218 tack = expand_seqterm (amble, alen);
225 result[0] = savestring (text);
231 tack = expand_amble (amble, alen, 0);
233 result = array_concat (result, tack);
235 strvec_dispose (tack);
237 postamble = text + i + 1;
239 tack = brace_expand (postamble);
240 result = array_concat (result, tack);
241 strvec_dispose (tack);
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
251 expand_amble (text, tlen, flags)
256 char **result, **partial;
262 result = (char **)NULL;
268 c = brace_gobbler (text, tlen, &i, brace_arg_separator);
270 tem = substring (text, start, i);
272 tem = (char *)xmalloc (1 + (i - start));
273 strncpy (tem, &text[start], (i - start));
274 tem[i- start] = '\0';
277 partial = brace_expand (tem);
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;
297 ADVANCE_CHAR (text, tlen, i);
309 mkseq (start, end, incr, type, width)
311 int incr, type, width;
317 i = abs (end - start) + 1;
318 result = strvec_create (i + 1);
323 if (start > end && incr > 0)
325 else if (start < end && incr < 0)
328 /* Make sure we go through the loop at least once, so {3..3} prints `3' */
334 QUIT; /* XXX - memory leak here */
337 result[i++] = itos (n);
338 else if (type == ST_ZINT)
342 len = asprintf (&t, "%0*d", width, arg);
347 t = (char *)xmalloc (2);
353 if ((incr < 0 && n < end) || (incr > 0 && n > end))
358 result[i] = (char *)0;
363 expand_seqterm (text, tlen)
368 int i, lhs_t, rhs_t, incr, lhs_l, rhs_l, width;
369 intmax_t lhs_v, rhs_v;
371 char **result, *ep, *oep;
373 t = strstr (text, BRACE_SEQ_SPECIFIER);
375 return ((char **)NULL);
377 lhs_l = t - text; /* index of start of BRACE_SEQ_SPECIFIER */
378 lhs = substring (text, 0, lhs_l);
379 rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
381 if (lhs[0] == 0 || rhs[0] == 0)
385 return ((char **)NULL);
388 /* Now figure out whether LHS and RHS are integers or letters. Both
389 sides have to match. */
390 lhs_t = (legal_number (lhs, &tl)) ? ST_INT :
391 ((ISALPHA (lhs[0]) && lhs[1] == 0) ? ST_CHAR : ST_BAD);
393 /* Decide on rhs and whether or not it looks like the user specified
396 if (ISDIGIT (rhs[0]) || ((rhs[0] == '+' || rhs[0] == '-') && ISDIGIT (rhs[1])))
399 tr = strtoimax (rhs, &ep, 10);
400 if (ep && *ep != 0 && *ep != '.')
401 rhs_t = ST_BAD; /* invalid */
403 else if (ISALPHA (rhs[0]) && (rhs[1] == 0 || rhs[1] == '.'))
418 if (ep && *ep == '.' && ep[1] == '.' && ep[2])
419 incr = strtoimax (ep + 2, &ep, 10);
421 rhs_t = ST_BAD; /* invalid incr */
425 if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
429 return ((char **)NULL);
432 /* OK, we have something. It's either a sequence of integers, ascending
433 or descending, or a sequence or letters, ditto. Generate the sequence,
434 put it into a string vector, and return it. */
436 if (lhs_t == ST_CHAR)
438 lhs_v = (unsigned char)lhs[0];
439 rhs_v = (unsigned char)rhs[0];
444 lhs_v = tl; /* integer truncation */
447 /* Decide whether or not the terms need zero-padding */
448 rhs_l = tlen - lhs_l - sizeof (BRACE_SEQ_SPECIFIER) + 1;
450 if (lhs_l > 1 && lhs[0] == '0')
451 width = lhs_l, lhs_t = ST_ZINT;
452 if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
453 width = lhs_l, lhs_t = ST_ZINT;
454 if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
455 width = rhs_l, lhs_t = ST_ZINT;
456 if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l)
457 width = rhs_l, lhs_t = ST_ZINT;
459 if (width < lhs_l && lhs_t == ST_ZINT)
461 if (width < rhs_l && lhs_t == ST_ZINT)
465 result = mkseq (lhs_v, rhs_v, incr, lhs_t, width);
473 /* Start at INDEX, and skip characters in TEXT. Set INDEX to the
474 index of the character matching SATISFY. This understands about
475 quoting. Return the character that caused us to stop searching;
476 this is either the same as SATISFY, or 0. */
477 /* If SATISFY is `}', we are looking for a brace expression, so we
478 should enforce the rules that govern valid brace expansions:
479 1) to count as an arg separator, a comma or `..' has to be outside
480 an inner set of braces.
483 brace_gobbler (text, tlen, indx, satisfy)
489 register int i, c, quoted, level, commas, pass_next;
496 level = quoted = pass_next = 0;
497 #if defined (CSH_BRACE_COMPAT)
500 commas = (satisfy == '}') ? 0 : 1;
509 ADVANCE_CHAR (text, tlen, i);
513 /* A backslash escapes the next character. This allows backslash to
514 escape the quote character in a double-quoted string. */
515 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
523 /* If compiling for the shell, treat ${...} like \{...} */
524 if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */
538 ADVANCE_CHAR (text, tlen, i);
542 if (c == '"' || c == '\'' || c == '`')
550 /* Pass new-style command and process substitutions through unchanged. */
551 if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */
554 t = extract_command_subst (text, &si, 0);
562 if (c == satisfy && level == 0 && quoted == 0 && commas > 0)
564 /* We ignore an open brace surrounded by whitespace, and also
565 an open brace followed immediately by a close brace preceded
568 ((!i || brace_whitespace (text[i - 1])) &&
569 (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
580 else if (c == '}' && level)
582 #if !defined (CSH_BRACE_COMPAT)
583 else if (satisfy == '}' && c == brace_arg_separator && level == 0)
585 else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) &&
586 text[i+2] != satisfy && level == 0)
590 ADVANCE_CHAR (text, tlen, i);
597 /* Return a new array of strings which is the result of appending each
598 string in ARR2 to each string in ARR1. The resultant array is
599 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
600 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
603 array_concat (arr1, arr2)
606 register int i, j, len, len1, len2;
607 register char **result;
610 return (strvec_copy (arr2));
613 return (strvec_copy (arr1));
615 len1 = strvec_len (arr1);
616 len2 = strvec_len (arr2);
618 result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
621 for (i = 0; i < len1; i++)
623 int strlen_1 = strlen (arr1[i]);
625 for (j = 0; j < len2; j++)
627 result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
628 strcpy (result[len], arr1[i]);
629 strcpy (result[len] + strlen_1, arr2[j]);
636 result[len] = (char *)NULL;
643 fatal_error (format, arg1, arg2)
644 char *format, *arg1, *arg2;
646 report_error (format, arg1, arg2);
650 report_error (format, arg1, arg2)
651 char *format, *arg1, *arg2;
653 fprintf (stderr, format, arg1, arg2);
654 fprintf (stderr, "\n");
666 fprintf (stderr, "brace_expand> ");
668 if ((!fgets (example, 256, stdin)) ||
669 (strncmp (example, "quit", 4) == 0))
672 if (strlen (example))
673 example[strlen (example) - 1] = '\0';
675 result = brace_expand (example);
677 for (i = 0; result[i]; i++)
678 printf ("%s\n", result[i]);
686 * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
691 #endif /* BRACE_EXPANSION */