• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- C++ -*-
2 //===-------------------- support/android/wchar_support.c ------------------===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is dual licensed under the MIT and the University of Illinois Open
7 // Source Licenses. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #include <string.h>
12 #include <wchar.h>
13 #include <wctype.h>
14 
15 // Returns 1 if 'wc' is in the 'delim' string, 0 otherwise.
_wc_indelim(wchar_t wc,const wchar_t * delim)16 static int _wc_indelim(wchar_t wc, const wchar_t* delim) {
17     while (*delim) {
18         if (wc == *delim)
19             return 1;
20         delim++;
21     }
22     return 0;
23 }
24 
wcpcpy(wchar_t * to,const wchar_t * from)25 wchar_t *wcpcpy(wchar_t *to, const wchar_t *from) {
26     size_t n = 0;
27     for (;;) {
28         wchar_t wc = from[n];
29         to[n] = wc;
30         if (wc == L'\0')
31             break;
32         n++;
33     }
34     return to + n;
35 }
36 
wcpncpy(wchar_t * dst,const wchar_t * src,size_t n)37 wchar_t *wcpncpy(wchar_t *dst, const wchar_t *src, size_t n) {
38     size_t i;
39     for (i = 0; i < n; ++i) {
40         wchar_t wc = src[i];
41         dst[i] = wc;
42         if (wc == L'\0')
43             break;
44     }
45     while (i < n) {
46         dst[i] = L'\0';
47         ++i;
48     }
49     return &dst[n-1];
50 }
51 
wcscasecmp(const wchar_t * s1,const wchar_t * s2)52 int wcscasecmp(const wchar_t *s1, const wchar_t *s2) {
53     size_t n = 0;
54     for (;;) {
55         wchar_t wc1 = towlower(s1[n]);
56         wchar_t wc2 = towlower(s2[n]);
57         if (wc1 != wc2)
58             return (wc1 > wc2) ? +1 : -1;
59         if (wc1 == L'\0')
60             return 0;
61         n++;
62     }
63 }
64 
wcscat(wchar_t * s1,const wchar_t * s2)65 wchar_t *wcscat(wchar_t *s1, const wchar_t *s2) {
66     size_t n = 0;
67     while (s1[n] != L'\0')
68         n++;
69 
70     size_t i = 0;
71     for (;;) {
72         wchar_t wc = s2[i];
73         s1[n+i] = wc;
74         if (wc == L'\0')
75             break;
76         i++;
77     }
78     return s1;
79 }
80 
wcslcat(wchar_t * dst,const wchar_t * src,size_t siz)81 size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t siz) {
82     // Sanity check simplifies code below
83     if (siz == 0)
84         return 0;
85 
86     // Skip dst characters.
87     size_t n = 0;
88     while (n < siz && dst[n] != L'\0')
89       n++;
90 
91     if (n == siz)
92       return n + wcslen(src);
93 
94     // Copy as much source characters as they fit into siz-1 bytes.
95     size_t i;
96     for (i = 0; n+i+1 < siz && src[i] != L'\0'; ++i)
97         dst[n+i] = src[i];
98 
99     // Always zero terminate destination
100     dst[n+i] = L'\0';
101 
102     // Skip remaining source characters
103     while (src[i] != L'\0')
104         i++;
105 
106     return n+i;
107 }
108 
wcslcpy(wchar_t * dst,const wchar_t * src,size_t siz)109 size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) {
110     size_t i;
111 
112     // Copy all non-zero bytes that fit into siz-1 destination bytes
113     for (i = 0; i + 1 < siz && src[i] != L'\0'; ++i)
114         dst[i] = src[i];
115 
116     // Always zero-terminate destination buffer
117     dst[i] = L'\0';
118 
119     // Skip other source characters.
120     while (src[i] != L'\0')
121         ++i;
122 
123     return i;
124 }
125 
wcslen(const wchar_t * s)126 size_t wcslen(const wchar_t *s) {
127     size_t n = 0;
128     for (;;) {
129         wchar_t wc = s[n];
130         if (wc == L'\0')
131             return n;
132         n++;
133     }
134 }
135 
wcsncasecmp(const wchar_t * s1,const wchar_t * s2,size_t n)136 int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) {
137     size_t i;
138     for (i = 0; i < n; ++i) {
139         wchar_t wc1 = towlower(s1[i]);
140         wchar_t wc2 = towlower(s2[i]);
141         if (wc1 != wc2)
142             return (wc1 > wc2) ? +1 : -1;
143     }
144     return 0;
145 }
146 
wcsncat(wchar_t * s1,const wchar_t * s2,size_t n)147 wchar_t *wcsncat(wchar_t *s1, const wchar_t *s2, size_t n) {
148     size_t start = 0;
149     while (s1[start] != L'\0')
150         start++;
151 
152     // Append s2.
153     size_t i;
154     for (i = 0; i < n; ++i) {
155         wchar_t wc = s2[i];
156         s1[start + i] = wc;
157         if (wc == L'\0')
158             break;
159     }
160     return (wchar_t*)s1;
161 }
162 
wcsncmp(const wchar_t * s1,const wchar_t * s2,size_t n)163 int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n) {
164     size_t i;
165     for (i = 0; i < n; ++i) {
166         wchar_t wc = s1[i];
167         if (wc != s2[i])
168             return (wc > s2[i]) ? +1 : -1;
169         if (wc == L'\0')
170             break;
171     }
172     return 0;
173 }
174 
wcsncpy(wchar_t * dst,const wchar_t * src,size_t n)175 wchar_t *wcsncpy(wchar_t *dst, const wchar_t *src, size_t n) {
176     // Copy initial characters.
177     size_t i;
178     for (i = 0; i < n; ++i) {
179         wchar_t wc = src[i];
180         if (wc == L'\0')
181             break;
182         dst[i] = wc;
183     }
184     // zero-pad the remainder.
185     for ( ; i < n; ++i)
186         dst[i] = L'\0';
187 
188     return dst;
189 }
190 
wcsnlen(const wchar_t * s,size_t maxlen)191 size_t wcsnlen(const wchar_t *s, size_t maxlen) {
192     size_t n;
193     for (n = 0; n < maxlen; ++n) {
194         if (s[n] == L'\0')
195             break;
196     }
197     return n;
198 }
199 
wcspbrk(const wchar_t * s,const wchar_t * set)200 wchar_t *wcspbrk(const wchar_t *s, const wchar_t *set) {
201     size_t n = 0;
202     for (;;) {
203         wchar_t wc = s[n];
204         if (!wc)
205             return NULL;
206         if (_wc_indelim(wc, set))
207             return (wchar_t*)&s[n];
208         n++;
209     }
210 }
211 
wcsrchr(const wchar_t * s,wchar_t c)212 wchar_t *wcsrchr(const wchar_t *s, wchar_t c) {
213     size_t n = 0;
214     wchar_t* last = NULL;
215     for (;;) {
216         wchar_t wc = s[n];
217         if (wc == c)
218             last = (wchar_t*)s + n;
219         if (wc == L'\0')
220             break;
221         n++;
222     }
223     return last;
224 }
225 
wcsspn(const wchar_t * s,const wchar_t * set)226 size_t wcsspn(const wchar_t *s, const wchar_t *set) {
227     size_t n = 0;
228     for (;;) {
229         wchar_t wc = s[n];
230         if (wc == L'\0')
231             break;
232         if (!_wc_indelim(wc, set))
233             break;
234         ++n;
235     }
236     return n;
237 }
238 
wcsstr(const wchar_t * s,const wchar_t * find)239 wchar_t *wcsstr(const wchar_t *s, const wchar_t *find) {
240     wchar_t find_c;
241 
242     // Always find the empty string
243     find_c = *find++;
244     if (!find_c)
245         return (wchar_t*)s;
246 
247     size_t find_len = wcslen(find);
248 
249     for (;;) {
250         wchar_t* p = wcschr(s, find_c);
251         if (p == NULL)
252             return NULL;
253 
254         if (!wmemcmp(p, find, find_len))
255             return p;
256 
257         s = p + 1;
258     }
259     return NULL;
260 }
261 
wcstok(wchar_t * s,const wchar_t * delim,wchar_t ** last)262 wchar_t *wcstok(wchar_t *s, const wchar_t *delim, wchar_t **last) {
263     if (s == NULL) {
264         s = *last;
265         if (s == NULL)
266             return NULL;
267     }
268 
269     // Skip leading delimiters first.
270     size_t i = 0;
271     wchar_t wc;
272     for (;;) {
273         wc = s[i];
274         if (wc && _wc_indelim(wc, delim)) {
275             i++;
276             continue;
277         }
278         break;
279     }
280 
281     if (!wc) {
282         // Nothing left.
283         *last = NULL;
284         return NULL;
285     }
286 
287     size_t tok_start = i;
288 
289     // Skip non delimiters now.
290     for (;;) {
291         wc = s[i];
292         if (wc && !_wc_indelim(wc, delim)) {
293             i++;
294             continue;
295         }
296         break;
297     }
298 
299     if (!wc) {
300         *last = NULL;
301     } else {
302         s[i] = L'\0';
303         *last = &s[i+1];
304     }
305     return &s[tok_start];
306 }
307 
wcswidth(const wchar_t * str,size_t n)308 int wcswidth(const wchar_t *str, size_t n) {
309     int len = 0;
310     size_t i;
311     for (i = 0; i < n; ++i) {
312         wchar_t wc = str[i];
313         if (wc == L'\0')
314             break;
315         int l = wcwidth(wc);
316         if (l < 0)
317             return -1;
318         len += l;
319     }
320     return len;
321 }
322 
323 // TODO(digit): Handle real collations.
wcsxfrm(wchar_t * dst,const wchar_t * src,size_t len)324 size_t wcsxfrm(wchar_t *dst, const wchar_t *src, size_t len) {
325     // Handle trivial case first.
326     if (src[0] == L'\0') {
327         if (len != 0)
328             dst[0] = L'\0';
329         return 0;
330     }
331 
332     size_t slen = wcslen(src);
333     if (len > 0) {
334         if (slen < len)
335             wcscpy(dst, src);
336         else {
337             wcsncpy(dst, src, len-1);
338             dst[len - 1] = L'\0';
339         }
340     }
341     return slen;
342 }
343 
wmemchr(const wchar_t * s,wchar_t c,size_t n)344 wchar_t * wmemchr(const wchar_t *s, wchar_t c, size_t n) {
345     size_t i;
346     for (i = 0; i < n; ++i) {
347         if (s[i] == c)
348             return (wchar_t*)&s[i];
349     }
350     return NULL;
351 }
352 
wmemcmp(const wchar_t * s1,const wchar_t * s2,size_t n)353 int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) {
354     size_t i;
355     for (i = 0; i < n; ++i) {
356         if (s1[i] == s2[i])
357             continue;
358         if (s1[i] > s2[i])
359             return 1;
360         else
361             return -1;
362     }
363     return 0;
364 }
365 
wmemcpy(wchar_t * d,const wchar_t * s,size_t n)366 wchar_t * wmemcpy(wchar_t *d, const wchar_t *s, size_t n) {
367         return (wchar_t *)memcpy((char*)d,
368                                  (const char*)s,
369                                  n * sizeof(wchar_t));
370 }
371 
wmemmove(wchar_t * d,const wchar_t * s,size_t n)372 wchar_t* wmemmove(wchar_t* d, const wchar_t* s, size_t n) {
373         return (wchar_t* )memmove((char*)d,
374                                   (const char*)s,
375                                   n * sizeof(wchar_t));
376 }
377 
wmemset(wchar_t * s,wchar_t c,size_t n)378 wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n) {
379     size_t i;
380     for (i = 0; i < n; ++i)
381         s[i] = c;
382     return s;
383 }
384 
wcstof(const wchar_t * nptr,wchar_t ** endptr)385 float wcstof(const wchar_t* nptr, wchar_t** endptr) {
386 #warning Not implemented
387   return 0;
388 }
389 
wcstol(const wchar_t * nptr,wchar_t ** endptr,int base)390 long wcstol(const wchar_t* nptr, wchar_t** endptr, int base) {
391 #warning Not implemented
392   return 0;
393 }
394 
wcstold(const wchar_t * nptr,wchar_t ** endptr)395 long double wcstold(const wchar_t* nptr, wchar_t** endptr) {
396 #warning Not implemented
397   return 0;
398 }
399 
wcstoll(const wchar_t * nptr,wchar_t ** endptr,int base)400 long long wcstoll(const wchar_t* nptr, wchar_t** endptr, int base) {
401 #warning Not implemented
402   return 0;
403 }
404 
wcstoull(const wchar_t * nptr,wchar_t ** endptr,int base)405 unsigned long long wcstoull(const wchar_t* nptr, wchar_t** endptr, int base) {
406 #warning Not implemented
407   return 0;
408 }
409 
wcsnrtombs(char * dst,const wchar_t ** src,size_t nwc,size_t len,mbstate_t * ps)410 size_t wcsnrtombs(char *dst,
411                   const wchar_t **src,
412                   size_t nwc, size_t len,
413                   mbstate_t *ps) {
414 #warning Not implemented
415   return 0;
416 }
417 
mbsnrtowcs(wchar_t * dst,const char ** src,size_t nmc,size_t len,mbstate_t * ps)418 size_t mbsnrtowcs(wchar_t *dst,
419                   const char **src, size_t nmc,
420                   size_t len, mbstate_t *ps) {
421 #warning Not implemented
422   return 0;
423 }
424