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