From 53600591311a129717abd2e3bcaa302622a6ce67 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 23 Oct 2010 21:06:06 +0200 Subject: libbb: introduce and use strcpy_and_process_escape_sequences function old new delta strcpy_and_process_escape_sequences - 50 +50 bb_process_escape_sequence 148 138 -10 printf_main 789 776 -13 getty_main 1897 1831 -66 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/3 up/down: 50/-89) Total: -39 bytes Signed-off-by: Denys Vlasenko --- coreutils/printf.c | 18 ++++++++--------- e2fsprogs/old_e2fsprogs/fsck.c | 10 +--------- include/libbb.h | 1 + libbb/parse_config.c | 14 +------------ libbb/process_escape_sequence.c | 44 ++++++++++++++++++++++++++++------------- loginutils/getty.c | 18 +++-------------- 6 files changed, 44 insertions(+), 61 deletions(-) diff --git a/coreutils/printf.c b/coreutils/printf.c index 2cc238439..c8395fa89 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -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); } } diff --git a/e2fsprogs/old_e2fsprogs/fsck.c b/e2fsprogs/old_e2fsprogs/fsck.c index 524b84652..3a0743bb1 100644 --- a/e2fsprogs/old_e2fsprogs/fsck.c +++ b/e2fsprogs/old_e2fsprogs/fsck.c @@ -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) diff --git a/include/libbb.h b/include/libbb.h index 409c434cb..c85dab282 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -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" diff --git a/libbb/parse_config.c b/libbb/parse_config.c index 3fff9f212..9dbfaf5d7 100644 --- a/libbb/parse_config.c +++ b/libbb/parse_config.c @@ -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 */ diff --git a/libbb/process_escape_sequence.c b/libbb/process_escape_sequence.c index 82cbe10dc..dd6e076b0 100644 --- a/libbb/process_escape_sequence.c +++ b/libbb/process_escape_sequence.c @@ -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 */ + --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++; + } +} diff --git a/loginutils/getty.c b/loginutils/getty.c index b1cd235fb..ab55ea4b0 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -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"); -- cgit v1.2.3