Home | History | Annotate | Download | only in bionic
      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 
     29 #include <ctype.h>
     30 #include <errno.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 #include <wchar.h>
     34 
     35 /* stubs for wide-char functions */
     36 
     37 wint_t btowc(int c) {
     38   return (c == EOF) ? WEOF : c;
     39 }
     40 
     41 int fwprintf(FILE* stream, const wchar_t* format, ...) {
     42   va_list args;
     43   va_start(args, format);
     44   int result = vfwprintf(stream, format, args);
     45   va_end(args);
     46   return result;
     47 }
     48 
     49 int wprintf(const wchar_t* format, ...) {
     50   va_list args;
     51   va_start(args, format);
     52   int result = vwprintf(format, args);
     53   va_end(args);
     54   return result;
     55 }
     56 
     57 int swprintf(wchar_t* s, size_t n, const wchar_t* format, ...) {
     58   va_list args;
     59   va_start(args, format);
     60   int result = vswprintf(s, n, format, args);
     61   va_end(args);
     62   return result;
     63 }
     64 
     65 int vwprintf(const wchar_t* format, va_list arg) {
     66   return vfwprintf(stdout, format, arg);
     67 }
     68 
     69 int vfwprintf(FILE* /*stream*/, const wchar_t* /*format*/, va_list /*arg*/) {
     70   errno = ENOTSUP;
     71   return -1;
     72 }
     73 
     74 int vswprintf(wchar_t* /*s*/, size_t /*n*/, const wchar_t* /*format*/, va_list /*arg*/) {
     75   errno = ENOTSUP;
     76   return -1;
     77 }
     78 
     79 int fwscanf(FILE* /*stream*/, const wchar_t* /*format*/, ... ) {
     80   errno = ENOTSUP;
     81   return -1;
     82 }
     83 
     84 int wscanf(const wchar_t* format, ... ) {
     85   va_list args;
     86   va_start (args, format);
     87   int result = fwscanf(stdout, format, args );
     88   va_end (args);
     89   return result;
     90 }
     91 
     92 int swscanf(const wchar_t* /*s*/, const wchar_t* /*format*/, ... ) {
     93   errno = ENOTSUP;
     94   return -1;
     95 }
     96 
     97 int iswalnum(wint_t wc) { return isalnum(wc); }
     98 int iswalpha(wint_t wc) { return isalpha(wc); }
     99 int iswcntrl(wint_t wc) { return iscntrl(wc); }
    100 int iswdigit(wint_t wc) { return isdigit(wc); }
    101 int iswgraph(wint_t wc) { return isgraph(wc); }
    102 int iswlower(wint_t wc) { return islower(wc); }
    103 int iswprint(wint_t wc) { return isprint(wc); }
    104 int iswpunct(wint_t wc) { return ispunct(wc); }
    105 int iswspace(wint_t wc) { return isspace(wc); }
    106 int iswupper(wint_t wc) { return isupper(wc); }
    107 int iswxdigit(wint_t wc) { return isxdigit(wc); }
    108 
    109 int iswctype(wint_t wc, wctype_t char_class) {
    110   switch (char_class) {
    111     case WC_TYPE_ALNUM: return isalnum(wc);
    112     case WC_TYPE_ALPHA: return isalpha(wc);
    113     case WC_TYPE_BLANK: return isblank(wc);
    114     case WC_TYPE_CNTRL: return iscntrl(wc);
    115     case WC_TYPE_DIGIT: return isdigit(wc);
    116     case WC_TYPE_GRAPH: return isgraph(wc);
    117     case WC_TYPE_LOWER: return islower(wc);
    118     case WC_TYPE_PRINT: return isprint(wc);
    119     case WC_TYPE_PUNCT: return ispunct(wc);
    120     case WC_TYPE_SPACE: return isspace(wc);
    121     case WC_TYPE_UPPER: return isupper(wc);
    122     case WC_TYPE_XDIGIT: return isxdigit(wc);
    123     default: return 0;
    124   }
    125 }
    126 
    127 wint_t fgetwc(FILE* stream) {
    128   return static_cast<wint_t>(fgetc(stream));
    129 }
    130 
    131 wchar_t* fgetws(wchar_t* ws, int n, FILE* stream) {
    132   return reinterpret_cast<wchar_t*>(fgets(reinterpret_cast<char*>(ws), n, stream));
    133 }
    134 
    135 wint_t fputwc(wchar_t wc, FILE* stream) {
    136   return static_cast<wint_t>(fputc(static_cast<char>(wc), stream));
    137 }
    138 
    139 int fputws(const wchar_t* str, FILE* stream) {
    140   return fputs(reinterpret_cast<const char*>(str), stream );
    141 }
    142 
    143 int fwide(FILE* /*stream*/, int mode) {
    144   return mode;
    145 }
    146 
    147 wint_t getwc(FILE* stream) {
    148   return getc(stream);
    149 }
    150 
    151 wint_t getwchar() {
    152   return getchar();
    153 }
    154 
    155 int mbsinit(const mbstate_t* /*ps*/) {
    156   return 1;
    157 }
    158 
    159 size_t mbrlen(const char* /*s*/, size_t n, mbstate_t* /*ps*/) {
    160   return (n != 0);
    161 }
    162 
    163 size_t mbrtowc(wchar_t* pwc, const char* s, size_t n, mbstate_t* /*ps*/) {
    164   if (s == NULL) {
    165     s   = "";
    166     pwc = NULL;
    167   }
    168   if (n == 0) {
    169     if (pwc) {
    170       *pwc = 0;
    171       return 0;
    172     }
    173   }
    174   if (pwc) {
    175     *pwc = *s;
    176   }
    177   return (*s != 0);
    178 }
    179 
    180 size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* /*ps*/) {
    181   const char* s  = *src;
    182   const char* s2 = reinterpret_cast<const char*>(memchr(s, 0, len));
    183 
    184   if (s2 != NULL) {
    185     len = (size_t)(s2 - s) + 1U;
    186   }
    187 
    188   if (dst) {
    189     memcpy(reinterpret_cast<char*>(dst), s, len );
    190   }
    191 
    192   *src = s + len;
    193   return len;
    194 }
    195 
    196 size_t mbstowcs(wchar_t* dst, const char* src, size_t len) {
    197   return mbsrtowcs(dst, &src, len, NULL);
    198 }
    199 
    200 wint_t putwc(wchar_t wc, FILE* stream) {
    201   return fputc(static_cast<char>(wc), stream);
    202 }
    203 
    204 wint_t putwchar(wchar_t wc) {
    205   return putchar(static_cast<char>(wc));
    206 }
    207 
    208 wint_t towlower(wint_t wc) {
    209   return tolower(wc);
    210 }
    211 
    212 wint_t towupper(wint_t wc) {
    213   return toupper(wc);
    214 }
    215 
    216 wint_t ungetwc(wint_t wc, FILE* stream) {
    217   return ungetc(static_cast<char>(wc), stream);
    218 }
    219 
    220 size_t wcrtomb(char* s, wchar_t /*wc*/, mbstate_t* /*ps*/) {
    221   if (s != NULL) {
    222     *s = 1;
    223   }
    224   return 1;
    225 }
    226 
    227 size_t wcsftime(wchar_t* wcs, size_t maxsize, const wchar_t* format,  const struct tm* timptr) {
    228   return strftime(reinterpret_cast<char*>(wcs), maxsize, reinterpret_cast<const char*>(format), timptr);
    229 }
    230 
    231 size_t wcsrtombs(char* dst, const wchar_t** src, size_t len, mbstate_t* /*ps*/) {
    232   const char* s = reinterpret_cast<const char*>(*src);
    233   const char* s2 = reinterpret_cast<const char*>(memchr(s, 0, len));
    234   if (s2 != NULL) {
    235     len = (s2 - s)+1;
    236   }
    237   if (dst != NULL) {
    238     memcpy( dst, s, len );
    239   }
    240   *src = (wchar_t*)(s + len);
    241   return len;
    242 }
    243 
    244 size_t wcstombs(char* dst, const wchar_t* src, size_t len) {
    245   return wcsrtombs(dst, &src, len, NULL);
    246 }
    247 
    248 double wcstod(const wchar_t* nptr, wchar_t** endptr) {
    249   return strtod(reinterpret_cast<const char*>(nptr), reinterpret_cast<char**>(endptr));
    250 }
    251 
    252 long int wcstol(const wchar_t* nptr, wchar_t** endptr, int base) {
    253   return strtol(reinterpret_cast<const char*>(nptr), reinterpret_cast<char**>(endptr), base);
    254 }
    255 
    256 unsigned long int wcstoul(const wchar_t* nptr, wchar_t** endptr, int base) {
    257   return strtoul(reinterpret_cast<const char*>(nptr), reinterpret_cast<char**>(endptr), base);
    258 }
    259 
    260 wchar_t* wcswcs(const wchar_t* ws1, const wchar_t* ws2) {
    261   const char* s1 = reinterpret_cast<const char*>(ws1);
    262   const char* s2 = reinterpret_cast<const char*>(ws2);
    263   return reinterpret_cast<wchar_t*>(strstr(s1, s2));
    264 }
    265 
    266 int wctob(wint_t c) {
    267   return c;
    268 }
    269 
    270 wctype_t wctype(const char* property) {
    271   static const char* const  properties[WC_TYPE_MAX] = {
    272     "<invalid>",
    273     "alnum", "alpha", "blank", "cntrl", "digit", "graph",
    274     "lower", "print", "punct", "space", "upper", "xdigit"
    275   };
    276   for (size_t i = 0; i < WC_TYPE_MAX; ++i) {
    277     if (!strcmp(properties[i], property)) {
    278       return static_cast<wctype_t>(i);
    279     }
    280   }
    281   return static_cast<wctype_t>(0);
    282 }
    283 
    284 int wcwidth(wchar_t wc) {
    285   return (wc > 0);
    286 }
    287