]> mj.ucw.cz Git - libucw.git/blob - ucw/unicode.c
Compatibility with GCC < 4.0 is not needed any longer
[libucw.git] / ucw / unicode.c
1 /*
2  *      UCW Library -- UTF-8 Functions
3  *
4  *      (c) 1997--2004 Martin Mares <mj@ucw.cz>
5  *      (c) 2003 Robert Spalek <robert@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 #include <ucw/lib.h>
12 #include <ucw/unicode.h>
13
14 size_t
15 utf8_strlen(const byte *str)
16 {
17   size_t len = 0;
18   while (*str)
19     {
20       UTF8_SKIP(str);
21       len++;
22     }
23   return len;
24 }
25
26 size_t
27 utf8_strnlen(const byte *str, size_t n)
28 {
29   size_t len = 0;
30   const byte *end = str + n;
31   while (str < end)
32     {
33       UTF8_SKIP(str);
34       len++;
35     }
36   return len;
37 }
38
39 #ifdef TEST
40
41 #include <string.h>
42 #include <stdio.h>
43
44 int main(int argc, char **argv)
45 {
46   byte buf[256];
47
48 #define FUNCS \
49   F(UTF8_GET) F(UTF8_32_GET) F(UTF16_BE_GET) F(UTF16_LE_GET) \
50   F(UTF8_PUT) F(UTF8_32_PUT) F(UTF16_BE_PUT) F(UTF16_LE_PUT)
51
52   enum {
53 #define F(x) FUNC_##x,
54     FUNCS
55 #undef F
56   };
57   char *names[] = {
58 #define F(x) [FUNC_##x] = #x,
59     FUNCS
60 #undef F
61   };
62
63   uint func = ~0U;
64   if (argc > 1)
65     for (uint i = 0; i < ARRAY_SIZE(names); i++)
66       if (!strcasecmp(names[i], argv[1]))
67         func = i;
68   if (!~func)
69     {
70       fprintf(stderr, "Invalid usage!\n");
71       return 1;
72     }
73
74   if (func < FUNC_UTF8_PUT)
75     {
76       byte *p = buf, *q = buf, *last;
77       uint u;
78       bzero(buf, sizeof(buf));
79       while (scanf("%x", &u) == 1)
80         *q++ = u;
81       while (p < q)
82         {
83           last = p;
84           if (p != buf)
85             putchar(' ');
86           switch (func)
87             {
88               case FUNC_UTF8_GET:
89                 p = utf8_get(p, &u);
90                 break;
91               case FUNC_UTF8_32_GET:
92                 p = utf8_32_get(p, &u);
93                 break;
94               case FUNC_UTF16_BE_GET:
95                 p = utf16_be_get(p, &u);
96                 break;
97               case FUNC_UTF16_LE_GET:
98                 p = utf16_le_get(p, &u);
99                 break;
100               default:
101                 ASSERT(0);
102             }
103           printf("%04x", u);
104           ASSERT(last < p && p <= q);
105         }
106       putchar('\n');
107     }
108   else
109     {
110       uint u, i=0;
111       while (scanf("%x", &u) == 1)
112         {
113           byte *p = buf, *q = buf;
114           switch (func)
115             {
116               case FUNC_UTF8_PUT:
117                 p = utf8_put(p, u);
118                 break;
119               case FUNC_UTF8_32_PUT:
120                 p = utf8_32_put(p, u);
121                 break;
122               case FUNC_UTF16_BE_PUT:
123                 p = utf16_be_put(p, u);
124                 break;
125               case FUNC_UTF16_LE_PUT:
126                 p = utf16_le_put(p, u);
127                 break;
128               default:
129                 ASSERT(0);
130             }
131           while (q < p)
132             {
133               if (i++)
134                 putchar(' ');
135               printf("%02x", *q++);
136             }
137         }
138       putchar('\n');
139     }
140   return 0;
141 }
142
143 #endif