1 /* POSIX.2 wordexp implementation.
2 Copyright (C) 1997, 1998 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. */
25 #include <sys/types.h>
30 #include <sys/types.h>
37 #include <sys/param.h>
41 #include <stdio-common/_itoa.h>
43 /* Undefine the following line for the production version. */
44 /* #define NDEBUG 1 */
48 * This is a recursive-descent-style word expansion routine.
51 /* These variables are defined and initialized in the startup code. */
52 extern int __libc_argc
;
53 extern char **__libc_argv
;
55 /* Some forward declarations */
56 static int parse_dollars (char **word
, size_t *word_length
, size_t *max_length
,
57 const char *words
, size_t *offset
, int flags
,
58 wordexp_t
*pwordexp
, const char *ifs
,
59 const char *ifs_white
, int quoted
, int *fsplit
)
61 static int parse_backtick (char **word
, size_t *word_length
,
62 size_t *max_length
, const char *words
,
63 size_t *offset
, int flags
, wordexp_t
*pwordexp
,
64 const char *ifs
, const char *ifs_white
)
66 static int parse_dquote (char **word
, size_t *word_length
, size_t *max_length
,
67 const char *words
, size_t *offset
, int flags
,
68 wordexp_t
*pwordexp
, const char *ifs
,
69 const char *ifs_white
)
71 static int eval_expr (char *expr
, long int *result
) internal_function
;
73 /* The w_*() functions manipulate word lists. */
77 /* Result of w_newword will be ignored if it the last word. */
79 w_newword (size_t *actlen
, size_t *maxlen
)
81 *actlen
= *maxlen
= 0;
86 w_addchar (char *buffer
, size_t *actlen
, size_t *maxlen
, char ch
)
87 /* (lengths exclude trailing zero) */
89 /* Add a character to the buffer, allocating room for it if needed.
92 if (*actlen
== *maxlen
)
94 char *old_buffer
= buffer
;
95 assert (buffer
== NULL
|| *maxlen
!= 0);
97 buffer
= realloc (buffer
, 1 + *maxlen
);
105 buffer
[*actlen
] = ch
;
106 buffer
[++(*actlen
)] = '\0';
114 w_addmem (char *buffer
, size_t *actlen
, size_t *maxlen
, const char *str
,
117 /* Add a string to the buffer, allocating room for it if needed.
119 if (*actlen
+ len
> *maxlen
)
121 char *old_buffer
= buffer
;
122 assert (buffer
== NULL
|| *maxlen
!= 0);
123 *maxlen
+= MAX (2 * len
, W_CHUNK
);
124 buffer
= realloc (old_buffer
, 1 + *maxlen
);
132 *((char *) __mempcpy (&buffer
[*actlen
], str
, len
)) = '\0';
141 w_addstr (char *buffer
, size_t *actlen
, size_t *maxlen
, const char *str
)
142 /* (lengths exclude trailing zero) */
144 /* Add a string to the buffer, allocating room for it if needed.
148 assert (str
!= NULL
); /* w_addstr only called from this file */
151 return w_addmem (buffer
, actlen
, maxlen
, str
, len
);
156 w_addword (wordexp_t
*pwordexp
, char *word
)
158 /* Add a word to the wordlist */
162 /* Internally, NULL acts like "". Convert NULLs to "" before
163 * the caller sees them.
167 word
= __strdup ("");
172 num_p
= 2 + pwordexp
->we_wordc
+ pwordexp
->we_offs
;
173 new_wordv
= realloc (pwordexp
->we_wordv
, sizeof (char *) * num_p
);
174 if (new_wordv
!= NULL
)
176 pwordexp
->we_wordv
= new_wordv
;
177 pwordexp
->we_wordv
[pwordexp
->we_wordc
++] = word
;
178 pwordexp
->we_wordv
[pwordexp
->we_wordc
] = NULL
;
188 field_split_word (char *word
, wordexp_t
*pwordexp
, const char *ifs
,
189 const char *ifs_white
)
193 char *field
= w_newword (&field_length
, &field_maxlen
);
194 char *field_begin
= word
;
195 int seen_nonws_ifs
= 0;
202 char *field_end
= field_begin
;
205 /* If this isn't the first field, start a new word */
206 if (field_begin
!= word
)
208 if (w_addword (pwordexp
, field
) == WRDE_NOSPACE
)
211 field
= w_newword (&field_length
, &field_maxlen
);
214 /* Skip IFS whitespace before the field */
215 field_begin
+= strspn (field_begin
, ifs_white
);
217 if (!seen_nonws_ifs
&& *field_begin
== 0)
218 /* Nothing but whitespace */
221 /* Search for the end of the field */
222 field_end
= field_begin
+ strcspn (field_begin
, ifs
);
224 /* Set up pointer to the character after end of field and
225 skip whitespace IFS after it. */
226 next_field
= field_end
+ strspn (field_end
, ifs_white
);
228 /* Skip at most one non-whitespace IFS character after the field */
230 if (*next_field
&& strchr (ifs
, *next_field
))
236 /* Null-terminate it */
239 /* Tag a copy onto the current word */
240 field
= w_addstr (field
, &field_length
, &field_maxlen
, field_begin
);
242 if (field
== NULL
&& *field_begin
!= '\0')
245 field_begin
= next_field
;
247 while (seen_nonws_ifs
|| *field_begin
);
249 if (field
&& w_addword (pwordexp
, field
))
258 /* The parse_*() functions should leave *offset being the offset in 'words'
259 * to the last character processed.
264 parse_backslash (char **word
, size_t *word_length
, size_t *max_length
,
265 const char *words
, size_t *offset
)
267 /* We are poised _at_ a backslash, not in quotes */
269 switch (words
[1 + *offset
])
272 /* Backslash is last character of input words */
280 *word
= w_addchar (*word
, word_length
, max_length
, words
[1 + *offset
]);
293 parse_qtd_backslash (char **word
, size_t *word_length
, size_t *max_length
,
294 const char *words
, size_t *offset
)
296 /* We are poised _at_ a backslash, inside quotes */
298 switch (words
[1 + *offset
])
301 /* Backslash is last character of input words */
312 *word
= w_addchar (*word
, word_length
, max_length
, words
[1 + *offset
]);
320 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
322 *word
= w_addchar (*word
, word_length
, max_length
, words
[1 + *offset
]);
336 parse_tilde (char **word
, size_t *word_length
, size_t *max_length
,
337 const char *words
, size_t *offset
, size_t wordc
)
339 /* We are poised _at_ a tilde */
342 if (*word_length
!= 0)
344 if (!((*word
)[*word_length
- 1] == '=' && wordc
== 0))
346 if (!((*word
)[*word_length
- 1] == ':'
347 && strchr (*word
, '=') && wordc
== 0))
349 *word
= w_addchar (*word
, word_length
, max_length
, '~');
350 return *word
? 0 : WRDE_NOSPACE
;
355 for (i
= 1 + *offset
; words
[i
]; i
++)
357 if (words
[i
] == ':' || words
[i
] == '/' || words
[i
] == ' ' ||
358 words
[i
] == '\t' || words
[i
] == 0 )
361 if (words
[i
] == '\\')
363 *word
= w_addchar (*word
, word_length
, max_length
, '~');
364 return *word
? 0 : WRDE_NOSPACE
;
368 if (i
== 1 + *offset
)
370 /* Tilde appears on its own */
372 struct passwd pwd
, *tpwd
;
374 char* buffer
= __alloca (buflen
);
379 while ((result
= __getpwuid_r (uid
, &pwd
, buffer
, buflen
, &tpwd
)) != 0
383 buffer
= __alloca (buflen
);
386 if (result
== 0 && pwd
.pw_dir
!= NULL
)
388 *word
= w_addstr (*word
, word_length
, max_length
, pwd
.pw_dir
);
394 *word
= w_addchar (*word
, word_length
, max_length
, '~');
401 /* Look up user name in database to get home directory */
402 char *user
= __strndup (&words
[1 + *offset
], i
- *offset
);
403 struct passwd pwd
, *tpwd
;
405 char* buffer
= __alloca (buflen
);
408 while ((result
= __getpwnam_r (user
, &pwd
, buffer
, buflen
, &tpwd
)) != 0
412 buffer
= __alloca (buflen
);
415 if (result
== 0 && pwd
.pw_dir
)
416 *word
= w_addstr (*word
, word_length
, max_length
, pwd
.pw_dir
);
419 /* (invalid login name) */
420 *word
= w_addchar (*word
, word_length
, max_length
, '~');
422 *word
= w_addstr (*word
, word_length
, max_length
, user
);
427 return *word
? 0 : WRDE_NOSPACE
;
433 do_parse_glob (const char *glob_word
, char **word
, size_t *word_length
,
434 size_t *max_length
, wordexp_t
*pwordexp
, const char *ifs
,
435 const char *ifs_white
)
441 error
= glob (glob_word
, GLOB_NOCHECK
, NULL
, &globbuf
);
445 /* We can only run into memory problems. */
446 assert (error
== GLOB_NOSPACE
);
452 /* No field splitting allowed. */
453 assert (globbuf
.gl_pathv
[0] != NULL
);
454 *word
= w_addstr (*word
, word_length
, max_length
, globbuf
.gl_pathv
[0]);
455 for (match
= 1; match
< globbuf
.gl_pathc
&& *word
!= NULL
; ++match
)
457 *word
= w_addchar (*word
, word_length
, max_length
, ' ');
459 *word
= w_addstr (*word
, word_length
, max_length
,
460 globbuf
.gl_pathv
[match
]);
464 return *word
? 0 : WRDE_NOSPACE
;
467 assert (ifs
== NULL
|| *ifs
!= '\0');
471 *word
= w_newword (word_length
, max_length
);
474 for (match
= 0; match
< globbuf
.gl_pathc
; ++match
)
476 char *matching_word
= __strdup (globbuf
.gl_pathv
[match
]);
477 if (matching_word
== NULL
|| w_addword (pwordexp
, matching_word
))
490 parse_glob (char **word
, size_t *word_length
, size_t *max_length
,
491 const char *words
, size_t *offset
, int flags
,
492 wordexp_t
*pwordexp
, const char *ifs
, const char *ifs_white
)
494 /* We are poised just after a '*', a '[' or a '?'. */
495 int error
= WRDE_NOSPACE
;
496 int quoted
= 0; /* 1 if singly-quoted, 2 if doubly */
498 wordexp_t glob_list
; /* List of words to glob */
501 glob_list
.we_wordc
= 0;
502 glob_list
.we_wordv
= NULL
;
503 glob_list
.we_offs
= 0;
504 for (; words
[*offset
] != '\0'; ++*offset
)
506 if (strchr (" \t\n", words
[*offset
]))
507 /* Reached end of word */
510 /* Sort out quoting */
511 if (words
[*offset
] == '\'')
518 else if (quoted
== 1)
524 else if (words
[*offset
] == '"')
531 else if (quoted
== 2)
538 /* Sort out other special characters */
539 if (quoted
!= 1 && words
[*offset
] == '$')
541 error
= parse_dollars (word
, word_length
, max_length
, words
,
542 offset
, flags
, &glob_list
, ifs
, ifs_white
,
543 quoted
== 2, &fieldsplit
);
549 else if (words
[*offset
] == '\\')
552 error
= parse_qtd_backslash (word
, word_length
, max_length
,
555 error
= parse_backslash (word
, word_length
, max_length
,
564 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
569 /* Don't forget to re-parse the character we stopped at. */
574 error
= field_split_word (*word
, &glob_list
, ifs
, ifs_white
);
579 error
= w_addword (&glob_list
, *word
);
582 *word
= w_newword (word_length
, max_length
);
583 for (i
= 0; error
== 0 && i
< glob_list
.we_wordc
; i
++)
584 error
= do_parse_glob (glob_list
.we_wordv
[i
], word
, word_length
,
585 max_length
, pwordexp
, ifs
, ifs_white
);
589 wordfree (&glob_list
);
595 parse_squote (char **word
, size_t *word_length
, size_t *max_length
,
596 const char *words
, size_t *offset
)
598 /* We are poised just after a single quote */
599 for (; words
[*offset
]; ++(*offset
))
601 if (words
[*offset
] != '\'')
603 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
610 /* Unterminated string */
614 /* Functions to evaluate an arithmetic expression */
617 eval_expr_val (char **expr
, long int *result
)
622 /* Skip white space */
623 for (digit
= *expr
; digit
&& *digit
&& isspace (*digit
); ++digit
);
629 /* Scan for closing paren */
630 for (++digit
; **expr
&& **expr
!= ')'; ++(*expr
));
638 if (eval_expr (digit
, result
))
643 case '+': /* Positive value */
647 case '-': /* Negative value */
653 if (!isdigit (*digit
))
658 for (; *digit
&& isdigit (*digit
); ++digit
)
659 *result
= (*result
* 10) + (*digit
- '0');
668 eval_expr_multdiv (char **expr
, long int *result
)
673 if (eval_expr_val (expr
, result
) != 0)
678 /* Skip white space */
679 for (; *expr
&& **expr
&& isspace (**expr
); ++(*expr
));
684 if (eval_expr_val (expr
, &arg
) != 0)
689 else if (**expr
== '/')
692 if (eval_expr_val (expr
, &arg
) != 0)
705 eval_expr (char *expr
, long int *result
)
710 if (eval_expr_multdiv (&expr
, result
) != 0)
715 /* Skip white space */
716 for (; expr
&& *expr
&& isspace (*expr
); ++expr
);
721 if (eval_expr_multdiv (&expr
, &arg
) != 0)
726 else if (*expr
== '-')
729 if (eval_expr_multdiv (&expr
, &arg
) != 0)
742 parse_arith (char **word
, size_t *word_length
, size_t *max_length
,
743 const char *words
, size_t *offset
, int flags
, int bracket
)
745 /* We are poised just after "$((" or "$[" */
752 expr
= w_newword (&expr_length
, &expr_maxlen
);
753 for (; words
[*offset
]; ++(*offset
))
755 switch (words
[*offset
])
758 error
= parse_dollars (&expr
, &expr_length
, &expr_maxlen
,
759 words
, offset
, flags
, NULL
, NULL
, NULL
, 1,
761 /* The ``1'' here is to tell parse_dollars not to
773 error
= parse_backtick (&expr
, &expr_length
, &expr_maxlen
,
774 words
, offset
, flags
, NULL
, NULL
, NULL
);
775 /* The first NULL here is to tell parse_backtick not to
786 error
= parse_qtd_backslash (&expr
, &expr_length
, &expr_maxlen
,
793 /* I think that a backslash within an
794 * arithmetic expansion is bound to
795 * cause an error sooner or later anyway though.
800 if (--paren_depth
== 0)
802 char result
[21]; /* 21 = ceil(log10(2^64)) + 1 */
803 long int numresult
= 0;
804 long long int convertme
;
806 if (bracket
|| words
[1 + *offset
] != ')')
815 if (*expr
&& eval_expr (expr
, &numresult
) != 0)
823 convertme
= -numresult
;
824 *word
= w_addchar (*word
, word_length
, max_length
, '-');
832 convertme
= numresult
;
835 *word
= w_addstr (*word
, word_length
, max_length
,
836 _itoa (convertme
, &result
[20], 10, 0));
838 return *word
? 0 : WRDE_NOSPACE
;
840 expr
= w_addchar (expr
, &expr_length
, &expr_maxlen
, words
[*offset
]);
847 if (bracket
&& paren_depth
== 1)
849 char result
[21]; /* 21 = ceil(log10(2^64)) + 1 */
850 long int numresult
= 0;
853 if (*expr
&& eval_expr (expr
, &numresult
) != 0)
860 *word
= w_addstr (*word
, word_length
, max_length
,
861 _itoa_word (numresult
, &result
[20], 10, 0));
863 return *word
? 0 : WRDE_NOSPACE
;
879 expr
= w_addchar (expr
, &expr_length
, &expr_maxlen
, words
[*offset
]);
890 /* Function to execute a command and retrieve the results */
891 /* pwordexp contains NULL if field-splitting is forbidden */
894 exec_comm (char *comm
, char **word
, size_t *word_length
, size_t *max_length
,
895 int flags
, wordexp_t
*pwordexp
, const char *ifs
,
896 const char *ifs_white
)
905 /* Don't fork() unless necessary */
913 if ((pid
= __fork ()) < 0)
924 const char *args
[4] = { _PATH_BSHELL
, "-c", comm
, NULL
};
926 /* Redirect output. */
927 __dup2 (fildes
[1], 1);
930 /* Redirect stderr to /dev/null if we have to. */
931 if ((flags
& WRDE_SHOWERR
) == 0)
935 fd
= __open (_PATH_DEVNULL
, O_WRONLY
);
936 if (fd
>= 0 && fd
!= 2)
944 __execve (_PATH_BSHELL
, (char *const *) args
, __environ
);
953 buffer
= __alloca (bufsize
);
955 /* Read fildes[0] and put it into a word. */
958 if ((buflen
= __read (fildes
[0], buffer
, bufsize
)) < 1)
960 if (__waitpid (pid
, NULL
, WNOHANG
) == 0)
962 if ((buflen
= __read (fildes
[0], buffer
, bufsize
)) < 1)
966 *word
= w_addmem (*word
, word_length
, max_length
, buffer
, buflen
);
971 /* Bash chops off trailing newlines, which seems sensible. */
972 while (*word_length
> 0 && (*word
)[*word_length
- 1] == '\n')
974 (*word
)[--*word_length
] = '\0';
976 /* If the last word was entirely newlines, turn it into a new word
977 * which can be ignored if there's nothing following it. */
978 if (*word_length
== 0)
981 *word
= w_newword (word_length
, max_length
);
990 __kill (pid
, SIGKILL
);
991 __waitpid (pid
, NULL
, 0);
998 parse_comm (char **word
, size_t *word_length
, size_t *max_length
,
999 const char *words
, size_t *offset
, int flags
, wordexp_t
*pwordexp
,
1000 const char *ifs
, const char *ifs_white
)
1002 /* We are poised just after "$(" */
1003 int paren_depth
= 1;
1005 int quoted
= 0; /* 1 for singly-quoted, 2 for doubly-quoted */
1008 char *comm
= w_newword (&comm_length
, &comm_maxlen
);
1010 for (; words
[*offset
]; ++(*offset
))
1012 switch (words
[*offset
])
1017 else if (quoted
== 1)
1025 else if (quoted
== 2)
1031 if (!quoted
&& --paren_depth
== 0)
1033 /* Go -- give script to the shell */
1036 error
= exec_comm (comm
, word
, word_length
, max_length
,
1037 flags
, pwordexp
, ifs
, ifs_white
);
1044 /* This is just part of the script */
1052 comm
= w_addchar (comm
, &comm_length
, &comm_maxlen
, words
[*offset
]);
1054 return WRDE_NOSPACE
;
1066 parse_param (char **word
, size_t *word_length
, size_t *max_length
,
1067 const char *words
, size_t *offset
, int flags
, wordexp_t
*pwordexp
,
1068 const char *ifs
, const char *ifs_white
, int quoted
)
1070 /* We are poised just after "$" */
1074 ACT_RP_SHORT_LEFT
= '#',
1075 ACT_RP_LONG_LEFT
= 'L',
1076 ACT_RP_SHORT_RIGHT
= '%',
1077 ACT_RP_LONG_RIGHT
= 'R',
1078 ACT_NULL_ERROR
= '?',
1079 ACT_NULL_SUBST
= '-',
1080 ACT_NONNULL_SUBST
= '+',
1081 ACT_NULL_ASSIGN
= '='
1087 size_t start
= *offset
;
1091 enum action action
= ACT_NONE
;
1096 int pattern_is_quoted
= 0; /* 1 for singly-quoted, 2 for doubly-quoted */
1100 int brace
= words
[*offset
] == '{';
1102 env
= w_newword (&env_length
, &env_maxlen
);
1103 pattern
= w_newword (&pat_length
, &pat_maxlen
);
1108 /* First collect the parameter name. */
1110 if (words
[*offset
] == '#')
1118 if (isalpha (words
[*offset
]) || words
[*offset
] == '_')
1120 /* Normal parameter name. */
1123 env
= w_addchar (env
, &env_length
, &env_maxlen
,
1128 while (isalnum (words
[++*offset
]) || words
[*offset
] == '_');
1130 else if (isdigit (words
[*offset
]))
1132 /* Numeric parameter name. */
1136 env
= w_addchar (env
, &env_length
, &env_maxlen
,
1143 while (isdigit(words
[++*offset
]));
1145 else if (strchr ("*@$", words
[*offset
]) != NULL
)
1147 /* Special parameter. */
1149 env
= w_addchar (env
, &env_length
, &env_maxlen
,
1163 /* Check for special action to be applied to the value. */
1164 switch (words
[*offset
])
1171 action
= ACT_RP_SHORT_LEFT
;
1172 if (words
[1 + *offset
] == '#')
1175 action
= ACT_RP_LONG_LEFT
;
1180 action
= ACT_RP_SHORT_RIGHT
;
1181 if (words
[1 + *offset
] == '%')
1184 action
= ACT_RP_LONG_RIGHT
;
1189 if (strchr ("-=?+", words
[1 + *offset
]) == NULL
)
1193 action
= words
[++*offset
];
1200 action
= words
[*offset
];
1207 /* Now collect the pattern. */
1209 for (; words
[*offset
]; ++(*offset
))
1211 switch (words
[*offset
])
1214 if (!pattern_is_quoted
)
1219 if (!pattern_is_quoted
)
1228 if (!pattern_is_quoted
&& words
[++*offset
] == '\0')
1233 if (pattern_is_quoted
== 0)
1234 pattern_is_quoted
= 1;
1235 else if (pattern_is_quoted
== 1)
1236 pattern_is_quoted
= 0;
1241 if (pattern_is_quoted
== 0)
1242 pattern_is_quoted
= 2;
1243 else if (pattern_is_quoted
== 2)
1244 pattern_is_quoted
= 0;
1249 pattern
= w_addchar (pattern
, &pat_length
, &pat_maxlen
,
1251 if (pattern
== NULL
)
1256 /* End of input string -- remember to reparse the character that we
1261 if (words
[start
] == '{' && words
[*offset
] != '}')
1268 /* $# expands to the number of positional parameters */
1270 value
= _itoa_word (__libc_argc
- 1, &buffer
[20], 10, 0);
1275 /* Just $ on its own */
1276 *offset
= start
- 1;
1277 *word
= w_addchar (*word
, word_length
, max_length
, '$');
1278 return *word
? 0 : WRDE_NOSPACE
;
1281 /* Is it a numeric parameter? */
1282 else if (isdigit (env
[0]))
1286 if (n
>= __libc_argc
)
1287 /* Substitute NULL. */
1290 /* Replace with appropriate positional parameter. */
1291 value
= __libc_argv
[n
];
1293 /* Is it a special parameter? */
1300 value
= _itoa_word (__getpid (), &buffer
[20], 10, 0);
1302 /* Is it `${#*}' or `${#@}'? */
1303 else if ((*env
== '*' || *env
== '@') && seen_hash
)
1306 value
= _itoa_word (__libc_argc
> 0 ? __libc_argc
- 1 : 0,
1307 &buffer
[20], 10, 0);
1308 *word
= w_addstr (*word
, word_length
, max_length
, value
);
1312 return *word
? 0 : WRDE_NOSPACE
;
1314 /* Is it `$*' or `$@' (unquoted) ? */
1315 else if (*env
== '*' || (*env
== '@' && !quoted
))
1317 size_t plist_len
= 0;
1321 /* Build up value parameter by parameter (copy them) */
1322 for (p
= 1; __libc_argv
[p
]; ++p
)
1323 plist_len
+= strlen (__libc_argv
[p
]) + 1; /* for space */
1324 value
= malloc (plist_len
);
1329 for (p
= 1; __libc_argv
[p
]; ++p
)
1333 end
= __stpcpy (end
, __libc_argv
[p
]);
1340 /* Must be a quoted `$@' */
1341 assert (*env
== '@' && quoted
);
1343 /* Each parameter is a separate word ("$@") */
1344 if (__libc_argc
== 2)
1345 value
= __libc_argv
[1];
1346 else if (__libc_argc
> 2)
1350 /* Append first parameter to current word. */
1351 value
= w_addstr (*word
, word_length
, max_length
,
1353 if (value
== NULL
|| w_addword (pwordexp
, value
))
1356 for (p
= 2; __libc_argv
[p
+ 1]; p
++)
1358 char *newword
= __strdup (__libc_argv
[p
]);
1359 if (newword
== NULL
|| w_addword (pwordexp
, newword
))
1363 /* Start a new word with the last parameter. */
1364 *word
= w_newword (word_length
, max_length
);
1365 value
= __libc_argv
[p
];
1376 value
= getenv (env
);
1378 if (value
== NULL
&& (flags
& WRDE_UNDEF
))
1380 /* Variable not defined. */
1381 error
= WRDE_BADVAL
;
1385 if (action
!= ACT_NONE
)
1389 case ACT_RP_SHORT_LEFT
:
1390 case ACT_RP_LONG_LEFT
:
1391 case ACT_RP_SHORT_RIGHT
:
1392 case ACT_RP_LONG_RIGHT
:
1398 if (value
== NULL
|| pattern
== NULL
|| *pattern
== '\0')
1401 end
= value
+ strlen (value
);
1405 case ACT_RP_SHORT_LEFT
:
1406 for (p
= value
; p
<= end
; ++p
)
1410 if (fnmatch (pattern
, value
, 0) != FNM_NOMATCH
)
1415 char *newval
= __strdup (p
);
1433 case ACT_RP_LONG_LEFT
:
1434 for (p
= end
; p
>= value
; --p
)
1438 if (fnmatch (pattern
, value
, 0) != FNM_NOMATCH
)
1443 char *newval
= __strdup (p
);
1461 case ACT_RP_SHORT_RIGHT
:
1462 for (p
= end
; p
>= value
; --p
)
1464 if (fnmatch (pattern
, p
, 0) != FNM_NOMATCH
)
1467 newval
= malloc (p
- value
+ 1);
1476 *(char *) __mempcpy (newval
, value
, p
- value
) = '\0';
1487 case ACT_RP_LONG_RIGHT
:
1488 for (p
= value
; p
<= end
; ++p
)
1490 if (fnmatch (pattern
, p
, 0) != FNM_NOMATCH
)
1493 newval
= malloc (p
- value
+ 1);
1502 *(char *) __mempcpy (newval
, value
, p
- value
) = '\0';
1520 case ACT_NULL_ERROR
:
1521 if (value
&& *value
)
1522 /* Substitute parameter */
1525 if (!colon_seen
&& value
)
1526 /* Substitute NULL */
1530 /* Expand 'pattern' and write it to stderr */
1533 error
= wordexp (pattern
, &we
, flags
);
1539 fprintf (stderr
, "%s:", env
);
1541 for (i
= 0; i
< we
.we_wordc
; ++i
)
1543 fprintf (stderr
, " %s", we
.we_wordv
[i
]);
1546 fprintf (stderr
, "\n");
1547 error
= WRDE_BADVAL
;
1554 fprintf (stderr
, "%s: parameter null or not set\n", env
);
1555 error
= WRDE_BADVAL
;
1562 case ACT_NULL_SUBST
:
1563 if (value
&& *value
)
1564 /* Substitute parameter */
1567 if (!colon_seen
&& value
)
1569 /* Substitute NULL */
1577 /* Substitute word */
1586 /* No field-splitting is allowed, so imagine
1587 quotes around the word. */
1588 char *qtd_pattern
= malloc (3 + strlen (pattern
));
1590 sprintf (qtd_pattern
, "\"%s\"", pattern
);
1592 pattern
= qtd_pattern
;
1595 if (pattern
== NULL
&& (pattern
= __strdup ("")) == NULL
)
1598 error
= wordexp (pattern
, &we
, flags
);
1602 /* Fingers crossed that the quotes worked.. */
1603 assert (!quoted
|| we
.we_wordc
== 1);
1606 for (i
= 0; i
< we
.we_wordc
; ++i
)
1607 if ((error
= w_addword (pwordexp
, __strdup (we
.we_wordv
[i
])))
1611 if (i
< we
.we_wordc
)
1613 /* Ran out of space */
1618 if (action
== ACT_NULL_ASSIGN
)
1622 size_t words_size
= 0;
1625 /* Cannot assign special parameters. */
1628 for (i
= 0; i
< we
.we_wordc
; i
++)
1629 words_size
+= strlen (we
.we_wordv
[i
]) + 1; /* for <space> */
1632 cp
= words
= __alloca (words_size
);
1634 for (i
= 0; i
< we
.we_wordc
- 1; i
++)
1636 cp
= __stpcpy (cp
, we
.we_wordv
[i
]);
1640 strcpy (cp
, we
.we_wordv
[i
]);
1643 setenv (env
, words
, 1);
1650 case ACT_NONNULL_SUBST
:
1651 if (value
&& *value
)
1654 if (!colon_seen
&& value
)
1657 /* Substitute NULL */
1662 case ACT_NULL_ASSIGN
:
1663 if (value
&& *value
)
1664 /* Substitute parameter */
1667 if (!colon_seen
&& value
)
1669 /* Substitute NULL */
1675 /* This checks for '=' so it knows to assign */
1679 assert (! "Unrecognised action!");
1683 free (env
); env
= NULL
;
1684 free (pattern
); pattern
= NULL
;
1688 char param_length
[21];
1689 param_length
[20] = '\0';
1690 *word
= w_addstr (*word
, word_length
, max_length
,
1691 _itoa_word (value
? strlen (value
) : 0,
1692 ¶m_length
[20], 10, 0));
1695 assert (value
!= NULL
);
1699 return *word
? 0 : WRDE_NOSPACE
;
1705 *word
= w_addstr (*word
, word_length
, max_length
, value
);
1709 return *word
? 0 : WRDE_NOSPACE
;
1716 error
= WRDE_NOSPACE
;
1720 error
= WRDE_SYNTAX
;
1734 parse_dollars (char **word
, size_t *word_length
, size_t *max_length
,
1735 const char *words
, size_t *offset
, int flags
,
1736 wordexp_t
*pwordexp
, const char *ifs
, const char *ifs_white
,
1737 int quoted
, int *fsplit
)
1739 /* We are poised _at_ "$" */
1740 switch (words
[1 + *offset
])
1745 *word
= w_addchar (*word
, word_length
, max_length
, '$');
1746 return *word
? 0 : WRDE_NOSPACE
;
1749 if (words
[2 + *offset
] == '(')
1751 /* Differentiate between $((1+3)) and $((echo);(ls)) */
1752 int i
= 3 + *offset
;
1754 while (words
[i
] && !(depth
== 0 && words
[i
] == ')'))
1756 if (words
[i
] == '(')
1758 else if (words
[i
] == ')')
1764 if (words
[i
] == ')' && words
[i
+ 1] == ')')
1768 /* This word is subject to field-splitting as long as
1769 * it isn't quoted. */
1773 /* Call parse_arith -- 0 is for "no brackets" */
1774 return parse_arith (word
, word_length
, max_length
, words
, offset
,
1779 if (flags
& WRDE_NOCMD
)
1784 /* This word is subject to field-splitting as long as
1785 * it isn't quoted. */
1789 return parse_comm (word
, word_length
, max_length
, words
, offset
, flags
,
1790 quoted
? NULL
: pwordexp
, ifs
, ifs_white
);
1795 /* This word is subject to field-splitting as long as
1796 * it isn't quoted. */
1800 /* Call parse_arith -- 1 is for "brackets" */
1801 return parse_arith (word
, word_length
, max_length
, words
, offset
, flags
,
1806 ++(*offset
); /* parse_param needs to know if "{" is there */
1808 /* This word is subject to field-splitting as long as
1809 * it isn't quoted. */
1813 return parse_param (word
, word_length
, max_length
, words
, offset
, flags
,
1814 pwordexp
, ifs
, ifs_white
, quoted
);
1819 parse_backtick (char **word
, size_t *word_length
, size_t *max_length
,
1820 const char *words
, size_t *offset
, int flags
,
1821 wordexp_t
*pwordexp
, const char *ifs
, const char *ifs_white
)
1823 /* We are poised just after "`" */
1828 char *comm
= w_newword (&comm_length
, &comm_maxlen
);
1830 for (; words
[*offset
]; ++(*offset
))
1832 switch (words
[*offset
])
1835 /* Go -- give the script to the shell */
1836 error
= exec_comm (comm
, word
, word_length
, max_length
, flags
,
1837 pwordexp
, ifs
, ifs_white
);
1844 error
= parse_qtd_backslash (&comm
, &comm_length
, &comm_maxlen
,
1857 error
= parse_backslash (&comm
, &comm_length
, &comm_maxlen
, words
,
1869 squoting
= 1 - squoting
;
1871 comm
= w_addchar (comm
, &comm_length
, &comm_maxlen
, words
[*offset
]);
1873 return WRDE_NOSPACE
;
1884 parse_dquote (char **word
, size_t *word_length
, size_t *max_length
,
1885 const char *words
, size_t *offset
, int flags
,
1886 wordexp_t
*pwordexp
, const char * ifs
, const char * ifs_white
)
1888 /* We are poised just after a double-quote */
1891 for (; words
[*offset
]; ++(*offset
))
1893 switch (words
[*offset
])
1899 error
= parse_dollars (word
, word_length
, max_length
, words
, offset
,
1900 flags
, pwordexp
, ifs
, ifs_white
, 1, NULL
);
1901 /* The ``1'' here is to tell parse_dollars not to
1902 * split the fields. It may need to, however ("$@").
1910 if (flags
& WRDE_NOCMD
)
1914 error
= parse_backtick (word
, word_length
, max_length
, words
,
1915 offset
, flags
, NULL
, NULL
, NULL
);
1916 /* The first NULL here is to tell parse_backtick not to
1925 error
= parse_qtd_backslash (word
, word_length
, max_length
, words
,
1934 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
1936 return WRDE_NOSPACE
;
1940 /* Unterminated string */
1945 * wordfree() is to be called after pwordexp is finished with.
1949 wordfree (wordexp_t
*pwordexp
)
1952 /* wordexp can set pwordexp to NULL */
1953 if (pwordexp
&& pwordexp
->we_wordv
)
1955 char **wordv
= pwordexp
->we_wordv
;
1957 for (wordv
+= pwordexp
->we_offs
; *wordv
; ++wordv
)
1960 free (pwordexp
->we_wordv
);
1961 pwordexp
->we_wordv
= NULL
;
1970 wordexp (const char *words
, wordexp_t
*pwordexp
, int flags
)
1972 size_t wordv_offset
;
1973 size_t words_offset
;
1976 char *word
= w_newword (&word_length
, &max_length
);
1980 char **old_wordv
= pwordexp
->we_wordv
;
1981 size_t old_wordc
= (flags
& WRDE_REUSE
) ? pwordexp
->we_wordc
: 0;
1982 int fieldsplit_this_word
= 0;
1984 if (flags
& WRDE_REUSE
)
1986 /* Minimal implementation of WRDE_REUSE for now */
1987 wordfree (pwordexp
);
1991 if (flags
& WRDE_DOOFFS
)
1993 pwordexp
->we_wordv
= calloc (1 + pwordexp
->we_offs
, sizeof (char *));
1994 if (pwordexp
->we_wordv
== NULL
)
1996 error
= WRDE_NOSPACE
;
2002 pwordexp
->we_wordv
= calloc (1, sizeof (char *));
2003 if (pwordexp
->we_wordv
== NULL
)
2005 error
= WRDE_NOSPACE
;
2009 pwordexp
->we_offs
= 0;
2012 if ((flags
& WRDE_APPEND
) == 0)
2013 pwordexp
->we_wordc
= 0;
2015 wordv_offset
= pwordexp
->we_offs
+ pwordexp
->we_wordc
;
2017 /* Find out what the field separators are.
2018 * There are two types: whitespace and non-whitespace.
2020 ifs
= getenv ("IFS");
2023 /* IFS unset - use <space><tab><newline>. */
2024 ifs
= strcpy (ifs_white
, " \t\n");
2028 char *whch
= ifs_white
;
2030 /* Start off with no whitespace IFS characters */
2031 ifs_white
[0] = '\0';
2033 while (*ifsch
!= '\0')
2035 if ((*ifsch
== ' ') || (*ifsch
== '\t') || (*ifsch
== '\n'))
2037 /* Whitespace IFS. See first whether it is already in our
2039 char *runp
= ifs_white
;
2041 while (runp
< whch
&& *runp
!= '\0' && *runp
!= *ifsch
)
2053 fieldsplit_this_word
= 0;
2054 for (words_offset
= 0 ; ; ++words_offset
)
2055 switch (words
[words_offset
])
2058 error
= parse_backslash (&word
, &word_length
, &max_length
, words
,
2067 error
= parse_dollars (&word
, &word_length
, &max_length
, words
,
2068 &words_offset
, flags
, pwordexp
, ifs
, ifs_white
,
2069 0, &fieldsplit_this_word
);
2077 if (flags
& WRDE_NOCMD
)
2079 error
= WRDE_CMDSUB
;
2084 error
= parse_backtick (&word
, &word_length
, &max_length
, words
,
2085 &words_offset
, flags
, pwordexp
, ifs
,
2091 fieldsplit_this_word
= 1;
2097 error
= parse_dquote (&word
, &word_length
, &max_length
, words
,
2098 &words_offset
, flags
, pwordexp
, ifs
, ifs_white
);
2107 error
= parse_squote (&word
, &word_length
, &max_length
, words
,
2116 error
= parse_tilde (&word
, &word_length
, &max_length
, words
,
2117 &words_offset
, pwordexp
->we_wordc
);
2127 error
= parse_glob (&word
, &word_length
, &max_length
, words
,
2128 &words_offset
, flags
, pwordexp
, ifs
, ifs_white
);
2136 /* Is it a word separator? */
2137 if (words
[words_offset
] != '\0' &&
2138 strchr (" \t", words
[words_offset
]) == NULL
)
2140 char ch
= words
[words_offset
];
2142 /* Not a word separator -- but is it a valid word char? */
2143 if (strchr ("\n|&;<>(){}", ch
))
2146 wordfree (pwordexp
);
2147 pwordexp
->we_wordc
= 0;
2148 pwordexp
->we_wordv
= old_wordv
;
2149 return WRDE_BADCHAR
;
2152 /* "Ordinary" character -- add it to word */
2153 word
= w_addchar (word
, &word_length
, &max_length
,
2157 error
= WRDE_NOSPACE
;
2164 /* If a word has been delimited, add it to the list. */
2167 if (fieldsplit_this_word
)
2169 error
= field_split_word (word
, pwordexp
, ifs
, ifs_white
);
2173 error
= w_addword (pwordexp
, word
);
2179 fieldsplit_this_word
= 0;
2181 if (words
[words_offset
] == '\0')
2182 /* End of string. */
2185 word
= w_newword (&word_length
, &max_length
);
2193 * free memory used (unless error is WRDE_NOSPACE), and
2194 * set we_wordc and wd_wordv back to what they were.
2200 if (error
== WRDE_NOSPACE
)
2201 return WRDE_NOSPACE
;
2203 wordfree (pwordexp
);
2204 pwordexp
->we_wordv
= old_wordv
;
2205 pwordexp
->we_wordc
= old_wordc
;