aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2004-07-29 23:15:16 +0000
committerManuel Novoa III <mjn3@codepoet.org>2004-07-29 23:15:16 +0000
commit413db4d583805badc686362705b5ea34555fffd7 (patch)
treec04c6ad63cf10d9f552b7356aa96b4aa0cc94916
parent27645b4345656342ee7a03f2620cf5433e5e1b71 (diff)
downloadbusybox-w32-413db4d583805badc686362705b5ea34555fffd7.tar.gz
busybox-w32-413db4d583805badc686362705b5ea34555fffd7.tar.bz2
busybox-w32-413db4d583805badc686362705b5ea34555fffd7.zip
Clean up hex escape support.
-rw-r--r--libbb/process_escape_sequence.c64
1 files changed, 43 insertions, 21 deletions
diff --git a/libbb/process_escape_sequence.c b/libbb/process_escape_sequence.c
index 9b57ff99e..28b1e3697 100644
--- a/libbb/process_escape_sequence.c
+++ b/libbb/process_escape_sequence.c
@@ -22,48 +22,69 @@
22 * 22 *
23 */ 23 */
24 24
25#include <string.h>
26#include <stdio.h> 25#include <stdio.h>
27#include <limits.h> 26#include <limits.h>
28#include <ctype.h> 27#include <ctype.h>
29#include "libbb.h" 28#include "libbb.h"
30 29
31#define isodigit(c) ((c) >= '0' && (c) <= '7') 30#define WANT_HEX_ESCAPES 1
32#define hextobin(c) ((c)>='a'&&(c)<='f' ? (c)-'a'+10 : (c)>='A'&&(c)<='F' ? (c)-'A'+10 : (c)-'0') 31
33#define octtobin(c) ((c) - '0') 32/* Usual "this only works for ascii compatible encodings" disclaimer. */
33#undef _tolower
34#define _tolower(X) ((X)|((char) 0x20))
35
34char bb_process_escape_sequence(const char **ptr) 36char bb_process_escape_sequence(const char **ptr)
35{ 37{
36 const char *p, *q;
37 unsigned int num_digits, r, n, hexescape;
38 static const char charmap[] = { 38 static const char charmap[] = {
39 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0, 39 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0,
40 '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' }; 40 '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
41 41
42 n = r = hexescape = num_digits = 0; 42 const char *p;
43 const char *q;
44 unsigned int num_digits;
45 unsigned int r;
46 unsigned int n;
47 unsigned int d;
48 unsigned int base;
49
50 num_digits = n = 0;
51 base = 8;
43 q = *ptr; 52 q = *ptr;
44 53
54#ifdef WANT_HEX_ESCAPES
45 if (*q == 'x') { 55 if (*q == 'x') {
46 hexescape++;
47 ++q; 56 ++q;
57 base = 16;
58 ++num_digits;
48 } 59 }
60#endif
49 61
50 do { 62 do {
51 if (hexescape && isxdigit(*q)) { 63 d = (unsigned int)(*q - '0');
52 r = n * 16 + hextobin(*q); 64#ifdef WANT_HEX_ESCAPES
53 } else if (isodigit(*q)) { 65 if (d >= 10) {
54 r = n * 8 + octtobin(*q); 66 d = ((unsigned int)(_tolower(*q) - 'a')) + 10;
55 } else {
56 break;
57 } 67 }
58 if (r <= UCHAR_MAX) { 68#endif
59 n = r; 69
60 ++q; 70 if (d >= base) {
61 if (++num_digits < 3) { 71#ifdef WANT_HEX_ESCAPES
62 continue; 72 if ((base == 16) && (!--num_digits)) {
73/* return '\\'; */
74 --q;
63 } 75 }
76#endif
77 break;
64 } 78 }
65 break; 79
66 } while (1); 80 r = n * base + d;
81 if (r > UCHAR_MAX) {
82 break;
83 }
84
85 n = r;
86 ++q;
87 } while (++num_digits < 3);
67 88
68 if (num_digits == 0) { /* mnemonic escape sequence? */ 89 if (num_digits == 0) { /* mnemonic escape sequence? */
69 p = charmap; 90 p = charmap;
@@ -77,6 +98,7 @@ char bb_process_escape_sequence(const char **ptr)
77 } 98 }
78 99
79 *ptr = q; 100 *ptr = q;
101
80 return (char) n; 102 return (char) n;
81} 103}
82 104