Home | History | Annotate | Download | only in src
      1 #include <string.h>
      2 #include <wchar.h>
      3 #include <wctype.h>
      4 #include <assert.h>
      5 
      6 // Returns 1 if 'wc' is in the 'delim' string, 0 otherwise.
      7 static int _wc_indelim(wchar_t wc, const wchar_t* delim) {
      8     while (*delim) {
      9         if (wc == *delim)
     10             return 1;
     11         delim++;
     12     }
     13     return 0;
     14 }
     15 
     16 wchar_t *wcpcpy(wchar_t *to, const wchar_t *from) {
     17     size_t n = 0;
     18     for (;;) {
     19         wchar_t wc = from[n];
     20         to[n] = wc;
     21         if (wc == L'\0')
     22             break;
     23         n++;
     24     }
     25     return to + n;
     26 }
     27 
     28 wchar_t *wcpncpy(wchar_t *dst, const wchar_t *src, size_t n) {
     29     size_t i;
     30     for (i = 0; i < n; ++i) {
     31         wchar_t wc = src[i];
     32         dst[i] = wc;
     33         if (wc == L'\0')
     34             break;
     35     }
     36     while (i < n) {
     37         dst[i] = L'\0';
     38         ++i;
     39     }
     40     return &dst[n-1];
     41 }
     42 
     43 int wcscasecmp(const wchar_t *s1, const wchar_t *s2) {
     44     size_t n = 0;
     45     for (;;) {
     46         wchar_t wc1 = towlower(s1[n]);
     47         wchar_t wc2 = towlower(s2[n]);
     48         if (wc1 != wc2)
     49             return (wc1 > wc2) ? +1 : -1;
     50         if (wc1 == L'\0')
     51             return 0;
     52         n++;
     53     }
     54 }
     55 
     56 wchar_t *wcscat(wchar_t *s1, const wchar_t *s2) {
     57     size_t n = 0;
     58     while (s1[n] != L'\0')
     59         n++;
     60 
     61     size_t i = 0;
     62     for (;;) {
     63         wchar_t wc = s2[i];
     64         s1[n+i] = wc;
     65         if (wc == L'\0')
     66             break;
     67         i++;
     68     }
     69     return s1;
     70 }
     71 
     72 size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t siz) {
     73     // Sanity check simplifies code below
     74     if (siz == 0)
     75         return 0;
     76 
     77     // Skip dst characters.
     78     size_t n = 0;
     79     while (n < siz && dst[n] != L'\0')
     80       n++;
     81 
     82     if (n == siz)
     83       return n + wcslen(src);
     84 
     85     // Copy as much source characters as they fit into siz-1 bytes.
     86     size_t i;
     87     for (i = 0; n+i+1 < siz && src[i] != L'\0'; ++i)
     88         dst[n+i] = src[i];
     89 
     90     // Always zero terminate destination
     91     dst[n+i] = L'\0';
     92 
     93     // Skip remaining source characters
     94     while (src[i] != L'\0')
     95         i++;
     96 
     97     return n+i;
     98 }
     99 
    100 size_t wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) {
    101     size_t i;
    102 
    103     // Copy all non-zero bytes that fit into siz-1 destination bytes
    104     for (i = 0; i + 1 < siz && src[i] != L'\0'; ++i)
    105         dst[i] = src[i];
    106 
    107     // Always zero-terminate destination buffer
    108     dst[i] = L'\0';
    109 
    110     // Skip other source characters.
    111     while (src[i] != L'\0')
    112         ++i;
    113 
    114     return i;
    115 }
    116 
    117 size_t wcslen(const wchar_t *s) {
    118     size_t n = 0;
    119     for (;;) {
    120         wchar_t wc = s[n];
    121         if (wc == L'\0')
    122             return n;
    123         n++;
    124     }
    125 }
    126 
    127 int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n) {
    128     size_t i;
    129     for (i = 0; i < n; ++i) {
    130         wchar_t wc1 = towlower(s1[i]);
    131         wchar_t wc2 = towlower(s2[i]);
    132         if (wc1 != wc2)
    133             return (wc1 > wc2) ? +1 : -1;
    134     }
    135     return 0;
    136 }
    137 
    138 wchar_t *wcsncat(wchar_t *s1, const wchar_t *s2, size_t n) {
    139     size_t start = 0;
    140     while (s1[start] != L'\0')
    141         start++;
    142 
    143     // Append s2.
    144     size_t i;
    145     for (i = 0; i < n; ++i) {
    146         wchar_t wc = s2[i];
    147         s1[start + i] = wc;
    148         if (wc == L'\0')
    149             break;
    150     }
    151     return (wchar_t*)s1;
    152 }
    153 
    154 int wcsncmp(const wchar_t *s1, const wchar_t *s2, size_t n) {
    155     size_t i;
    156     for (i = 0; i < n; ++i) {
    157         wchar_t wc = s1[i];
    158         if (wc != s2[i])
    159             return (wc > s2[i]) ? +1 : -1;
    160         if (wc == L'\0')
    161             break;
    162     }
    163     return 0;
    164 }
    165 
    166 wchar_t *wcsncpy(wchar_t *dst, const wchar_t *src, size_t n) {
    167     // Copy initial characters.
    168     size_t i;
    169     for (i = 0; i < n; ++i) {
    170         wchar_t wc = src[i];
    171         if (wc == L'\0')
    172             break;
    173         dst[i] = wc;
    174     }
    175     // zero-pad the remainder.
    176     for ( ; i < n; ++i)
    177         dst[i] = L'\0';
    178 
    179     return dst;
    180 }
    181 
    182 size_t wcsnlen(const wchar_t *s, size_t maxlen) {
    183     size_t n;
    184     for (n = 0; n < maxlen; ++n) {
    185         if (s[n] == L'\0')
    186             break;
    187     }
    188     return n;
    189 }
    190 
    191 wchar_t *wcspbrk(const wchar_t *s, const wchar_t *set) {
    192     size_t n = 0;
    193     for (;;) {
    194         wchar_t wc = s[n];
    195         if (!wc)
    196             return NULL;
    197         if (_wc_indelim(wc, set))
    198             return (wchar_t*)&s[n];
    199         n++;
    200     }
    201 }
    202 
    203 wchar_t *wcschr(const wchar_t *s, wchar_t c) {
    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