libbb: introduce and use strcpy_and_process_escape_sequences
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 23 Oct 2010 19:06:06 +0000 (21:06 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 23 Oct 2010 19:06:06 +0000 (21:06 +0200)
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 <vda.linux@googlemail.com>
coreutils/printf.c
e2fsprogs/old_e2fsprogs/fsck.c
include/libbb.h
libbb/parse_config.c
libbb/process_escape_sequence.c
loginutils/getty.c

index 2cc238439177598b0c1f4018672414b9ad6485b2..c8395fa8990f622984df17f9238a8a5fe30246b2 100644 (file)
@@ -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);
                }
        }
 
index 524b84652242bedd5987af47e476306168b97cdd..3a0743bb12d738425cbf8c7615da2be466121079 100644 (file)
@@ -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)
index 409c434cb8bcf9eab030c40dcc2c13db6f31e7e1..c85dab282a83850dfd5542a6264151b90692a63b 100644 (file)
@@ -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"
index 3fff9f212ec612a283950c57e407722c20905ee8..9dbfaf5d7838d9a290a1f9eea373e299aed52e05 100644 (file)
@@ -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 */
index 82cbe10dc7f9217e45b047aa2767f17249b1481f..dd6e076b0cb0c8102897e45117087ebb2ce0a12f 100644 (file)
@@ -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++;
+       }
+}
index b1cd235fbd770328cbfd5ea6b689e96354c47284..ab55ea4b003847df29f7474ccebbdff322d1211a 100644 (file)
@@ -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");