#if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS
/* Subroutines for copying $(...) and `...` things */
-static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
/* '...' */
static int add_till_single_quote(o_string *dest, struct in_str *input)
{
o_addchr(dest, ch);
}
}
+static int add_till_single_quote_dquoted(o_string *dest, struct in_str *input)
+{
+ while (1) {
+ int ch = i_getch(input);
+ if (ch == EOF) {
+ syntax_error_unterm_ch('\'');
+ return 0;
+ }
+ if (ch == '\'')
+ return 1;
+ o_addqchr(dest, ch);
+ }
+}
/* "...\"...`..`...." - do we need to handle "...$(..)..." too? */
+static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
static int add_till_double_quote(o_string *dest, struct in_str *input)
{
while (1) {
#if ENABLE_HUSH_TICK
static int process_command_subs(o_string *dest, const char *s);
#endif
+static int expand_vars_to_list(o_string *output, int n, char *arg);
/* expand_strvec_to_strvec() takes a list of strings, expands
* all variable references within and returns a pointer to
return exp_str;
}
+/* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}.
+ * These can contain single- and double-quoted strings,
+ * and treated as if the ARG string is initially unquoted. IOW:
+ * ${var#ARG} and "${var#ARG}" treat ARG the same (ARG can even be
+ * a dquoted string: "${var#"zz"}"), the difference only comes later
+ * (word splitting and globbing of the ${var...} result).
+ */
#if !BASH_PATTERN_SUBST
#define encode_then_expand_vararg(str, handle_squotes, do_unbackslash) \
encode_then_expand_vararg(str, handle_squotes)
cp++;
}
- /* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}.
- * These can contain single- and double-quoted strings,
- * and treated as if the ARG string is initially unquoted. IOW:
- * ${var#ARG} and "${var#ARG}" treat ARG the same (ARG can even be
- * a dquoted string: "${var#"zz"}"), the difference only comes later
- * (word splitting and globbing of the ${var...} result).
- */
-
setup_string_in_str(&input, str);
dest.data = xzalloc(1); /* start as "", not as NULL */
exp_str = NULL;
int ch;
ch = i_getch(&input);
- if (ch == EOF) {
- if (dest.o_expflags) { /* EXP_FLAG_ESC_GLOB_CHARS set? */
- syntax_error_unterm_ch('"');
- goto ret; /* error */
- }
- break;
- }
debug_printf_parse("%s: ch=%c (%d) escape=%d\n",
__func__, ch, ch, !!dest.o_expflags);
- if (ch == '\'' && handle_squotes && !dest.o_expflags) {
-//quoting version of add_till_single_quote() (try to merge?):
- for (;;) {
- ch = i_getch(&input);
- if (ch == EOF) {
- syntax_error_unterm_ch('\'');
+
+ if (!dest.o_expflags) {
+ if (ch == EOF)
+ break;
+ if (handle_squotes && ch == '\'') {
+ if (!add_till_single_quote_dquoted(&dest, &input))
goto ret; /* error */
- }
- if (ch == '\'')
- break;
- o_addqchr(&dest, ch);
+ continue;
}
- continue;
+ }
+ if (ch == EOF) {
+ syntax_error_unterm_ch('"');
+ goto ret; /* error */
}
if (ch == '"') {
dest.o_expflags ^= EXP_FLAG_ESC_GLOB_CHARS;
return exp_str;
}
-static int expand_vars_to_list(o_string *output, int n, char *arg);
-
+/* Expanding ARG in ${var+ARG}, ${var-ARG}
+ */
static int encode_then_append_var_plusminus(o_string *output, int n,
const char *str, int dquoted)
{
}
#endif
- /* Expanding ARG in ${var+ARG}, ${var-ARG} */
-
setup_string_in_str(&input, str);
for (;;) {
continue;
}
if (!dquoted && ch == '\'') {
-//quoting version of add_till_single_quote() (try to merge?):
- for (;;) {
- ch = i_getch(&input);
- if (ch == EOF) {
- syntax_error_unterm_ch('\'');
- goto ret; /* error */
- }
- if (ch == '\'')
- break;
- o_addqchr(&dest, ch);
- }
+ if (!add_till_single_quote_dquoted(&dest, &input))
+ goto ret; /* error */
o_addchr(&dest, SPECIAL_VAR_SYMBOL);
o_addchr(&dest, SPECIAL_VAR_SYMBOL);
continue;
return n;
}
-/* Helper:
- * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
+/* Handle <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
*/
-static NOINLINE int expand_one_var(o_string *output,
- int n, int first_ch, char *arg, char **pp)
+static NOINLINE int expand_one_var(o_string *output, int n,
+ int first_ch, char *arg, char **pp)
{
const char *val;
char *to_be_freed;
* $ x=; f "${x:='x y' z}"
* |'x y' z|
*
- * $ x=x; f ${x:+'x y' z}|
+ * $ x=x; f ${x:+'x y' z}
* |x y|
* |z|
* $ x=x; f "${x:+'x y' z}"
arg = ++p;
} /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
- if (arg[0]) {
+ if (*arg) {
+ /* handle trailing string */
if (output->ended_in_ifs) {
o_addchr(output, '\0');
n = o_save_ptr(output, n);