]> mj.ucw.cz Git - libucw.git/blob - ucw/str-esc.c
Merge branch 'dev-uint'
[libucw.git] / ucw / str-esc.c
1 /*
2  *      UCW Library -- String Unescaping
3  *
4  *      (c) 2006 Pavel Charvat <pchar@ucw.cz>
5  *      (c) 2007 Martin Mares <mj@ucw.cz>
6  *
7  *      This software may be freely distributed and used according to the terms
8  *      of the GNU Lesser General Public License.
9  */
10
11 #undef LOCAL_DEBUG
12
13 #include <ucw/lib.h>
14 #include <ucw/string.h>
15 #include <ucw/chartype.h>
16 #include <stdlib.h>
17
18 char *
19 str_unesc(char *d, const char *s)
20 {
21   while (*s)
22     {
23       if (*s == '\\')
24         switch (s[1])
25           {
26             case 'a': *d++ = '\a'; s += 2; break;
27             case 'b': *d++ = '\b'; s += 2; break;
28             case 'f': *d++ = '\f'; s += 2; break;
29             case 'n': *d++ = '\n'; s += 2; break;
30             case 'r': *d++ = '\r'; s += 2; break;
31             case 't': *d++ = '\t'; s += 2; break;
32             case 'v': *d++ = '\v'; s += 2; break;
33             case '\?': *d++ = '\?'; s += 2; break;
34             case '\'': *d++ = '\''; s += 2; break;
35             case '\"': *d++ = '\"'; s += 2; break;
36             case '\\': *d++ = '\\'; s += 2; break;
37             case 'x':
38               if (!Cxdigit(s[2]))
39                 {
40                   s++;
41                   DBG("\\x used with no following hex digits");
42                 }
43               else
44                 {
45                   char *p;
46                   uint v = strtoul(s + 2, &p, 16);
47                   if (v <= 255)
48                     *d++ = v;
49                   else
50                     DBG("hex escape sequence out of range");
51                   s = (char *)p;
52                 }
53               break;
54             default:
55               if (s[1] >= '0' && s[1] <= '7')
56                 {
57                   uint v = s[1] - '0';
58                   s += 2;
59                   for (uint i = 0; i < 2 && *s >= '0' && *s <= '7'; s++, i++)
60                     v = (v << 3) + *s - '0';
61                   if (v <= 255)
62                     *d++ = v;
63                   else
64                     DBG("octal escape sequence out of range");
65                 }
66               else
67                 *d++ = *s++;
68               break;
69           }
70       else
71         *d++ = *s++;
72     }
73   *d = 0;
74   return d;
75 }
76
77 #ifdef TEST
78
79 #include <stdio.h>
80 #include <string.h>
81
82 int main(int argc, char **argv)
83 {
84   if (argc < 2)
85     return 1;
86
87   char tmp[strlen(argv[1]) + 1];
88   int len = str_unesc(tmp, argv[1]) - tmp;
89
90   char hex[2*len + 1];
91   mem_to_hex(hex, tmp, len, ' ');
92   puts(hex);
93
94   return 0;
95 }
96
97 #endif