diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-20 21:46:45 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-05-20 21:46:45 +0200 |
commit | 53b513331add89e83c1327579f3da91ebbe97570 (patch) | |
tree | 766859b51744af5b705bf785c95ff597feb9cd1c /shell/hush.c | |
parent | ee0775dd13a84316f6fd49c930237e6dec241dba (diff) | |
download | busybox-w32-53b513331add89e83c1327579f3da91ebbe97570.tar.gz busybox-w32-53b513331add89e83c1327579f3da91ebbe97570.tar.bz2 busybox-w32-53b513331add89e83c1327579f3da91ebbe97570.zip |
hush: explain various parameter expansion ops in comments
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/shell/hush.c b/shell/hush.c index d5cea07a1..06e9af21a 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -2614,8 +2614,16 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char | |||
2614 | debug_printf_expand("%s\n", val); | 2614 | debug_printf_expand("%s\n", val); |
2615 | } else if (exp_op) { | 2615 | } else if (exp_op) { |
2616 | if (exp_op == '%' || exp_op == '#') { | 2616 | if (exp_op == '%' || exp_op == '#') { |
2617 | /* Standard-mandated substring removal ops: | ||
2618 | * ${parameter%word} - remove smallest suffix pattern | ||
2619 | * ${parameter%%word} - remove largest suffix pattern | ||
2620 | * ${parameter#word} - remove smallest prefix pattern | ||
2621 | * ${parameter##word} - remove largest prefix pattern | ||
2622 | * | ||
2623 | * Word is expanded to produce a glob pattern. | ||
2624 | * Then var's value is matched to it and matching part removed. | ||
2625 | */ | ||
2617 | if (val) { | 2626 | if (val) { |
2618 | /* we need to do a pattern match */ | ||
2619 | bool match_at_left; | 2627 | bool match_at_left; |
2620 | char *loc; | 2628 | char *loc; |
2621 | scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left); | 2629 | scan_t scan = pick_scan(exp_op, *exp_word, &match_at_left); |
@@ -2629,18 +2637,38 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char | |||
2629 | *loc = '\0'; | 2637 | *loc = '\0'; |
2630 | } | 2638 | } |
2631 | } else { /* one of :-=+? */ | 2639 | } else { /* one of :-=+? */ |
2640 | //TODO: check validity of exp_op. Currently it can be anything. | ||
2632 | //TODO: handle ${VAR:N[:M]} here. N, M can be expressions similar to $((EXPR)): 2+2, 2+var etc | 2641 | //TODO: handle ${VAR:N[:M]} here. N, M can be expressions similar to $((EXPR)): 2+2, 2+var etc |
2633 | /* we need to do an expansion */ | 2642 | /* Standard-mandated substitution ops: |
2634 | int exp_test = (!val || ((exp_save == ':') && !val[0])); | 2643 | * ${var?word} - indicate error if unset |
2644 | * If var is unset, word (or a message indicating it is unset | ||
2645 | * if word is null) is written to standard error | ||
2646 | * and the shell exits with a non-zero exit status. | ||
2647 | * Otherwise, the value of var is substituted. | ||
2648 | * ${var-word} - use default value | ||
2649 | * If var is unset, word is substituted. | ||
2650 | * ${var=word} - assign and use default value | ||
2651 | * If var is unset, word is assigned to var. | ||
2652 | * In all cases, final value of var is substituted. | ||
2653 | * ${var+word} - use alternative value | ||
2654 | * If var is unset, null is substituted. | ||
2655 | * Otherwise, word is substituted. | ||
2656 | * | ||
2657 | * Word is subjected to tilde expansion, parameter expansion, | ||
2658 | * command substitution, and arithmetic expansion. | ||
2659 | * If word is not needed, it is not expanded. | ||
2660 | * | ||
2661 | * Colon forms (${var:-word}, ${var:=word} etc) do the same, | ||
2662 | * but also treat null var as if it is unset. | ||
2663 | */ | ||
2664 | int use_word = (!val || ((exp_save == ':') && !val[0])); | ||
2635 | if (exp_op == '+') | 2665 | if (exp_op == '+') |
2636 | exp_test = !exp_test; | 2666 | use_word = !use_word; |
2637 | debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, | 2667 | debug_printf_expand("expand: op:%c (null:%s) test:%i\n", exp_op, |
2638 | (exp_save == ':') ? "true" : "false", exp_test); | 2668 | (exp_save == ':') ? "true" : "false", use_word); |
2639 | if (exp_test) { | 2669 | if (use_word) { |
2640 | if (exp_op == '?') { | 2670 | if (exp_op == '?') { |
2641 | //TODO: how interactive bash aborts expansion mid-command? | 2671 | //TODO: how interactive bash aborts expansion mid-command? |
2642 | /* ${var?[error_msg_if_unset]} */ | ||
2643 | /* ${var:?[error_msg_if_unset_or_null]} */ | ||
2644 | /* mimic bash message */ | 2672 | /* mimic bash message */ |
2645 | die_if_script("%s: %s", | 2673 | die_if_script("%s: %s", |
2646 | var, | 2674 | var, |