(HAVE_DWARF2_UNWIND_INFO_STATIC): Define it if gcc uses static
[glibc/history.git] / posix / wordexp.c
blob42b22ec8de61695623ea8478326303c10980e68c
1 /* POSIX.2 wordexp implementation.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Tim Waugh <tim@cyberelk.demon.co.uk>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <wordexp.h>
22 #include <signal.h>
23 #include <stdlib.h>
24 #include <pwd.h>
25 #include <sys/types.h>
26 #include <string.h>
27 #include <glob.h>
28 #include <ctype.h>
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #include <sys/wait.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <sys/stat.h>
35 #include <paths.h>
36 #include <errno.h>
37 #include <sys/param.h>
38 #include <stdio.h>
39 #include <fnmatch.h>
41 #include <stdio-common/_itoa.h>
43 /* Undefine the following line for the production version. */
44 /* #define NDEBUG 1 */
45 #include <assert.h>
48 * This is a recursive-descent-style word expansion routine.
51 /* Some forward declarations */
52 static int parse_dollars (char **word, size_t *word_length, size_t *max_length,
53 const char *words, size_t *offset, int flags,
54 wordexp_t *pwordexp)
55 internal_function;
56 static int parse_backtick (char **word, size_t *word_length,
57 size_t *max_length, const char *words,
58 size_t *offset, int flags, wordexp_t *pwordexp)
59 internal_function;
60 static int eval_expr (char *expr, int *result) internal_function;
62 /* The w_*() functions manipulate word lists. */
64 #define W_CHUNK (100)
66 static inline char *
67 w_addchar (char *buffer, size_t *actlen, size_t *maxlen, char ch)
68 /* (lengths exclude trailing zero) */
70 /* Add a character to the buffer, allocating room for it if needed.
73 if (*actlen == *maxlen)
75 char *old_buffer = buffer;
76 assert (buffer == NULL || *maxlen != 0);
77 *maxlen += W_CHUNK;
78 buffer = realloc (buffer, 1 + *maxlen);
80 if (buffer == NULL)
81 free (old_buffer);
84 if (buffer != NULL)
86 buffer[*actlen] = ch;
87 buffer[++(*actlen)] = '\0';
90 return buffer;
93 static char *
94 w_addstr (char *buffer, size_t *actlen, size_t *maxlen, const char *str)
95 /* (lengths exclude trailing zero) */
97 /* Add a string to the buffer, allocating room for it if needed.
99 size_t len;
101 assert (str != NULL); /* w_addstr only called from this file */
102 len = strlen (str);
104 if (*actlen + len > *maxlen)
106 char *old_buffer = buffer;
107 assert (buffer == NULL || *maxlen != 0);
108 *maxlen += MAX (2 * len, W_CHUNK);
109 buffer = realloc (old_buffer, 1 + *maxlen);
111 if (buffer == NULL)
112 free (old_buffer);
115 if (buffer != NULL)
117 *((char *) __mempcpy (&buffer[*actlen], str, len)) = '\0';
118 *actlen += len;
121 return buffer;
124 static int
125 w_addword (wordexp_t *pwordexp, char *word)
127 /* Add a word to the wordlist */
128 size_t num_p;
130 num_p = 2 + pwordexp->we_wordc + pwordexp->we_offs;
131 pwordexp->we_wordv = realloc (pwordexp->we_wordv, sizeof (char *) * num_p);
132 if (pwordexp->we_wordv != NULL)
134 pwordexp->we_wordv[pwordexp->we_wordc++] = word;
135 pwordexp->we_wordv[pwordexp->we_wordc] = NULL;
136 return 0;
139 return WRDE_NOSPACE;
142 /* The parse_*() functions should leave *offset being the offset in 'words'
143 * to the last character processed.
146 static int
147 internal_function
148 parse_backslash (char **word, size_t *word_length, size_t *max_length,
149 const char *words, size_t *offset)
151 /* We are poised _at_ a backslash, not in quotes */
153 switch (words[1 + *offset])
155 case 0:
156 /* Backslash is last character of input words */
157 return WRDE_SYNTAX;
159 case '\n':
160 ++(*offset);
161 break;
163 default:
164 *word = w_addchar (*word, word_length, max_length, words[1 + *offset]);
165 if (*word == NULL)
166 return WRDE_NOSPACE;
168 ++(*offset);
169 break;
172 return 0;
175 static int
176 internal_function
177 parse_qtd_backslash (char **word, size_t *word_length, size_t *max_length,
178 const char *words, size_t *offset)
180 /* We are poised _at_ a backslash, inside quotes */
182 switch (words[1 + *offset])
184 case 0:
185 /* Backslash is last character of input words */
186 return WRDE_SYNTAX;
188 case '\n':
189 ++(*offset);
190 break;
192 case '$':
193 case '`':
194 case '"':
195 case '\\':
196 *word = w_addchar (*word, word_length, max_length, words[1 + *offset]);
197 if (*word == NULL)
198 return WRDE_NOSPACE;
200 ++(*offset);
201 break;
203 default:
204 *word = w_addchar (*word, word_length, max_length, words[*offset]);
205 if (*word != NULL)
206 *word = w_addchar (*word, word_length, max_length, words[1 + *offset]);
208 if (*word == NULL)
209 return WRDE_NOSPACE;
211 ++(*offset);
212 break;
215 return 0;
218 static int
219 internal_function
220 parse_tilde (char **word, size_t *word_length, size_t *max_length,
221 const char *words, size_t *offset, size_t wordc)
223 /* We are poised _at_ a tilde */
224 size_t i;
226 if (*word_length != 0)
228 if (!((*word)[*word_length - 1] == '=' && wordc == 0))
230 if (!((*word)[*word_length - 1] == ':' &&
231 strchr (*word, '=') && wordc == 0))
233 *word = w_addchar (*word, word_length, max_length, '~');
234 return *word ? 0 : WRDE_NOSPACE;
239 for (i = 1 + *offset; words[i]; i++)
241 if (words[i] == ':' || words[i] == '/' || words[i] == ' ' ||
242 words[i] == '\t' || words[i] == 0 )
243 break;
245 if (words[i] == '\\')
247 *word = w_addchar (*word, word_length, max_length, '~');
248 return *word ? 0 : WRDE_NOSPACE;
252 if (i == 1 + *offset)
254 /* Tilde appears on its own */
255 uid_t uid;
256 struct passwd pwd, *tpwd;
257 int buflen = 1000;
258 char* buffer = __alloca (buflen);
259 int result;
261 uid = getuid ();
263 while ((result = __getpwuid_r (uid, &pwd, buffer, buflen, &tpwd)) != 0
264 && errno == ERANGE)
266 buflen += 1000;
267 buffer = __alloca (buflen);
270 if (result == 0 && pwd.pw_dir != NULL)
272 *word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
273 if (*word == NULL)
274 return WRDE_NOSPACE;
276 else
278 *word = w_addchar (*word, word_length, max_length, '~');
279 if (*word == NULL)
280 return WRDE_NOSPACE;
283 else
285 /* Look up user name in database to get home directory */
286 char *user = __strndup (&words[1 + *offset], i - *offset);
287 struct passwd pwd, *tpwd;
288 int buflen = 1000;
289 char* buffer = __alloca (buflen);
290 int result;
292 while ((result = __getpwnam_r (user, &pwd, buffer, buflen, &tpwd)) != 0
293 && errno == ERANGE)
295 buflen += 1000;
296 buffer = __alloca (buflen);
299 if (result == 0 && pwd.pw_dir)
300 *word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
301 else
303 /* (invalid login name) */
304 *word = w_addchar (*word, word_length, max_length, '~');
305 if (*word != NULL)
306 *word = w_addstr (*word, word_length, max_length, user);
309 *offset = i - 1;
311 return *word ? 0 : WRDE_NOSPACE;
314 static int
315 internal_function
316 parse_glob (char **word, size_t *word_length, size_t *max_length,
317 const char *words, size_t *offset, int flags,
318 wordexp_t *pwordexp, char *ifs)
320 /* We are poised just after a '*' or a '{'. */
321 int error;
322 glob_t globbuf;
323 int match;
324 char *matching_word;
326 for (; words[*offset]; (*offset)++)
327 switch (words[*offset])
329 case ' ':
330 case '\t':
331 break;
333 case '$':
334 error = parse_dollars (word, word_length, max_length, words, offset,
335 flags, pwordexp);
336 if (error)
337 return error;
339 continue;
341 default:
342 if (ifs == NULL || strchr (ifs, words[*offset]) == NULL)
344 *word = w_addchar (*word, word_length, max_length, words[*offset]);
345 if (*word == NULL)
346 return WRDE_NOSPACE;
348 continue;
351 break;
354 error = glob (*word, GLOB_NOCHECK, NULL, &globbuf);
356 if (error != 0)
358 /* We can only run into memory problems. */
359 assert (error == GLOB_NOSPACE);
361 return WRDE_NOSPACE;
364 if (ifs && !*ifs)
366 /* No field splitting allowed */
367 size_t length = strlen (globbuf.gl_pathv[0]);
368 *word = realloc (*word, length + 1);
369 if (*word == NULL)
370 goto no_space;
372 memcpy (*word, globbuf.gl_pathv[0], length + 1);
373 *word_length = length;
375 for (match = 1; match < globbuf.gl_pathc && *word != NULL; ++match)
377 *word = w_addchar (*word, word_length, max_length, ' ');
378 if (*word != NULL)
379 *word = w_addstr (*word, word_length, max_length,
380 globbuf.gl_pathv[match]);
383 /* Re-parse white space on return */
384 globfree (&globbuf);
385 --(*offset);
386 return *word ? 0 : WRDE_NOSPACE;
389 /* here ifs != "" */
390 free (*word);
391 *word = NULL;
392 *word_length = 0;
394 matching_word = __strdup (globbuf.gl_pathv[0]);
395 if (matching_word == NULL)
396 goto no_space;
398 if (w_addword (pwordexp, matching_word) == WRDE_NOSPACE)
399 goto no_space;
401 for (match = 1; match < globbuf.gl_pathc; ++match)
403 matching_word = __strdup (globbuf.gl_pathv[match]);
404 if (matching_word == NULL)
405 goto no_space;
407 if (w_addword (pwordexp, matching_word) == WRDE_NOSPACE)
408 goto no_space;
411 globfree (&globbuf);
413 /* Re-parse white space on return */
414 --(*offset);
415 return 0;
417 no_space:
418 globfree (&globbuf);
419 return WRDE_NOSPACE;
422 static int
423 parse_squote (char **word, size_t *word_length, size_t *max_length,
424 const char *words, size_t *offset)
426 /* We are poised just after a single quote */
427 for (; words[*offset]; ++(*offset))
429 if (words[*offset] != '\'')
431 *word = w_addchar (*word, word_length, max_length, words[*offset]);
432 if (*word == NULL)
433 return WRDE_NOSPACE;
435 else return 0;
438 /* Unterminated string */
439 return WRDE_SYNTAX;
442 /* Functions to evaluate an arithmetic expression */
443 static int
444 internal_function
445 eval_expr_val (char **expr, int *result)
447 int sgn = +1;
448 char *digit;
450 /* Skip white space */
451 for (digit = *expr; digit && *digit && isspace (*digit); ++digit);
453 switch (*digit)
455 case '(':
457 /* Scan for closing paren */
458 for (++digit; **expr && **expr != ')'; ++(*expr));
460 /* Is there one? */
461 if (!**expr)
462 return WRDE_SYNTAX;
464 *(*expr)++ = 0;
466 if (eval_expr (digit, result))
467 return WRDE_SYNTAX;
469 return 0;
471 case '+': /* Positive value */
472 ++digit;
473 break;
475 case '-': /* Negative value */
476 ++digit;
477 sgn = -1;
478 break;
480 default:
481 if (!isdigit (*digit))
482 return WRDE_SYNTAX;
485 *result = 0;
486 for (; *digit && isdigit (*digit); ++digit)
487 *result = (*result * 10) + (*digit - '0');
489 *expr = digit;
490 *result *= sgn;
491 return 0;
494 static int
495 internal_function
496 eval_expr_multdiv (char **expr, int *result)
498 int arg;
500 /* Read a Value */
501 if (eval_expr_val (expr, result))
502 return WRDE_SYNTAX;
504 while (**expr)
506 /* Skip white space */
507 for (; *expr && **expr && isspace (**expr); ++(*expr));
509 if (**expr == '*')
511 (*expr)++;
512 if ((eval_expr_val (expr, &arg)) != 0)
513 return WRDE_SYNTAX;
515 *result *= arg;
517 else if (**expr == '/')
519 (*expr)++;
520 if ((eval_expr_val (expr, &arg)) != 0)
521 return WRDE_SYNTAX;
523 *result /= arg;
525 else break;
528 return 0;
531 static int
532 internal_function
533 eval_expr (char *expr, int *result)
535 int arg;
537 /* Read a Multdiv */
538 if ((eval_expr_multdiv (&expr, result)) != 0)
539 return WRDE_SYNTAX;
541 while (*expr)
543 /* Skip white space */
544 for (; expr && *expr && isspace (*expr); ++expr);
546 if (*expr == '+')
548 expr++;
549 if ((eval_expr_multdiv (&expr, &arg)) != 0)
550 return WRDE_SYNTAX;
552 *result += arg;
554 else if (*expr == '-')
556 expr++;
557 if ((eval_expr_multdiv (&expr, &arg)) != 0)
558 return WRDE_SYNTAX;
560 *result -= arg;
562 else break;
565 return 0;
568 static int
569 internal_function
570 parse_arith (char **word, size_t *word_length, size_t *max_length,
571 const char *words, size_t *offset, int flags, int bracket)
573 /* We are poised just after "$((" or "$[" */
574 int error;
575 int paren_depth = 1;
576 size_t expr_length = 0;
577 size_t expr_maxlen = 0;
578 char *expr = NULL;
580 for (; words[*offset]; ++(*offset))
582 switch (words[*offset])
584 case '$':
585 error = parse_dollars (&expr, &expr_length, &expr_maxlen,
586 words, offset, flags, NULL);
587 /* The NULL here is to tell parse_dollars not to
588 * split the fields.
590 if (error)
592 free (expr);
593 return error;
595 break;
597 case '`':
598 (*offset)++;
599 error = parse_backtick (&expr, &expr_length, &expr_maxlen,
600 words, offset, flags, NULL);
601 /* The NULL here is to tell parse_backtick not to
602 * split the fields.
604 if (error)
606 free (expr);
607 return error;
609 break;
611 case '\\':
612 error = parse_qtd_backslash (&expr, &expr_length, &expr_maxlen,
613 words, offset);
614 if (error)
616 free (expr);
617 return error;
619 /* I think that a backslash within an
620 * arithmetic expansion is bound to
621 * cause an error sooner or later anyway though.
623 break;
625 case ')':
626 if (--paren_depth == 0)
628 char result[21]; /* 21 = ceil(log10(2^64)) + 1 */
629 int numresult = 0;
631 if (bracket || words[1 + *offset] != ')')
632 return WRDE_SYNTAX;
634 ++(*offset);
636 /* Go - evaluate. */
637 if (*expr &&
638 eval_expr (expr, &numresult) != 0)
639 return WRDE_SYNTAX;
641 result[20] = '\0';
642 *word = w_addstr (*word, word_length, max_length,
643 _itoa_word (numresult, &result[20], 10, 0));
644 free (expr);
645 return *word ? 0 : WRDE_NOSPACE;
647 expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]);
648 if (expr == NULL)
649 return WRDE_NOSPACE;
651 break;
653 case ']':
654 if (bracket && paren_depth == 1)
656 char result[21]; /* 21 = ceil(log10(2^64)) + 1 */
657 int numresult = 0;
659 /* Go - evaluate. */
660 if (*expr && eval_expr (expr, &numresult) != 0)
661 return WRDE_SYNTAX;
663 result[20] = '\0';
664 *word = w_addstr (*word, word_length, max_length,
665 _itoa_word (numresult, &result[20], 10, 0));
666 free (expr);
667 return *word ? 0 : WRDE_NOSPACE;
670 free (expr);
671 return WRDE_SYNTAX;
673 case '\n':
674 case ';':
675 case '{':
676 case '}':
677 free (expr);
678 return WRDE_BADCHAR;
680 case '(':
681 ++paren_depth;
682 default:
683 expr = w_addchar (expr, &expr_length, &expr_maxlen, words[*offset]);
684 if (expr == NULL)
685 return WRDE_NOSPACE;
689 /* Premature end */
690 free (expr);
691 return WRDE_SYNTAX;
694 /* Function to execute a command and retrieve the results */
695 /* pwordexp contains NULL if field-splitting is forbidden */
696 static int
697 internal_function
698 exec_comm (char *comm, char **word, size_t *word_length, size_t *max_length,
699 int flags, wordexp_t *pwordexp)
701 int fildes[2];
702 int bufsize = 128;
703 int buflen;
704 int state = 0;
705 int i;
706 char *buffer;
707 pid_t pid;
708 /* 'state' is:
709 * 0 until first non-(whitespace-ifs)
710 * 1 after a non-ifs
711 * 2 after non-(whitespace-ifs)
714 /* Don't fork() unless necessary */
715 if (!comm || !*comm)
716 return 0;
718 if (pipe (fildes))
719 /* Bad */
720 return WRDE_NOSPACE;
722 if ((pid = fork ()) < 0)
724 /* Bad */
725 return WRDE_NOSPACE;
728 if (pid == 0)
730 /* Child */
731 const char *args[4] = { _PATH_BSHELL, "-c", comm, NULL };
733 /* Redirect input and output */
734 dup2 (fildes[1], 1);
736 /* Close stderr if we have to */
737 if ((flags & WRDE_SHOWERR) == 0)
738 close (2);
740 __execve (_PATH_BSHELL, (char *const *) args, __environ);
742 /* Bad. What now? */
743 abort ();
746 /* Parent */
748 close (fildes[1]);
749 buffer = __alloca (bufsize);
751 if (!pwordexp)
752 { /* Quoted - no field splitting */
754 while (1)
756 if ((buflen = read (fildes[0], buffer, bufsize)) < 1)
758 if (__waitpid (pid, NULL, WNOHANG) == 0)
759 continue;
760 if ((buflen = read (fildes[0], buffer, bufsize)) < 1)
761 break;
764 for (i = 0; i < buflen; ++i)
766 *word = w_addchar (*word, word_length, max_length, buffer[i]);
767 if (*word == NULL)
769 close (fildes[0]);
770 return WRDE_NOSPACE;
775 close (fildes[0]);
776 return 0;
779 /* Not quoted - split fields.
780 * NB. This isn't done properly yet.
782 while (1)
784 if ((buflen = read (fildes[0], buffer, bufsize)) < 1)
786 if (__waitpid (pid, NULL, WNOHANG) == 0)
787 continue;
788 if ((read (fildes[0], buffer, bufsize)) < 1)
789 break;
792 for (i = 0; i < buflen; ++i)
794 /* What if these aren't field separators? FIX */
795 if (buffer[i] == ' ' || buffer[i] == '\t' || buffer[i] == '\n')
797 if (state != 0)
798 state = 2;
799 continue;
802 if (state == 2)
804 /* End of word */
805 if (w_addword (pwordexp, *word) == WRDE_NOSPACE)
807 close (fildes[0]);
808 return WRDE_NOSPACE;
811 *word = NULL;
812 *word_length = 0;
815 state = 1;
816 *word = w_addchar (*word, word_length, max_length, buffer[i]);
817 if (*word == NULL)
819 close (fildes[0]);
820 return WRDE_NOSPACE;
825 close (fildes[0]);
826 return 0;
829 static int
830 parse_comm (char **word, size_t *word_length, size_t *max_length,
831 const char *words, size_t *offset, int flags, wordexp_t *pwordexp)
833 /* We are poised just after "$(" */
834 int paren_depth = 1;
835 int error;
836 size_t comm_length = 0;
837 size_t comm_maxlen = 0;
838 char *comm = NULL;
840 for (; words[*offset]; ++(*offset))
842 switch (words[*offset])
844 case ')':
845 if (--paren_depth == 0)
847 /* Go -- give script to the shell */
848 error = exec_comm (comm, word, word_length, max_length, flags,
849 pwordexp);
850 free (comm);
851 return error;
854 /* This is just part of the script */
855 comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]);
856 if (comm == NULL)
857 return WRDE_NOSPACE;
859 break;
861 case '(':
862 ++paren_depth;
863 default:
864 comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]);
865 if (comm == NULL)
866 return WRDE_NOSPACE;
868 break;
872 /* Premature end */
873 free (comm);
874 return WRDE_SYNTAX;
877 static int
878 internal_function
879 parse_param (char **word, size_t *word_length, size_t *max_length,
880 const char *words, size_t *offset, int flags, wordexp_t *pwordexp)
882 /* We are poised just after "$" */
883 enum remove_pattern_enum
885 RP_NONE = 0,
886 RP_SHORT_LEFT,
887 RP_LONG_LEFT,
888 RP_SHORT_RIGHT,
889 RP_LONG_RIGHT
891 size_t start = *offset;
892 size_t env_length = 0;
893 size_t env_maxlen = 0;
894 size_t pat_length = 0;
895 size_t pat_maxlen = 0;
896 char *env = NULL;
897 char *pattern = NULL;
898 char *value;
899 char action = '\0';
900 enum remove_pattern_enum remove = RP_NONE;
901 int colon_seen = 0;
902 int depth = 0;
903 int error;
905 for (; words[*offset]; ++(*offset))
907 switch (words[*offset])
909 case '{':
910 ++depth;
912 if (action != '\0' || remove != RP_NONE)
914 pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
915 words[*offset]);
916 if (pattern == NULL)
917 goto no_space;
919 break;
922 if (*offset == start)
923 break;
925 /* Otherwise evaluate */
926 /* (and re-parse this character) */
927 --(*offset);
928 goto envsubst;
930 case '}':
931 if (words[start] != '{')
932 --(*offset);
934 if (action != '\0' || remove != RP_NONE)
936 if (--depth)
938 pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
939 words[*offset]);
940 if (pattern == NULL)
941 goto no_space;
943 break;
947 /* Evaluate */
948 goto envsubst;
950 case '#':
951 /* At the start? (ie. 'string length') */
952 if (*offset == start + 1)
953 /* FIXME: This isn't written yet! */
954 break;
956 if (words[start] != '{')
958 /* Evaluate */
959 /* (and re-parse this character) */
960 --(*offset);
961 goto envsubst;
964 /* Separating variable name from prefix pattern? */
966 if (remove == RP_NONE)
968 remove = RP_SHORT_LEFT;
969 break;
971 else if (remove == RP_SHORT_LEFT)
973 remove = RP_LONG_LEFT;
974 break;
977 /* Must be part of prefix/suffix pattern. */
978 pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
979 words[*offset]);
980 if (pattern == NULL)
981 goto no_space;
983 break;
985 case '%':
986 if (!*env)
987 goto syntax;
989 /* Separating variable name from suffix pattern? */
990 if (remove == RP_NONE)
992 remove = RP_SHORT_RIGHT;
993 break;
995 else if (remove == RP_SHORT_RIGHT)
997 remove = RP_LONG_RIGHT;
998 break;
1001 /* Must be part of prefix/suffix pattern. */
1002 pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
1003 words[*offset]);
1004 if (pattern == NULL)
1005 goto no_space;
1007 break;
1009 case ':':
1010 if (!*env)
1011 goto syntax;
1013 if (action != '\0' || remove != RP_NONE)
1015 pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
1016 words[*offset]);
1017 if (pattern == NULL)
1018 goto no_space;
1020 break;
1023 if ((words[1 + *offset] == '-') || (words[1 + *offset] == '=') ||
1024 (words[1 + *offset] == '?') || (words[1 + *offset] == '+'))
1026 colon_seen = 1;
1027 break;
1030 goto syntax;
1032 case '-':
1033 case '=':
1034 case '?':
1035 case '+':
1036 if (!*env)
1037 goto syntax;
1039 if (action != '\0' || remove != RP_NONE)
1041 pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
1042 words[*offset]);
1043 if (pattern == NULL)
1044 goto no_space;
1046 break;
1049 action = words[*offset];
1050 break;
1052 case '\\':
1053 if (action != '\0' || remove != RP_NONE)
1055 /* Um. Is this right? */
1056 error = parse_qtd_backslash (word, word_length, max_length,
1057 words, offset);
1058 if (error == 0)
1059 break;
1061 else
1063 error = WRDE_SYNTAX;
1066 if (env)
1067 free (env);
1069 if (pattern != NULL)
1070 free (pattern);
1072 return error;
1074 default:
1075 if (action != '\0' || remove != RP_NONE)
1077 pattern = w_addchar (pattern, &pat_length, &pat_maxlen,
1078 words[*offset]);
1079 if (pattern == NULL)
1080 goto no_space;
1082 break;
1085 if ((words[start] == '{') || isalpha (words[*offset]))
1087 env = w_addchar (env, &env_length, &env_maxlen, words[*offset]);
1088 if (env == NULL)
1089 goto no_space;
1091 break;
1094 --(*offset);
1095 goto envsubst;
1099 /* End of input string */
1100 --(*offset);
1102 envsubst:
1103 if (words[start] == '{' && words[*offset] != '}')
1104 goto syntax;
1106 if (!env || !*env)
1108 *offset = start - 1;
1109 *word = w_addchar (*word, word_length, max_length, '$');
1110 free (env);
1111 free (pattern);
1112 return *word ? 0 : WRDE_NOSPACE;
1115 value = getenv (env);
1117 if (action != '\0' || remove != RP_NONE)
1119 switch (action)
1121 case 0:
1123 char *p;
1124 char c;
1125 char *end;
1127 if (!pattern || !*pattern)
1128 break;
1130 end = value + strlen (value);
1132 if (value == NULL)
1133 break;
1135 switch (remove)
1137 case RP_SHORT_LEFT:
1138 for (p = value; p <= end; p++)
1140 c = *p;
1141 *p = '\0';
1142 if (fnmatch (pattern, value, 0) != FNM_NOMATCH)
1144 *p = c;
1145 value = p;
1146 break;
1148 *p = c;
1151 break;
1153 case RP_LONG_LEFT:
1154 for (p = end; p >= value; p--)
1156 c = *p;
1157 *p = '\0';
1158 if (fnmatch (pattern, value, 0) != FNM_NOMATCH)
1160 *p = c;
1161 value = p;
1162 break;
1164 *p = c;
1167 break;
1169 case RP_SHORT_RIGHT:
1170 for (p = end; p >= value; p--)
1172 if (fnmatch (pattern, p, 0) != FNM_NOMATCH)
1174 *p = '\0';
1175 break;
1179 break;
1181 case RP_LONG_RIGHT:
1182 for (p = value; p <= end; p++)
1184 if (fnmatch (pattern, p, 0) != FNM_NOMATCH)
1186 *p = '\0';
1187 break;
1191 break;
1193 default:
1194 assert (! "Unexpected `remove' value\n");
1197 break;
1200 case '?':
1201 if (value && *value)
1202 break;
1204 if (!colon_seen && value)
1206 /* Substitute NULL */
1207 free (env);
1208 free (pattern);
1209 return 0;
1212 /* Error - exit */
1213 fprintf (stderr, "%s: ", env);
1215 if (*pattern)
1217 /* Expand 'pattern' and write it to stderr */
1218 wordexp_t we;
1220 error = wordexp (pattern, &we, flags);
1222 if (error == 0)
1224 int i;
1226 for (i = 0; i < we.we_wordc; ++i)
1228 fprintf (stderr, "%s%s", i ? " " : "", we.we_wordv[i]);
1231 fprintf (stderr, "\n");
1232 error = WRDE_BADVAL;
1235 wordfree (&we);
1236 free (env);
1237 free (pattern);
1238 return error;
1241 fprintf (stderr, "parameter null or not set\n");
1242 free (env);
1243 free (pattern);
1244 return WRDE_BADVAL;
1246 default:
1247 printf ("warning: parameter substitution does not yet support \"%s%c\"\n", colon_seen?":":"", action);
1251 free (env);
1252 free (pattern);
1254 if (value == NULL)
1256 /* Variable not defined */
1257 if (flags & WRDE_UNDEF)
1258 return WRDE_SYNTAX;
1260 return 0;
1263 if (pwordexp == NULL)
1264 /* Quoted - no field split */
1265 *word = w_addstr (*word, word_length, max_length, value);
1266 else
1267 /* Should field-split here - FIX */
1268 *word = w_addstr (*word, word_length, max_length, value);
1270 return *word ? 0 : WRDE_NOSPACE;
1272 no_space:
1273 if (env)
1274 free (env);
1276 if (pattern)
1277 free (pattern);
1279 return WRDE_NOSPACE;
1281 syntax:
1282 if (env)
1283 free (env);
1285 if (pattern)
1286 free (pattern);
1288 return WRDE_SYNTAX;
1291 static int
1292 internal_function
1293 parse_dollars (char **word, size_t *word_length, size_t *max_length,
1294 const char *words, size_t *offset, int flags,
1295 wordexp_t *pwordexp)
1297 /* We are poised _at_ "$" */
1298 switch (words[1 + *offset])
1300 case '"':
1301 case '\'':
1302 case 0:
1303 *word = w_addchar (*word, word_length, max_length, '$');
1304 return *word ? 0 : WRDE_NOSPACE;
1306 case '(':
1307 if (words[2 + *offset] == '(')
1309 (*offset) += 3;
1310 /* Call parse_arith -- 0 is for "no brackets" */
1311 return parse_arith (word, word_length, max_length, words, offset,
1312 flags, 0);
1315 if (flags & WRDE_NOCMD)
1316 return WRDE_CMDSUB;
1318 (*offset) += 2;
1319 return parse_comm (word, word_length, max_length, words, offset, flags,
1320 pwordexp);
1322 case '[':
1323 (*offset) += 2;
1324 /* Call parse_arith -- 1 is for "brackets" */
1325 return parse_arith (word, word_length, max_length, words, offset, flags,
1328 case '{':
1329 default:
1330 ++(*offset); /* parse_param needs to know if "{" is there */
1331 return parse_param (word, word_length, max_length, words, offset, flags,
1332 pwordexp);
1336 static int
1337 parse_backtick (char **word, size_t *word_length, size_t *max_length,
1338 const char *words, size_t *offset, int flags,
1339 wordexp_t *pwordexp)
1341 /* We are poised just after "`" */
1342 int error;
1343 size_t comm_length = 0;
1344 size_t comm_maxlen = 0;
1345 char *comm = NULL;
1346 int squoting = 0;
1348 for (; words[*offset]; ++(*offset))
1350 switch (words[*offset])
1352 case '`':
1353 /* Go -- give the script to the shell */
1354 error = exec_comm (comm, word, word_length, max_length, flags,
1355 pwordexp);
1356 free (comm);
1357 return error;
1359 case '\\':
1360 if (squoting)
1362 error = parse_qtd_backslash (&comm, &comm_length, &comm_maxlen,
1363 words, offset);
1365 if (error)
1367 free (comm);
1368 return error;
1371 break;
1374 ++(*offset);
1375 error = parse_backslash (&comm, &comm_length, &comm_maxlen, words,
1376 offset);
1378 if (error)
1380 free (comm);
1381 return error;
1384 break;
1386 case '\'':
1387 squoting = 1 - squoting;
1388 default:
1389 comm = w_addchar (comm, &comm_length, &comm_maxlen, words[*offset]);
1390 if (comm == NULL)
1391 return WRDE_NOSPACE;
1395 /* Premature end */
1396 free (comm);
1397 return WRDE_SYNTAX;
1400 static int
1401 internal_function
1402 parse_dquote (char **word, size_t *word_length, size_t *max_length,
1403 const char *words, size_t *offset, int flags)
1405 /* We are poised just after a double-quote */
1406 int error;
1408 for (; words[*offset]; ++(*offset))
1410 switch (words[*offset])
1412 case '"':
1413 return 0;
1415 case '$':
1416 error = parse_dollars (word, word_length, max_length, words, offset,
1417 flags, NULL);
1418 /* The NULL here is to tell parse_dollars not to
1419 * split the fields.
1421 if (error)
1422 return error;
1424 break;
1426 case '`':
1427 if (flags & WRDE_NOCMD)
1428 return WRDE_CMDSUB;
1430 ++(*offset);
1431 error = parse_backtick (word, word_length, max_length, words,
1432 offset, flags, NULL);
1433 /* The NULL here is to tell parse_backtick not to
1434 * split the fields.
1436 if (error)
1437 return error;
1439 break;
1441 case '\\':
1442 error = parse_qtd_backslash (word, word_length, max_length, words,
1443 offset);
1445 if (error)
1446 return error;
1448 break;
1450 default:
1451 *word = w_addchar (*word, word_length, max_length, words[*offset]);
1452 if (*word == NULL)
1453 return WRDE_NOSPACE;
1457 /* Unterminated string */
1458 return WRDE_SYNTAX;
1462 * wordfree() is to be called after pwordexp is finished with.
1465 void
1466 wordfree (wordexp_t *pwordexp)
1469 /* wordexp can set pwordexp to NULL */
1470 if (pwordexp && pwordexp->we_wordv)
1472 char **wordv = pwordexp->we_wordv;
1474 for (wordv += pwordexp->we_offs; *wordv; ++wordv)
1475 free (*wordv);
1477 free (pwordexp->we_wordv);
1478 pwordexp->we_wordv = NULL;
1483 * wordexp()
1487 wordexp (const char *words, wordexp_t *pwordexp, int flags)
1489 size_t wordv_offset;
1490 size_t words_offset;
1491 size_t word_length = 0;
1492 size_t max_length = 0;
1493 char *word = NULL;
1494 int error;
1495 char *ifs;
1496 char ifs_white[4];
1497 char **old_wordv = pwordexp->we_wordv;
1498 size_t old_wordc = pwordexp->we_wordc;
1500 if (flags & WRDE_REUSE)
1501 /* Minimal implementation of WRDE_REUSE for now */
1502 wordfree (pwordexp);
1504 if (flags & WRDE_DOOFFS)
1506 pwordexp->we_wordv = calloc (1 + pwordexp->we_offs, sizeof (char *));
1507 if (pwordexp->we_wordv == NULL)
1508 return WRDE_NOSPACE;
1510 else
1512 pwordexp->we_wordv = calloc (1, sizeof (char *));
1513 if (pwordexp->we_wordv == NULL)
1514 return WRDE_NOSPACE;
1516 pwordexp->we_offs = 0;
1519 if ((flags & WRDE_APPEND) == 0)
1520 pwordexp->we_wordc = 0;
1522 wordv_offset = pwordexp->we_offs + pwordexp->we_wordc;
1524 /* Find out what the field separators are.
1525 * There are two types: whitespace and non-whitespace.
1527 ifs = getenv ("IFS");
1529 if (!ifs)
1530 ifs = strcpy (ifs_white, " \t\n");
1531 else
1533 char *ifsch = ifs;
1534 char *whch = ifs_white;
1536 while (*ifsch != '\0')
1537 if ((*ifsch == ' ') || (*ifsch == '\t') || (*ifsch == '\n'))
1539 /* White space IFS. See first whether it is already in our
1540 collection. */
1541 char *runp = ifs_white;
1543 while (runp < whch && *runp != '\0' && *runp != *ifsch)
1544 ++runp;
1546 if (runp == whch)
1547 *whch++ = *ifsch;
1549 *whch = '\0';
1552 for (words_offset = 0 ; words[words_offset] ; ++words_offset)
1553 switch (words[words_offset])
1555 case '\n':
1556 case '|':
1557 case '&':
1558 case ';':
1559 case '<':
1560 case '>':
1561 case '(':
1562 case ')':
1563 case '}':
1564 /* Fail */
1565 wordfree (pwordexp);
1566 pwordexp->we_wordc = 0;
1567 pwordexp->we_wordv = old_wordv;
1568 return WRDE_BADCHAR;
1570 case '\\':
1571 error = parse_backslash (&word, &word_length, &max_length, words,
1572 &words_offset);
1574 if (error)
1575 goto do_error;
1577 break;
1579 case '$':
1580 error = parse_dollars (&word, &word_length, &max_length, words,
1581 &words_offset, flags, pwordexp);
1583 if (error)
1584 goto do_error;
1586 break;
1588 case '`':
1589 if (flags & WRDE_NOCMD)
1590 return WRDE_CMDSUB;
1592 ++words_offset;
1593 error = parse_backtick (&word, &word_length, &max_length, words,
1594 &words_offset, flags, pwordexp);
1596 if (error)
1597 goto do_error;
1599 break;
1601 case '"':
1602 ++words_offset;
1603 error = parse_dquote (&word, &word_length, &max_length, words,
1604 &words_offset, flags);
1606 if (error)
1607 goto do_error;
1609 break;
1611 case '\'':
1612 ++words_offset;
1613 error = parse_squote (&word, &word_length, &max_length, words,
1614 &words_offset);
1616 if (error)
1617 goto do_error;
1619 break;
1621 case '~':
1622 error = parse_tilde (&word, &word_length, &max_length, words,
1623 &words_offset, pwordexp->we_wordc);
1625 if (error)
1626 goto do_error;
1628 break;
1630 case '*':
1631 case '{':
1632 error = parse_glob (&word, &word_length, &max_length, words,
1633 &words_offset, flags, pwordexp, ifs);
1635 if (error)
1636 goto do_error;
1638 break;
1640 default:
1641 /* Is it a field separator? */
1642 if (strchr (ifs, words[words_offset]) == NULL)
1644 /* "Ordinary" character -- add it to word */
1646 word = w_addchar (word, &word_length, &max_length,
1647 words[words_offset]);
1648 if (word == NULL)
1650 error = WRDE_NOSPACE;
1651 goto do_error;
1654 break;
1657 /* Field separator */
1658 if (strchr (ifs_white, words[words_offset]))
1660 /* It's a whitespace IFS char. Ignore it at the beginning
1661 of a line and ignore multiple instances. */
1662 if (!word || !*word)
1663 break;
1665 if (w_addword (pwordexp, word) == WRDE_NOSPACE)
1667 error = WRDE_NOSPACE;
1668 goto do_error;
1671 word = NULL;
1672 word_length = 0;
1673 break;
1676 /* It's a non-whitespace IFS char */
1678 /* Multiple non-whitespace IFS chars are treated as one;
1679 * IS THIS CORRECT?
1681 if (word != NULL)
1683 if (w_addword (pwordexp, word) == WRDE_NOSPACE)
1685 error = WRDE_NOSPACE;
1686 goto do_error;
1690 word = NULL;
1691 word_length = 0;
1692 max_length = 0;
1695 /* End of string */
1697 /* There was a field separator at the end */
1698 if (word == NULL)
1699 return 0;
1701 /* There was no field separator at the end */
1702 return w_addword (pwordexp, word);
1704 do_error:
1705 /* Error:
1706 free memory used, set we_wordc and wd_wordv back to what they were.
1708 if (word != NULL)
1709 free (word);
1711 wordfree (pwordexp);
1712 pwordexp->we_wordv = old_wordv;
1713 pwordexp->we_wordc = old_wordc;
1714 return error;