1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *  * Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *  * Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in
12 *    the documentation and/or other materials provided with the
13 *    distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28#include <wchar.h>
29#include <ctype.h>
30#include <string.h>
31#include <stdlib.h>
32#include <errno.h>
33
34/* stubs for wide-char functions */
35wint_t  btowc(int c)
36{
37  return (c == EOF) ? WEOF : c;
38}
39
40int fwprintf(FILE *stream, const wchar_t *format, ...)
41{
42    va_list  args;
43    int      result;
44
45    va_start(args, format);
46    result = vfwprintf(stream, format, args);
47    va_end(args);
48    return result;
49}
50
51int wprintf(const wchar_t *format, ...)
52{
53    va_list  args;
54    int      result;
55
56    va_start(args, format);
57    result = vwprintf(format, args);
58    va_end(args);
59    return result;
60}
61
62int swprintf(wchar_t *s, size_t n, const wchar_t *format, ...)
63{
64    va_list  args;
65    int      result;
66
67    va_start(args, format);
68    result = vswprintf(s, n, format, args);
69    va_end(args);
70    return result;
71}
72
73int vwprintf(const wchar_t *format, va_list arg)
74{
75    return vfwprintf(stdout, format, arg);
76}
77
78int vfwprintf(FILE *stream, const wchar_t *format, va_list arg)
79{
80    errno = ENOTSUP;
81    return -1;
82}
83
84int vswprintf(wchar_t *s, size_t n, const wchar_t *format, va_list arg)
85{
86    errno = ENOTSUP;
87    return -1;
88}
89
90int fwscanf(FILE *stream, const wchar_t *format, ... )
91{
92    errno = ENOTSUP;
93    return -1;
94}
95
96int wscanf(const wchar_t *format, ... )
97{
98    va_list  args;
99    int      result;
100
101    va_start (args, format);
102    result = fwscanf(stdout, format, args );
103    va_end (args);
104    return result;
105}
106
107int swscanf(const wchar_t *s, const wchar_t *format, ... )
108{
109    errno = ENOTSUP;
110    return -1;
111}
112
113int iswalnum(wint_t wc) { return isalnum(wc); }
114int iswalpha(wint_t wc) { return isalpha(wc); }
115int iswcntrl(wint_t wc) { return iscntrl(wc); }
116int iswdigit(wint_t wc) { return isdigit(wc); }
117int iswgraph(wint_t wc) { return isgraph(wc); }
118int iswlower(wint_t wc) { return islower(wc); }
119int iswprint(wint_t wc) { return isprint(wc); }
120int iswpunct(wint_t wc) { return ispunct(wc); }
121int iswspace(wint_t wc) { return isspace(wc); }
122int iswupper(wint_t wc) { return isupper(wc); }
123int iswxdigit(wint_t wc) { return isxdigit(wc); }
124
125int iswctype(wint_t wc, wctype_t charclass)
126{
127    switch (charclass) {
128        case WC_TYPE_ALNUM: return isalnum(wc);
129        case WC_TYPE_ALPHA: return isalpha(wc);
130        case WC_TYPE_BLANK: return isblank(wc);
131        case WC_TYPE_CNTRL: return iscntrl(wc);
132        case WC_TYPE_DIGIT: return isdigit(wc);
133        case WC_TYPE_GRAPH: return isgraph(wc);
134        case WC_TYPE_LOWER: return islower(wc);
135        case WC_TYPE_PRINT: return isprint(wc);
136        case WC_TYPE_PUNCT: return ispunct(wc);
137        case WC_TYPE_SPACE: return isspace(wc);
138        case WC_TYPE_UPPER: return isupper(wc);
139        case WC_TYPE_XDIGIT: return isxdigit(wc);
140        default: return 0;
141    };
142}
143
144wint_t fgetwc(FILE *stream)
145{
146    return (wint_t)fgetc(stream);
147}
148
149wchar_t *fgetws(wchar_t *ws, int n, FILE *stream)
150{
151    return (wchar_t*) fgets((char*)ws, n, stream);
152}
153
154wint_t   fputwc(wchar_t wc, FILE *stream)
155{
156    return (wint_t)fputc((char)wc, stream);
157}
158
159int  fputws(const wchar_t *str, FILE *stream)
160{
161    return fputs( (const char*)str, stream );
162}
163
164int  fwide(FILE *stream, int  mode)
165{
166    stream=stream;
167    return (mode);
168}
169
170wint_t  getwc(FILE *stream)
171{
172    return getc(stream);
173}
174
175wint_t  getwchar(void)
176{
177    return getchar();
178}
179
180int mbsinit(const mbstate_t *ps)
181{
182    ps=ps;
183    return 1;
184}
185
186size_t mbrlen(const char *s, size_t n, mbstate_t *ps)
187{
188    return (n != 0);
189}
190
191size_t mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
192{
193    if (s == NULL) {
194        s   = "";
195        pwc = NULL;
196    }
197    if (n == 0) {
198        if (pwc)
199            *pwc = 0;
200        return 0;
201    }
202    if (pwc)
203        *pwc = *s;
204
205    return (*s != 0);
206}
207
208size_t mbsrtowcs(wchar_t *dst, const char **src, size_t len, mbstate_t *ps)
209{
210    const char*  s  = *src;
211    const char*  s2 = memchr( s, 0, len );
212
213    if (s2 != NULL)
214        len = (size_t)(s2 - s) + 1U;
215
216    if (dst)
217        memcpy( (char*)dst, s, len );
218
219    *src = s + len;
220    return len;
221}
222
223size_t mbstowcs(wchar_t *dst, const char *src, size_t len)
224{
225    return mbsrtowcs(dst, &src, len, NULL);
226}
227
228wint_t  putwc(wchar_t wc, FILE *stream)
229{
230    return fputc((char)wc, stream);
231}
232
233wint_t  putwchar(wchar_t wc)
234{
235    return  putchar((char)wc);
236}
237
238wint_t  towlower(wint_t wc)
239{
240    return tolower(wc);
241}
242
243wint_t  towupper(wint_t  wc)
244{
245    return toupper(wc);
246}
247
248wint_t  ungetwc(wint_t wc, FILE *stream)
249{
250    return ungetc((char)wc, stream);
251}
252
253size_t wcrtomb(char *s, wchar_t wc, mbstate_t *ps)
254{
255    if (s != NULL)
256        *s = 1;
257    return 1;
258}
259
260size_t wcsftime(wchar_t *wcs, size_t maxsize, const wchar_t *format,  const struct tm *timptr)
261{
262    return strftime( (char*)wcs, maxsize, (const char*)format, timptr );
263}
264
265size_t wcsrtombs(char *dst, const wchar_t **src, size_t len, mbstate_t *ps)
266{
267    const char*  s = (const char*)*src;
268    const char*  s2 = memchr( s, 0, len );
269
270    if (s2 != NULL)
271        len = (s2 - s)+1;
272
273    if (dst != NULL)
274        memcpy( dst, s, len );
275
276    *src = (wchar_t*)(s + len);
277    return len;
278}
279
280size_t wcstombs(char *dst, const wchar_t *src, size_t len)
281{
282    return wcsrtombs(dst, &src, len, NULL);
283}
284
285double wcstod(const wchar_t *nptr, wchar_t **endptr)
286{
287    return strtod( (const char*)nptr, (char**)endptr );
288}
289
290long int wcstol(const wchar_t *nptr, wchar_t **endptr, int base)
291{
292    return strtol( (const char*)nptr, (char**)endptr, base );
293}
294
295unsigned long int wcstoul(const wchar_t *nptr, wchar_t **endptr, int base)
296{
297    return strtoul( (const char*)nptr, (char**)endptr, base );
298}
299
300wchar_t *wcswcs(const wchar_t *ws1, const wchar_t *ws2)
301{
302    return (wchar_t*) strstr( (const char*)ws1, (const char*)ws2 );
303}
304
305int wctob(wint_t c)
306{
307    return c;
308}
309
310wctype_t wctype(const char *property)
311{
312    static const char* const  properties[WC_TYPE_MAX] =
313    {
314        "<invalid>",
315        "alnum", "alpha", "blank", "cntrl", "digit", "graph",
316        "lower", "print", "punct", "space", "upper", "xdigit"
317    };
318    int  nn;
319
320    for ( nn = 0; nn < WC_TYPE_MAX; nn++ )
321        if ( !strcmp( properties[nn], property ) )
322            return (wctype_t)(nn);
323
324    return 0;
325}
326
327int wcwidth(wchar_t wc)
328{
329    return (wc > 0);
330}
331