diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-24 01:58:04 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-10-24 01:58:04 +0200 |
commit | 2b299fed6a77d3aaf7e4e768fb519f2536c2eff0 (patch) | |
tree | 1d86a176ddfbc1f853842629b758c0ab4e8ada9a | |
parent | 53600591311a129717abd2e3bcaa302622a6ce67 (diff) | |
download | busybox-w32-2b299fed6a77d3aaf7e4e768fb519f2536c2eff0.tar.gz busybox-w32-2b299fed6a77d3aaf7e4e768fb519f2536c2eff0.tar.bz2 busybox-w32-2b299fed6a77d3aaf7e4e768fb519f2536c2eff0.zip |
awk: fix breakage in last commit
While at it, made bb_process_escape_sequence faster (same size)
function old new delta
nextchar 49 53 +4
bb_process_escape_sequence 138 140 +2
next_token 838 839 +1
static.charmap 20 18 -2
is_assignment 143 135 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/2 up/down: 7/-10) Total: -3 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | editors/awk.c | 27 | ||||
-rw-r--r-- | libbb/process_escape_sequence.c | 46 |
2 files changed, 38 insertions, 35 deletions
diff --git a/editors/awk.c b/editors/awk.c index fb3bf6b47..9646cedd6 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -684,8 +684,11 @@ static char nextchar(char **s) | |||
684 | pps = *s; | 684 | pps = *s; |
685 | if (c == '\\') | 685 | if (c == '\\') |
686 | c = bb_process_escape_sequence((const char**)s); | 686 | c = bb_process_escape_sequence((const char**)s); |
687 | if (c == '\\' && *s == pps) | 687 | if (c == '\\' && *s == pps) { /* unrecognized \z? */ |
688 | c = *(*s)++; | 688 | c = *(*s); /* yes, fetch z */ |
689 | if (c) | ||
690 | (*s)++; /* advance unless z = NUL */ | ||
691 | } | ||
689 | return c; | 692 | return c; |
690 | } | 693 | } |
691 | 694 | ||
@@ -1007,9 +1010,10 @@ static uint32_t next_token(uint32_t expected) | |||
1007 | /* it's a string */ | 1010 | /* it's a string */ |
1008 | t_string = s = ++p; | 1011 | t_string = s = ++p; |
1009 | while (*p != '\"') { | 1012 | while (*p != '\"') { |
1010 | char *pp = p; | 1013 | char *pp; |
1011 | if (*p == '\0' || *p == '\n') | 1014 | if (*p == '\0' || *p == '\n') |
1012 | syntax_error(EMSG_UNEXP_EOS); | 1015 | syntax_error(EMSG_UNEXP_EOS); |
1016 | pp = p; | ||
1013 | *s++ = nextchar(&pp); | 1017 | *s++ = nextchar(&pp); |
1014 | p = pp; | 1018 | p = pp; |
1015 | } | 1019 | } |
@@ -2926,22 +2930,21 @@ static int awk_exit(int r) | |||
2926 | * otherwise return 0 */ | 2930 | * otherwise return 0 */ |
2927 | static int is_assignment(const char *expr) | 2931 | static int is_assignment(const char *expr) |
2928 | { | 2932 | { |
2929 | char *exprc, *s, *s0, *s1; | 2933 | char *exprc, *val, *s, *s1; |
2930 | 2934 | ||
2931 | if (!isalnum_(*expr) || (s0 = strchr(expr, '=')) == NULL) { | 2935 | if (!isalnum_(*expr) || (val = strchr(expr, '=')) == NULL) { |
2932 | return FALSE; | 2936 | return FALSE; |
2933 | } | 2937 | } |
2934 | 2938 | ||
2935 | exprc = xstrdup(expr); | 2939 | exprc = xstrdup(expr); |
2936 | s0 = exprc + (s0 - expr); | 2940 | val = exprc + (val - expr); |
2937 | *s++ = '\0'; | 2941 | *val++ = '\0'; |
2938 | 2942 | ||
2939 | s = s1 = s0; | 2943 | s = s1 = val; |
2940 | while (*s) | 2944 | while ((*s1 = nextchar(&s)) != '\0') |
2941 | *s1++ = nextchar(&s); | 2945 | s1++; |
2942 | *s1 = '\0'; | ||
2943 | 2946 | ||
2944 | setvar_u(newvar(exprc), s0); | 2947 | setvar_u(newvar(exprc), val); |
2945 | free(exprc); | 2948 | free(exprc); |
2946 | return TRUE; | 2949 | return TRUE; |
2947 | } | 2950 | } |
diff --git a/libbb/process_escape_sequence.c b/libbb/process_escape_sequence.c index dd6e076b0..7b1d97f9c 100644 --- a/libbb/process_escape_sequence.c +++ b/libbb/process_escape_sequence.c | |||
@@ -18,18 +18,8 @@ | |||
18 | 18 | ||
19 | char FAST_FUNC bb_process_escape_sequence(const char **ptr) | 19 | char FAST_FUNC bb_process_escape_sequence(const char **ptr) |
20 | { | 20 | { |
21 | /* bash builtin "echo -e '\ec'" interprets \e as ESC, | ||
22 | * but coreutils "/bin/echo -e '\ec'" does not. | ||
23 | * manpages tend to support coreutils way. | ||
24 | * Update: coreutils added support for \e on 28 Oct 2009. */ | ||
25 | static const char charmap[] ALIGN1 = { | ||
26 | 'a', 'b', 'e', 'f', 'n', 'r', 't', 'v', '\\', 0, | ||
27 | '\a', '\b', 27, '\f', '\n', '\r', '\t', '\v', '\\', '\\' }; | ||
28 | |||
29 | const char *p; | ||
30 | const char *q; | 21 | const char *q; |
31 | unsigned num_digits; | 22 | unsigned num_digits; |
32 | unsigned r; | ||
33 | unsigned n; | 23 | unsigned n; |
34 | unsigned base; | 24 | unsigned base; |
35 | 25 | ||
@@ -37,18 +27,17 @@ char FAST_FUNC bb_process_escape_sequence(const char **ptr) | |||
37 | base = 8; | 27 | base = 8; |
38 | q = *ptr; | 28 | q = *ptr; |
39 | 29 | ||
40 | #if WANT_HEX_ESCAPES | 30 | if (WANT_HEX_ESCAPES && *q == 'x') { |
41 | if (*q == 'x') { | ||
42 | ++q; | 31 | ++q; |
43 | base = 16; | 32 | base = 16; |
44 | ++num_digits; | 33 | ++num_digits; |
45 | } | 34 | } |
46 | #endif | ||
47 | 35 | ||
48 | /* bash requires leading 0 in octal escapes: | 36 | /* bash requires leading 0 in octal escapes: |
49 | * \02 works, \2 does not (prints \ and 2). | 37 | * \02 works, \2 does not (prints \ and 2). |
50 | * We treat \2 as a valid octal escape sequence. */ | 38 | * We treat \2 as a valid octal escape sequence. */ |
51 | do { | 39 | do { |
40 | unsigned r; | ||
52 | #if !WANT_HEX_ESCAPES | 41 | #if !WANT_HEX_ESCAPES |
53 | unsigned d = (unsigned char)(*q) - '0'; | 42 | unsigned d = (unsigned char)(*q) - '0'; |
54 | #else | 43 | #else |
@@ -60,8 +49,9 @@ char FAST_FUNC bb_process_escape_sequence(const char **ptr) | |||
60 | if (WANT_HEX_ESCAPES && base == 16) { | 49 | if (WANT_HEX_ESCAPES && base == 16) { |
61 | --num_digits; | 50 | --num_digits; |
62 | if (num_digits == 0) { | 51 | if (num_digits == 0) { |
63 | /* \x<bad_char> */ | 52 | /* \x<bad_char>: return '\', |
64 | --q; /* go back to x */ | 53 | * leave ptr pointing to x */ |
54 | return '\\'; | ||
65 | } | 55 | } |
66 | } | 56 | } |
67 | break; | 57 | break; |
@@ -76,20 +66,30 @@ char FAST_FUNC bb_process_escape_sequence(const char **ptr) | |||
76 | ++q; | 66 | ++q; |
77 | } while (++num_digits < 3); | 67 | } while (++num_digits < 3); |
78 | 68 | ||
79 | if (num_digits == 0) { /* mnemonic escape sequence? */ | 69 | if (num_digits == 0) { |
80 | p = charmap; | 70 | /* Not octal or hex escape sequence. |
71 | * Is it one-letter one? */ | ||
72 | |||
73 | /* bash builtin "echo -e '\ec'" interprets \e as ESC, | ||
74 | * but coreutils "/bin/echo -e '\ec'" does not. | ||
75 | * Manpages tend to support coreutils way. | ||
76 | * Update: coreutils added support for \e on 28 Oct 2009. */ | ||
77 | static const char charmap[] ALIGN1 = { | ||
78 | 'a', 'b', 'e', 'f', 'n', 'r', 't', 'v', '\\', | ||
79 | '\a', '\b', 27, '\f', '\n', '\r', '\t', '\v', '\\', | ||
80 | }; | ||
81 | const char *p = charmap; | ||
81 | do { | 82 | do { |
82 | if (*p == *q) { | 83 | if (*p == *q) { |
83 | q++; | 84 | q++; |
84 | break; | 85 | break; |
85 | } | 86 | } |
86 | } while (*++p); | 87 | } while (*++p != '\\'); |
87 | /* p points to found escape char or NUL, | 88 | /* p points to found escape char or '\', |
88 | * advance it and find what it translates to. | 89 | * advance it and find what it translates to. |
89 | * Note that unrecognized sequence \z returns '\' | 90 | * Note that \NUL and unrecognized sequence \z return '\' |
90 | * and leaves ptr pointing to z. */ | 91 | * and leave ptr pointing to NUL or z. */ |
91 | p += sizeof(charmap) / 2; | 92 | n = p[sizeof(charmap) / 2]; |
92 | n = *p; | ||
93 | } | 93 | } |
94 | 94 | ||
95 | *ptr = q; | 95 | *ptr = q; |