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