1 /* braces.c -- code for doing word expansion in curly braces. */
3 /* Copyright (C) 1987-2003 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 it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 Bash is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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 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));
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 ();
74 /* Return an array of strings; the brace expansion of TEXT. */
81 char *preamble, *postamble, *amble;
83 char **tack, **result;
88 /* Find the text of the preamble. */
91 c = brace_gobbler (text, tlen, &i, '{');
93 preamble = (char *)xmalloc (i + 1);
94 strncpy (preamble, text, i);
97 result = (char **)xmalloc (2 * sizeof (char *));
99 result[1] = (char *)NULL;
101 /* Special case. If we never found an exciting character, then
102 the preamble is all of the text, so just return that. */
106 /* Find the amble. This is the stuff inside this set of braces. */
108 c = brace_gobbler (text, tlen, &i, '}');
110 /* What if there isn't a matching close brace? */
114 /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
115 and I, then this should be an error. Otherwise, it isn't. */
122 ADVANCE_CHAR (text, tlen, j);
126 if (text[j] == brace_arg_separator)
128 strvec_dispose (result);
129 report_error ("no closing `%c' in %s", '}', text);
130 throw_to_top_level ();
132 ADVANCE_CHAR (text, tlen, j);
135 free (preamble); /* Same as result[0]; see initialization. */
136 result[0] = savestring (text);
141 amble = substring (text, start, i);
144 amble = (char *)xmalloc (1 + (i - start));
145 strncpy (amble, &text[start], (i - start));
153 /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
154 just return without doing any expansion. */
158 if (amble[j] == '\\')
161 ADVANCE_CHAR (amble, alen, j);
165 if (amble[j] == brace_arg_separator)
168 ADVANCE_CHAR (amble, alen, j);
173 tack = expand_seqterm (amble, alen);
180 result[0] = savestring (text);
186 tack = expand_amble (amble, alen, 0);
188 result = array_concat (result, tack);
190 strvec_dispose (tack);
192 postamble = text + i + 1;
194 tack = brace_expand (postamble);
195 result = array_concat (result, tack);
196 strvec_dispose (tack);
201 /* Expand the text found inside of braces. We simply try to split the
202 text at BRACE_ARG_SEPARATORs into separate strings. We then brace
203 expand each slot which needs it, until there are no more slots which
206 expand_amble (text, tlen, flags)
211 char **result, **partial;
217 result = (char **)NULL;
223 c = brace_gobbler (text, tlen, &i, brace_arg_separator);
225 tem = substring (text, start, i);
227 tem = (char *)xmalloc (1 + (i - start));
228 strncpy (tem, &text[start], (i - start));
229 tem[i- start] = '\0';
232 partial = brace_expand (tem);
238 register int lr, lp, j;
240 lr = strvec_len (result);
241 lp = strvec_len (partial);
243 result = strvec_resize (result, lp + lr + 1);
245 for (j = 0; j < lp; j++)
246 result[lr + j] = partial[j];
248 result[lr + j] = (char *)NULL;
252 ADVANCE_CHAR (text, tlen, i);
263 mkseq (start, end, type)
264 int start, end, type;
269 n = abs (end - start) + 1;
270 result = strvec_create (n + 1);
272 incr = (start < end) ? 1 : -1;
274 /* Make sure we go through the loop at least once, so {3..3} prints `3' */
280 result[i++] = itos (n);
283 t = (char *)xmalloc (2);
294 result[i] = (char *)0;
299 expand_seqterm (text, tlen)
304 int i, lhs_t, rhs_t, lhs_v, rhs_v;
308 t = strstr (text, BRACE_SEQ_SPECIFIER);
310 return ((char **)NULL);
312 i = t - text; /* index of start of BRACE_SEQ_SPECIFIER */
313 lhs = substring (text, 0, i);
314 rhs = substring (text, i + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
316 if (lhs[0] == 0 || rhs[0] == 0)
320 return ((char **)NULL);
323 /* Now figure out whether LHS and RHS are integers or letters. Both
324 sides have to match. */
325 lhs_t = (legal_number (lhs, &tl)) ? ST_INT :
326 ((ISALPHA (lhs[0]) && lhs[1] == 0) ? ST_CHAR : ST_BAD);
327 rhs_t = (legal_number (rhs, &tr)) ? ST_INT :
328 ((ISALPHA (rhs[0]) && rhs[1] == 0) ? ST_CHAR : ST_BAD);
330 if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
334 return ((char **)NULL);
337 /* OK, we have something. It's either a sequence of integers, ascending
338 or descending, or a sequence or letters, ditto. Generate the sequence,
339 put it into a string vector, and return it. */
341 if (lhs_t == ST_CHAR)
343 lhs_v = (unsigned char)lhs[0];
344 rhs_v = (unsigned char)rhs[0];
348 lhs_v = tl; /* integer truncation */
352 result = mkseq (lhs_v, rhs_v, lhs_t);
360 /* Start at INDEX, and skip characters in TEXT. Set INDEX to the
361 index of the character matching SATISFY. This understands about
362 quoting. Return the character that caused us to stop searching;
363 this is either the same as SATISFY, or 0. */
365 brace_gobbler (text, tlen, indx, satisfy)
371 register int i, c, quoted, level, pass_next;
378 level = quoted = pass_next = 0;
386 ADVANCE_CHAR (text, tlen, i);
390 /* A backslash escapes the next character. This allows backslash to
391 escape the quote character in a double-quoted string. */
392 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
400 /* If compiling for the shell, treat ${...} like \{...} */
401 if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */
414 ADVANCE_CHAR (text, tlen, i);
418 if (c == '"' || c == '\'' || c == '`')
426 /* Pass new-style command substitutions through unchanged. */
427 if (c == '$' && text[i+1] == '(') /* ) */
430 t = extract_command_subst (text, &si);
438 if (c == satisfy && level == 0 && quoted == 0)
440 /* We ignore an open brace surrounded by whitespace, and also
441 an open brace followed immediately by a close brace preceded
444 ((!i || brace_whitespace (text[i - 1])) &&
445 (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
456 else if (c == '}' && level)
459 ADVANCE_CHAR (text, tlen, i);
466 /* Return a new array of strings which is the result of appending each
467 string in ARR2 to each string in ARR1. The resultant array is
468 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
469 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
472 array_concat (arr1, arr2)
475 register int i, j, len, len1, len2;
476 register char **result;
479 return (strvec_copy (arr2));
482 return (strvec_copy (arr1));
484 len1 = strvec_len (arr1);
485 len2 = strvec_len (arr2);
487 result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
490 for (i = 0; i < len1; i++)
492 int strlen_1 = strlen (arr1[i]);
494 for (j = 0; j < len2; j++)
496 result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
497 strcpy (result[len], arr1[i]);
498 strcpy (result[len] + strlen_1, arr2[j]);
505 result[len] = (char *)NULL;
512 fatal_error (format, arg1, arg2)
513 char *format, *arg1, *arg2;
515 report_error (format, arg1, arg2);
519 report_error (format, arg1, arg2)
520 char *format, *arg1, *arg2;
522 fprintf (stderr, format, arg1, arg2);
523 fprintf (stderr, "\n");
535 fprintf (stderr, "brace_expand> ");
537 if ((!fgets (example, 256, stdin)) ||
538 (strncmp (example, "quit", 4) == 0))
541 if (strlen (example))
542 example[strlen (example) - 1] = '\0';
544 result = brace_expand (example);
546 for (i = 0; result[i]; i++)
547 printf ("%s\n", result[i]);
555 * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
560 #endif /* BRACE_EXPANSION */