]> mj.ucw.cz Git - libucw.git/blob - lib/string.c
noted that utf8_{put/get} supports only a subset of the Unicode range
[libucw.git] / lib / string.c
1 /*
2  *      UCW Library -- String Routines
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 "lib/lib.h"
14 #include "lib/chartype.h"
15 #include <stdlib.h>
16
17 /* Expands C99-like escape sequences.
18  * It is safe to use the same buffer for both input and output. */
19 char *
20 str_unesc(char *d, const char *s)
21 {
22   while (*s)
23     {
24       if (*s == '\\')
25         switch (s[1])
26           {
27             case 'a': *d++ = '\a'; s += 2; break;
28             case 'b': *d++ = '\b'; s += 2; break;
29             case 'f': *d++ = '\f'; s += 2; break;
30             case 'n': *d++ = '\n'; s += 2; break;
31             case 'r': *d++ = '\r'; s += 2; break;
32             case 't': *d++ = '\t'; s += 2; break;
33             case 'v': *d++ = '\v'; s += 2; break;
34             case '\?': *d++ = '\?'; s += 2; break;
35             case '\'': *d++ = '\''; s += 2; break;
36             case '\"': *d++ = '\"'; s += 2; break;
37             case '\\': *d++ = '\\'; s += 2; break;
38             case 'x':
39               if (!Cxdigit(s[2]))
40                 {
41                   s++;
42                   DBG("\\x used with no following hex digits");
43                 }
44               else
45                 {
46                   char *p;
47                   uns v = strtoul(s + 2, &p, 16);
48                   if (v <= 255)
49                     *d++ = v;
50                   else
51                     DBG("hex escape sequence out of range");
52                   s = (char *)p;
53                 }
54               break;
55             default:
56               if (s[1] >= '0' && s[1] <= '7')
57                 {
58                   uns v = s[1] - '0';
59                   s += 2;
60                   for (uns i = 0; i < 2 && *s >= '0' && *s <= '7'; s++, i++)
61                     v = (v << 3) + *s - '0';
62                   if (v <= 255)
63                     *d++ = v;
64                   else
65                     DBG("octal escape sequence out of range");
66                 }
67               *d++ = *s++;
68               break;
69           }
70       else
71         *d++ = *s++;
72     }
73   *d = 0;
74   return d;
75 }
76
77 char *
78 str_format_flags(char *dest, const char *fmt, uns flags)
79 {
80   char *start = dest;
81   for (uns i=0; fmt[i]; i++)
82     {
83       if (flags & (1 << i))
84         *dest++ = fmt[i];
85       else
86         *dest++ = '-';
87     }
88   *dest = 0;
89   return start;
90 }