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 15 size_t 16 mbrtowc(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 27 size_t 28 mbrtowc_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 33 size_t 34 wcrtomb(char *str, wchar_t wc, mbstate_t *ps) 35 { 36 *str = wc & 0xFF; 37 return 1; 38 } 39 40 41 size_t 42 wcrtomb_l(char *str, wchar_t wc, mbstate_t *ps, locale_t loc) 43 { 44 return wcrtomb(str, wc, ps); 45 } 46 47 int 48 wctob(wint_t x) 49 { 50 return x; 51 } 52 53 int 54 wctob_l(wint_t x, locale_t loc) 55 { 56 return x; 57 } 58 59 wint_t 60 btowc(int x) 61 { 62 return x; 63 } 64 65 wint_t 66 btowc_l(int x, locale_t loc) 67 { 68 return x; 69 } 70 71 size_t 72 mbrlen(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 82 size_t 83 mbrlen_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 89 int 90 mbsinit(const mbstate_t *s) 91 { 92 return 0; 93 } 94 95 size_t 96 mbsrtowcs(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 114 size_t 115 mbsrtowcs_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 121 size_t 122 wcsrtombs(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 139 size_t 140 wcsrtombs_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 146 size_t 147 _mb_cur_max_l(locale_t loc) 148 { 149 return MB_CUR_MAX; 150 } 151 152 wint_t 153 fgetwc(FILE *stream) 154 { 155 return fgetc(stream); 156 } 157 158 wint_t 159 fputwc(wchar_t wc, FILE *stream) 160 { 161 return fputc(wc & 0xFF, stream); 162 } 163 164 wint_t __fputwc_unlock(wchar_t wc, FILE *stream); 165 wint_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 178 MAPSINGLE(alnum) 179 MAPSINGLE(alpha) 180 MAPSINGLE(blank) 181 MAPSINGLE(cntrl) 182 MAPSINGLE(digit) 183 MAPSINGLE(graph) 184 MAPSINGLE(lower) 185 MAPSINGLE(print) 186 MAPSINGLE(punct) 187 MAPSINGLE(space) 188 MAPSINGLE(upper) 189 MAPSINGLE(xdigit) 190 191 int 192 iswspace_l(wint_t wc, locale_t loc) 193 { 194 return iswspace(wc); 195 } 196 197 struct wct_entry_hack { 198 const char *name; 199 int (*predicate)(wint_t); 200 }; 201 202 #define WCTENTRY(T) { .name= #T , .predicate= isw##T }, 203 static 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 219 wctype_t 220 wctype(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 230 int 231 iswctype(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 241 size_t 242 wcslen(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 255 int 256 wcswidth(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 272 int 273 wcwidth(wchar_t wc) 274 { 275 if (wc == 0) 276 return 0; 277 if (!isprint(wc & 0xFF)) 278 return -1; 279 return 1; 280 } 281 282 wchar_t * 283 wmemchr(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 295 wchar_t * 296 wmemcpy(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 306 wint_t 307 towlower(wint_t wc) 308 { 309 return tolower(wc & 0xFF); 310 } 311 312 wint_t 313 towupper(wint_t wc) 314 { 315 return toupper(wc & 0xFF); 316 } 317 318 319