libbb: introduce and use strcpy_and_process_escape_sequences
No binary (build failed)
—
(log yok)
| @@ -122,16 +122,14 @@ static double my_xstrtod(const char *arg) | |
| return result; | |
| } | |
| - | static void print_esc_string(char *str) |
| + | static void print_esc_string(const char *str) |
| { | |
| - | while (*str) { |
| - | if (*str == '\\') { |
| - | str++; |
| - | bb_putchar(bb_process_escape_sequence((const char **)&str)); |
| - | } else { |
| - | bb_putchar(*str); |
| - | str++; |
| - | } |
| + | char c; |
| + | while ((c = *str) != '\0') { |
| + | str++; |
| + | if (c == '\\') |
| + | c = bb_process_escape_sequence(&str); |
| + | putchar(c); |
| } | |
| } | |
| @@ -344,7 +342,7 @@ static char **print_formatted(char *f, char **argv, int *conv_err) | |
| f--; | |
| break; | |
| default: | |
| - | bb_putchar(*f); |
| + | putchar(*f); |
| } | |
| } | |
| @@ -349,15 +349,7 @@ static void parse_escape(char *word) | |
| if (!word) | |
| return; | |
| - | for (p = q = word; *p; q++) { |
| - | c = *p++; |
| - | if (c != '\\') { |
| - | *q = c; |
| - | } else { |
| - | *q = bb_process_escape_sequence(&p); |
| - | } |
| - | } |
| - | *q = 0; |
| + | strcpy_and_process_escape_sequences(word, word); |
| } | |
| static void free_instance(struct fsck_instance *i) | |
| @@ -324,6 +324,7 @@ extern void bb_copyfd_exact_size(int fd1, int fd2, off_t size) FAST_FUNC; | |
| /* this helper yells "short read!" if param is not -1 */ | |
| extern void complain_copyfd_and_die(off_t sz) NORETURN FAST_FUNC; | |
| extern char bb_process_escape_sequence(const char **ptr) FAST_FUNC; | |
| + | char* strcpy_and_process_escape_sequences(char *dst, const char *src) FAST_FUNC; |
| /* xxxx_strip version can modify its parameter: | |
| * "/" -> "/" | |
| * "abc" -> "abc" | |
| @@ -187,19 +187,7 @@ again: | |
| #if 0 /* unused so far */ | |
| if (flags & PARSE_ESCAPE) { | |
| - | const char *from; |
| - | char *to; |
| - | |
| - | from = to = tokens[t]; |
| - | while (*from) { |
| - | if (*from == '\\') { |
| - | from++; |
| - | *to++ = bb_process_escape_sequence(&from); |
| - | } else { |
| - | *to++ = *from++; |
| - | } |
| - | } |
| - | *to = '\0'; |
| + | strcpy_and_process_escape_sequences(tokens[t], tokens[t]); |
| } | |
| #endif | |
| /* Skip possible delimiters */ | |
| @@ -31,14 +31,13 @@ char FAST_FUNC bb_process_escape_sequence(const char **ptr) | |
| unsigned num_digits; | |
| unsigned r; | |
| unsigned n; | |
| - | unsigned d; |
| unsigned base; | |
| num_digits = n = 0; | |
| base = 8; | |
| q = *ptr; | |
| - | #ifdef WANT_HEX_ESCAPES |
| + | #if WANT_HEX_ESCAPES |
| if (*q == 'x') { | |
| ++q; | |
| base = 16; | |
| @@ -50,20 +49,21 @@ char FAST_FUNC bb_process_escape_sequence(const char **ptr) | |
| * \02 works, \2 does not (prints \ and 2). | |
| * We treat \2 as a valid octal escape sequence. */ | |
| do { | |
| - | d = (unsigned char)(*q) - '0'; |
| - | #ifdef WANT_HEX_ESCAPES |
| - | if (d >= 10) { |
| - | d = (unsigned char)(_tolower(*q)) - 'a' + 10; |
| - | } |
| + | #if !WANT_HEX_ESCAPES |
| + | unsigned d = (unsigned char)(*q) - '0'; |
| + | #else |
| + | unsigned d = (unsigned char)_tolower(*q) - '0'; |
| + | if (d >= 10) |
| + | d += ('0' - 'a' + 10); |
| #endif | |
| - | |
| if (d >= base) { | |
| - | #ifdef WANT_HEX_ESCAPES |
| - | if ((base == 16) && (!--num_digits)) { |
| - | /* return '\\'; */ |
| - | --q; |
| + | if (WANT_HEX_ESCAPES && base == 16) { |
| + | --num_digits; |
| + | if (num_digits == 0) { |
| + | /* \x<bad_char> */ |
| + | --q; /* go back to x */ |
| + | } |
| } | |
| - | #endif |
| break; | |
| } | |
| @@ -85,7 +85,9 @@ char FAST_FUNC bb_process_escape_sequence(const char **ptr) | |
| } | |
| } while (*++p); | |
| /* p points to found escape char or NUL, | |
| - | * advance it and find what it translates to */ |
| + | * advance it and find what it translates to. |
| + | * Note that unrecognized sequence \z returns '\' |
| + | * and leaves ptr pointing to z. */ |
| p += sizeof(charmap) / 2; | |
| n = *p; | |
| } | |
| @@ -94,3 +96,17 @@ char FAST_FUNC bb_process_escape_sequence(const char **ptr) | |
| return (char) n; | |
| } | |
| + | |
| + | char* FAST_FUNC strcpy_and_process_escape_sequences(char *dst, const char *src) |
| + | { |
| + | while (1) { |
| + | char c, c1; |
| + | c = c1 = *src++; |
| + | if (c1 == '\\') |
| + | c1 = bb_process_escape_sequence(&src); |
| + | *dst = c1; |
| + | if (c == '\0') |
| + | return dst; |
| + | dst++; |
| + | } |
| + | } |
| @@ -188,21 +188,9 @@ static void parse_args(char **argv, struct options *op, char **fakehost_p) | |
| &(op->login), &op->timeout); | |
| argv += optind; | |
| if (op->flags & F_INITSTRING) { | |
| - | const char *p = op->initstring; |
| - | char *q; |
| - | |
| - | op->initstring = q = xstrdup(p); |
| - | /* copy optarg into op->initstring decoding \ddd |
| - | octal codes into chars */ |
| - | while (*p) { |
| - | if (*p == '\\') { |
| - | p++; |
| - | *q++ = bb_process_escape_sequence(&p); |
| - | } else { |
| - | *q++ = *p++; |
| - | } |
| - | } |
| - | *q = '\0'; |
| + | op->initstring = xstrdup(op->initstring); |
| + | /* decode \ddd octal codes into chars */ |
| + | strcpy_and_process_escape_sequences((char*)op->initstring, op->initstring); |
| } | |
| op->flags ^= F_ISSUE; /* invert flag "show /etc/issue" */ | |
| debug("after getopt\n"); | |