diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-02 20:17:49 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-02 20:17:49 +0000 |
commit | b7aaae9052025426b669a0edeec1da5997fea8be (patch) | |
tree | 062eff7de09b9307a57260c47571888ed3f598b7 | |
parent | 7a79afa3cab4d35f6c042a1038554948ebe9b2e1 (diff) | |
download | busybox-w32-b7aaae9052025426b669a0edeec1da5997fea8be.tar.gz busybox-w32-b7aaae9052025426b669a0edeec1da5997fea8be.tar.bz2 busybox-w32-b7aaae9052025426b669a0edeec1da5997fea8be.zip |
hush: rename ->o_quote to ->o_escape
hush_test/hush-arith/*: new tests for arithmetic evaluation
-rw-r--r-- | shell/hush.c | 56 | ||||
-rw-r--r-- | shell/hush_test/hush-arith/arith.right | 138 | ||||
-rwxr-xr-x | shell/hush_test/hush-arith/arith.tests | 302 | ||||
-rwxr-xr-x | shell/hush_test/hush-arith/arith1.sub | 40 | ||||
-rwxr-xr-x | shell/hush_test/hush-arith/arith2.sub | 57 |
5 files changed, 565 insertions, 28 deletions
diff --git a/shell/hush.c b/shell/hush.c index b46a1fd76..f0d372625 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -392,9 +392,9 @@ typedef struct o_string { | |||
392 | char *data; | 392 | char *data; |
393 | int length; /* position where data is appended */ | 393 | int length; /* position where data is appended */ |
394 | int maxlen; | 394 | int maxlen; |
395 | /* Misnomer! it's not "quoting", it's "protection against globbing"! | 395 | /* Protect newly added chars against globbing |
396 | * (by prepending \ to *, ?, [ and to \ too) */ | 396 | * (by prepending \ to *, ?, [, \) */ |
397 | smallint o_quote; | 397 | smallint o_escape; |
398 | smallint o_glob; | 398 | smallint o_glob; |
399 | smallint nonnull; | 399 | smallint nonnull; |
400 | smallint has_empty_slot; | 400 | smallint has_empty_slot; |
@@ -1440,7 +1440,7 @@ static void o_addqchr(o_string *o, int ch) | |||
1440 | static void o_addQchr(o_string *o, int ch) | 1440 | static void o_addQchr(o_string *o, int ch) |
1441 | { | 1441 | { |
1442 | int sz = 1; | 1442 | int sz = 1; |
1443 | if (o->o_quote && strchr("*?[\\", ch)) { | 1443 | if (o->o_escape && strchr("*?[\\", ch)) { |
1444 | sz++; | 1444 | sz++; |
1445 | o->data[o->length] = '\\'; | 1445 | o->data[o->length] = '\\'; |
1446 | o->length++; | 1446 | o->length++; |
@@ -1453,7 +1453,7 @@ static void o_addQchr(o_string *o, int ch) | |||
1453 | 1453 | ||
1454 | static void o_addQstr(o_string *o, const char *str, int len) | 1454 | static void o_addQstr(o_string *o, const char *str, int len) |
1455 | { | 1455 | { |
1456 | if (!o->o_quote) { | 1456 | if (!o->o_escape) { |
1457 | o_addstr(o, str, len); | 1457 | o_addstr(o, str, len); |
1458 | return; | 1458 | return; |
1459 | } | 1459 | } |
@@ -1668,7 +1668,7 @@ static int expand_on_ifs(o_string *output, int n, const char *str) | |||
1668 | while (1) { | 1668 | while (1) { |
1669 | int word_len = strcspn(str, G.ifs); | 1669 | int word_len = strcspn(str, G.ifs); |
1670 | if (word_len) { | 1670 | if (word_len) { |
1671 | if (output->o_quote || !output->o_glob) | 1671 | if (output->o_escape || !output->o_glob) |
1672 | o_addQstr(output, str, word_len); | 1672 | o_addQstr(output, str, word_len); |
1673 | else /* protect backslashes against globbing up :) */ | 1673 | else /* protect backslashes against globbing up :) */ |
1674 | o_addstr_duplicate_backslash(output, str, word_len); | 1674 | o_addstr_duplicate_backslash(output, str, word_len); |
@@ -1751,9 +1751,9 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
1751 | break; | 1751 | break; |
1752 | ored_ch |= first_ch; /* do it for "$@" _now_, when we know it's not empty */ | 1752 | ored_ch |= first_ch; /* do it for "$@" _now_, when we know it's not empty */ |
1753 | if (!(first_ch & 0x80)) { /* unquoted $* or $@ */ | 1753 | if (!(first_ch & 0x80)) { /* unquoted $* or $@ */ |
1754 | smallint sv = output->o_quote; | 1754 | smallint sv = output->o_escape; |
1755 | /* unquoted var's contents should be globbed, so don't quote */ | 1755 | /* unquoted var's contents should be globbed, so don't escape */ |
1756 | output->o_quote = 0; | 1756 | output->o_escape = 0; |
1757 | while (G.global_argv[i]) { | 1757 | while (G.global_argv[i]) { |
1758 | n = expand_on_ifs(output, n, G.global_argv[i]); | 1758 | n = expand_on_ifs(output, n, G.global_argv[i]); |
1759 | debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1); | 1759 | debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1); |
@@ -1766,7 +1766,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
1766 | debug_print_list("expand_vars_to_list[3]", output, n); | 1766 | debug_print_list("expand_vars_to_list[3]", output, n); |
1767 | } | 1767 | } |
1768 | } | 1768 | } |
1769 | output->o_quote = sv; | 1769 | output->o_escape = sv; |
1770 | } else | 1770 | } else |
1771 | /* If or_mask is nonzero, we handle assignment 'a=....$@.....' | 1771 | /* If or_mask is nonzero, we handle assignment 'a=....$@.....' |
1772 | * and in this case should treat it like '$*' - see 'else...' below */ | 1772 | * and in this case should treat it like '$*' - see 'else...' below */ |
@@ -1945,17 +1945,17 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask) | |||
1945 | store_val: | 1945 | store_val: |
1946 | #endif | 1946 | #endif |
1947 | if (!(first_ch & 0x80)) { /* unquoted $VAR */ | 1947 | if (!(first_ch & 0x80)) { /* unquoted $VAR */ |
1948 | debug_printf_expand("unquoted '%s', output->o_quote:%d\n", val, output->o_quote); | 1948 | debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, output->o_escape); |
1949 | if (val) { | 1949 | if (val) { |
1950 | /* unquoted var's contents should be globbed, so don't quote */ | 1950 | /* unquoted var's contents should be globbed, so don't escape */ |
1951 | smallint sv = output->o_quote; | 1951 | smallint sv = output->o_escape; |
1952 | output->o_quote = 0; | 1952 | output->o_escape = 0; |
1953 | n = expand_on_ifs(output, n, val); | 1953 | n = expand_on_ifs(output, n, val); |
1954 | val = NULL; | 1954 | val = NULL; |
1955 | output->o_quote = sv; | 1955 | output->o_escape = sv; |
1956 | } | 1956 | } |
1957 | } else { /* quoted $VAR, val will be appended below */ | 1957 | } else { /* quoted $VAR, val will be appended below */ |
1958 | debug_printf_expand("quoted '%s', output->o_quote:%d\n", val, output->o_quote); | 1958 | debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, output->o_escape); |
1959 | } | 1959 | } |
1960 | } /* default: */ | 1960 | } /* default: */ |
1961 | } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ | 1961 | } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ |
@@ -1999,7 +1999,7 @@ static char **expand_variables(char **argv, int or_mask) | |||
1999 | o_string output = NULL_O_STRING; | 1999 | o_string output = NULL_O_STRING; |
2000 | 2000 | ||
2001 | if (or_mask & 0x100) { | 2001 | if (or_mask & 0x100) { |
2002 | output.o_quote = 1; /* protect against globbing for "$var" */ | 2002 | output.o_escape = 1; /* protect against globbing for "$var" */ |
2003 | /* (unquoted $var will temporarily switch it off) */ | 2003 | /* (unquoted $var will temporarily switch it off) */ |
2004 | output.o_glob = 1; | 2004 | output.o_glob = 1; |
2005 | } | 2005 | } |
@@ -3979,7 +3979,7 @@ static int handle_dollar(o_string *dest, struct in_str *input) | |||
3979 | { | 3979 | { |
3980 | int expansion; | 3980 | int expansion; |
3981 | int ch = i_peek(input); /* first character after the $ */ | 3981 | int ch = i_peek(input); /* first character after the $ */ |
3982 | unsigned char quote_mask = dest->o_quote ? 0x80 : 0; | 3982 | unsigned char quote_mask = dest->o_escape ? 0x80 : 0; |
3983 | 3983 | ||
3984 | debug_printf_parse("handle_dollar entered: ch='%c'\n", ch); | 3984 | debug_printf_parse("handle_dollar entered: ch='%c'\n", ch); |
3985 | if (isalpha(ch)) { | 3985 | if (isalpha(ch)) { |
@@ -4143,7 +4143,7 @@ static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote | |||
4143 | if (ch == dquote_end) { /* may be only '"' or EOF */ | 4143 | if (ch == dquote_end) { /* may be only '"' or EOF */ |
4144 | dest->nonnull = 1; | 4144 | dest->nonnull = 1; |
4145 | if (dest->o_assignment == NOT_ASSIGNMENT) | 4145 | if (dest->o_assignment == NOT_ASSIGNMENT) |
4146 | dest->o_quote ^= 1; | 4146 | dest->o_escape ^= 1; |
4147 | debug_printf_parse("parse_stream_dquoted return 0\n"); | 4147 | debug_printf_parse("parse_stream_dquoted return 0\n"); |
4148 | return 0; | 4148 | return 0; |
4149 | } | 4149 | } |
@@ -4157,8 +4157,8 @@ static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote | |||
4157 | if (ch != '\n') { | 4157 | if (ch != '\n') { |
4158 | next = i_peek(input); | 4158 | next = i_peek(input); |
4159 | } | 4159 | } |
4160 | debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n", | 4160 | debug_printf_parse(": ch=%c (%d) m=%d escape=%d\n", |
4161 | ch, ch, m, dest->o_quote); | 4161 | ch, ch, m, dest->o_escape); |
4162 | /* Basically, checking every CHAR_SPECIAL char except '"' */ | 4162 | /* Basically, checking every CHAR_SPECIAL char except '"' */ |
4163 | if (ch == '\\') { | 4163 | if (ch == '\\') { |
4164 | if (next == EOF) { | 4164 | if (next == EOF) { |
@@ -4225,13 +4225,13 @@ static int parse_stream(o_string *dest, struct parse_context *ctx, | |||
4225 | int is_in_dquote; | 4225 | int is_in_dquote; |
4226 | int next; | 4226 | int next; |
4227 | 4227 | ||
4228 | /* Only double-quote state is handled in the state variable dest->o_quote. | 4228 | /* Double-quote state is handled in the state variable is_in_dquote. |
4229 | * A single-quote triggers a bypass of the main loop until its mate is | 4229 | * A single-quote triggers a bypass of the main loop until its mate is |
4230 | * found. When recursing, quote state is passed in via dest->o_quote. */ | 4230 | * found. When recursing, quote state is passed in via dest->o_escape. */ |
4231 | 4231 | ||
4232 | debug_printf_parse("parse_stream entered, end_trigger='%s' dest->o_assignment:%d\n", end_trigger, dest->o_assignment); | 4232 | debug_printf_parse("parse_stream entered, end_trigger='%s' dest->o_assignment:%d\n", end_trigger, dest->o_assignment); |
4233 | 4233 | ||
4234 | is_in_dquote = dest->o_quote; | 4234 | is_in_dquote = dest->o_escape; |
4235 | while (1) { | 4235 | while (1) { |
4236 | if (is_in_dquote) { | 4236 | if (is_in_dquote) { |
4237 | if (parse_stream_dquoted(dest, input, '"')) | 4237 | if (parse_stream_dquoted(dest, input, '"')) |
@@ -4248,8 +4248,8 @@ static int parse_stream(o_string *dest, struct parse_context *ctx, | |||
4248 | next = i_peek(input); | 4248 | next = i_peek(input); |
4249 | } | 4249 | } |
4250 | } | 4250 | } |
4251 | debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n", | 4251 | debug_printf_parse(": ch=%c (%d) m=%d escape=%d\n", |
4252 | ch, ch, m, dest->o_quote); | 4252 | ch, ch, m, dest->o_escape); |
4253 | if (m == CHAR_ORDINARY) { | 4253 | if (m == CHAR_ORDINARY) { |
4254 | o_addQchr(dest, ch); | 4254 | o_addQchr(dest, ch); |
4255 | if ((dest->o_assignment == MAYBE_ASSIGNMENT | 4255 | if ((dest->o_assignment == MAYBE_ASSIGNMENT |
@@ -4365,7 +4365,7 @@ static int parse_stream(o_string *dest, struct parse_context *ctx, | |||
4365 | dest->nonnull = 1; | 4365 | dest->nonnull = 1; |
4366 | is_in_dquote ^= 1; /* invert */ | 4366 | is_in_dquote ^= 1; /* invert */ |
4367 | if (dest->o_assignment == NOT_ASSIGNMENT) | 4367 | if (dest->o_assignment == NOT_ASSIGNMENT) |
4368 | dest->o_quote ^= 1; | 4368 | dest->o_escape ^= 1; |
4369 | break; | 4369 | break; |
4370 | #if ENABLE_HUSH_TICK | 4370 | #if ENABLE_HUSH_TICK |
4371 | case '`': { | 4371 | case '`': { |
@@ -4594,7 +4594,7 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag) | |||
4594 | } | 4594 | } |
4595 | #endif | 4595 | #endif |
4596 | /*temp.nonnull = 0; - o_free does it below */ | 4596 | /*temp.nonnull = 0; - o_free does it below */ |
4597 | /*temp.o_quote = 0; - o_free does it below */ | 4597 | /*temp.o_escape = 0; - o_free does it below */ |
4598 | free_pipe_list(ctx.list_head, /* indent: */ 0); | 4598 | free_pipe_list(ctx.list_head, /* indent: */ 0); |
4599 | /* Discard all unprocessed line input, force prompt on */ | 4599 | /* Discard all unprocessed line input, force prompt on */ |
4600 | inp->p = NULL; | 4600 | inp->p = NULL; |
diff --git a/shell/hush_test/hush-arith/arith.right b/shell/hush_test/hush-arith/arith.right new file mode 100644 index 000000000..a35fe893f --- /dev/null +++ b/shell/hush_test/hush-arith/arith.right | |||
@@ -0,0 +1,138 @@ | |||
1 | Format: 'expected actual' | ||
2 | 163 163 | ||
3 | 4 4 | ||
4 | 16 16 | ||
5 | 8 8 | ||
6 | 2 2 | ||
7 | 4 4 | ||
8 | 2 2 | ||
9 | 2 2 | ||
10 | 1 1 | ||
11 | 0 0 | ||
12 | 0 0 | ||
13 | 0 0 | ||
14 | 1 1 | ||
15 | 1 1 | ||
16 | 2 2 | ||
17 | -3 -3 | ||
18 | -2 -2 | ||
19 | 1 1 | ||
20 | 0 0 | ||
21 | 2 2 | ||
22 | 131072 131072 | ||
23 | 29 29 | ||
24 | 33 33 | ||
25 | 49 49 | ||
26 | 1 1 | ||
27 | 1 1 | ||
28 | 0 0 | ||
29 | 0 0 | ||
30 | 1 1 | ||
31 | 1 1 | ||
32 | 1 1 | ||
33 | 2 2 | ||
34 | 3 3 | ||
35 | 1 1 | ||
36 | 58 58 | ||
37 | 2 2 | ||
38 | 60 60 | ||
39 | 1 1 | ||
40 | 256 256 | ||
41 | 16 16 | ||
42 | 62 62 | ||
43 | 4 4 | ||
44 | 29 29 | ||
45 | 5 5 | ||
46 | -4 -4 | ||
47 | 4 4 | ||
48 | 1 1 | ||
49 | 32 32 | ||
50 | 32 32 | ||
51 | 1 1 | ||
52 | 1 1 | ||
53 | 32 32 | ||
54 | 20 20 | ||
55 | 30 30 | ||
56 | 20 20 | ||
57 | 30 30 | ||
58 | hush: arith: syntax error | ||
59 | 6 6 | ||
60 | 6,5,3 6,5,3 | ||
61 | 263 263 | ||
62 | 255 255 | ||
63 | 40 40 | ||
64 | hush: arith: syntax error | ||
65 | hush: arith: divide by zero | ||
66 | hush: can't exec 'let': No such file or directory | ||
67 | hush: arith: syntax error | ||
68 | hush: can't exec 'let': No such file or directory | ||
69 | abc | ||
70 | def | ||
71 | ghi | ||
72 | hush: arith: syntax error | ||
73 | 16 16 | ||
74 | hush: arith: syntax error | ||
75 | hush: arith: syntax error | ||
76 | hush: arith: syntax error | ||
77 | 9 9 | ||
78 | hush: arith: syntax error | ||
79 | hush: arith: syntax error | ||
80 | 9 9 | ||
81 | 9 9 | ||
82 | 9 9 | ||
83 | 7 7 | ||
84 | 7 | ||
85 | 4 4 | ||
86 | 32767 32767 | ||
87 | 32768 32768 | ||
88 | 131072 131072 | ||
89 | 2147483647 2147483647 | ||
90 | 1 1 | ||
91 | 4 4 | ||
92 | 4 4 | ||
93 | 5 5 | ||
94 | 5 5 | ||
95 | 4 4 | ||
96 | 3 3 | ||
97 | 3 3 | ||
98 | 4 4 | ||
99 | 4 4 | ||
100 | hush: arith: syntax error | ||
101 | hush: arith: syntax error | ||
102 | hush: arith: syntax error | ||
103 | hush: arith: syntax error | ||
104 | hush: arith: syntax error | ||
105 | 4 4 | ||
106 | 7 7 | ||
107 | -7 -7 | ||
108 | hush: arith: syntax error | ||
109 | hush: arith: syntax error | ||
110 | hush: arith: syntax error | ||
111 | hush: arith: syntax error | ||
112 | 6 6 | ||
113 | 3 3 | ||
114 | 7 7 | ||
115 | 4 4 | ||
116 | 0 0 | ||
117 | 3 3 | ||
118 | 7 7 | ||
119 | 2 2 | ||
120 | -2 -2 | ||
121 | 1 1 | ||
122 | hush: arith: syntax error | ||
123 | hush: arith: syntax error | ||
124 | hush: arith: syntax error | ||
125 | hush: arith: syntax error | ||
126 | hush: arith: syntax error | ||
127 | 5 5 | ||
128 | 1 1 | ||
129 | 4 4 | ||
130 | 0 0 | ||
131 | hush: arith: syntax error | ||
132 | hush: arith: syntax error | ||
133 | 8 12 | ||
134 | hush: arith: syntax error | ||
135 | 42 | ||
136 | 42 | ||
137 | 42 | ||
138 | hush: can't exec 'a[b[c]d]=e': No such file or directory | ||
diff --git a/shell/hush_test/hush-arith/arith.tests b/shell/hush_test/hush-arith/arith.tests new file mode 100755 index 000000000..57e66e888 --- /dev/null +++ b/shell/hush_test/hush-arith/arith.tests | |||
@@ -0,0 +1,302 @@ | |||
1 | #ash# set +o posix | ||
2 | #ash# declare -i iv jv | ||
3 | |||
4 | echo "Format: 'expected actual'" | ||
5 | |||
6 | iv=$(( 3 + 5 * 32 )) | ||
7 | echo 163 $iv | ||
8 | #ash# iv=iv+3 | ||
9 | #ash# echo 166 $iv | ||
10 | iv=2 | ||
11 | jv=iv | ||
12 | |||
13 | : $((jv *= 2)) ##hush## let "jv *= 2" | ||
14 | echo 4 $jv | ||
15 | jv=$(( $jv << 2 )) | ||
16 | echo 16 $jv | ||
17 | |||
18 | : $((jv=$jv / 2)) ##hush## let jv="$jv / 2" | ||
19 | echo 8 $jv | ||
20 | #ash# jv="jv >> 2" | ||
21 | : $((jv=jv >> 2)) ##hush## let jv="jv >> 2" | ||
22 | echo 2 $jv | ||
23 | |||
24 | iv=$((iv+ $jv)) | ||
25 | echo 4 $iv | ||
26 | echo 2 $((iv -= jv)) | ||
27 | echo 2 $iv | ||
28 | echo 1 $(( iv == jv )) | ||
29 | echo 0 $(( iv != $jv )) | ||
30 | echo 0 $(( iv < jv )) | ||
31 | echo 0 $(( $iv > $jv )) | ||
32 | echo 1 $(( iv <= $jv )) | ||
33 | echo 1 $(( $iv >= jv )) | ||
34 | |||
35 | echo 2 $jv | ||
36 | echo -3 $(( ~$jv )) | ||
37 | echo -2 $(( ~1 )) | ||
38 | echo 1 $(( ! 0 )) | ||
39 | |||
40 | echo 0 $(( jv % 2 )) | ||
41 | echo 2 $(( $iv % 4 )) | ||
42 | |||
43 | echo 131072 $(( iv <<= 16 )) | ||
44 | echo 29 $(( iv %= 33 )) | ||
45 | |||
46 | echo 33 $(( 33 & 55 )) | ||
47 | echo 49 $(( 33 | 17 )) | ||
48 | |||
49 | echo 1 $(( iv && $jv )) | ||
50 | echo 1 $(( $iv || jv )) | ||
51 | |||
52 | echo 0 $(( iv && 0 )) | ||
53 | echo 0 $(( iv & 0 )) | ||
54 | echo 1 $(( iv && 1 )) | ||
55 | echo 1 $(( iv & 1 )) | ||
56 | |||
57 | echo 1 $(( $jv || 0 )) | ||
58 | echo 2 $(( jv | 0 )) | ||
59 | echo 3 $(( jv | 1 )) | ||
60 | echo 1 $(( $jv || 1 )) | ||
61 | |||
62 | : $((iv *= jv)) ##hush## let 'iv *= jv' | ||
63 | echo 58 $iv | ||
64 | echo 2 $jv | ||
65 | : $((jv += $iv)) ##hush## let "jv += $iv" | ||
66 | echo 60 $jv | ||
67 | |||
68 | echo 1 $(( jv /= iv )) | ||
69 | echo 256 $(( jv <<= 8 )) | ||
70 | echo 16 $(( jv >>= 4 )) | ||
71 | |||
72 | echo 62 $(( iv |= 4 )) | ||
73 | echo 4 $(( iv &= 4 )) | ||
74 | |||
75 | echo 29 $(( iv += (jv + 9))) | ||
76 | echo 5 $(( (iv + 4) % 7 )) | ||
77 | |||
78 | # unary plus, minus | ||
79 | echo -4 $(( +4 - 8 )) | ||
80 | echo 4 $(( -4 + 8 )) | ||
81 | |||
82 | # conditional expressions | ||
83 | echo 1 $(( 4<5 ? 1 : 32)) | ||
84 | echo 32 $(( 4>5 ? 1 : 32)) | ||
85 | echo 32 $(( 4>(2+3) ? 1 : 32)) | ||
86 | echo 1 $(( 4<(2+3) ? 1 : 32)) | ||
87 | echo 1 $(( (2+2)<(2+3) ? 1 : 32)) | ||
88 | echo 32 $(( (2+2)>(2+3) ? 1 : 32)) | ||
89 | |||
90 | # check that the unevaluated part of the ternary operator does not do | ||
91 | # evaluation or assignment | ||
92 | x=i+=2 | ||
93 | y=j+=2 | ||
94 | #ash# declare -i i=1 j=1 | ||
95 | i=1 | ||
96 | j=1 | ||
97 | echo 20 $((1 ? 20 : (x+=2))) | ||
98 | #ash# echo $i,$x # ash mishandles this | ||
99 | echo 30 $((0 ? (y+=2) : 30)) | ||
100 | #ash# echo $j,$y # ash mishandles this | ||
101 | |||
102 | x=i+=2 | ||
103 | y=j+=2 | ||
104 | #ash# declare -i i=1 j=1 | ||
105 | i=1 | ||
106 | j=1 | ||
107 | echo 20 $((1 ? 20 : (x+=2))) | ||
108 | #ash# echo $i,$x # ash mishandles this | ||
109 | echo 30 $((0 ? (y+=2) : 30)) | ||
110 | #ash# echo $i,$y # ash mishandles this | ||
111 | |||
112 | # check precedence of assignment vs. conditional operator | ||
113 | # should be an error | ||
114 | #ash# declare -i x=2 | ||
115 | x=2 | ||
116 | #ashnote# bash reports error but continues, ash aborts - using subshell to 'emulate' bash: | ||
117 | ( y=$((1 ? 20 : x+=2)) ) | ||
118 | |||
119 | # check precedence of assignment vs. conditional operator | ||
120 | #ash# declare -i x=2 | ||
121 | x=2 | ||
122 | # ash says "line NNN: syntax error: 0 ? x+=2 : 20" | ||
123 | #ash# echo 20 $((0 ? x+=2 : 20)) | ||
124 | |||
125 | # associativity of assignment-operator operator | ||
126 | #ash# declare -i i=1 j=2 k=3 | ||
127 | i=1 | ||
128 | j=2 | ||
129 | k=3 | ||
130 | echo 6 $((i += j += k)) | ||
131 | echo 6,5,3 $i,$j,$k | ||
132 | |||
133 | # octal, hex | ||
134 | echo 263 $(( 0x100 | 007 )) | ||
135 | echo 255 $(( 0xff )) | ||
136 | #ash# echo 255 $(( 16#ff )) | ||
137 | #ash# echo 127 $(( 16#FF/2 )) | ||
138 | #ash# echo 36 $(( 8#44 )) | ||
139 | |||
140 | echo 40 $(( 8 ^ 32 )) | ||
141 | |||
142 | #ash# # other bases | ||
143 | #ash# echo 10 $(( 16#a )) | ||
144 | #ash# echo 10 $(( 32#a )) | ||
145 | #ash# echo 10 $(( 56#a )) | ||
146 | #ash# echo 10 $(( 64#a )) | ||
147 | #ash# | ||
148 | #ash# echo 10 $(( 16#A )) | ||
149 | #ash# echo 10 $(( 32#A )) | ||
150 | #ash# echo 36 $(( 56#A )) | ||
151 | #ash# echo 36 $(( 64#A )) | ||
152 | #ash# | ||
153 | #ash# echo 62 $(( 64#@ )) | ||
154 | #ash# echo 63 $(( 64#_ )) | ||
155 | |||
156 | #ash# # weird bases (error) | ||
157 | #ash# echo $(( 3425#56 )) | ||
158 | |||
159 | #ash# # missing number after base | ||
160 | #ash# echo 0 $(( 2# )) | ||
161 | |||
162 | # these should generate errors | ||
163 | ( echo $(( 7 = 43 )) ) | ||
164 | #ash# echo $(( 2#44 )) | ||
165 | ( echo $(( 44 / 0 )) ) | ||
166 | ( let 'jv += $iv' ) | ||
167 | ( echo $(( jv += \$iv )) ) | ||
168 | ( let 'rv = 7 + (43 * 6' ) | ||
169 | |||
170 | #ash# # more errors | ||
171 | #ash# declare -i i | ||
172 | #ash# i=0#4 | ||
173 | #ash# i=2#110#11 | ||
174 | |||
175 | ((echo abc; echo def;); echo ghi) | ||
176 | |||
177 | #ash# if (((4+4) + (4 + 7))); then | ||
178 | #ash# echo ok | ||
179 | #ash# fi | ||
180 | |||
181 | #ash# (()) # make sure the null expression works OK | ||
182 | |||
183 | #ash# a=(0 2 4 6) | ||
184 | #ash# echo 6 $(( a[1] + a[2] )) | ||
185 | #ash# echo 1 $(( (a[1] + a[2]) == a[3] )) | ||
186 | #ash# (( (a[1] + a[2]) == a[3] )) ; echo 0 $? | ||
187 | |||
188 | # test pushing and popping the expression stack | ||
189 | unset A | ||
190 | A="4 + " | ||
191 | ( echo A $(( ( 4 + A ) + 4 )) ) | ||
192 | A="3 + 5" | ||
193 | echo 16 $(( ( 4 + A ) + 4 )) | ||
194 | |||
195 | # badly-formed conditional expressions | ||
196 | ( echo $(( 4 ? : $A )) ) | ||
197 | ( echo $(( 1 ? 20 )) ) | ||
198 | ( echo $(( 4 ? 20 : )) ) | ||
199 | |||
200 | # precedence and short-circuit evaluation | ||
201 | B=9 | ||
202 | echo 9 $B | ||
203 | |||
204 | # error | ||
205 | ( echo $(( 0 && B=42 )); echo 9 $B ) | ||
206 | |||
207 | # error | ||
208 | ( echo $(( 1 || B=88 )); echo 9 $B ) | ||
209 | |||
210 | # ash mistakenly evaluates B=... below | ||
211 | #ash# echo 0 $(( 0 && (B=42) )) | ||
212 | echo 9 $B | ||
213 | #ash# echo 0 $(( (${$} - $$) && (B=42) )) | ||
214 | echo 9 $B | ||
215 | #ash# echo 1 $(( 1 || (B=88) )) | ||
216 | echo 9 $B | ||
217 | |||
218 | |||
219 | # until command with (( )) command | ||
220 | x=7 | ||
221 | |||
222 | echo 7 $x | ||
223 | #ash# until (( x == 4 )) | ||
224 | until test "$x" = 4 | ||
225 | do | ||
226 | echo $x | ||
227 | x=4 | ||
228 | done | ||
229 | |||
230 | echo 4 $x | ||
231 | |||
232 | # exponentiation | ||
233 | echo 32767 $(( 2**15 - 1)) | ||
234 | echo 32768 $(( 2**(16-1))) | ||
235 | echo 131072 $(( 2**16*2 )) | ||
236 | echo 2147483647 $(( 2**31-1)) | ||
237 | echo 1 $(( 2**0 )) | ||
238 | |||
239 | # {pre,post}-{inc,dec}rement and associated errors | ||
240 | |||
241 | x=4 | ||
242 | |||
243 | echo 4 $x | ||
244 | echo 4 $(( x++ )) | ||
245 | echo 5 $x | ||
246 | echo 5 $(( x-- )) | ||
247 | echo 4 $x | ||
248 | |||
249 | echo 3 $(( --x )) | ||
250 | echo 3 $x | ||
251 | |||
252 | echo 4 $(( ++x )) | ||
253 | echo 4 $x | ||
254 | |||
255 | # bash 3.2 apparently thinks that ++7 is 7 | ||
256 | #ash# echo 7 $(( ++7 )) | ||
257 | ( echo $(( 7-- )) ) | ||
258 | |||
259 | ( echo $(( --x=7 )) ) | ||
260 | ( echo $(( ++x=7 )) ) | ||
261 | |||
262 | ( echo $(( x++=7 )) ) | ||
263 | ( echo $(( x--=7 )) ) | ||
264 | |||
265 | echo 4 $x | ||
266 | |||
267 | echo 7 $(( +7 )) | ||
268 | echo -7 $(( -7 )) | ||
269 | |||
270 | # bash 3.2 apparently thinks that ++7 is 7 | ||
271 | #ash# echo $(( ++7 )) | ||
272 | #ash# echo $(( --7 )) | ||
273 | |||
274 | ${THIS_SH} ./arith1.sub | ||
275 | ${THIS_SH} ./arith2.sub | ||
276 | |||
277 | x=4 | ||
278 | y=7 | ||
279 | |||
280 | #ash# (( x=8 , y=12 )) | ||
281 | x=8 | ||
282 | y=12 | ||
283 | echo $x $y | ||
284 | |||
285 | #ash# # should be an error | ||
286 | #ash# (( x=9 y=41 )) | ||
287 | |||
288 | # These are errors | ||
289 | unset b | ||
290 | ( echo $((a b)) ) | ||
291 | #ash# ((a b)) | ||
292 | |||
293 | n=42 | ||
294 | printf "%d\n" $n | ||
295 | printf "%i\n" $n | ||
296 | #ash# echo $(( 8#$(printf "%o\n" $n) )) | ||
297 | printf "%u\n" $n | ||
298 | #ash# echo $(( 16#$(printf "%x\n" $n) )) | ||
299 | #ash# echo $(( 16#$(printf "%X\n" $n) )) | ||
300 | |||
301 | # causes longjmp botches through bash-2.05b | ||
302 | a[b[c]d]=e | ||
diff --git a/shell/hush_test/hush-arith/arith1.sub b/shell/hush_test/hush-arith/arith1.sub new file mode 100755 index 000000000..80aa99922 --- /dev/null +++ b/shell/hush_test/hush-arith/arith1.sub | |||
@@ -0,0 +1,40 @@ | |||
1 | # test of redone post-increment and post-decrement code | ||
2 | ( echo $(( 4-- )) ) | ||
3 | ( echo $(( 4++ )) ) | ||
4 | ( echo $(( 4 -- )) ) | ||
5 | ( echo $(( 4 ++ )) ) | ||
6 | |||
7 | #ash# (( array[0]++ )) | ||
8 | #ash# echo ${array} | ||
9 | |||
10 | #ash# (( array[0] ++ )) | ||
11 | #ash# echo ${array} | ||
12 | |||
13 | #ash# (( a++ )) | ||
14 | #ash# echo $a | ||
15 | #ash# (( a ++ )) | ||
16 | #ash# echo $a | ||
17 | a=2 | ||
18 | |||
19 | echo 6 $(( a ++ + 4 )) | ||
20 | echo 3 $a | ||
21 | |||
22 | echo 7 $(( a+++4 )) | ||
23 | echo 4 $a | ||
24 | |||
25 | echo 0 $(( a---4 )) | ||
26 | echo 3 $a | ||
27 | |||
28 | echo 7 $(( a -- + 4 )) | ||
29 | echo 2 $a | ||
30 | |||
31 | echo -2 $(( a -- - 4 )) | ||
32 | echo 1 $a | ||
33 | |||
34 | #ash# (( ++ + 7 )) | ||
35 | |||
36 | #ash# (( ++ )) | ||
37 | ( echo $(( +++7 )) ) | ||
38 | # bash 3.2 apparently thinks that ++ +7 is 7 | ||
39 | #ash# echo $(( ++ + 7 )) | ||
40 | #ash# (( -- )) | ||
diff --git a/shell/hush_test/hush-arith/arith2.sub b/shell/hush_test/hush-arith/arith2.sub new file mode 100755 index 000000000..f7e3c9235 --- /dev/null +++ b/shell/hush_test/hush-arith/arith2.sub | |||
@@ -0,0 +1,57 @@ | |||
1 | # bash 3.2 apparently thinks that ++7 is 7 etc | ||
2 | ( echo $(( --7 )) ) | ||
3 | ( echo $(( ++7 )) ) | ||
4 | ( echo $(( -- 7 )) ) | ||
5 | ( echo $(( ++ 7 )) ) | ||
6 | |||
7 | #ash# ((++array[0] )) | ||
8 | #ash# echo 1 $array | ||
9 | #ash# (( ++ array[0] )) | ||
10 | #ash# echo 2 $array | ||
11 | |||
12 | #ash# (( ++a )) | ||
13 | #ash# echo 1 $a | ||
14 | #ash# (( ++ a )) | ||
15 | #ash# echo 2 $a | ||
16 | |||
17 | #ash# (( --a )) | ||
18 | #ash# echo 1 $a | ||
19 | #ash# (( -- a )) | ||
20 | #ash# echo 0 $a | ||
21 | a=0 | ||
22 | |||
23 | echo 5 $(( 4 + ++a )) | ||
24 | echo 1 $a | ||
25 | |||
26 | # ash doesn't handle it right... | ||
27 | #ash# echo 6 $(( 4+++a )) | ||
28 | #ash# echo 2 $a | ||
29 | a=2 | ||
30 | |||
31 | # ash doesn't handle it right... | ||
32 | #ash# echo 3 $(( 4---a )) | ||
33 | #ash# echo 1 $a | ||
34 | a=1 | ||
35 | |||
36 | echo 4 $(( 4 - -- a )) | ||
37 | echo 0 $a | ||
38 | |||
39 | #ash# (( -- )) | ||
40 | # bash 3.2 apparently thinks that ---7 is -7 | ||
41 | #ash# echo $(( ---7 )) | ||
42 | ( echo $(( -- - 7 )) ) | ||
43 | |||
44 | #ash# (( ++ )) | ||
45 | # bash 3.2: 7 | ||
46 | #ash# echo 7 $(( ++7 )) | ||
47 | ( echo $(( ++ + 7 )) ) | ||
48 | |||
49 | # bash 3.2: -7 | ||
50 | #ash# echo -7 $(( ++-7 )) | ||
51 | # bash 3.2: -7 | ||
52 | #ash# echo -7 $(( ++ - 7 )) | ||
53 | |||
54 | # bash 3.2: 7 | ||
55 | #ash# echo 7 $(( +--7 )) | ||
56 | # bash 3.2: 7 | ||
57 | #ash# echo 7 $(( -- + 7 )) | ||