diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-04-07 06:03:22 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-04-07 06:03:22 +0000 |
commit | a4f331d3c3ea5b358613992a48556cc9cbfdf139 (patch) | |
tree | 316143ec21a1efd2eb7e135121134c0b8b86221e /shell/hush.c | |
parent | 6c9be7f4518bf5594f5b9aaf981ed5dcc4a6939c (diff) | |
download | busybox-w32-a4f331d3c3ea5b358613992a48556cc9cbfdf139.tar.gz busybox-w32-a4f331d3c3ea5b358613992a48556cc9cbfdf139.tar.bz2 busybox-w32-a4f331d3c3ea5b358613992a48556cc9cbfdf139.zip |
implement support for parameter substitution via #/% operators
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 65 |
1 files changed, 41 insertions, 24 deletions
diff --git a/shell/hush.c b/shell/hush.c index 792886944..1740187d4 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -43,7 +43,6 @@ | |||
43 | * Here Documents ( << word ) | 43 | * Here Documents ( << word ) |
44 | * Functions | 44 | * Functions |
45 | * Tilde Expansion | 45 | * Tilde Expansion |
46 | * Parameter Expansion for substring processing ${var#word} ${var%word} | ||
47 | * | 46 | * |
48 | * Bash stuff (maybe optionally enable?): | 47 | * Bash stuff (maybe optionally enable?): |
49 | * &> and >& redirection of stdout+stderr | 48 | * &> and >& redirection of stdout+stderr |
@@ -76,6 +75,7 @@ | |||
76 | #include <fnmatch.h> | 75 | #include <fnmatch.h> |
77 | #endif | 76 | #endif |
78 | #include "math.h" | 77 | #include "math.h" |
78 | #include "match.h" | ||
79 | 79 | ||
80 | #ifdef WANT_TO_TEST_NOMMU | 80 | #ifdef WANT_TO_TEST_NOMMU |
81 | # undef BB_MMU | 81 | # undef BB_MMU |
@@ -1667,8 +1667,9 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
1667 | char first_ch, ored_ch; | 1667 | char first_ch, ored_ch; |
1668 | int i; | 1668 | int i; |
1669 | const char *val; | 1669 | const char *val; |
1670 | char *p; | 1670 | char *dyn_val, *p; |
1671 | 1671 | ||
1672 | dyn_val = NULL; | ||
1672 | ored_ch = 0; | 1673 | ored_ch = 0; |
1673 | 1674 | ||
1674 | debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg); | 1675 | debug_printf_expand("expand_vars_to_list: arg '%s'\n", arg); |
@@ -1844,7 +1845,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
1844 | ++var; | 1845 | ++var; |
1845 | } else { | 1846 | } else { |
1846 | /* maybe handle parameter expansion */ | 1847 | /* maybe handle parameter expansion */ |
1847 | exp_off = strcspn(var, ":-=+?"); | 1848 | exp_off = strcspn(var, ":-=+?%#"); |
1848 | if (!var[exp_off]) | 1849 | if (!var[exp_off]) |
1849 | exp_off = 0; | 1850 | exp_off = 0; |
1850 | if (exp_off) { | 1851 | if (exp_off) { |
@@ -1873,29 +1874,45 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
1873 | val = utoa(val ? strlen(val) : 0); | 1874 | val = utoa(val ? strlen(val) : 0); |
1874 | debug_printf_expand("%s\n", val); | 1875 | debug_printf_expand("%s\n", val); |
1875 | } else if (exp_off) { | 1876 | } else if (exp_off) { |
1876 | /* we need to do an expansion */ | 1877 | if (exp_op == '%' || exp_op == '#') { |
1877 | int exp_test = (!val || (exp_null && !val[0])); | 1878 | /* we need to do a pattern match */ |
1878 | if (exp_op == '+') | 1879 | bool zero; |
1879 | exp_test = !exp_test; | 1880 | char *loc; |
1880 | debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, | 1881 | scan_t scan = pick_scan(exp_op, *exp_word, &zero); |
1881 | exp_null ? "true" : "false", exp_test); | 1882 | if (exp_op == *exp_word) /* ## or %% */ |
1882 | if (exp_test) { | 1883 | ++exp_word; |
1883 | if (exp_op == '?') | 1884 | val = dyn_val = xstrdup(val); |
1884 | maybe_die(var, *exp_word ? exp_word : "parameter null or not set"); | 1885 | loc = scan(dyn_val, exp_word, zero); |
1886 | if (zero) | ||
1887 | val = loc; | ||
1885 | else | 1888 | else |
1886 | val = exp_word; | 1889 | *loc = '\0'; |
1887 | 1890 | } else { | |
1888 | if (exp_op == '=') { | 1891 | /* we need to do an expansion */ |
1889 | if (isdigit(var[0]) || var[0] == '#') { | 1892 | int exp_test = (!val || (exp_null && !val[0])); |
1890 | maybe_die(var, "special vars cannot assign in this way"); | 1893 | if (exp_op == '+') |
1891 | val = NULL; | 1894 | exp_test = !exp_test; |
1892 | } else { | 1895 | debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, |
1893 | char *new_var = xmalloc(strlen(var) + strlen(val) + 2); | 1896 | exp_null ? "true" : "false", exp_test); |
1894 | sprintf(new_var, "%s=%s", var, val); | 1897 | if (exp_test) { |
1895 | set_local_var(new_var, -1, 0); | 1898 | if (exp_op == '?') |
1899 | maybe_die(var, *exp_word ? exp_word : "parameter null or not set"); | ||
1900 | else | ||
1901 | val = exp_word; | ||
1902 | |||
1903 | if (exp_op == '=') { | ||
1904 | if (isdigit(var[0]) || var[0] == '#') { | ||
1905 | maybe_die(var, "special vars cannot assign in this way"); | ||
1906 | val = NULL; | ||
1907 | } else { | ||
1908 | char *new_var = xmalloc(strlen(var) + strlen(val) + 2); | ||
1909 | sprintf(new_var, "%s=%s", var, val); | ||
1910 | set_local_var(new_var, -1, 0); | ||
1911 | } | ||
1896 | } | 1912 | } |
1897 | } | 1913 | } |
1898 | } | 1914 | } |
1915 | |||
1899 | var[exp_off] = exp_save; | 1916 | var[exp_off] = exp_save; |
1900 | } | 1917 | } |
1901 | 1918 | ||
@@ -1921,6 +1938,8 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
1921 | if (val) { | 1938 | if (val) { |
1922 | o_addQstr(output, val, strlen(val)); | 1939 | o_addQstr(output, val, strlen(val)); |
1923 | } | 1940 | } |
1941 | free(dyn_val); | ||
1942 | dyn_val = NULL; | ||
1924 | /* Do the check to avoid writing to a const string */ | 1943 | /* Do the check to avoid writing to a const string */ |
1925 | if (*p != SPECIAL_VAR_SYMBOL) | 1944 | if (*p != SPECIAL_VAR_SYMBOL) |
1926 | *p = SPECIAL_VAR_SYMBOL; | 1945 | *p = SPECIAL_VAR_SYMBOL; |
@@ -4428,7 +4447,6 @@ static int handle_dollar(o_string *as_string, | |||
4428 | break; | 4447 | break; |
4429 | } | 4448 | } |
4430 | goto case_default; | 4449 | goto case_default; |
4431 | #if 0 /* not implemented yet :( */ | ||
4432 | case '#': /* remove prefix */ | 4450 | case '#': /* remove prefix */ |
4433 | case '%': /* remove suffix */ | 4451 | case '%': /* remove suffix */ |
4434 | if (expansion == 0) { | 4452 | if (expansion == 0) { |
@@ -4437,7 +4455,6 @@ static int handle_dollar(o_string *as_string, | |||
4437 | break; | 4455 | break; |
4438 | } | 4456 | } |
4439 | goto case_default; | 4457 | goto case_default; |
4440 | #endif | ||
4441 | case '-': /* default value */ | 4458 | case '-': /* default value */ |
4442 | case '=': /* assign default */ | 4459 | case '=': /* assign default */ |
4443 | case '+': /* alternative */ | 4460 | case '+': /* alternative */ |