1/* $NetBSD: multibyte.c,v 1.9 2019/08/01 12:28:53 martin Exp $ */ 2 3/* 4 * Ignore all multibyte sequences, removes all the citrus code. 5 * Probably only used by vfprintf() when parsing the format string. 6 * And possibly from libcurses if compiled with HAVE_WCHAR. 7 */ 8 9#include <stdlib.h> 10#include <string.h> 11#include <wchar.h> 12#include <wctype.h> 13#include <ctype.h> 14 15size_t 16mbrtowc(wchar_t *wc, const char *str, size_t max_sz, mbstate_t *ps) 17{ 18 if (str == NULL) 19 return 0; 20 21 if (wc != NULL) 22 *wc = (unsigned char)*str; 23 24 return *str == '\0' ? 0 : 1; 25} 26 27size_t 28mbrtowc_l(wchar_t *wc, const char *str, size_t max_sz, mbstate_t *ps, locale_t loc) 29{ 30 return mbrtowc(wc, str, max_sz, ps); 31} 32 33size_t 34wcrtomb(char *str, wchar_t wc, mbstate_t *ps) 35{ 36 *str = wc & 0xFF; 37 return 1; 38} 39 40 41size_t 42wcrtomb_l(char *str, wchar_t wc, mbstate_t *ps, locale_t loc) 43{ 44 return wcrtomb(str, wc, ps); 45} 46 47int 48wctob(wint_t x) 49{ 50 return x; 51} 52 53int 54wctob_l(wint_t x, locale_t loc) 55{ 56 return x; 57} 58 59wint_t 60btowc(int x) 61{ 62 return x; 63} 64 65wint_t 66btowc_l(int x, locale_t loc) 67{ 68 return x; 69} 70 71size_t 72mbrlen(const char * __restrict p, size_t l, mbstate_t * __restrict v) 73{ 74 size_t i; 75 for (i = 0; i < l; i++) 76 if (p[i] == '\0') 77 return i; 78 return l; 79} 80 81 82size_t 83mbrlen_l(const char * __restrict p, size_t l, mbstate_t * __restrict v, 84 locale_t loc) 85{ 86 return mbrlen(p, l, v); 87} 88 89int 90mbsinit(const mbstate_t *s) 91{ 92 return 0; 93} 94 95size_t 96mbsrtowcs(wchar_t * __restrict pwcs, const char ** __restrict s, size_t n, 97 mbstate_t * __restrict ps) 98{ 99 const char *p; 100 wchar_t *d; 101 size_t count; 102 103 for (p = *s, d = pwcs, count = 0; 104 count <= n; 105 count++, d++, p++) 106 { 107 if (mbrtowc(d, p, 1, ps) == 0) 108 break; 109 } 110 return count; 111} 112 113 114size_t 115mbsrtowcs_l(wchar_t * __restrict pwcs, const char ** __restrict s, size_t n, 116 mbstate_t * __restrict ps, locale_t loc) 117{ 118 return mbsrtowcs(pwcs, s, n, ps); 119} 120 121size_t 122wcsrtombs(char * __restrict s, const wchar_t ** __restrict pwcs, size_t n, 123 mbstate_t * __restrict ps) 124{ 125 char *d; 126 const wchar_t *p; 127 size_t count; 128 129 for (p = *pwcs, d = s, count = 0; 130 count <= n && *p != 0; 131 count++, d++, p++) 132 { 133 wcrtomb(d, *p, ps); 134 } 135 *d = 0; 136 return count; 137} 138 139size_t 140wcsrtombs_l(char * __restrict s, const wchar_t ** __restrict pwcs, size_t n, 141 mbstate_t * __restrict ps, locale_t loc) 142{ 143 return wcsrtombs(s, pwcs, n, ps); 144} 145 146size_t 147_mb_cur_max_l(locale_t loc) 148{ 149 return MB_CUR_MAX; 150} 151 152wint_t 153fgetwc(FILE *stream) 154{ 155 return fgetc(stream); 156} 157 158wint_t 159fputwc(wchar_t wc, FILE *stream) 160{ 161 return fputc(wc & 0xFF, stream); 162} 163 164wint_t __fputwc_unlock(wchar_t wc, FILE *stream); 165wint_t 166__fputwc_unlock(wchar_t wc, FILE *stream) 167{ 168 return __sputc(wc & 0xFF, stream); 169} 170 171#define MAPSINGLE(CT) \ 172 int \ 173 isw##CT(wint_t wc) \ 174 { \ 175 return is##CT(wc & 0xFF); \ 176 } 177 178MAPSINGLE(alnum) 179MAPSINGLE(alpha) 180MAPSINGLE(blank) 181MAPSINGLE(cntrl) 182MAPSINGLE(digit) 183MAPSINGLE(graph) 184MAPSINGLE(lower) 185MAPSINGLE(print) 186MAPSINGLE(punct) 187MAPSINGLE(space) 188MAPSINGLE(upper) 189MAPSINGLE(xdigit) 190 191int 192iswspace_l(wint_t wc, locale_t loc) 193{ 194 return iswspace(wc); 195} 196 197struct wct_entry_hack { 198 const char *name; 199 int (*predicate)(wint_t); 200}; 201 202#define WCTENTRY(T) { .name= #T , .predicate= isw##T }, 203static const struct wct_entry_hack my_wcts[] = { 204 { .name = NULL }, 205 WCTENTRY(alnum) 206 WCTENTRY(alpha) 207 WCTENTRY(blank) 208 WCTENTRY(cntrl) 209 WCTENTRY(digit) 210 WCTENTRY(graph) 211 WCTENTRY(lower) 212 WCTENTRY(print) 213 WCTENTRY(punct) 214 WCTENTRY(space) 215 WCTENTRY(upper) 216 WCTENTRY(xdigit) 217}; 218 219wctype_t 220wctype(const char *charclass) 221{ 222 223 for (size_t i = 1; i < __arraycount(my_wcts); i++) 224 if (strcmp(charclass, my_wcts[i].name) == 0) 225 return (wctype_t)i; 226 227 return (wctype_t)0; 228} 229 230int 231iswctype(wint_t wc, wctype_t charclass) 232{ 233 size_t ndx = (size_t)charclass; 234 235 if (ndx < 1 || ndx >= __arraycount(my_wcts)) 236 return 0; 237 238 return my_wcts[ndx].predicate(wc); 239} 240 241size_t 242wcslen(const wchar_t *s) 243{ 244 size_t l; 245 246 if (s == NULL) 247 return 0; 248 249 for (l = 0; *s; l++) 250 s++; 251 252 return l; 253} 254 255int 256wcswidth(const wchar_t *pwcs, size_t n) 257{ 258 int cols; 259 260 if (pwcs == NULL) 261 return 0; 262 263 if (*pwcs == 0) 264 return 0; 265 266 for (cols = 0; *pwcs && n > 0; cols++) 267 if (!isprint(*pwcs & 0xFF)) 268 return -1; 269 return cols; 270} 271 272int 273wcwidth(wchar_t wc) 274{ 275 if (wc == 0) 276 return 0; 277 if (!isprint(wc & 0xFF)) 278 return -1; 279 return 1; 280} 281 282wchar_t * 283wmemchr(const wchar_t *s, wchar_t c, size_t n) 284{ 285 286 if (s == NULL) 287 return NULL; 288 while (*s != 0 && *s != c) 289 s++; 290 if (*s != 0) 291 return __UNCONST(s); 292 return NULL; 293} 294 295wchar_t * 296wmemcpy(wchar_t * restrict s1, const wchar_t * restrict s2, size_t n) 297{ 298 wchar_t *p; 299 300 for (p = s1; n > 0; n--) 301 *p++ = *s2++; 302 303 return s1; 304} 305 306wint_t 307towlower(wint_t wc) 308{ 309 return tolower(wc & 0xFF); 310} 311 312wint_t 313towupper(wint_t wc) 314{ 315 return toupper(wc & 0xFF); 316} 317 318 319