diff options
author | Ron Yorston <rmy@pobox.com> | 2021-10-13 14:37:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-10-13 14:37:51 +0100 |
commit | 0ecf1aea459571b48dc68ddc2b7b9265740fa960 (patch) | |
tree | 491d6184a44b8b525a4ca35759d622aecd7f6344 /shell | |
parent | 4859ddcb20616718efbea12c6bf8b27c469b68de (diff) | |
parent | aaf3d5ba74c5da97ff80b61f30cb8dd225d39096 (diff) | |
download | busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.gz busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.bz2 busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash.c | 68 | ||||
-rw-r--r-- | shell/ash_test/ash-arith/arith-postinc.right | 3 | ||||
-rwxr-xr-x | shell/ash_test/ash-arith/arith-postinc.tests | 4 | ||||
-rw-r--r-- | shell/ash_test/ash-arith/arith.right | 78 | ||||
-rwxr-xr-x | shell/ash_test/ash-arith/arith.tests | 55 | ||||
-rwxr-xr-x | shell/ash_test/ash-arith/arith1.sub | 4 | ||||
-rwxr-xr-x | shell/ash_test/ash-arith/arith2.sub | 22 | ||||
-rw-r--r-- | shell/ash_test/ash-comm/comm.right | 6 | ||||
-rwxr-xr-x | shell/ash_test/ash-comm/comm.tests | 20 | ||||
-rw-r--r-- | shell/hush.c | 48 | ||||
-rw-r--r-- | shell/hush_test/hush-arith/arith-postinc.right | 3 | ||||
-rwxr-xr-x | shell/hush_test/hush-arith/arith-postinc.tests | 4 | ||||
-rw-r--r-- | shell/hush_test/hush-arith/arith.right | 37 | ||||
-rwxr-xr-x | shell/hush_test/hush-arith/arith.tests | 40 | ||||
-rwxr-xr-x | shell/hush_test/hush-arith/arith1.sub | 4 | ||||
-rwxr-xr-x | shell/hush_test/hush-arith/arith2.sub | 22 | ||||
-rw-r--r-- | shell/hush_test/hush-comm/comm.right | 6 | ||||
-rwxr-xr-x | shell/hush_test/hush-comm/comm.tests | 20 | ||||
-rw-r--r-- | shell/math.c | 71 |
19 files changed, 331 insertions, 184 deletions
diff --git a/shell/ash.c b/shell/ash.c index 9214982c1..98da20f8a 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -351,19 +351,6 @@ typedef long arith_t; | |||
351 | # error "Do not even bother, ash will not run on NOMMU machine" | 351 | # error "Do not even bother, ash will not run on NOMMU machine" |
352 | #endif | 352 | #endif |
353 | 353 | ||
354 | /* We use a trick to have more optimized code (fewer pointer reloads): | ||
355 | * ash.c: extern struct globals *const ash_ptr_to_globals; | ||
356 | * ash_ptr_hack.c: struct globals *ash_ptr_to_globals; | ||
357 | * This way, compiler in ash.c knows the pointer can not change. | ||
358 | * | ||
359 | * However, this may break on weird arches or toolchains. In this case, | ||
360 | * set "-DBB_GLOBAL_CONST=''" in CONFIG_EXTRA_CFLAGS to disable | ||
361 | * this optimization. | ||
362 | */ | ||
363 | #ifndef BB_GLOBAL_CONST | ||
364 | # define BB_GLOBAL_CONST const | ||
365 | #endif | ||
366 | |||
367 | #if ENABLE_PLATFORM_MINGW32 | 354 | #if ENABLE_PLATFORM_MINGW32 |
368 | # define FORKSHELL_DEBUG 0 | 355 | # define FORKSHELL_DEBUG 0 |
369 | 356 | ||
@@ -693,8 +680,7 @@ extern struct globals_misc *BB_GLOBAL_CONST ash_ptr_to_globals_misc; | |||
693 | #endif | 680 | #endif |
694 | 681 | ||
695 | #define INIT_G_misc() do { \ | 682 | #define INIT_G_misc() do { \ |
696 | (*(struct globals_misc**)not_const_pp(&ash_ptr_to_globals_misc)) = xzalloc(sizeof(G_misc)); \ | 683 | XZALLOC_CONST_PTR(&ash_ptr_to_globals_misc, sizeof(G_misc)); \ |
697 | barrier(); \ | ||
698 | savestatus = -1; \ | 684 | savestatus = -1; \ |
699 | curdir = nullstr; \ | 685 | curdir = nullstr; \ |
700 | physdir = nullstr; \ | 686 | physdir = nullstr; \ |
@@ -1783,8 +1769,7 @@ extern struct globals_memstack *BB_GLOBAL_CONST ash_ptr_to_globals_memstack; | |||
1783 | #define g_stacknleft (G_memstack.g_stacknleft) | 1769 | #define g_stacknleft (G_memstack.g_stacknleft) |
1784 | #define stackbase (G_memstack.stackbase ) | 1770 | #define stackbase (G_memstack.stackbase ) |
1785 | #define INIT_G_memstack() do { \ | 1771 | #define INIT_G_memstack() do { \ |
1786 | (*(struct globals_memstack**)not_const_pp(&ash_ptr_to_globals_memstack)) = xzalloc(sizeof(G_memstack)); \ | 1772 | XZALLOC_CONST_PTR(&ash_ptr_to_globals_memstack, sizeof(G_memstack)); \ |
1787 | barrier(); \ | ||
1788 | g_stackp = &stackbase; \ | 1773 | g_stackp = &stackbase; \ |
1789 | g_stacknxt = stackbase.space; \ | 1774 | g_stacknxt = stackbase.space; \ |
1790 | g_stacknleft = MINSIZE; \ | 1775 | g_stacknleft = MINSIZE; \ |
@@ -2445,8 +2430,7 @@ extern struct globals_var *BB_GLOBAL_CONST ash_ptr_to_globals_var; | |||
2445 | #endif | 2430 | #endif |
2446 | #define INIT_G_var() do { \ | 2431 | #define INIT_G_var() do { \ |
2447 | unsigned i; \ | 2432 | unsigned i; \ |
2448 | (*(struct globals_var**)not_const_pp(&ash_ptr_to_globals_var)) = xzalloc(sizeof(G_var)); \ | 2433 | XZALLOC_CONST_PTR(&ash_ptr_to_globals_var, sizeof(G_var)); \ |
2449 | barrier(); \ | ||
2450 | for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ | 2434 | for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \ |
2451 | varinit[i].flags = varinit_data[i].flags; \ | 2435 | varinit[i].flags = varinit_data[i].flags; \ |
2452 | varinit[i].var_text = varinit_data[i].var_text; \ | 2436 | varinit[i].var_text = varinit_data[i].var_text; \ |
@@ -7840,14 +7824,19 @@ subevalvar(char *start, char *str, int strloc, | |||
7840 | if ((unsigned)len > (orig_len - pos)) | 7824 | if ((unsigned)len > (orig_len - pos)) |
7841 | len = orig_len - pos; | 7825 | len = orig_len - pos; |
7842 | 7826 | ||
7843 | for (vstr = startp; pos; vstr++, pos--) { | 7827 | if (!quotes) { |
7844 | if (quotes && (unsigned char)*vstr == CTLESC) | 7828 | loc = mempcpy(startp, startp + pos, len); |
7829 | } else { | ||
7830 | for (vstr = startp; pos != 0; pos--) { | ||
7831 | if ((unsigned char)*vstr == CTLESC) | ||
7832 | vstr++; | ||
7845 | vstr++; | 7833 | vstr++; |
7846 | } | 7834 | } |
7847 | for (loc = startp; len; len--) { | 7835 | for (loc = startp; len != 0; len--) { |
7848 | if (quotes && (unsigned char)*vstr == CTLESC) | 7836 | if ((unsigned char)*vstr == CTLESC) |
7837 | *loc++ = *vstr++; | ||
7849 | *loc++ = *vstr++; | 7838 | *loc++ = *vstr++; |
7850 | *loc++ = *vstr++; | 7839 | } |
7851 | } | 7840 | } |
7852 | *loc = '\0'; | 7841 | *loc = '\0'; |
7853 | goto out; | 7842 | goto out; |
@@ -7901,7 +7890,7 @@ subevalvar(char *start, char *str, int strloc, | |||
7901 | #if BASH_PATTERN_SUBST | 7890 | #if BASH_PATTERN_SUBST |
7902 | workloc = expdest - (char *)stackblock(); | 7891 | workloc = expdest - (char *)stackblock(); |
7903 | if (subtype == VSREPLACE || subtype == VSREPLACEALL) { | 7892 | if (subtype == VSREPLACE || subtype == VSREPLACEALL) { |
7904 | size_t no_meta_len; | 7893 | size_t no_meta_len, first_escaped; |
7905 | int len; | 7894 | int len; |
7906 | char *idx, *end; | 7895 | char *idx, *end; |
7907 | 7896 | ||
@@ -7919,28 +7908,34 @@ subevalvar(char *start, char *str, int strloc, | |||
7919 | if (str[0] == '\0') | 7908 | if (str[0] == '\0') |
7920 | goto out1; | 7909 | goto out1; |
7921 | 7910 | ||
7922 | no_meta_len = (ENABLE_ASH_OPTIMIZE_FOR_SIZE || strpbrk(str, "*?[\\")) ? 0 : strlen(str); | 7911 | first_escaped = (str[0] == '\\' && str[1]); |
7912 | /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars" | ||
7913 | * as literal too (as it is semi-common, and easy to accomodate | ||
7914 | * by just using str + 1). | ||
7915 | */ | ||
7916 | no_meta_len = strpbrk(str + first_escaped * 2, "*?[\\") ? 0 : strlen(str); | ||
7923 | len = 0; | 7917 | len = 0; |
7924 | idx = startp; | 7918 | idx = startp; |
7925 | end = str - 1; | 7919 | end = str - 1; |
7926 | while (idx <= end) { | 7920 | while (idx <= end) { |
7927 | try_to_match: | 7921 | try_to_match: |
7928 | if (no_meta_len == 0) { | 7922 | if (no_meta_len == 0) { |
7929 | /* pattern has meta chars, have to glob; or ENABLE_ASH_OPTIMIZE_FOR_SIZE */ | 7923 | /* pattern has meta chars, have to glob */ |
7930 | loc = scanright(idx, rmesc, rmescend, str, quotes, /*match_at_start:*/ 1); | 7924 | loc = scanright(idx, rmesc, rmescend, str, quotes, /*match_at_start:*/ 1); |
7931 | } else { | 7925 | } else { |
7932 | /* Testcase for very slow replace (performs about 22k replaces): | 7926 | /* Testcase for very slow replace (performs about 22k replaces): |
7933 | * x=:::::::::::::::::::::: | 7927 | * x=:::::::::::::::::::::: |
7934 | * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} | 7928 | * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} |
7935 | * echo "${x//:/|}" | 7929 | * echo "${x//:/|}" |
7930 | * To test "first_escaped" logic, replace : with *. | ||
7936 | */ | 7931 | */ |
7937 | if (strncmp(rmesc, str, no_meta_len) != 0) | 7932 | if (strncmp(rmesc, str + first_escaped, no_meta_len - first_escaped) != 0) |
7938 | goto no_match; | 7933 | goto no_match; |
7939 | loc = idx; | 7934 | loc = idx; |
7940 | if (!quotes) { | 7935 | if (!quotes) { |
7941 | loc += no_meta_len; | 7936 | loc += no_meta_len - first_escaped; |
7942 | } else { | 7937 | } else { |
7943 | size_t n = no_meta_len; | 7938 | size_t n = no_meta_len - first_escaped; |
7944 | do { | 7939 | do { |
7945 | if ((unsigned char)*loc == CTLESC) | 7940 | if ((unsigned char)*loc == CTLESC) |
7946 | loc++; | 7941 | loc++; |
@@ -11811,14 +11806,14 @@ static void freestrings(struct strpush *sp) | |||
11811 | INT_OFF; | 11806 | INT_OFF; |
11812 | do { | 11807 | do { |
11813 | struct strpush *psp; | 11808 | struct strpush *psp; |
11814 | 11809 | #if ENABLE_ASH_ALIAS | |
11815 | if (sp->ap) { | 11810 | if (sp->ap) { |
11816 | sp->ap->flag &= ~ALIASINUSE; | 11811 | sp->ap->flag &= ~ALIASINUSE; |
11817 | if (sp->ap->flag & ALIASDEAD) { | 11812 | if (sp->ap->flag & ALIASDEAD) { |
11818 | unalias(sp->ap->name); | 11813 | unalias(sp->ap->name); |
11819 | } | 11814 | } |
11820 | } | 11815 | } |
11821 | 11816 | #endif | |
11822 | psp = sp; | 11817 | psp = sp; |
11823 | sp = sp->spfree; | 11818 | sp = sp->spfree; |
11824 | 11819 | ||
@@ -15497,7 +15492,7 @@ init(void) | |||
15497 | 15492 | ||
15498 | 15493 | ||
15499 | //usage:#define ash_trivial_usage | 15494 | //usage:#define ash_trivial_usage |
15500 | //usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]" | 15495 | //usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]" |
15501 | //////// comes from ^^^^^^^^^^optletters | 15496 | //////// comes from ^^^^^^^^^^optletters |
15502 | //usage:#define ash_full_usage "\n\n" | 15497 | //usage:#define ash_full_usage "\n\n" |
15503 | //usage: "Unix shell interpreter" | 15498 | //usage: "Unix shell interpreter" |
@@ -15764,13 +15759,12 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
15764 | } | 15759 | } |
15765 | state2: | 15760 | state2: |
15766 | state = 3; | 15761 | state = 3; |
15767 | if ( | 15762 | if (iflag |
15768 | #if ENABLE_PLATFORM_POSIX | 15763 | #if ENABLE_PLATFORM_POSIX |
15769 | #ifndef linux | 15764 | #ifndef linux |
15770 | getuid() == geteuid() && getgid() == getegid() && | 15765 | && getuid() == geteuid() && getgid() == getegid() |
15771 | #endif | 15766 | #endif |
15772 | #endif | 15767 | #endif |
15773 | iflag | ||
15774 | ) { | 15768 | ) { |
15775 | const char *shinit = lookupvar("ENV"); | 15769 | const char *shinit = lookupvar("ENV"); |
15776 | if (shinit != NULL && *shinit != '\0') | 15770 | if (shinit != NULL && *shinit != '\0') |
diff --git a/shell/ash_test/ash-arith/arith-postinc.right b/shell/ash_test/ash-arith/arith-postinc.right index c95ce02bf..5cd4ba6b4 100644 --- a/shell/ash_test/ash-arith/arith-postinc.right +++ b/shell/ash_test/ash-arith/arith-postinc.right | |||
@@ -2,4 +2,7 @@ | |||
2 | 1 1 | 2 | 1 1 |
3 | 1 1 | 3 | 1 1 |
4 | 1 1 | 4 | 1 1 |
5 | 6 6 | ||
6 | 7 7 | ||
7 | 7 7 | ||
5 | Ok:0 | 8 | Ok:0 |
diff --git a/shell/ash_test/ash-arith/arith-postinc.tests b/shell/ash_test/ash-arith/arith-postinc.tests index 3fd9bfed5..f2ae778df 100755 --- a/shell/ash_test/ash-arith/arith-postinc.tests +++ b/shell/ash_test/ash-arith/arith-postinc.tests | |||
@@ -2,4 +2,8 @@ echo 1 $((0++1)) | |||
2 | echo 1 $((0--1)) | 2 | echo 1 $((0--1)) |
3 | x=-1; echo 1 $((0-$x)) | 3 | x=-1; echo 1 $((0-$x)) |
4 | x=+1; echo 1 $((0+$x)) | 4 | x=+1; echo 1 $((0+$x)) |
5 | a=3 | ||
6 | echo 6 $((a+++3)) # a++ + 3 | ||
7 | echo 7 $(((a)+++3)) # a + + + 3 | ||
8 | echo 7 $(((a)+++3)) # a + + + 3 | ||
5 | echo Ok:$? | 9 | echo Ok:$? |
diff --git a/shell/ash_test/ash-arith/arith.right b/shell/ash_test/ash-arith/arith.right index 6936f1269..61fcab55e 100644 --- a/shell/ash_test/ash-arith/arith.right +++ b/shell/ash_test/ash-arith/arith.right | |||
@@ -43,40 +43,60 @@ Format: 'expected actual' | |||
43 | 4 4 | 43 | 4 4 |
44 | 29 29 | 44 | 29 29 |
45 | 5 5 | 45 | 5 5 |
46 | unary plus, minus | ||
46 | -4 -4 | 47 | -4 -4 |
47 | 4 4 | 48 | 4 4 |
49 | conditional expressions | ||
48 | 1 1 | 50 | 1 1 |
49 | 32 32 | 51 | 32 32 |
50 | 32 32 | 52 | 32 32 |
51 | 1 1 | 53 | 1 1 |
52 | 1 1 | 54 | 1 1 |
53 | 32 32 | 55 | 32 32 |
56 | check that the unevaluated part of the ternary operator does not do evaluation or assignment | ||
54 | 20 20 | 57 | 20 20 |
55 | 30 30 | 58 | 30 30 |
56 | 20 20 | 59 | 20 20 |
57 | 30 30 | 60 | 30 30 |
58 | ./arith.tests: line 117: arithmetic syntax error | 61 | check precedence of assignment vs. conditional operator |
62 | ./arith.tests: line 116: arithmetic syntax error | ||
63 | check precedence of assignment vs. conditional operator | ||
64 | associativity of assignment-operator operator | ||
59 | 6 6 | 65 | 6 6 |
60 | 6,5,3 6,5,3 | 66 | 6,5,3 6,5,3 |
67 | octal, hex | ||
61 | 263 263 | 68 | 263 263 |
62 | 255 255 | 69 | 255 255 |
63 | 40 40 | 70 | 40 40 |
64 | ./arith.tests: line 163: arithmetic syntax error | 71 | other bases |
65 | ./arith.tests: line 165: divide by zero | 72 | 10 10 |
66 | ./arith.tests: let: line 166: arithmetic syntax error | 73 | 10 10 |
67 | ./arith.tests: line 167: arithmetic syntax error | 74 | 10 10 |
68 | ./arith.tests: let: line 168: arithmetic syntax error | 75 | 10 10 |
76 | 10 10 | ||
77 | 10 10 | ||
78 | 36 36 | ||
79 | 36 36 | ||
80 | 62 62 | ||
81 | 63 63 | ||
82 | missing number after base | ||
83 | 0 0 | ||
84 | ./arith.tests: line 162: arithmetic syntax error | ||
85 | ./arith.tests: line 164: divide by zero | ||
86 | ./arith.tests: let: line 165: arithmetic syntax error | ||
87 | ./arith.tests: line 166: arithmetic syntax error | ||
88 | ./arith.tests: let: line 167: arithmetic syntax error | ||
69 | abc | 89 | abc |
70 | def | 90 | def |
71 | ghi | 91 | ghi |
72 | ./arith.tests: line 191: arithmetic syntax error | 92 | ./arith.tests: line 190: arithmetic syntax error |
73 | 16 16 | 93 | 16 16 |
74 | ./arith.tests: line 196: arithmetic syntax error | 94 | ./arith.tests: line 195: arithmetic syntax error |
75 | ./arith.tests: line 197: malformed ?: operator | 95 | ./arith.tests: line 196: malformed ?: operator |
76 | ./arith.tests: line 198: arithmetic syntax error | 96 | ./arith.tests: line 197: arithmetic syntax error |
77 | 9 9 | 97 | 9 9 |
78 | ./arith.tests: line 205: arithmetic syntax error | 98 | ./arith.tests: line 204: arithmetic syntax error |
79 | ./arith.tests: line 208: arithmetic syntax error | 99 | ./arith.tests: line 207: arithmetic syntax error |
80 | 9 9 | 100 | 9 9 |
81 | 9 9 | 101 | 9 9 |
82 | 9 9 | 102 | 9 9 |
@@ -97,14 +117,17 @@ ghi | |||
97 | 3 3 | 117 | 3 3 |
98 | 4 4 | 118 | 4 4 |
99 | 4 4 | 119 | 4 4 |
100 | ./arith.tests: line 257: arithmetic syntax error | 120 | 7 7 |
121 | ./arith.tests: line 256: arithmetic syntax error | ||
122 | ./arith.tests: line 258: arithmetic syntax error | ||
101 | ./arith.tests: line 259: arithmetic syntax error | 123 | ./arith.tests: line 259: arithmetic syntax error |
102 | ./arith.tests: line 260: arithmetic syntax error | 124 | ./arith.tests: line 261: arithmetic syntax error |
103 | ./arith.tests: line 262: arithmetic syntax error | 125 | ./arith.tests: line 262: arithmetic syntax error |
104 | ./arith.tests: line 263: arithmetic syntax error | ||
105 | 4 4 | 126 | 4 4 |
106 | 7 7 | 127 | 7 7 |
107 | -7 -7 | 128 | -7 -7 |
129 | 7 | ||
130 | 7 | ||
108 | ./arith1.sub: line 2: arithmetic syntax error | 131 | ./arith1.sub: line 2: arithmetic syntax error |
109 | ./arith1.sub: line 3: arithmetic syntax error | 132 | ./arith1.sub: line 3: arithmetic syntax error |
110 | ./arith1.sub: line 4: arithmetic syntax error | 133 | ./arith1.sub: line 4: arithmetic syntax error |
@@ -119,11 +142,12 @@ ghi | |||
119 | 2 2 | 142 | 2 2 |
120 | -2 -2 | 143 | -2 -2 |
121 | 1 1 | 144 | 1 1 |
122 | ./arith1.sub: line 37: arithmetic syntax error | 145 | 7 |
123 | ./arith2.sub: line 2: arithmetic syntax error | 146 | 7 |
124 | ./arith2.sub: line 3: arithmetic syntax error | 147 | 7 |
125 | ./arith2.sub: line 4: arithmetic syntax error | 148 | 7 |
126 | ./arith2.sub: line 5: arithmetic syntax error | 149 | 7 |
150 | 7 | ||
127 | 5 5 | 151 | 5 5 |
128 | 1 1 | 152 | 1 1 |
129 | 6 6 | 153 | 6 6 |
@@ -132,11 +156,17 @@ ghi | |||
132 | 1 1 | 156 | 1 1 |
133 | 4 4 | 157 | 4 4 |
134 | 0 0 | 158 | 0 0 |
135 | ./arith2.sub: line 42: arithmetic syntax error | 159 | -7 |
136 | ./arith2.sub: line 47: arithmetic syntax error | 160 | -7 |
161 | 7 | ||
162 | 7 | ||
163 | -7 -7 | ||
164 | -7 -7 | ||
165 | 7 7 | ||
166 | 7 7 | ||
137 | 8 12 | 167 | 8 12 |
138 | ./arith.tests: line 290: arithmetic syntax error | 168 | ./arith.tests: line 289: arithmetic syntax error |
139 | 42 | 169 | 42 |
140 | 42 | 170 | 42 |
141 | 42 | 171 | 42 |
142 | ./arith.tests: line 302: a[b[c]d]=e: not found | 172 | ./arith.tests: line 301: a[b[c]d]=e: not found |
diff --git a/shell/ash_test/ash-arith/arith.tests b/shell/ash_test/ash-arith/arith.tests index d65758e7d..b9cb8ba4c 100755 --- a/shell/ash_test/ash-arith/arith.tests +++ b/shell/ash_test/ash-arith/arith.tests | |||
@@ -75,11 +75,11 @@ echo 4 $(( iv &= 4 )) | |||
75 | echo 29 $(( iv += (jv + 9))) | 75 | echo 29 $(( iv += (jv + 9))) |
76 | echo 5 $(( (iv + 4) % 7 )) | 76 | echo 5 $(( (iv + 4) % 7 )) |
77 | 77 | ||
78 | # unary plus, minus | 78 | echo unary plus, minus |
79 | echo -4 $(( +4 - 8 )) | 79 | echo -4 $(( +4 - 8 )) |
80 | echo 4 $(( -4 + 8 )) | 80 | echo 4 $(( -4 + 8 )) |
81 | 81 | ||
82 | # conditional expressions | 82 | echo conditional expressions |
83 | echo 1 $(( 4<5 ? 1 : 32)) | 83 | echo 1 $(( 4<5 ? 1 : 32)) |
84 | echo 32 $(( 4>5 ? 1 : 32)) | 84 | echo 32 $(( 4>5 ? 1 : 32)) |
85 | echo 32 $(( 4>(2+3) ? 1 : 32)) | 85 | echo 32 $(( 4>(2+3) ? 1 : 32)) |
@@ -87,8 +87,7 @@ echo 1 $(( 4<(2+3) ? 1 : 32)) | |||
87 | echo 1 $(( (2+2)<(2+3) ? 1 : 32)) | 87 | echo 1 $(( (2+2)<(2+3) ? 1 : 32)) |
88 | echo 32 $(( (2+2)>(2+3) ? 1 : 32)) | 88 | echo 32 $(( (2+2)>(2+3) ? 1 : 32)) |
89 | 89 | ||
90 | # check that the unevaluated part of the ternary operator does not do | 90 | echo check that the unevaluated part of the ternary operator does not do evaluation or assignment |
91 | # evaluation or assignment | ||
92 | x=i+=2 | 91 | x=i+=2 |
93 | y=j+=2 | 92 | y=j+=2 |
94 | #ash# declare -i i=1 j=1 | 93 | #ash# declare -i i=1 j=1 |
@@ -109,20 +108,20 @@ echo 20 $((1 ? 20 : (x+=2))) | |||
109 | echo 30 $((0 ? (y+=2) : 30)) | 108 | echo 30 $((0 ? (y+=2) : 30)) |
110 | #ash# echo $i,$y # ash mishandles this | 109 | #ash# echo $i,$y # ash mishandles this |
111 | 110 | ||
112 | # check precedence of assignment vs. conditional operator | 111 | echo check precedence of assignment vs. conditional operator |
113 | # should be an error | 112 | # should be an error |
114 | #ash# declare -i x=2 | 113 | #ash# declare -i x=2 |
115 | x=2 | 114 | x=2 |
116 | #ashnote# bash reports error but continues, ash aborts - using subshell to 'emulate' bash: | 115 | #ashnote# bash reports error but continues, ash aborts - using subshell to 'emulate' bash: |
117 | ( y=$((1 ? 20 : x+=2)) ) | 116 | ( y=$((1 ? 20 : x+=2)) ) |
118 | 117 | ||
119 | # check precedence of assignment vs. conditional operator | 118 | echo check precedence of assignment vs. conditional operator |
120 | #ash# declare -i x=2 | 119 | #ash# declare -i x=2 |
121 | x=2 | 120 | x=2 |
122 | # ash says "line NNN: syntax error: 0 ? x+=2 : 20" | 121 | # ash says "line NNN: syntax error: 0 ? x+=2 : 20" |
123 | #ash# echo 20 $((0 ? x+=2 : 20)) | 122 | #ash# echo 20 $((0 ? x+=2 : 20)) |
124 | 123 | ||
125 | # associativity of assignment-operator operator | 124 | echo associativity of assignment-operator operator |
126 | #ash# declare -i i=1 j=2 k=3 | 125 | #ash# declare -i i=1 j=2 k=3 |
127 | i=1 | 126 | i=1 |
128 | j=2 | 127 | j=2 |
@@ -130,7 +129,7 @@ k=3 | |||
130 | echo 6 $((i += j += k)) | 129 | echo 6 $((i += j += k)) |
131 | echo 6,5,3 $i,$j,$k | 130 | echo 6,5,3 $i,$j,$k |
132 | 131 | ||
133 | # octal, hex | 132 | echo octal, hex |
134 | echo 263 $(( 0x100 | 007 )) | 133 | echo 263 $(( 0x100 | 007 )) |
135 | echo 255 $(( 0xff )) | 134 | echo 255 $(( 0xff )) |
136 | #ash# echo 255 $(( 16#ff )) | 135 | #ash# echo 255 $(( 16#ff )) |
@@ -139,25 +138,25 @@ echo 255 $(( 0xff )) | |||
139 | 138 | ||
140 | echo 40 $(( 8 ^ 32 )) | 139 | echo 40 $(( 8 ^ 32 )) |
141 | 140 | ||
142 | #ash# # other bases | 141 | echo other bases |
143 | #ash# echo 10 $(( 16#a )) | 142 | echo 10 $(( 16#a )) |
144 | #ash# echo 10 $(( 32#a )) | 143 | echo 10 $(( 32#a )) |
145 | #ash# echo 10 $(( 56#a )) | 144 | echo 10 $(( 56#a )) |
146 | #ash# echo 10 $(( 64#a )) | 145 | echo 10 $(( 64#a )) |
147 | #ash# | 146 | |
148 | #ash# echo 10 $(( 16#A )) | 147 | echo 10 $(( 16#A )) |
149 | #ash# echo 10 $(( 32#A )) | 148 | echo 10 $(( 32#A )) |
150 | #ash# echo 36 $(( 56#A )) | 149 | echo 36 $(( 56#A )) |
151 | #ash# echo 36 $(( 64#A )) | 150 | echo 36 $(( 64#A )) |
152 | #ash# | 151 | |
153 | #ash# echo 62 $(( 64#@ )) | 152 | echo 62 $(( 64#@ )) |
154 | #ash# echo 63 $(( 64#_ )) | 153 | echo 63 $(( 64#_ )) |
155 | 154 | ||
156 | #ash# # weird bases (error) | 155 | #ash# # weird bases (error) |
157 | #ash# echo $(( 3425#56 )) | 156 | #ash# echo $(( 3425#56 )) |
158 | 157 | ||
159 | #ash# # missing number after base | 158 | echo missing number after base |
160 | #ash# echo 0 $(( 2# )) | 159 | echo 0 $(( 2# )) |
161 | 160 | ||
162 | # these should generate errors | 161 | # these should generate errors |
163 | ( echo $(( 7 = 43 )) ) | 162 | ( echo $(( 7 = 43 )) ) |
@@ -252,8 +251,8 @@ echo 3 $x | |||
252 | echo 4 $(( ++x )) | 251 | echo 4 $(( ++x )) |
253 | echo 4 $x | 252 | echo 4 $x |
254 | 253 | ||
255 | # bash 3.2 apparently thinks that ++7 is 7 | 254 | # ++ is not a inc operator on non-variable, it is the + + sequence |
256 | #ash# echo 7 $(( ++7 )) | 255 | echo 7 $(( ++7 )) |
257 | ( echo $(( 7-- )) ) | 256 | ( echo $(( 7-- )) ) |
258 | 257 | ||
259 | ( echo $(( --x=7 )) ) | 258 | ( echo $(( --x=7 )) ) |
@@ -267,9 +266,9 @@ echo 4 $x | |||
267 | echo 7 $(( +7 )) | 266 | echo 7 $(( +7 )) |
268 | echo -7 $(( -7 )) | 267 | echo -7 $(( -7 )) |
269 | 268 | ||
270 | # bash 3.2 apparently thinks that ++7 is 7 | 269 | # ++ is not a inc operator on non-variable, it is the + + sequence |
271 | #ash# echo $(( ++7 )) | 270 | echo $(( ++7 )) |
272 | #ash# echo $(( --7 )) | 271 | echo $(( --7 )) |
273 | 272 | ||
274 | ${THIS_SH} ./arith1.sub | 273 | ${THIS_SH} ./arith1.sub |
275 | ${THIS_SH} ./arith2.sub | 274 | ${THIS_SH} ./arith2.sub |
diff --git a/shell/ash_test/ash-arith/arith1.sub b/shell/ash_test/ash-arith/arith1.sub index 80aa99922..a36785c67 100755 --- a/shell/ash_test/ash-arith/arith1.sub +++ b/shell/ash_test/ash-arith/arith1.sub | |||
@@ -35,6 +35,6 @@ echo 1 $a | |||
35 | 35 | ||
36 | #ash# (( ++ )) | 36 | #ash# (( ++ )) |
37 | ( echo $(( +++7 )) ) | 37 | ( echo $(( +++7 )) ) |
38 | # bash 3.2 apparently thinks that ++ +7 is 7 | 38 | # ++ is not a inc operator on non-variable, it is the + + sequence |
39 | #ash# echo $(( ++ + 7 )) | 39 | echo $(( ++ + 7 )) |
40 | #ash# (( -- )) | 40 | #ash# (( -- )) |
diff --git a/shell/ash_test/ash-arith/arith2.sub b/shell/ash_test/ash-arith/arith2.sub index 9105059db..8d7918114 100755 --- a/shell/ash_test/ash-arith/arith2.sub +++ b/shell/ash_test/ash-arith/arith2.sub | |||
@@ -1,4 +1,4 @@ | |||
1 | # bash 3.2 apparently thinks that ++7 is 7 etc | 1 | # ++ and -- are not inc/dec operators on non-variables, they are + + and - - sequences |
2 | ( echo $(( --7 )) ) | 2 | ( echo $(( --7 )) ) |
3 | ( echo $(( ++7 )) ) | 3 | ( echo $(( ++7 )) ) |
4 | ( echo $(( -- 7 )) ) | 4 | ( echo $(( -- 7 )) ) |
@@ -37,21 +37,17 @@ echo 4 $(( 4 - -- a )) | |||
37 | echo 0 $a | 37 | echo 0 $a |
38 | 38 | ||
39 | #ash# (( -- )) | 39 | #ash# (( -- )) |
40 | # bash 3.2 apparently thinks that ---7 is -7 | 40 | # -- is not a dec operator on non-variable, it is the - - sequence |
41 | #ash# echo $(( ---7 )) | 41 | echo $(( ---7 )) |
42 | ( echo $(( -- - 7 )) ) | 42 | ( echo $(( -- - 7 )) ) |
43 | 43 | ||
44 | #ash# (( ++ )) | 44 | #ash# (( ++ )) |
45 | # bash 3.2: 7 | 45 | # ++ is not a inc operator on non-variable, it is the + + sequence |
46 | #ash# echo 7 $(( ++7 )) | 46 | echo $(( ++7 )) |
47 | ( echo $(( ++ + 7 )) ) | 47 | ( echo $(( ++ + 7 )) ) |
48 | 48 | ||
49 | # bash 3.2: -7 | 49 | echo -7 $(( ++-7 )) |
50 | #ash# echo -7 $(( ++-7 )) | 50 | echo -7 $(( ++ - 7 )) |
51 | # bash 3.2: -7 | ||
52 | #ash# echo -7 $(( ++ - 7 )) | ||
53 | 51 | ||
54 | # bash 3.2: 7 | 52 | echo 7 $(( +--7 )) |
55 | #ash# echo 7 $(( +--7 )) | 53 | echo 7 $(( -- + 7 )) |
56 | # bash 3.2: 7 | ||
57 | #ash# echo 7 $(( -- + 7 )) | ||
diff --git a/shell/ash_test/ash-comm/comm.right b/shell/ash_test/ash-comm/comm.right new file mode 100644 index 000000000..1d836656f --- /dev/null +++ b/shell/ash_test/ash-comm/comm.right | |||
@@ -0,0 +1,6 @@ | |||
1 | ./SCRIPT.sh: | ||
2 | /proc/N/comm: SCRIPT.sh | ||
3 | exec ./SCRIPT.sh: | ||
4 | /proc/N/comm: SCRIPT.sh | ||
5 | sh ./SCRIPT.sh: | ||
6 | /proc/N/comm: ash | ||
diff --git a/shell/ash_test/ash-comm/comm.tests b/shell/ash_test/ash-comm/comm.tests new file mode 100755 index 000000000..671bfc176 --- /dev/null +++ b/shell/ash_test/ash-comm/comm.tests | |||
@@ -0,0 +1,20 @@ | |||
1 | { | ||
2 | echo "#!$THIS_SH" | ||
3 | echo 'procdir=/proc/$$' | ||
4 | #echo 'echo " /proc/N/exe: $(basename $(readlink $procdir/exe))"' | ||
5 | echo 'echo " /proc/N/comm: $(cat $procdir/comm)"' | ||
6 | } >SCRIPT.sh | ||
7 | chmod 755 SCRIPT.sh | ||
8 | |||
9 | # comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y | ||
10 | echo './SCRIPT.sh:' | ||
11 | ./SCRIPT.sh | ||
12 | |||
13 | # comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y | ||
14 | echo 'exec ./SCRIPT.sh:' | ||
15 | (exec ./SCRIPT.sh) | ||
16 | |||
17 | echo 'sh ./SCRIPT.sh:' | ||
18 | $THIS_SH ./SCRIPT.sh | ||
19 | |||
20 | rm SCRIPT.sh | ||
diff --git a/shell/hush.c b/shell/hush.c index 6d472337f..6a27b1634 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -339,7 +339,7 @@ | |||
339 | * therefore we don't show them either. | 339 | * therefore we don't show them either. |
340 | */ | 340 | */ |
341 | //usage:#define hush_trivial_usage | 341 | //usage:#define hush_trivial_usage |
342 | //usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]" | 342 | //usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE ARGS | -s ARGS]" |
343 | //usage:#define hush_full_usage "\n\n" | 343 | //usage:#define hush_full_usage "\n\n" |
344 | //usage: "Unix shell interpreter" | 344 | //usage: "Unix shell interpreter" |
345 | 345 | ||
@@ -373,7 +373,7 @@ | |||
373 | # define F_DUPFD_CLOEXEC F_DUPFD | 373 | # define F_DUPFD_CLOEXEC F_DUPFD |
374 | #endif | 374 | #endif |
375 | 375 | ||
376 | #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !(ENABLE_ASH || ENABLE_SH_IS_ASH || ENABLE_BASH_IS_ASH) | 376 | #if ENABLE_FEATURE_SH_EMBEDDED_SCRIPTS && !ENABLE_SHELL_ASH |
377 | # include "embedded_scripts.h" | 377 | # include "embedded_scripts.h" |
378 | #else | 378 | #else |
379 | # define NUM_SCRIPTS 0 | 379 | # define NUM_SCRIPTS 0 |
@@ -3360,7 +3360,7 @@ static int glob_brace(char *pattern, o_string *o, int n) | |||
3360 | * NEXT points past the terminator of the first element, and REST | 3360 | * NEXT points past the terminator of the first element, and REST |
3361 | * points past the final }. We will accumulate result names from | 3361 | * points past the final }. We will accumulate result names from |
3362 | * recursive runs for each brace alternative in the buffer using | 3362 | * recursive runs for each brace alternative in the buffer using |
3363 | * GLOB_APPEND. */ | 3363 | * GLOB_APPEND. */ |
3364 | 3364 | ||
3365 | p = begin + 1; | 3365 | p = begin + 1; |
3366 | while (1) { | 3366 | while (1) { |
@@ -6311,7 +6311,7 @@ static char *encode_then_expand_vararg(const char *str, int handle_squotes, int | |||
6311 | 6311 | ||
6312 | /* Expanding ARG in ${var+ARG}, ${var-ARG} | 6312 | /* Expanding ARG in ${var+ARG}, ${var-ARG} |
6313 | */ | 6313 | */ |
6314 | static int encode_then_append_var_plusminus(o_string *output, int n, | 6314 | static NOINLINE int encode_then_append_var_plusminus(o_string *output, int n, |
6315 | char *str, int dquoted) | 6315 | char *str, int dquoted) |
6316 | { | 6316 | { |
6317 | struct in_str input; | 6317 | struct in_str input; |
@@ -6472,16 +6472,21 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) | |||
6472 | /* ${var/[/]pattern[/repl]} helpers */ | 6472 | /* ${var/[/]pattern[/repl]} helpers */ |
6473 | static char *strstr_pattern(char *val, const char *pattern, int *size) | 6473 | static char *strstr_pattern(char *val, const char *pattern, int *size) |
6474 | { | 6474 | { |
6475 | int sz = strcspn(pattern, "*?[\\"); | 6475 | int first_escaped = (pattern[0] == '\\' && pattern[1]); |
6476 | if (pattern[sz] == '\0') { | 6476 | /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars" |
6477 | * as literal too (as it is semi-common, and easy to accomodate | ||
6478 | * by just using str + 1). | ||
6479 | */ | ||
6480 | int sz = strcspn(pattern + first_escaped * 2, "*?[\\"); | ||
6481 | if ((pattern + first_escaped * 2)[sz] == '\0') { | ||
6477 | /* Optimization for trivial patterns. | 6482 | /* Optimization for trivial patterns. |
6478 | * Testcase for very slow replace (performs about 22k replaces): | 6483 | * Testcase for very slow replace (performs about 22k replaces): |
6479 | * x=:::::::::::::::::::::: | 6484 | * x=:::::::::::::::::::::: |
6480 | * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} | 6485 | * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} |
6481 | * echo "${x//:/|}" | 6486 | * echo "${x//:/|}" |
6482 | */ | 6487 | */ |
6483 | *size = sz; | 6488 | *size = sz + first_escaped; |
6484 | return strstr(val, pattern); | 6489 | return strstr(val, pattern + first_escaped); |
6485 | } | 6490 | } |
6486 | 6491 | ||
6487 | while (1) { | 6492 | while (1) { |
@@ -10220,7 +10225,7 @@ int hush_main(int argc, char **argv) | |||
10220 | 10225 | ||
10221 | cached_getpid = getpid(); /* for tcsetpgrp() during init */ | 10226 | cached_getpid = getpid(); /* for tcsetpgrp() during init */ |
10222 | G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ | 10227 | G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ |
10223 | G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */ | 10228 | G.root_ppid = getppid(); /* for $PPID (NOMMU can override) */ |
10224 | 10229 | ||
10225 | /* Deal with HUSH_VERSION */ | 10230 | /* Deal with HUSH_VERSION */ |
10226 | debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); | 10231 | debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); |
@@ -10351,6 +10356,29 @@ int hush_main(int argc, char **argv) | |||
10351 | /* Well, we cannot just declare interactiveness, | 10356 | /* Well, we cannot just declare interactiveness, |
10352 | * we have to have some stuff (ctty, etc) */ | 10357 | * we have to have some stuff (ctty, etc) */ |
10353 | /* G_interactive_fd++; */ | 10358 | /* G_interactive_fd++; */ |
10359 | //There are a few cases where bash -i -c 'SCRIPT' | ||
10360 | //has visible effect (differs from bash -c 'SCRIPT'): | ||
10361 | //it ignores TERM: | ||
10362 | // bash -i -c 'kill $$; echo ALIVE' | ||
10363 | // ALIVE | ||
10364 | //it resets SIG_INGed HUP to SIG_DFL: | ||
10365 | // trap '' hup; bash -i -c 'kill -hup $$; echo ALIVE' | ||
10366 | // Hangup [the message is not printed by bash, it's the shell which started it] | ||
10367 | //is talkative about jobs and exiting: | ||
10368 | // bash -i -c 'sleep 1 & exit' | ||
10369 | // [1] 16170 | ||
10370 | // exit | ||
10371 | //includes $ENV file (only if run as "sh"): | ||
10372 | // echo last >/tmp/ENV; ENV=/tmp/ENV sh -i -c 'echo HERE' | ||
10373 | // last: cannot open /var/log/wtmp: No such file or directory | ||
10374 | // HERE | ||
10375 | //(under "bash", it's the opposite: it runs $BASH_ENV file only *without* -i). | ||
10376 | // | ||
10377 | //ash -i -c 'sleep 3; sleep 3', on ^C, drops into a prompt instead of exiting | ||
10378 | //(this may be a bug, bash does not do this). | ||
10379 | //(ash -i -c 'sleep 3' won't show this, the last command gets auto-"exec"ed) | ||
10380 | // | ||
10381 | //None of the above feel like useful features people would rely on. | ||
10354 | break; | 10382 | break; |
10355 | case 's': | 10383 | case 's': |
10356 | G.opt_s = 1; | 10384 | G.opt_s = 1; |
@@ -11727,7 +11755,7 @@ static int FAST_FUNC builtin_fg_bg(char **argv) | |||
11727 | /* TODO: bash prints a string representation | 11755 | /* TODO: bash prints a string representation |
11728 | * of job being foregrounded (like "sleep 1 | cat") */ | 11756 | * of job being foregrounded (like "sleep 1 | cat") */ |
11729 | if (argv[0][0] == 'f' && G_saved_tty_pgrp) { | 11757 | if (argv[0][0] == 'f' && G_saved_tty_pgrp) { |
11730 | /* Put the job into the foreground. */ | 11758 | /* Put the job into the foreground. */ |
11731 | tcsetpgrp(G_interactive_fd, pi->pgrp); | 11759 | tcsetpgrp(G_interactive_fd, pi->pgrp); |
11732 | } | 11760 | } |
11733 | 11761 | ||
diff --git a/shell/hush_test/hush-arith/arith-postinc.right b/shell/hush_test/hush-arith/arith-postinc.right index c95ce02bf..5cd4ba6b4 100644 --- a/shell/hush_test/hush-arith/arith-postinc.right +++ b/shell/hush_test/hush-arith/arith-postinc.right | |||
@@ -2,4 +2,7 @@ | |||
2 | 1 1 | 2 | 1 1 |
3 | 1 1 | 3 | 1 1 |
4 | 1 1 | 4 | 1 1 |
5 | 6 6 | ||
6 | 7 7 | ||
7 | 7 7 | ||
5 | Ok:0 | 8 | Ok:0 |
diff --git a/shell/hush_test/hush-arith/arith-postinc.tests b/shell/hush_test/hush-arith/arith-postinc.tests index 3fd9bfed5..f2ae778df 100755 --- a/shell/hush_test/hush-arith/arith-postinc.tests +++ b/shell/hush_test/hush-arith/arith-postinc.tests | |||
@@ -2,4 +2,8 @@ echo 1 $((0++1)) | |||
2 | echo 1 $((0--1)) | 2 | echo 1 $((0--1)) |
3 | x=-1; echo 1 $((0-$x)) | 3 | x=-1; echo 1 $((0-$x)) |
4 | x=+1; echo 1 $((0+$x)) | 4 | x=+1; echo 1 $((0+$x)) |
5 | a=3 | ||
6 | echo 6 $((a+++3)) # a++ + 3 | ||
7 | echo 7 $(((a)+++3)) # a + + + 3 | ||
8 | echo 7 $(((a)+++3)) # a + + + 3 | ||
5 | echo Ok:$? | 9 | echo Ok:$? |
diff --git a/shell/hush_test/hush-arith/arith.right b/shell/hush_test/hush-arith/arith.right index c48e468a5..a8612295e 100644 --- a/shell/hush_test/hush-arith/arith.right +++ b/shell/hush_test/hush-arith/arith.right | |||
@@ -70,6 +70,19 @@ octal, hex | |||
70 | 263 263 | 70 | 263 263 |
71 | 255 255 | 71 | 255 255 |
72 | 40 40 | 72 | 40 40 |
73 | other bases | ||
74 | 10 10 | ||
75 | 10 10 | ||
76 | 10 10 | ||
77 | 10 10 | ||
78 | 10 10 | ||
79 | 10 10 | ||
80 | 36 36 | ||
81 | 36 36 | ||
82 | 62 62 | ||
83 | 63 63 | ||
84 | missing number after base | ||
85 | 0 0 | ||
73 | hush: arithmetic syntax error | 86 | hush: arithmetic syntax error |
74 | hush: divide by zero | 87 | hush: divide by zero |
75 | hush: can't execute 'let': No such file or directory | 88 | hush: can't execute 'let': No such file or directory |
@@ -106,6 +119,7 @@ hush: arithmetic syntax error | |||
106 | 3 3 | 119 | 3 3 |
107 | 4 4 | 120 | 4 4 |
108 | 4 4 | 121 | 4 4 |
122 | 7 7 | ||
109 | hush: arithmetic syntax error | 123 | hush: arithmetic syntax error |
110 | hush: arithmetic syntax error | 124 | hush: arithmetic syntax error |
111 | hush: arithmetic syntax error | 125 | hush: arithmetic syntax error |
@@ -114,6 +128,8 @@ hush: arithmetic syntax error | |||
114 | 4 4 | 128 | 4 4 |
115 | 7 7 | 129 | 7 7 |
116 | -7 -7 | 130 | -7 -7 |
131 | 7 | ||
132 | 7 | ||
117 | hush: arithmetic syntax error | 133 | hush: arithmetic syntax error |
118 | hush: arithmetic syntax error | 134 | hush: arithmetic syntax error |
119 | hush: arithmetic syntax error | 135 | hush: arithmetic syntax error |
@@ -128,11 +144,12 @@ hush: arithmetic syntax error | |||
128 | 2 2 | 144 | 2 2 |
129 | -2 -2 | 145 | -2 -2 |
130 | 1 1 | 146 | 1 1 |
131 | hush: arithmetic syntax error | 147 | 7 |
132 | hush: arithmetic syntax error | 148 | 7 |
133 | hush: arithmetic syntax error | 149 | 7 |
134 | hush: arithmetic syntax error | 150 | 7 |
135 | hush: arithmetic syntax error | 151 | 7 |
152 | 7 | ||
136 | 5 5 | 153 | 5 5 |
137 | 1 1 | 154 | 1 1 |
138 | 6 6 | 155 | 6 6 |
@@ -141,8 +158,14 @@ hush: arithmetic syntax error | |||
141 | 1 1 | 158 | 1 1 |
142 | 4 4 | 159 | 4 4 |
143 | 0 0 | 160 | 0 0 |
144 | hush: arithmetic syntax error | 161 | -7 |
145 | hush: arithmetic syntax error | 162 | -7 |
163 | 7 | ||
164 | 7 | ||
165 | -7 -7 | ||
166 | -7 -7 | ||
167 | 7 7 | ||
168 | 7 7 | ||
146 | 8 12 | 169 | 8 12 |
147 | hush: arithmetic syntax error | 170 | hush: arithmetic syntax error |
148 | 42 | 171 | 42 |
diff --git a/shell/hush_test/hush-arith/arith.tests b/shell/hush_test/hush-arith/arith.tests index bc6b341d1..6b707486c 100755 --- a/shell/hush_test/hush-arith/arith.tests +++ b/shell/hush_test/hush-arith/arith.tests | |||
@@ -142,25 +142,25 @@ echo 255 $(( 0xff )) | |||
142 | 142 | ||
143 | echo 40 $(( 8 ^ 32 )) | 143 | echo 40 $(( 8 ^ 32 )) |
144 | 144 | ||
145 | #ash# # other bases | 145 | echo other bases |
146 | #ash# echo 10 $(( 16#a )) | 146 | echo 10 $(( 16#a )) |
147 | #ash# echo 10 $(( 32#a )) | 147 | echo 10 $(( 32#a )) |
148 | #ash# echo 10 $(( 56#a )) | 148 | echo 10 $(( 56#a )) |
149 | #ash# echo 10 $(( 64#a )) | 149 | echo 10 $(( 64#a )) |
150 | #ash# | 150 | |
151 | #ash# echo 10 $(( 16#A )) | 151 | echo 10 $(( 16#A )) |
152 | #ash# echo 10 $(( 32#A )) | 152 | echo 10 $(( 32#A )) |
153 | #ash# echo 36 $(( 56#A )) | 153 | echo 36 $(( 56#A )) |
154 | #ash# echo 36 $(( 64#A )) | 154 | echo 36 $(( 64#A )) |
155 | #ash# | 155 | |
156 | #ash# echo 62 $(( 64#@ )) | 156 | echo 62 $(( 64#@ )) |
157 | #ash# echo 63 $(( 64#_ )) | 157 | echo 63 $(( 64#_ )) |
158 | 158 | ||
159 | #ash# # weird bases (error) | 159 | #ash# # weird bases (error) |
160 | #ash# echo $(( 3425#56 )) | 160 | #ash# echo $(( 3425#56 )) |
161 | 161 | ||
162 | #ash# # missing number after base | 162 | echo missing number after base |
163 | #ash# echo 0 $(( 2# )) | 163 | echo 0 $(( 2# )) |
164 | 164 | ||
165 | # these should generate errors | 165 | # these should generate errors |
166 | ( echo $(( 7 = 43 )) ) | 166 | ( echo $(( 7 = 43 )) ) |
@@ -255,8 +255,8 @@ echo 3 $x | |||
255 | echo 4 $(( ++x )) | 255 | echo 4 $(( ++x )) |
256 | echo 4 $x | 256 | echo 4 $x |
257 | 257 | ||
258 | # bash 3.2 apparently thinks that ++7 is 7 | 258 | # ++ is not a inc operator on non-variable, it is the + + sequence |
259 | #ash# echo 7 $(( ++7 )) | 259 | echo 7 $(( ++7 )) |
260 | ( echo $(( 7-- )) ) | 260 | ( echo $(( 7-- )) ) |
261 | 261 | ||
262 | ( echo $(( --x=7 )) ) | 262 | ( echo $(( --x=7 )) ) |
@@ -270,9 +270,9 @@ echo 4 $x | |||
270 | echo 7 $(( +7 )) | 270 | echo 7 $(( +7 )) |
271 | echo -7 $(( -7 )) | 271 | echo -7 $(( -7 )) |
272 | 272 | ||
273 | # bash 3.2 apparently thinks that ++7 is 7 | 273 | # ++ is not a inc operator on non-variable, it is the + + sequence |
274 | #ash# echo $(( ++7 )) | 274 | echo $(( ++7 )) |
275 | #ash# echo $(( --7 )) | 275 | echo $(( --7 )) |
276 | 276 | ||
277 | ${THIS_SH} ./arith1.sub | 277 | ${THIS_SH} ./arith1.sub |
278 | ${THIS_SH} ./arith2.sub | 278 | ${THIS_SH} ./arith2.sub |
diff --git a/shell/hush_test/hush-arith/arith1.sub b/shell/hush_test/hush-arith/arith1.sub index 80aa99922..a36785c67 100755 --- a/shell/hush_test/hush-arith/arith1.sub +++ b/shell/hush_test/hush-arith/arith1.sub | |||
@@ -35,6 +35,6 @@ echo 1 $a | |||
35 | 35 | ||
36 | #ash# (( ++ )) | 36 | #ash# (( ++ )) |
37 | ( echo $(( +++7 )) ) | 37 | ( echo $(( +++7 )) ) |
38 | # bash 3.2 apparently thinks that ++ +7 is 7 | 38 | # ++ is not a inc operator on non-variable, it is the + + sequence |
39 | #ash# echo $(( ++ + 7 )) | 39 | echo $(( ++ + 7 )) |
40 | #ash# (( -- )) | 40 | #ash# (( -- )) |
diff --git a/shell/hush_test/hush-arith/arith2.sub b/shell/hush_test/hush-arith/arith2.sub index 9105059db..8d7918114 100755 --- a/shell/hush_test/hush-arith/arith2.sub +++ b/shell/hush_test/hush-arith/arith2.sub | |||
@@ -1,4 +1,4 @@ | |||
1 | # bash 3.2 apparently thinks that ++7 is 7 etc | 1 | # ++ and -- are not inc/dec operators on non-variables, they are + + and - - sequences |
2 | ( echo $(( --7 )) ) | 2 | ( echo $(( --7 )) ) |
3 | ( echo $(( ++7 )) ) | 3 | ( echo $(( ++7 )) ) |
4 | ( echo $(( -- 7 )) ) | 4 | ( echo $(( -- 7 )) ) |
@@ -37,21 +37,17 @@ echo 4 $(( 4 - -- a )) | |||
37 | echo 0 $a | 37 | echo 0 $a |
38 | 38 | ||
39 | #ash# (( -- )) | 39 | #ash# (( -- )) |
40 | # bash 3.2 apparently thinks that ---7 is -7 | 40 | # -- is not a dec operator on non-variable, it is the - - sequence |
41 | #ash# echo $(( ---7 )) | 41 | echo $(( ---7 )) |
42 | ( echo $(( -- - 7 )) ) | 42 | ( echo $(( -- - 7 )) ) |
43 | 43 | ||
44 | #ash# (( ++ )) | 44 | #ash# (( ++ )) |
45 | # bash 3.2: 7 | 45 | # ++ is not a inc operator on non-variable, it is the + + sequence |
46 | #ash# echo 7 $(( ++7 )) | 46 | echo $(( ++7 )) |
47 | ( echo $(( ++ + 7 )) ) | 47 | ( echo $(( ++ + 7 )) ) |
48 | 48 | ||
49 | # bash 3.2: -7 | 49 | echo -7 $(( ++-7 )) |
50 | #ash# echo -7 $(( ++-7 )) | 50 | echo -7 $(( ++ - 7 )) |
51 | # bash 3.2: -7 | ||
52 | #ash# echo -7 $(( ++ - 7 )) | ||
53 | 51 | ||
54 | # bash 3.2: 7 | 52 | echo 7 $(( +--7 )) |
55 | #ash# echo 7 $(( +--7 )) | 53 | echo 7 $(( -- + 7 )) |
56 | # bash 3.2: 7 | ||
57 | #ash# echo 7 $(( -- + 7 )) | ||
diff --git a/shell/hush_test/hush-comm/comm.right b/shell/hush_test/hush-comm/comm.right new file mode 100644 index 000000000..1b62b617e --- /dev/null +++ b/shell/hush_test/hush-comm/comm.right | |||
@@ -0,0 +1,6 @@ | |||
1 | ./SCRIPT.sh: | ||
2 | /proc/N/comm: SCRIPT.sh | ||
3 | exec ./SCRIPT.sh: | ||
4 | /proc/N/comm: SCRIPT.sh | ||
5 | sh ./SCRIPT.sh: | ||
6 | /proc/N/comm: hush | ||
diff --git a/shell/hush_test/hush-comm/comm.tests b/shell/hush_test/hush-comm/comm.tests new file mode 100755 index 000000000..671bfc176 --- /dev/null +++ b/shell/hush_test/hush-comm/comm.tests | |||
@@ -0,0 +1,20 @@ | |||
1 | { | ||
2 | echo "#!$THIS_SH" | ||
3 | echo 'procdir=/proc/$$' | ||
4 | #echo 'echo " /proc/N/exe: $(basename $(readlink $procdir/exe))"' | ||
5 | echo 'echo " /proc/N/comm: $(cat $procdir/comm)"' | ||
6 | } >SCRIPT.sh | ||
7 | chmod 755 SCRIPT.sh | ||
8 | |||
9 | # comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y | ||
10 | echo './SCRIPT.sh:' | ||
11 | ./SCRIPT.sh | ||
12 | |||
13 | # comm field was wrong if CONFIG_FEATURE_PREFER_APPLETS=y | ||
14 | echo 'exec ./SCRIPT.sh:' | ||
15 | (exec ./SCRIPT.sh) | ||
16 | |||
17 | echo 'sh ./SCRIPT.sh:' | ||
18 | $THIS_SH ./SCRIPT.sh | ||
19 | |||
20 | rm SCRIPT.sh | ||
diff --git a/shell/math.c b/shell/math.c index 2942cdd26..76d22c9bd 100644 --- a/shell/math.c +++ b/shell/math.c | |||
@@ -116,10 +116,6 @@ | |||
116 | #include "libbb.h" | 116 | #include "libbb.h" |
117 | #include "math.h" | 117 | #include "math.h" |
118 | 118 | ||
119 | #define lookupvar (math_state->lookupvar) | ||
120 | #define setvar (math_state->setvar ) | ||
121 | //#define endofname (math_state->endofname) | ||
122 | |||
123 | typedef unsigned char operator; | 119 | typedef unsigned char operator; |
124 | 120 | ||
125 | /* An operator's token id is a bit of a bitfield. The lower 5 bits are the | 121 | /* An operator's token id is a bit of a bitfield. The lower 5 bits are the |
@@ -258,7 +254,7 @@ static const char* | |||
258 | arith_lookup_val(arith_state_t *math_state, var_or_num_t *t) | 254 | arith_lookup_val(arith_state_t *math_state, var_or_num_t *t) |
259 | { | 255 | { |
260 | if (t->var) { | 256 | if (t->var) { |
261 | const char *p = lookupvar(t->var); | 257 | const char *p = math_state->lookupvar(t->var); |
262 | if (p) { | 258 | if (p) { |
263 | remembered_name *cur; | 259 | remembered_name *cur; |
264 | remembered_name cur_save; | 260 | remembered_name cur_save; |
@@ -445,16 +441,15 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_ | |||
445 | 441 | ||
446 | if (top_of_stack->var == NULL) { | 442 | if (top_of_stack->var == NULL) { |
447 | /* Hmm, 1=2 ? */ | 443 | /* Hmm, 1=2 ? */ |
448 | //TODO: actually, bash allows ++7 but for some reason it evals to 7, not 8 | ||
449 | goto err; | 444 | goto err; |
450 | } | 445 | } |
451 | /* Save to shell variable */ | 446 | /* Save to shell variable */ |
452 | sprintf(buf, ARITH_FMT, rez); | 447 | sprintf(buf, ARITH_FMT, rez); |
453 | setvar(top_of_stack->var, buf); | 448 | math_state->setvar(top_of_stack->var, buf); |
454 | /* After saving, make previous value for v++ or v-- */ | 449 | /* After saving, make previous value for v++ or v-- */ |
455 | if (op == TOK_POST_INC) | 450 | if (op == TOK_POST_INC) |
456 | rez--; | 451 | rez--; |
457 | else if (op == TOK_POST_DEC) | 452 | if (op == TOK_POST_DEC) |
458 | rez++; | 453 | rez++; |
459 | } | 454 | } |
460 | 455 | ||
@@ -607,11 +602,9 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
607 | const char *p; | 602 | const char *p; |
608 | operator op; | 603 | operator op; |
609 | operator prec; | 604 | operator prec; |
610 | char arithval; | ||
611 | 605 | ||
612 | expr = skip_whitespace(expr); | 606 | expr = skip_whitespace(expr); |
613 | arithval = *expr; | 607 | if (*expr == '\0') { |
614 | if (arithval == '\0') { | ||
615 | if (expr == start_expr) { | 608 | if (expr == start_expr) { |
616 | /* Null expression */ | 609 | /* Null expression */ |
617 | numstack->val = 0; | 610 | numstack->val = 0; |
@@ -628,6 +621,7 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
628 | * append a closing right paren | 621 | * append a closing right paren |
629 | * and let the loop process it */ | 622 | * and let the loop process it */ |
630 | expr = ptr_to_rparen; | 623 | expr = ptr_to_rparen; |
624 | //bb_error_msg("expr=')'"); | ||
631 | continue; | 625 | continue; |
632 | } | 626 | } |
633 | /* At this point, we're done with the expression */ | 627 | /* At this point, we're done with the expression */ |
@@ -635,19 +629,16 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
635 | /* ...but if there isn't, it's bad */ | 629 | /* ...but if there isn't, it's bad */ |
636 | goto err; | 630 | goto err; |
637 | } | 631 | } |
638 | if (numstack->var) { | ||
639 | /* expression is $((var)) only, lookup now */ | ||
640 | errmsg = arith_lookup_val(math_state, numstack); | ||
641 | } | ||
642 | goto ret; | 632 | goto ret; |
643 | } | 633 | } |
644 | 634 | ||
645 | p = endofname(expr); | 635 | p = endofname(expr); |
646 | if (p != expr) { | 636 | if (p != expr) { |
647 | /* Name */ | 637 | /* Name */ |
648 | size_t var_name_size = (p-expr) + 1; /* +1 for NUL */ | 638 | size_t var_name_size = (p - expr) + 1; /* +1 for NUL */ |
649 | numstackptr->var = alloca(var_name_size); | 639 | numstackptr->var = alloca(var_name_size); |
650 | safe_strncpy(numstackptr->var, expr, var_name_size); | 640 | safe_strncpy(numstackptr->var, expr, var_name_size); |
641 | //bb_error_msg("var:'%s'", numstackptr->var); | ||
651 | expr = p; | 642 | expr = p; |
652 | num: | 643 | num: |
653 | numstackptr->second_val_present = 0; | 644 | numstackptr->second_val_present = 0; |
@@ -656,11 +647,12 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
656 | continue; | 647 | continue; |
657 | } | 648 | } |
658 | 649 | ||
659 | if (isdigit(arithval)) { | 650 | if (isdigit(*expr)) { |
660 | /* Number */ | 651 | /* Number */ |
661 | numstackptr->var = NULL; | 652 | numstackptr->var = NULL; |
662 | errno = 0; | 653 | errno = 0; |
663 | numstackptr->val = strto_arith_t(expr, (char**) &expr); | 654 | numstackptr->val = strto_arith_t(expr, (char**) &expr); |
655 | //bb_error_msg("val:%lld", numstackptr->val); | ||
664 | if (errno) | 656 | if (errno) |
665 | numstackptr->val = 0; /* bash compat */ | 657 | numstackptr->val = 0; /* bash compat */ |
666 | goto num; | 658 | goto num; |
@@ -668,19 +660,26 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
668 | 660 | ||
669 | /* Should be an operator */ | 661 | /* Should be an operator */ |
670 | 662 | ||
671 | /* Special case: NUM-- and NUM++ are not recognized if NUM | 663 | /* Special case: XYZ--, XYZ++, --XYZ, ++XYZ are recognized |
672 | * is a literal number, not a variable. IOW: | 664 | * only if XYZ is a variable name, not a number or EXPR. IOW: |
673 | * "a+++v" is a++ + v. | 665 | * "a+++v" is a++ + v. |
666 | * "(a)+++7" is ( a ) + + + 7. | ||
674 | * "7+++v" is 7 + ++v, not 7++ + v. | 667 | * "7+++v" is 7 + ++v, not 7++ + v. |
668 | * "--7" is - - 7, not --7. | ||
669 | * "++++a" is + + ++a, not ++ ++a. | ||
675 | */ | 670 | */ |
676 | if (lasttok == TOK_NUM && !numstackptr[-1].var /* number literal */ | 671 | if ((expr[0] == '+' || expr[0] == '-') |
677 | && (expr[0] == '+' || expr[0] == '-') | ||
678 | && (expr[1] == expr[0]) | 672 | && (expr[1] == expr[0]) |
679 | ) { | 673 | ) { |
680 | //bb_error_msg("special %c%c", expr[0], expr[0]); | 674 | if (numstackptr == numstack || !numstackptr[-1].var) { /* not a VAR++ */ |
681 | op = (expr[0] == '+' ? TOK_ADD : TOK_SUB); | 675 | char next = skip_whitespace(expr + 2)[0]; |
682 | expr += 1; | 676 | if (!(isalpha(next) || next == '_')) { /* not a ++VAR */ |
683 | goto tok_found1; | 677 | //bb_error_msg("special %c%c", expr[0], expr[0]); |
678 | op = (expr[0] == '+' ? TOK_ADD : TOK_SUB); | ||
679 | expr++; | ||
680 | goto tok_found1; | ||
681 | } | ||
682 | } | ||
684 | } | 683 | } |
685 | 684 | ||
686 | p = op_tokens; | 685 | p = op_tokens; |
@@ -749,26 +748,40 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
749 | * "applied" in this way. | 748 | * "applied" in this way. |
750 | */ | 749 | */ |
751 | prec = PREC(op); | 750 | prec = PREC(op); |
751 | //bb_error_msg("prec:%02x", prec); | ||
752 | if ((prec > 0 && prec < UNARYPREC) || prec == SPEC_PREC) { | 752 | if ((prec > 0 && prec < UNARYPREC) || prec == SPEC_PREC) { |
753 | /* not left paren or unary */ | 753 | /* not left paren or unary */ |
754 | if (lasttok != TOK_NUM) { | 754 | if (lasttok != TOK_NUM) { |
755 | /* binary op must be preceded by a num */ | 755 | /* binary op must be preceded by a num */ |
756 | goto err; | 756 | goto err; |
757 | } | 757 | } |
758 | /* The algorithm employed here is simple: while we don't | ||
759 | * hit an open paren nor the bottom of the stack, pop | ||
760 | * tokens and apply them */ | ||
758 | while (stackptr != stack) { | 761 | while (stackptr != stack) { |
759 | operator prev_op = *--stackptr; | 762 | operator prev_op = *--stackptr; |
760 | if (op == TOK_RPAREN) { | 763 | if (op == TOK_RPAREN) { |
761 | /* The algorithm employed here is simple: while we don't | 764 | //bb_error_msg("op == TOK_RPAREN"); |
762 | * hit an open paren nor the bottom of the stack, pop | ||
763 | * tokens and apply them */ | ||
764 | if (prev_op == TOK_LPAREN) { | 765 | if (prev_op == TOK_LPAREN) { |
766 | //bb_error_msg("prev_op == TOK_LPAREN"); | ||
767 | //bb_error_msg(" %p %p numstackptr[-1].var:'%s'", numstack, numstackptr-1, numstackptr[-1].var); | ||
768 | if (numstackptr[-1].var) { | ||
769 | /* Expression is (var), lookup now */ | ||
770 | errmsg = arith_lookup_val(math_state, &numstackptr[-1]); | ||
771 | if (errmsg) | ||
772 | goto err_with_custom_msg; | ||
773 | /* Erase var name: (var) is just a number, for example, (var) = 1 is not valid */ | ||
774 | numstackptr[-1].var = NULL; | ||
775 | } | ||
765 | /* Any operator directly after a | 776 | /* Any operator directly after a |
766 | * close paren should consider itself binary */ | 777 | * close paren should consider itself binary */ |
767 | lasttok = TOK_NUM; | 778 | lasttok = TOK_NUM; |
768 | goto next; | 779 | goto next; |
769 | } | 780 | } |
781 | //bb_error_msg("prev_op != TOK_LPAREN"); | ||
770 | } else { | 782 | } else { |
771 | operator prev_prec = PREC(prev_op); | 783 | operator prev_prec = PREC(prev_op); |
784 | //bb_error_msg("op != TOK_RPAREN"); | ||
772 | fix_assignment_prec(prec); | 785 | fix_assignment_prec(prec); |
773 | fix_assignment_prec(prev_prec); | 786 | fix_assignment_prec(prev_prec); |
774 | if (prev_prec < prec | 787 | if (prev_prec < prec |
@@ -778,6 +791,7 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
778 | break; | 791 | break; |
779 | } | 792 | } |
780 | } | 793 | } |
794 | //bb_error_msg("arith_apply(prev_op:%02x)", prev_op); | ||
781 | errmsg = arith_apply(math_state, prev_op, numstack, &numstackptr); | 795 | errmsg = arith_apply(math_state, prev_op, numstack, &numstackptr); |
782 | if (errmsg) | 796 | if (errmsg) |
783 | goto err_with_custom_msg; | 797 | goto err_with_custom_msg; |
@@ -787,6 +801,7 @@ evaluate_string(arith_state_t *math_state, const char *expr) | |||
787 | } | 801 | } |
788 | 802 | ||
789 | /* Push this operator to the stack and remember it */ | 803 | /* Push this operator to the stack and remember it */ |
804 | //bb_error_msg("push op:%02x", op); | ||
790 | *stackptr++ = lasttok = op; | 805 | *stackptr++ = lasttok = op; |
791 | next: ; | 806 | next: ; |
792 | } /* while (1) */ | 807 | } /* while (1) */ |