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 != '\'') /* } */
415 ADVANCE_CHAR (text, tlen, i);
419 if (c == '"' || c == '\'' || c == '`')
427 /* Pass new-style command substitutions through unchanged. */
428 if (c == '$' && text[i+1] == '(') /* ) */
431 t = extract_command_subst (text, &si);
439 if (c == satisfy && level == 0 && quoted == 0)
441 /* We ignore an open brace surrounded by whitespace, and also
442 an open brace followed immediately by a close brace preceded
445 ((!i || brace_whitespace (text[i - 1])) &&
446 (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
457 else if (c == '}' && level)
460 ADVANCE_CHAR (text, tlen, i);
467 /* Return a new array of strings which is the result of appending each
468 string in ARR2 to each string in ARR1. The resultant array is
469 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
470 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
473 array_concat (arr1, arr2)
476 register int i, j, len, len1, len2;
477 register char **result;
480 return (strvec_copy (arr2));
483 return (strvec_copy (arr1));
485 len1 = strvec_len (arr1);
486 len2 = strvec_len (arr2);
488 result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
491 for (i = 0; i < len1; i++)
493 int strlen_1 = strlen (arr1[i]);
495 for (j = 0; j < len2; j++)
497 result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
498 strcpy (result[len], arr1[i]);
499 strcpy (result[len] + strlen_1, arr2[j]);
506 result[len] = (char *)NULL;
513 fatal_error (format, arg1, arg2)
514 char *format, *arg1, *arg2;
516 report_error (format, arg1, arg2);
520 report_error (format, arg1, arg2)
521 char *format, *arg1, *arg2;
523 fprintf (stderr, format, arg1, arg2);
524 fprintf (stderr, "\n");
536 fprintf (stderr, "brace_expand> ");
538 if ((!fgets (example, 256, stdin)) ||
539 (strncmp (example, "quit", 4) == 0))
542 if (strlen (example))
543 example[strlen (example) - 1] = '\0';
545 result = brace_expand (example);
547 for (i = 0; result[i]; i++)
548 printf ("%s\n", result[i]);
556 * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
561 #endif /* BRACE_EXPANSION */