]> mj.ucw.cz Git - libucw.git/blob - lib/string.c
Simple parser for escape sequences.
[libucw.git] / lib / string.c
1 /*
2  *      UCW Library -- String Routines
3  *
4  *      (c) 2006 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/chartype.h"
12
13 /* Expands C99-like escape sequences.
14  * It is safe to use the same buffer for both input and output. */
15 byte *
16 str_unesc(byte *d, byte *s)
17 {
18   while (*s)
19     {
20       if (*s == '\\')
21         switch (s[1])
22           {
23             case 'a': *d++ = '\a'; s += 2; break;
24             case 'b': *d++ = '\b'; s += 2; break;
25             case 'f': *d++ = '\f'; s += 2; break;
26             case 'n': *d++ = '\n'; s += 2; break;
27             case 'r': *d++ = '\r'; s += 2; break;
28             case 't': *d++ = '\t'; s += 2; break;
29             case 'v': *d++ = '\v'; s += 2; break;
30             case '\?': *d++ = '\?'; s += 2; break;
31             case '\'': *d++ = '\''; s += 2; break;
32             case '\"': *d++ = '\"'; s += 2; break;
33             case '\\': *d++ = '\\'; s += 2; break;
34             case '0':
35               if (s[2] < '0' || s[2] > '7')
36                 *d++ = *s++;
37               else
38                 {
39                   uns v = 0;
40                   for (s += 2; *s >= '0' && *s <= '7' && v < 32; s++)
41                     v = (v << 3) + *s - '0';
42                   *d++ = v;
43                 }
44               break;
45             case 'x':
46               if (!Cxdigit(s[2]))
47                 *d++ = *s++;
48               else
49                 {
50                   uns v = 0;
51                   for (s += 2; Cxdigit(*s) && v < 16; s++)
52                     v = (v << 4) + (Cdigit(*s) ? (*s - '0') : ((*s | 32) - 'A' + 10));
53                   *d++ = v;
54                 }
55               break;
56             default:
57               *d++ = *s++;
58               break;
59           }
60       else
61         *d++ = *s++;
62     }
63   *d = 0;
64   return d;
65 }
66