lineedit: do not hang on error, but return error indicator.
[oweals/busybox.git] / libbb / process_escape_sequence.c
index 1cadbd373e5e4ed09a2ec78ad514d88844ee78a7..82cbe10dc7f9217e45b047aa2767f17249b1481f 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (C) Manuel Novoa III <mjn3@codepoet.org>
  * and Vladimir Oleynik <dzo@simtreas.ru>
  *
- * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  */
 
 #include "libbb.h"
 #undef _tolower
 #define _tolower(X) ((X)|((char) 0x20))
 
-char bb_process_escape_sequence(const char **ptr)
+char FAST_FUNC bb_process_escape_sequence(const char **ptr)
 {
+       /* bash builtin "echo -e '\ec'" interprets \e as ESC,
+        * but coreutils "/bin/echo -e '\ec'" does not.
+        * manpages tend to support coreutils way.
+        * Update: coreutils added support for \e on 28 Oct 2009. */
        static const char charmap[] ALIGN1 = {
-               'a',  'b',  'f',  'n',  'r',  't',  'v',  '\\', 0,
-               '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
+               'a',  'b', 'e', 'f',  'n',  'r',  't',  'v',  '\\', 0,
+               '\a', '\b', 27, '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
 
        const char *p;
        const char *q;
-       unsigned int num_digits;
-       unsigned int r;
-       unsigned int n;
-       unsigned int d;
-       unsigned int base;
+       unsigned num_digits;
+       unsigned r;
+       unsigned n;
+       unsigned d;
+       unsigned base;
 
        num_digits = n = 0;
        base = 8;
@@ -42,6 +46,9 @@ char bb_process_escape_sequence(const char **ptr)
        }
 #endif
 
+       /* bash requires leading 0 in octal escapes:
+        * \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
@@ -77,7 +84,10 @@ char bb_process_escape_sequence(const char **ptr)
                                break;
                        }
                } while (*++p);
-               n = *(p + (sizeof(charmap)/2));
+               /* p points to found escape char or NUL,
+                * advance it and find what it translates to */
+               p += sizeof(charmap) / 2;
+               n = *p;
        }
 
        *ptr = q;