Added debian/ from 1:1.10.2-1 debian package
[busybox4maemo] / libbb / process_escape_sequence.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Utility routines.
4  *
5  * Copyright (C) Manuel Novoa III <mjn3@codepoet.org>
6  * and Vladimir Oleynik <dzo@simtreas.ru>
7  *
8  * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
9  */
10
11 #include "libbb.h"
12
13 #define WANT_HEX_ESCAPES 1
14
15 /* Usual "this only works for ascii compatible encodings" disclaimer. */
16 #undef _tolower
17 #define _tolower(X) ((X)|((char) 0x20))
18
19 char bb_process_escape_sequence(const char **ptr)
20 {
21         static const char charmap[] ALIGN1 = {
22                 'a',  'b',  'f',  'n',  'r',  't',  'v',  '\\', 0,
23                 '\a', '\b', '\f', '\n', '\r', '\t', '\v', '\\', '\\' };
24
25         const char *p;
26         const char *q;
27         unsigned int num_digits;
28         unsigned int r;
29         unsigned int n;
30         unsigned int d;
31         unsigned int base;
32
33         num_digits = n = 0;
34         base = 8;
35         q = *ptr;
36
37 #ifdef WANT_HEX_ESCAPES
38         if (*q == 'x') {
39                 ++q;
40                 base = 16;
41                 ++num_digits;
42         }
43 #endif
44
45         do {
46                 d = (unsigned char)(*q) - '0';
47 #ifdef WANT_HEX_ESCAPES
48                 if (d >= 10) {
49                         d = (unsigned char)(_tolower(*q)) - 'a' + 10;
50                 }
51 #endif
52
53                 if (d >= base) {
54 #ifdef WANT_HEX_ESCAPES
55                         if ((base == 16) && (!--num_digits)) {
56 /*                              return '\\'; */
57                                 --q;
58                         }
59 #endif
60                         break;
61                 }
62
63                 r = n * base + d;
64                 if (r > UCHAR_MAX) {
65                         break;
66                 }
67
68                 n = r;
69                 ++q;
70         } while (++num_digits < 3);
71
72         if (num_digits == 0) {  /* mnemonic escape sequence? */
73                 p = charmap;
74                 do {
75                         if (*p == *q) {
76                                 q++;
77                                 break;
78                         }
79                 } while (*++p);
80                 n = *(p + (sizeof(charmap)/2));
81         }
82
83         *ptr = q;
84
85         return (char) n;
86 }