blob: 61c1ab15607c6ba523294252b0a223058dab3020 [file] [log] [blame]
Jari Aalto726f6381996-08-26 18:22:31 +00001/* braces.c -- code for doing word expansion in curly braces. */
2
Chet Rameyac50fba2014-02-26 09:36:43 -05003/* Copyright (C) 1987-2012 Free Software Foundation, Inc.
Jari Aalto726f6381996-08-26 18:22:31 +00004
5 This file is part of GNU Bash, the Bourne Again SHell.
6
Jari Aalto31859422009-01-12 13:36:28 +00007 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.
Jari Aalto726f6381996-08-26 18:22:31 +000011
Jari Aalto31859422009-01-12 13:36:28 +000012 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.
Jari Aalto726f6381996-08-26 18:22:31 +000016
17 You should have received a copy of the GNU General Public License
Jari Aalto31859422009-01-12 13:36:28 +000018 along with Bash. If not, see <http://www.gnu.org/licenses/>.
19*/
Jari Aalto726f6381996-08-26 18:22:31 +000020
Jari Aaltoccc6cda1996-12-23 17:02:34 +000021/* Stuff in curly braces gets expanded before all other shell expansions. */
Jari Aalto726f6381996-08-26 18:22:31 +000022
Jari Aaltoccc6cda1996-12-23 17:02:34 +000023#include "config.h"
24
25#if defined (BRACE_EXPANSION)
26
27#if defined (HAVE_UNISTD_H)
Jari Aaltocce855b1998-04-17 19:52:44 +000028# ifdef _MINIX
29# include <sys/types.h>
30# endif
Jari Aaltoccc6cda1996-12-23 17:02:34 +000031# include <unistd.h>
32#endif
Jari Aalto726f6381996-08-26 18:22:31 +000033
Chet Rameyac50fba2014-02-26 09:36:43 -050034#include <errno.h>
35
Jari Aaltod166f041997-06-05 14:59:13 +000036#include "bashansi.h"
Chet Rameyac50fba2014-02-26 09:36:43 -050037#include "bashintl.h"
Jari Aalto726f6381996-08-26 18:22:31 +000038
39#if defined (SHELL)
Jari Aaltoccc6cda1996-12-23 17:02:34 +000040# include "shell.h"
Jari Aalto726f6381996-08-26 18:22:31 +000041#endif /* SHELL */
42
Chet Rameyac50fba2014-02-26 09:36:43 -050043#include "typemax.h" /* INTMAX_MIN, INTMAX_MAX */
Jari Aalto726f6381996-08-26 18:22:31 +000044#include "general.h"
Jari Aalto7117c2d2002-07-17 14:10:11 +000045#include "shmbutil.h"
Jari Aaltob80f6442004-07-27 13:29:18 +000046#include "chartypes.h"
Jari Aalto7117c2d2002-07-17 14:10:11 +000047
Chet Rameyac50fba2014-02-26 09:36:43 -050048#ifndef errno
49extern int errno;
50#endif
51
Jari Aalto726f6381996-08-26 18:22:31 +000052#define brace_whitespace(c) (!(c) || (c) == ' ' || (c) == '\t' || (c) == '\n')
53
Jari Aaltob80f6442004-07-27 13:29:18 +000054#define BRACE_SEQ_SPECIFIER ".."
55
Jari Aalto31859422009-01-12 13:36:28 +000056extern int asprintf __P((char **, const char *, ...)) __attribute__((__format__ (printf, 2, 3)));
57
Chet Rameyac50fba2014-02-26 09:36:43 -050058extern int last_command_exit_value;
59
Jari Aalto726f6381996-08-26 18:22:31 +000060/* Basic idea:
61
62 Segregate the text into 3 sections: preamble (stuff before an open brace),
63 postamble (stuff after the matching close brace) and amble (stuff after
64 preamble, and before postamble). Expand amble, and then tack on the
65 expansions to preamble. Expand postamble, and tack on the expansions to
66 the result so far.
67 */
68
69/* The character which is used to separate arguments. */
Jari Aalto31859422009-01-12 13:36:28 +000070static const int brace_arg_separator = ',';
Jari Aalto726f6381996-08-26 18:22:31 +000071
Jari Aaltof73dda02001-11-13 17:56:06 +000072#if defined (__P)
Jari Aalto7117c2d2002-07-17 14:10:11 +000073static int brace_gobbler __P((char *, size_t, int *, int));
Jari Aaltob80f6442004-07-27 13:29:18 +000074static char **expand_amble __P((char *, size_t, int));
75static char **expand_seqterm __P((char *, size_t));
Chet Rameyac50fba2014-02-26 09:36:43 -050076static char **mkseq __P((intmax_t, intmax_t, intmax_t, int, int));
Jari Aaltof73dda02001-11-13 17:56:06 +000077static char **array_concat __P((char **, char **));
78#else
Jari Aalto726f6381996-08-26 18:22:31 +000079static int brace_gobbler ();
Jari Aaltof73dda02001-11-13 17:56:06 +000080static char **expand_amble ();
Jari Aaltob80f6442004-07-27 13:29:18 +000081static char **expand_seqterm ();
82static char **mkseq();
Jari Aaltof73dda02001-11-13 17:56:06 +000083static char **array_concat ();
84#endif
Jari Aalto726f6381996-08-26 18:22:31 +000085
Jari Aalto06285672006-10-10 14:15:34 +000086#if 0
87static void
88dump_result (a)
89 char **a;
90{
91 int i;
92
93 for (i = 0; a[i]; i++)
94 printf ("dump_result: a[%d] = -%s-\n", i, a[i]);
95}
96#endif
97
Jari Aalto726f6381996-08-26 18:22:31 +000098/* Return an array of strings; the brace expansion of TEXT. */
99char **
100brace_expand (text)
101 char *text;
102{
103 register int start;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000104 size_t tlen;
Jari Aalto726f6381996-08-26 18:22:31 +0000105 char *preamble, *postamble, *amble;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000106 size_t alen;
Jari Aalto726f6381996-08-26 18:22:31 +0000107 char **tack, **result;
Jari Aalto06285672006-10-10 14:15:34 +0000108 int i, j, c, c1;
Jari Aalto726f6381996-08-26 18:22:31 +0000109
Jari Aalto7117c2d2002-07-17 14:10:11 +0000110 DECLARE_MBSTATE;
111
Jari Aalto726f6381996-08-26 18:22:31 +0000112 /* Find the text of the preamble. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000113 tlen = strlen (text);
Jari Aalto726f6381996-08-26 18:22:31 +0000114 i = 0;
Jari Aalto06285672006-10-10 14:15:34 +0000115#if defined (CSH_BRACE_COMPAT)
116 c = brace_gobbler (text, tlen, &i, '{'); /* } */
117#else
118 /* Make sure that when we exit this loop, c == 0 or text[i] begins a
119 valid brace expansion sequence. */
120 do
121 {
122 c = brace_gobbler (text, tlen, &i, '{'); /* } */
123 c1 = c;
124 /* Verify that c begins a valid brace expansion word. If it doesn't, we
125 go on. Loop stops when there are no more open braces in the word. */
126 if (c)
127 {
128 start = j = i + 1; /* { */
129 c = brace_gobbler (text, tlen, &j, '}');
130 if (c == 0) /* it's not */
131 {
132 i++;
133 c = c1;
134 continue;
135 }
136 else /* it is */
137 {
138 c = c1;
139 break;
140 }
141 }
142 else
143 break;
144 }
145 while (c);
146#endif /* !CSH_BRACE_COMPAT */
Jari Aalto726f6381996-08-26 18:22:31 +0000147
148 preamble = (char *)xmalloc (i + 1);
Chet Rameyac50fba2014-02-26 09:36:43 -0500149 if (i > 0)
150 strncpy (preamble, text, i);
Jari Aalto726f6381996-08-26 18:22:31 +0000151 preamble[i] = '\0';
152
153 result = (char **)xmalloc (2 * sizeof (char *));
154 result[0] = preamble;
155 result[1] = (char *)NULL;
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000156
Jari Aalto726f6381996-08-26 18:22:31 +0000157 /* Special case. If we never found an exciting character, then
158 the preamble is all of the text, so just return that. */
159 if (c != '{')
160 return (result);
161
162 /* Find the amble. This is the stuff inside this set of braces. */
163 start = ++i;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000164 c = brace_gobbler (text, tlen, &i, '}');
Jari Aalto726f6381996-08-26 18:22:31 +0000165
166 /* What if there isn't a matching close brace? */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000167 if (c == 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000168 {
169#if defined (NOTDEF)
Jari Aalto726f6381996-08-26 18:22:31 +0000170 /* Well, if we found an unquoted BRACE_ARG_SEPARATOR between START
171 and I, then this should be an error. Otherwise, it isn't. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000172 j = start;
173 while (j < i)
Jari Aalto726f6381996-08-26 18:22:31 +0000174 {
175 if (text[j] == '\\')
176 {
177 j++;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000178 ADVANCE_CHAR (text, tlen, j);
Jari Aalto726f6381996-08-26 18:22:31 +0000179 continue;
180 }
181
182 if (text[j] == brace_arg_separator)
Jari Aaltob80f6442004-07-27 13:29:18 +0000183 { /* { */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000184 strvec_dispose (result);
Chet Rameyac50fba2014-02-26 09:36:43 -0500185 last_command_exit_value = 1;
Jari Aaltob80f6442004-07-27 13:29:18 +0000186 report_error ("no closing `%c' in %s", '}', text);
Jari Aalto726f6381996-08-26 18:22:31 +0000187 throw_to_top_level ();
188 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000189 ADVANCE_CHAR (text, tlen, j);
Jari Aalto726f6381996-08-26 18:22:31 +0000190 }
191#endif
192 free (preamble); /* Same as result[0]; see initialization. */
193 result[0] = savestring (text);
194 return (result);
195 }
196
Jari Aaltobb706242000-03-17 21:46:59 +0000197#if defined (SHELL)
198 amble = substring (text, start, i);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000199 alen = i - start;
Jari Aaltobb706242000-03-17 21:46:59 +0000200#else
Jari Aalto726f6381996-08-26 18:22:31 +0000201 amble = (char *)xmalloc (1 + (i - start));
202 strncpy (amble, &text[start], (i - start));
Jari Aalto7117c2d2002-07-17 14:10:11 +0000203 alen = i - start;
204 amble[alen] = '\0';
Jari Aaltobb706242000-03-17 21:46:59 +0000205#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000206
207#if defined (SHELL)
Jari Aalto7117c2d2002-07-17 14:10:11 +0000208 INITIALIZE_MBSTATE;
209
Jari Aalto726f6381996-08-26 18:22:31 +0000210 /* If the amble does not contain an unquoted BRACE_ARG_SEPARATOR, then
211 just return without doing any expansion. */
Jari Aalto7117c2d2002-07-17 14:10:11 +0000212 j = 0;
213 while (amble[j])
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000214 {
215 if (amble[j] == '\\')
216 {
217 j++;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000218 ADVANCE_CHAR (amble, alen, j);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000219 continue;
220 }
Jari Aalto7117c2d2002-07-17 14:10:11 +0000221
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000222 if (amble[j] == brace_arg_separator)
223 break;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000224
225 ADVANCE_CHAR (amble, alen, j);
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000226 }
Jari Aalto726f6381996-08-26 18:22:31 +0000227
Jari Aaltob80f6442004-07-27 13:29:18 +0000228 if (amble[j] == 0)
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000229 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000230 tack = expand_seqterm (amble, alen);
231 if (tack)
232 goto add_tack;
Chet Rameyac50fba2014-02-26 09:36:43 -0500233 else if (text[i + 1])
234 {
235 /* If the sequence expansion fails (e.g., because the integers
236 overflow), but there is more in the string, try and process
237 the rest of the string, which may contain additional brace
238 expansions. Treat the unexpanded sequence term as a simple
239 string (including the braces). */
240 tack = strvec_create (2);
241 tack[0] = savestring (text+start-1);
242 tack[0][i-start+2] = '\0';
243 tack[1] = (char *)0;
244 goto add_tack;
245 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000246 else
247 {
248 free (amble);
249 free (preamble);
250 result[0] = savestring (text);
251 return (result);
252 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000253 }
Jari Aalto726f6381996-08-26 18:22:31 +0000254#endif /* SHELL */
255
Jari Aaltob80f6442004-07-27 13:29:18 +0000256 tack = expand_amble (amble, alen, 0);
257add_tack:
Jari Aalto726f6381996-08-26 18:22:31 +0000258 result = array_concat (result, tack);
259 free (amble);
Chet Rameyac50fba2014-02-26 09:36:43 -0500260 if (tack != result)
261 strvec_dispose (tack);
Jari Aalto726f6381996-08-26 18:22:31 +0000262
Jari Aaltob80f6442004-07-27 13:29:18 +0000263 postamble = text + i + 1;
264
Chet Rameyac50fba2014-02-26 09:36:43 -0500265 if (postamble && *postamble)
266 {
267 tack = brace_expand (postamble);
268 result = array_concat (result, tack);
269 if (tack != result)
270 strvec_dispose (tack);
271 }
Jari Aalto726f6381996-08-26 18:22:31 +0000272
273 return (result);
274}
275
276/* Expand the text found inside of braces. We simply try to split the
277 text at BRACE_ARG_SEPARATORs into separate strings. We then brace
278 expand each slot which needs it, until there are no more slots which
279 need it. */
280static char **
Jari Aaltob80f6442004-07-27 13:29:18 +0000281expand_amble (text, tlen, flags)
Jari Aalto726f6381996-08-26 18:22:31 +0000282 char *text;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000283 size_t tlen;
Jari Aaltob80f6442004-07-27 13:29:18 +0000284 int flags;
Jari Aalto726f6381996-08-26 18:22:31 +0000285{
Chet Rameyac50fba2014-02-26 09:36:43 -0500286 char **result, **partial, **tresult;
Jari Aalto726f6381996-08-26 18:22:31 +0000287 char *tem;
288 int start, i, c;
289
Jari Aalto7117c2d2002-07-17 14:10:11 +0000290 DECLARE_MBSTATE;
291
Jari Aalto726f6381996-08-26 18:22:31 +0000292 result = (char **)NULL;
293
Jari Aalto7117c2d2002-07-17 14:10:11 +0000294 start = i = 0;
295 c = 1;
296 while (c)
Jari Aalto726f6381996-08-26 18:22:31 +0000297 {
Jari Aalto7117c2d2002-07-17 14:10:11 +0000298 c = brace_gobbler (text, tlen, &i, brace_arg_separator);
Jari Aaltobb706242000-03-17 21:46:59 +0000299#if defined (SHELL)
300 tem = substring (text, start, i);
301#else
Jari Aalto726f6381996-08-26 18:22:31 +0000302 tem = (char *)xmalloc (1 + (i - start));
303 strncpy (tem, &text[start], (i - start));
304 tem[i- start] = '\0';
Jari Aaltobb706242000-03-17 21:46:59 +0000305#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000306
307 partial = brace_expand (tem);
308
309 if (!result)
310 result = partial;
311 else
312 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000313 register int lr, lp, j;
314
315 lr = strvec_len (result);
316 lp = strvec_len (partial);
Jari Aalto726f6381996-08-26 18:22:31 +0000317
Chet Rameyac50fba2014-02-26 09:36:43 -0500318 tresult = strvec_mresize (result, lp + lr + 1);
319 if (tresult == 0)
320 {
321 internal_error (_("brace expansion: cannot allocate memory for %s"), tem);
322 strvec_dispose (result);
323 result = (char **)NULL;
324 return result;
325 }
326 else
327 result = tresult;
Jari Aalto726f6381996-08-26 18:22:31 +0000328
329 for (j = 0; j < lp; j++)
330 result[lr + j] = partial[j];
331
332 result[lr + j] = (char *)NULL;
333 free (partial);
334 }
335 free (tem);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000336 ADVANCE_CHAR (text, tlen, i);
337 start = i;
Jari Aalto726f6381996-08-26 18:22:31 +0000338 }
339 return (result);
340}
341
Jari Aaltob80f6442004-07-27 13:29:18 +0000342#define ST_BAD 0
343#define ST_INT 1
344#define ST_CHAR 2
Jari Aalto31859422009-01-12 13:36:28 +0000345#define ST_ZINT 3
Jari Aaltob80f6442004-07-27 13:29:18 +0000346
Chet Rameyac50fba2014-02-26 09:36:43 -0500347#ifndef sh_imaxabs
348# define sh_imaxabs(x) (((x) >= 0) ? (x) : -(x))
349#endif
350
351/* Handle signed arithmetic overflow and underflow. Have to do it this way
352 to avoid compilers optimizing out simpler overflow checks. */
353
354/* Make sure that a+b does not exceed MAXV or is smaller than MINV (if b < 0).
355 Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
356#define ADDOVERFLOW(a,b,minv,maxv) \
357 ((((a) > 0) && ((b) > ((maxv) - (a)))) || \
358 (((a) < 0) && ((b) < ((minv) - (a)))))
359
360/* Make sure that a-b is not smaller than MINV or exceeds MAXV (if b < 0).
361 Assumes that b > 0 if a > 0 and b < 0 if a < 0 */
362#define SUBOVERFLOW(a,b,minv,maxv) \
363 ((((b) > 0) && ((a) < ((minv) + (b)))) || \
364 (((b) < 0) && ((a) > ((maxv) + (b)))))
365
Jari Aaltob80f6442004-07-27 13:29:18 +0000366static char **
Jari Aalto31859422009-01-12 13:36:28 +0000367mkseq (start, end, incr, type, width)
Chet Rameyac50fba2014-02-26 09:36:43 -0500368 intmax_t start, end, incr;
369 int type, width;
Jari Aaltob80f6442004-07-27 13:29:18 +0000370{
Chet Rameyac50fba2014-02-26 09:36:43 -0500371 intmax_t n, prevn;
372 int i, j, nelem;
Jari Aaltob80f6442004-07-27 13:29:18 +0000373 char **result, *t;
374
Jari Aalto06285672006-10-10 14:15:34 +0000375 if (incr == 0)
376 incr = 1;
Chet Rameyac50fba2014-02-26 09:36:43 -0500377
Jari Aalto06285672006-10-10 14:15:34 +0000378 if (start > end && incr > 0)
379 incr = -incr;
380 else if (start < end && incr < 0)
Chet Rameyac50fba2014-02-26 09:36:43 -0500381 {
382 if (incr == INTMAX_MIN) /* Don't use -INTMAX_MIN */
383 return ((char **)NULL);
384 incr = -incr;
385 }
386
387 /* Check that end-start will not overflow INTMAX_MIN, INTMAX_MAX. The +3
388 and -2, not strictly necessary, are there because of the way the number
389 of elements and value passed to strvec_create() are calculated below. */
390 if (SUBOVERFLOW (end, start, INTMAX_MIN+3, INTMAX_MAX-2))
391 return ((char **)NULL);
392
393 prevn = sh_imaxabs (end - start);
394 /* Need to check this way in case INT_MAX == INTMAX_MAX */
395 if (INT_MAX == INTMAX_MAX && (ADDOVERFLOW (prevn, 2, INT_MIN, INT_MAX)))
396 return ((char **)NULL);
397 /* Make sure the assignment to nelem below doesn't end up <= 0 due to
398 intmax_t overflow */
399 else if (ADDOVERFLOW ((prevn/sh_imaxabs(incr)), 1, INTMAX_MIN, INTMAX_MAX))
400 return ((char **)NULL);
401
402 /* XXX - TOFIX: potentially allocating a lot of extra memory if
403 imaxabs(incr) != 1 */
404 /* Instead of a simple nelem = prevn + 1, something like:
405 nelem = (prevn / imaxabs(incr)) + 1;
406 would work */
407 nelem = (prevn / sh_imaxabs(incr)) + 1;
408 if (nelem > INT_MAX - 2) /* Don't overflow int */
409 return ((char **)NULL);
410 result = strvec_mcreate (nelem + 1);
411 if (result == 0)
412 {
413 internal_error (_("brace expansion: failed to allocate memory for %d elements"), nelem);
414 return ((char **)NULL);
415 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000416
417 /* Make sure we go through the loop at least once, so {3..3} prints `3' */
418 i = 0;
419 n = start;
420 do
421 {
Jari Aalto06285672006-10-10 14:15:34 +0000422#if defined (SHELL)
423 QUIT; /* XXX - memory leak here */
424#endif
Jari Aaltob80f6442004-07-27 13:29:18 +0000425 if (type == ST_INT)
Chet Rameyac50fba2014-02-26 09:36:43 -0500426 result[i++] = t = itos (n);
Jari Aalto31859422009-01-12 13:36:28 +0000427 else if (type == ST_ZINT)
428 {
Chet Ramey495aee42011-11-22 19:11:26 -0500429 int len, arg;
430 arg = n;
431 len = asprintf (&t, "%0*d", width, arg);
Jari Aalto31859422009-01-12 13:36:28 +0000432 result[i++] = t;
433 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000434 else
435 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500436 if (t = (char *)malloc (2))
437 {
438 t[0] = n;
439 t[1] = '\0';
440 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000441 result[i++] = t;
442 }
Chet Rameyac50fba2014-02-26 09:36:43 -0500443
444 /* We failed to allocate memory for this number, so we bail. */
445 if (t == 0)
446 {
447 char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1];
448
449 /* Easier to do this than mess around with various intmax_t printf
450 formats (%ld? %lld? %jd?) and PRIdMAX. */
451 p = inttostr (n, lbuf, sizeof (lbuf));
452 internal_error (_("brace expansion: failed to allocate memory for `%s'"), p);
453 strvec_dispose (result);
454 return ((char **)NULL);
455 }
456
457 /* Handle overflow and underflow of n+incr */
458 if (ADDOVERFLOW (n, incr, INTMAX_MIN, INTMAX_MAX))
459 break;
460
Jari Aaltob80f6442004-07-27 13:29:18 +0000461 n += incr;
Chet Rameyac50fba2014-02-26 09:36:43 -0500462
Jari Aalto31859422009-01-12 13:36:28 +0000463 if ((incr < 0 && n < end) || (incr > 0 && n > end))
464 break;
Jari Aaltob80f6442004-07-27 13:29:18 +0000465 }
466 while (1);
467
468 result[i] = (char *)0;
469 return (result);
470}
471
472static char **
473expand_seqterm (text, tlen)
474 char *text;
475 size_t tlen;
476{
477 char *t, *lhs, *rhs;
Chet Rameyac50fba2014-02-26 09:36:43 -0500478 int i, lhs_t, rhs_t, lhs_l, rhs_l, width;
479 intmax_t lhs_v, rhs_v, incr;
Jari Aaltob80f6442004-07-27 13:29:18 +0000480 intmax_t tl, tr;
Chet Ramey00018032011-11-21 20:51:19 -0500481 char **result, *ep, *oep;
Jari Aaltob80f6442004-07-27 13:29:18 +0000482
483 t = strstr (text, BRACE_SEQ_SPECIFIER);
484 if (t == 0)
485 return ((char **)NULL);
486
Jari Aalto31859422009-01-12 13:36:28 +0000487 lhs_l = t - text; /* index of start of BRACE_SEQ_SPECIFIER */
488 lhs = substring (text, 0, lhs_l);
489 rhs = substring (text, lhs_l + sizeof(BRACE_SEQ_SPECIFIER) - 1, tlen);
Jari Aaltob80f6442004-07-27 13:29:18 +0000490
491 if (lhs[0] == 0 || rhs[0] == 0)
492 {
493 free (lhs);
494 free (rhs);
495 return ((char **)NULL);
496 }
497
498 /* Now figure out whether LHS and RHS are integers or letters. Both
499 sides have to match. */
500 lhs_t = (legal_number (lhs, &tl)) ? ST_INT :
501 ((ISALPHA (lhs[0]) && lhs[1] == 0) ? ST_CHAR : ST_BAD);
Jari Aalto31859422009-01-12 13:36:28 +0000502
503 /* Decide on rhs and whether or not it looks like the user specified
504 an increment */
505 ep = 0;
506 if (ISDIGIT (rhs[0]) || ((rhs[0] == '+' || rhs[0] == '-') && ISDIGIT (rhs[1])))
507 {
508 rhs_t = ST_INT;
Chet Rameyac50fba2014-02-26 09:36:43 -0500509 errno = 0;
Jari Aalto31859422009-01-12 13:36:28 +0000510 tr = strtoimax (rhs, &ep, 10);
Chet Rameyac50fba2014-02-26 09:36:43 -0500511 if (errno == ERANGE || (ep && *ep != 0 && *ep != '.'))
Jari Aalto31859422009-01-12 13:36:28 +0000512 rhs_t = ST_BAD; /* invalid */
513 }
514 else if (ISALPHA (rhs[0]) && (rhs[1] == 0 || rhs[1] == '.'))
515 {
516 rhs_t = ST_CHAR;
517 ep = rhs + 1;
518 }
519 else
520 {
521 rhs_t = ST_BAD;
522 ep = 0;
523 }
524
525 incr = 1;
526 if (rhs_t != ST_BAD)
527 {
Chet Ramey00018032011-11-21 20:51:19 -0500528 oep = ep;
Chet Rameyac50fba2014-02-26 09:36:43 -0500529 errno = 0;
Jari Aalto31859422009-01-12 13:36:28 +0000530 if (ep && *ep == '.' && ep[1] == '.' && ep[2])
531 incr = strtoimax (ep + 2, &ep, 10);
Chet Rameyac50fba2014-02-26 09:36:43 -0500532 if (*ep != 0 || errno == ERANGE)
533 rhs_t = ST_BAD; /* invalid incr or overflow */
Chet Ramey00018032011-11-21 20:51:19 -0500534 tlen -= ep - oep;
Jari Aalto31859422009-01-12 13:36:28 +0000535 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000536
537 if (lhs_t != rhs_t || lhs_t == ST_BAD || rhs_t == ST_BAD)
538 {
539 free (lhs);
540 free (rhs);
541 return ((char **)NULL);
542 }
543
544 /* OK, we have something. It's either a sequence of integers, ascending
545 or descending, or a sequence or letters, ditto. Generate the sequence,
546 put it into a string vector, and return it. */
547
548 if (lhs_t == ST_CHAR)
549 {
Jari Aaltoeb873672004-11-09 21:37:25 +0000550 lhs_v = (unsigned char)lhs[0];
551 rhs_v = (unsigned char)rhs[0];
Jari Aalto31859422009-01-12 13:36:28 +0000552 width = 1;
Jari Aaltob80f6442004-07-27 13:29:18 +0000553 }
554 else
555 {
556 lhs_v = tl; /* integer truncation */
557 rhs_v = tr;
Jari Aalto31859422009-01-12 13:36:28 +0000558
559 /* Decide whether or not the terms need zero-padding */
560 rhs_l = tlen - lhs_l - sizeof (BRACE_SEQ_SPECIFIER) + 1;
561 width = 0;
562 if (lhs_l > 1 && lhs[0] == '0')
563 width = lhs_l, lhs_t = ST_ZINT;
564 if (lhs_l > 2 && lhs[0] == '-' && lhs[1] == '0')
565 width = lhs_l, lhs_t = ST_ZINT;
566 if (rhs_l > 1 && rhs[0] == '0' && width < rhs_l)
567 width = rhs_l, lhs_t = ST_ZINT;
568 if (rhs_l > 2 && rhs[0] == '-' && rhs[1] == '0' && width < rhs_l)
569 width = rhs_l, lhs_t = ST_ZINT;
Chet Ramey00018032011-11-21 20:51:19 -0500570
571 if (width < lhs_l && lhs_t == ST_ZINT)
572 width = lhs_l;
573 if (width < rhs_l && lhs_t == ST_ZINT)
574 width = rhs_l;
Jari Aaltob80f6442004-07-27 13:29:18 +0000575 }
576
Jari Aalto31859422009-01-12 13:36:28 +0000577 result = mkseq (lhs_v, rhs_v, incr, lhs_t, width);
Jari Aaltob80f6442004-07-27 13:29:18 +0000578
579 free (lhs);
580 free (rhs);
581
582 return (result);
583}
584
Jari Aalto726f6381996-08-26 18:22:31 +0000585/* Start at INDEX, and skip characters in TEXT. Set INDEX to the
586 index of the character matching SATISFY. This understands about
587 quoting. Return the character that caused us to stop searching;
588 this is either the same as SATISFY, or 0. */
Jari Aalto06285672006-10-10 14:15:34 +0000589/* If SATISFY is `}', we are looking for a brace expression, so we
590 should enforce the rules that govern valid brace expansions:
591 1) to count as an arg separator, a comma or `..' has to be outside
592 an inner set of braces.
593*/
Jari Aalto726f6381996-08-26 18:22:31 +0000594static int
Jari Aalto7117c2d2002-07-17 14:10:11 +0000595brace_gobbler (text, tlen, indx, satisfy)
Jari Aalto726f6381996-08-26 18:22:31 +0000596 char *text;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000597 size_t tlen;
Jari Aalto726f6381996-08-26 18:22:31 +0000598 int *indx;
599 int satisfy;
600{
Jari Aalto06285672006-10-10 14:15:34 +0000601 register int i, c, quoted, level, commas, pass_next;
Jari Aaltod166f041997-06-05 14:59:13 +0000602#if defined (SHELL)
603 int si;
604 char *t;
605#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000606 DECLARE_MBSTATE;
Jari Aalto726f6381996-08-26 18:22:31 +0000607
608 level = quoted = pass_next = 0;
Jari Aalto06285672006-10-10 14:15:34 +0000609#if defined (CSH_BRACE_COMPAT)
610 commas = 1;
611#else
612 commas = (satisfy == '}') ? 0 : 1;
613#endif
Jari Aalto726f6381996-08-26 18:22:31 +0000614
Jari Aalto7117c2d2002-07-17 14:10:11 +0000615 i = *indx;
616 while (c = text[i])
Jari Aalto726f6381996-08-26 18:22:31 +0000617 {
618 if (pass_next)
619 {
620 pass_next = 0;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000621 ADVANCE_CHAR (text, tlen, i);
Jari Aalto726f6381996-08-26 18:22:31 +0000622 continue;
623 }
624
625 /* A backslash escapes the next character. This allows backslash to
626 escape the quote character in a double-quoted string. */
627 if (c == '\\' && (quoted == 0 || quoted == '"' || quoted == '`'))
Jari Aalto28ef6c32001-04-06 19:14:31 +0000628 {
629 pass_next = 1;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000630 i++;
Jari Aalto28ef6c32001-04-06 19:14:31 +0000631 continue;
632 }
Jari Aalto726f6381996-08-26 18:22:31 +0000633
Jari Aaltob80f6442004-07-27 13:29:18 +0000634#if defined (SHELL)
635 /* If compiling for the shell, treat ${...} like \{...} */
636 if (c == '$' && text[i+1] == '{' && quoted != '\'') /* } */
637 {
638 pass_next = 1;
639 i++;
Jari Aaltoeb873672004-11-09 21:37:25 +0000640 if (quoted == 0)
641 level++;
Jari Aaltob80f6442004-07-27 13:29:18 +0000642 continue;
643 }
644#endif
645
Jari Aalto726f6381996-08-26 18:22:31 +0000646 if (quoted)
647 {
648 if (c == quoted)
649 quoted = 0;
Chet Rameyac50fba2014-02-26 09:36:43 -0500650#if defined (SHELL)
651 /* The shell allows quoted command substitutions */
652 if (quoted == '"' && c == '$' && text[i+1] == '(') /*)*/
653 goto comsub;
654#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000655 ADVANCE_CHAR (text, tlen, i);
Jari Aalto726f6381996-08-26 18:22:31 +0000656 continue;
657 }
658
659 if (c == '"' || c == '\'' || c == '`')
660 {
661 quoted = c;
Jari Aalto7117c2d2002-07-17 14:10:11 +0000662 i++;
Jari Aalto726f6381996-08-26 18:22:31 +0000663 continue;
664 }
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000665
Jari Aaltod166f041997-06-05 14:59:13 +0000666#if defined (SHELL)
Jari Aalto31859422009-01-12 13:36:28 +0000667 /* Pass new-style command and process substitutions through unchanged. */
668 if ((c == '$' || c == '<' || c == '>') && text[i+1] == '(') /* ) */
Jari Aaltod166f041997-06-05 14:59:13 +0000669 {
Chet Rameyac50fba2014-02-26 09:36:43 -0500670comsub:
Jari Aaltod166f041997-06-05 14:59:13 +0000671 si = i + 2;
Jari Aalto31859422009-01-12 13:36:28 +0000672 t = extract_command_subst (text, &si, 0);
Jari Aaltod166f041997-06-05 14:59:13 +0000673 i = si;
674 free (t);
Jari Aalto7117c2d2002-07-17 14:10:11 +0000675 i++;
Jari Aaltod166f041997-06-05 14:59:13 +0000676 continue;
677 }
678#endif
679
Jari Aalto06285672006-10-10 14:15:34 +0000680 if (c == satisfy && level == 0 && quoted == 0 && commas > 0)
Jari Aalto726f6381996-08-26 18:22:31 +0000681 {
682 /* We ignore an open brace surrounded by whitespace, and also
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000683 an open brace followed immediately by a close brace preceded
684 by whitespace. */
Jari Aalto726f6381996-08-26 18:22:31 +0000685 if (c == '{' &&
686 ((!i || brace_whitespace (text[i - 1])) &&
687 (brace_whitespace (text[i + 1]) || text[i + 1] == '}')))
Jari Aalto7117c2d2002-07-17 14:10:11 +0000688 {
689 i++;
690 continue;
691 }
Jari Aaltob80f6442004-07-27 13:29:18 +0000692
Jari Aalto726f6381996-08-26 18:22:31 +0000693 break;
694 }
695
696 if (c == '{')
697 level++;
698 else if (c == '}' && level)
699 level--;
Jari Aalto06285672006-10-10 14:15:34 +0000700#if !defined (CSH_BRACE_COMPAT)
701 else if (satisfy == '}' && c == brace_arg_separator && level == 0)
702 commas++;
703 else if (satisfy == '}' && STREQN (text+i, BRACE_SEQ_SPECIFIER, 2) &&
704 text[i+2] != satisfy && level == 0)
705 commas++;
706#endif
Jari Aalto7117c2d2002-07-17 14:10:11 +0000707
708 ADVANCE_CHAR (text, tlen, i);
Jari Aalto726f6381996-08-26 18:22:31 +0000709 }
710
711 *indx = i;
712 return (c);
713}
714
Chet Rameyac50fba2014-02-26 09:36:43 -0500715/* Return 1 if ARR has any non-empty-string members. Used to short-circuit
716 in array_concat() below. */
717static int
718degenerate_array (arr)
719 char **arr;
720{
721 register int i;
722
723 for (i = 0; arr[i]; i++)
724 if (arr[i][0] != '\0')
725 return 0;
726 return 1;
727}
728
Jari Aalto726f6381996-08-26 18:22:31 +0000729/* Return a new array of strings which is the result of appending each
730 string in ARR2 to each string in ARR1. The resultant array is
731 len (arr1) * len (arr2) long. For convenience, ARR1 (and its contents)
732 are free ()'ed. ARR1 can be NULL, in that case, a new version of ARR2
733 is returned. */
734static char **
735array_concat (arr1, arr2)
736 char **arr1, **arr2;
737{
738 register int i, j, len, len1, len2;
739 register char **result;
740
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000741 if (arr1 == 0)
Chet Rameyac50fba2014-02-26 09:36:43 -0500742 return (arr2); /* XXX - see if we can get away without copying? */
Jari Aalto726f6381996-08-26 18:22:31 +0000743
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000744 if (arr2 == 0)
Chet Rameyac50fba2014-02-26 09:36:43 -0500745 return (arr1); /* XXX - caller expects us to free arr1 */
746
747 /* We can only short-circuit if the array consists of a single null element;
748 otherwise we need to replicate the contents of the other array and
749 prefix (or append, below) an empty element to each one. */
750 if (arr1[0] && arr1[0][0] == 0 && arr1[1] == 0)
751 {
752 strvec_dispose (arr1);
753 return (arr2); /* XXX - use flags to see if we can avoid copying here */
754 }
755
756 if (arr2[0] && arr2[0][0] == 0 && arr2[1] == 0)
757 return (arr1); /* XXX - rather than copying and freeing it */
Jari Aalto726f6381996-08-26 18:22:31 +0000758
Jari Aalto7117c2d2002-07-17 14:10:11 +0000759 len1 = strvec_len (arr1);
760 len2 = strvec_len (arr2);
Jari Aalto726f6381996-08-26 18:22:31 +0000761
762 result = (char **)xmalloc ((1 + (len1 * len2)) * sizeof (char *));
763
764 len = 0;
765 for (i = 0; i < len1; i++)
766 {
767 int strlen_1 = strlen (arr1[i]);
768
769 for (j = 0; j < len2; j++)
770 {
Jari Aaltob80f6442004-07-27 13:29:18 +0000771 result[len] = (char *)xmalloc (1 + strlen_1 + strlen (arr2[j]));
Jari Aalto726f6381996-08-26 18:22:31 +0000772 strcpy (result[len], arr1[i]);
773 strcpy (result[len] + strlen_1, arr2[j]);
774 len++;
775 }
776 free (arr1[i]);
777 }
778 free (arr1);
779
780 result[len] = (char *)NULL;
781 return (result);
782}
783
784#if defined (TEST)
785#include <stdio.h>
786
787fatal_error (format, arg1, arg2)
788 char *format, *arg1, *arg2;
789{
790 report_error (format, arg1, arg2);
791 exit (1);
792}
793
794report_error (format, arg1, arg2)
795 char *format, *arg1, *arg2;
796{
797 fprintf (stderr, format, arg1, arg2);
798 fprintf (stderr, "\n");
799}
800
801main ()
802{
803 char example[256];
804
805 for (;;)
806 {
807 char **result;
808 int i;
809
810 fprintf (stderr, "brace_expand> ");
811
812 if ((!fgets (example, 256, stdin)) ||
813 (strncmp (example, "quit", 4) == 0))
814 break;
815
816 if (strlen (example))
817 example[strlen (example) - 1] = '\0';
818
819 result = brace_expand (example);
820
821 for (i = 0; result[i]; i++)
822 printf ("%s\n", result[i]);
823
824 free_array (result);
825 }
826}
827
828/*
829 * Local variables:
830 * compile-command: "gcc -g -Bstatic -DTEST -o brace_expand braces.c general.o"
831 * end:
832 */
833
834#endif /* TEST */
Jari Aaltoccc6cda1996-12-23 17:02:34 +0000835#endif /* BRACE_EXPANSION */