1 /* braces.c -- code for doing word expansion in curly braces. */
3 /* Copyright (C) 1987-2008 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 ".."
50 Segregate the text into 3 sections: preamble (stuff before an open brace),
51 postamble (stuff after the matching close brace) and amble (stuff after
52 preamble, and before postamble). Expand amble, and then tack on the
53 expansions to preamble. Expand postamble, and tack on the expansions to
57 /* The character which is used to separate arguments. */
58 static const int brace_arg_separator = ',';
61 static int brace_gobbler __P((char *, size_t, int *, int));
62 static char **expand_amble __P((char *, size_t, int));
63 static char **expand_seqterm __P((char *, size_t));
64 static char **mkseq __P((int, int, int, int, int));
65 static char **array_concat __P((char **, char **));
67 static int brace_gobbler ();
68 static char **expand_amble ();
69 static char **expand_seqterm ();
70 static char **mkseq();
71 static char **array_concat ();
81 for (i = 0; a[i]; i++)
82 printf ("dump_result: a[%d] = -%s-\n", i, a[i]);
86 /* Return an array of strings; the brace expansion of TEXT. */
93 char *preamble, *postamble, *amble;
95 char **tack, **result;
100 /* Find the text of the preamble. */
101 tlen = strlen (text);
103 #if defined (CSH_BRACE_COMPAT)
104 c = brace_gobbler (text, tlen, &i, '{'); /* } */
106 /* Make sure that when we exit this loop, c == 0 or text[i] begins a
107 valid brace expansion sequence. */
110 c = brace_gobbler (text, tlen, &i, '{'); /* } */
112 /* Verify that c begins a valid brace expansion word. If it doesn't, we
113 go on. Loop stops when there are no more open braces in the word. */
116 start = j = i + 1; /* { */
117 c = brace_gobbler (text, tlen, &j, '}');
118 if (c == 0) /* it's not */
134 #endif /* !CSH_BRACE_COMPAT */
136 preamble = (char *)xmalloc (i + 1);
137 strncpy (preamble, text, i);
140 result = (char **)xmalloc (2 * sizeof (char *));
141 result[0] = preamble;
142 result[1] = (char *)NULL;
144 /* Special case. If we never found an exciting character, then
145 the preamble is all of the text, so just return that. */
149 /* Find the amble. This is the stuff inside this set of braces. */
151 c = brace_gobbler (text, tlen, &i, '}');
153 /* What if there isn't a matching close brace? */
157 /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
158 and I, then this should be an error. Otherwise, it isn't. */
165 ADVANCE_CHAR (text, tlen, j);
169 if (text[j] == brace_arg_separator)
171 strvec_dispose (result);
172 report_error ("no closing `%c' in %s", '}', text);
173 throw_to_top_level ();
175 ADVANCE_CHAR (text, tlen, j);
178 free (preamble); /* Same as result[0]; see initialization. */
179 result[0] = savestring (text);
184 amble = substring (text, start, i);
187 amble = (char *)xmalloc (1 + (i - start));
188 strncpy (amble, &text[start], (i - start));
196 /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
197 just return without doing any expansion. */
201 if (amble[j] == '\\')
204 ADVANCE_CHAR (amble, alen, j);
208 if (amble[j] == brace_arg_separator)
211 ADVANCE_CHAR (amble, alen, j);
216 tack = expand_seqterm (amble, alen);
223 result[0] = savestring (text);
229 tack = expand_amble (amble, alen, 0);
231 result = array_concat (result, tack);
233 strvec_dispose (tack);
235 postamble = text + i + 1;
237 tack = brace_expand (postamble);
238 result = array_concat (result, tack);
239 strvec_dispose (tack);
244 /* Expand the text found inside of braces. We simply try to split the
245 text at BRACE_ARG_SEPARATORs into separate strings. We then brace
246 expand each slot which needs it, until there are no more slots which
249 expand_amble (text, tlen, flags)
254 char **result, **partial;
260 result = (char **)NULL;
266 c = brace_gobbler (text, tlen, &i, brace_arg_separator);
268 tem = substring (text, start, i);
270 tem = (char *)xmalloc (1 + (i - start));
271 strncpy (tem, &text[start], (i - start));
272 tem[i- start] = '\0';
275 partial = brace_expand (tem);
281 register int lr, lp, j;
283 lr = strvec_len (result);
284 lp = strvec_len (partial);
286 result = strvec_resize (result, lp + lr + 1);
288 for (j = 0; j < lp; j++)
289 result[lr + j] = partial[j];
291 result[lr + j] = (char *)NULL;
295 ADVANCE_CHAR (text, tlen, i);
307 mkseq (start, end, incr, type, width)
308 int start, end, incr, type, width;
313 n = abs (end - start) + 1;
314 result = strvec_create (n + 1);
319 if (start > end && incr > 0)
321 else if (start < end && incr < 0)
324 /* Make sure we go through the loop at least once, so {3..3} prints `3' */
330 QUIT; /* XXX - memory leak here */
333 result[i++] = itos (n);
334 else if (type == ST_ZINT)
337 len = asprintf (&t, "%0*d", width, n);
342 t = (char *)xmalloc (2);
348 if ((incr < 0 && n < end) || (incr > 0 && n > end))
353 result[i] = (char *)0;
358 expand_seqterm (text, tlen)
363 int i, lhs_t, rhs_t, lhs_v, rhs_v, incr, lhs_l, rhs_l, width;
367 t = strstr (text, BRACE_SEQ_SPECIFIER);
369 return ((char **)NULL);
371 lhs_l = t - text; /* index of start of BRACE_SEQ_SPECIFIER */
372 lhs = substring (text, 0, lhs_l);
373 rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
375 if (lhs[0] == 0 || rhs[0] == 0)
379 return ((char **)NULL);
382 /* Now figure out whether LHS and RHS are integers or letters. Both
383 sides have to match. */
384 lhs_t = (legal_number (lhs, &tl)) ? ST_INT :
385 ((ISALPHA (lhs[0]) && lhs[1] == 0) ? ST_CHAR : ST_BAD);
387 /* Decide on rhs and whether or not it looks like the user specified
390 if (ISDIGIT (rhs[0]) || ((rhs[0] == '+' || rhs[0] == '-') && ISDIGIT (rhs[1])))
393 tr = strtoimax (rhs, &ep, 10);
394 if (ep && *ep != 0 && *ep != '.')
395 rhs_t = ST_BAD; /* invalid */
397 else if (ISALPHA (rhs[0]) && (rhs[1] == 0 || rhs[1] == '.'))
411 if (ep && *ep == '.' && ep[1] == '.' && ep[2])
412 incr = strtoimax (ep + 2, &ep, 10);
414 rhs_t = ST_BAD; /* invalid incr */
417 if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
421 return ((char **)NULL);
424 /* OK, we have something. It's either a sequence of integers, ascending
425 or descending, or a sequence or letters, ditto. Generate the sequence,
426 put it into a string vector, and return it. */
428 if (lhs_t == ST_CHAR)
430 lhs_v = (unsigned char)lhs[0];
431 rhs_v = (unsigned char)rhs[0];
436 lhs_v = tl; /* integer truncation */
439 /* Decide whether or not the terms need zero-padding */
440 rhs_l = tlen - lhs_l - sizeof (BRACE_SEQ_SPECIFIER) + 1;
442 if (lhs_l > 1 && lhs[0] == '0')
443 width = lhs_l, lhs_t = ST_ZINT;
444 if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
445 width = lhs_l, lhs_t = ST_ZINT;
446 if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
447 width = rhs_l, lhs_t = ST_ZINT;
448 if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l)
449 width = rhs_l, lhs_t = ST_ZINT;
452 result = mkseq (lhs_v, rhs_v, incr, lhs_t, width);
460 /* Start at INDEX, and skip characters in TEXT. Set INDEX to the
461 index of the character matching SATISFY. This understands about
462 quoting. Return the character that caused us to stop searching;
463 this is either the same as SATISFY, or 0. */
464 /* If SATISFY is `}', we are looking for a brace expression, so we
465 should enforce the rules that govern valid brace expansions:
466 1) to count as an arg separator, a comma or `..' has to be outside
467 an inner set of braces.
470 brace_gobbler (text, tlen, indx, satisfy)
476 register int i, c, quoted, level, commas, pass_next;
483 level = quoted = pass_next = 0;
484 #if defined (CSH_BRACE_COMPAT)
487 commas = (satisfy == '}') ? 0 : 1;
496 ADVANCE_CHAR (text, tlen, i);
500 /* A backslash escapes the next character. This allows backslash to
501 escape the quote character in a double-quoted string. */
502 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
510 /* If compiling for the shell, treat ${...} like \{...} */
511 if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */
525 ADVANCE_CHAR (text, tlen, i);
529 if (c == '"' || c == '\'' || c == '`')
537 /* Pass new-style command and process substitutions through unchanged. */
538 if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */
541 t = extract_command_subst (text, &si, 0);
549 if (c == satisfy && level == 0 && quoted == 0 && commas > 0)
551 /* We ignore an open brace surrounded by whitespace, and also
552 an open brace followed immediately by a close brace preceded
555 ((!i || brace_whitespace (text[i - 1])) &&
556 (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
567 else if (c == '}' && level)
569 #if !defined (CSH_BRACE_COMPAT)
570 else if (satisfy == '}' && c == brace_arg_separator && level == 0)
572 else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) &&
573 text[i+2] != satisfy && level == 0)
577 ADVANCE_CHAR (text, tlen, i);
584 /* Return a new array of strings which is the result of appending each
585 string in ARR2 to each string in ARR1. The resultant array is
586 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
587 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
590 array_concat (arr1, arr2)
593 register int i, j, len, len1, len2;
594 register char **result;
597 return (strvec_copy (arr2));
600 return (strvec_copy (arr1));
602 len1 = strvec_len (arr1);
603 len2 = strvec_len (arr2);
605 result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
608 for (i = 0; i < len1; i++)
610 int strlen_1 = strlen (arr1[i]);
612 for (j = 0; j < len2; j++)
614 result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
615 strcpy (result[len], arr1[i]);
616 strcpy (result[len] + strlen_1, arr2[j]);
623 result[len] = (char *)NULL;
630 fatal_error (format, arg1, arg2)
631 char *format, *arg1, *arg2;
633 report_error (format, arg1, arg2);
637 report_error (format, arg1, arg2)
638 char *format, *arg1, *arg2;
640 fprintf (stderr, format, arg1, arg2);
641 fprintf (stderr, "\n");
653 fprintf (stderr, "brace_expand> ");
655 if ((!fgets (example, 256, stdin)) ||
656 (strncmp (example, "quit", 4) == 0))
659 if (strlen (example))
660 example[strlen (example) - 1] = '\0';
662 result = brace_expand (example);
664 for (i = 0; result[i]; i++)
665 printf ("%s\n", result[i]);
673 * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
678 #endif /* BRACE_EXPANSION */