1 /* $MirOS: src/include/wchar.h,v 1.37 2014/03/26 00:13:09 tg Exp $ */ 2 3 /*- 4 * Copyright (c) 2007, 2008, 2013, 2014 5 * Thorsten Glaser <tg@mirbsd.de> 6 * 7 * Provided that these terms and disclaimer and all copyright notices 8 * are retained or reproduced in an accompanying document, permission 9 * is granted to deal in this work without restriction, including un- 10 * limited rights to use, publicly perform, distribute, sell, modify, 11 * merge, give away, or sublicence. 12 * 13 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 14 * the utmost extent permitted by applicable law, neither express nor 15 * implied; without malicious intent or gross negligence. In no event 16 * may a licensor, author or contributor be held liable for indirect, 17 * direct, other damage, loss, or other issues arising in any way out 18 * of dealing in the work, even if advised of the possibility of such 19 * damage or existence of a defect, except proven that it results out 20 * of said person's immediate fault when using the work as intended. 21 * 22 * The author reserves the right to steward the OPTU encoding forms. 23 */ 24 25 #ifndef _WCHAR_H_ 26 #define _WCHAR_H_ 27 28 #include <stdlib.h> 29 #include <ctype.h> 30 #include <string.h> 31 #include <stdarg.h> 32 #include <stddef.h> 33 #include <stdio.h> 34 #include <time.h> 35 36 /* ISO/IEC 9899:1999/Cor.3:2007(E) */ 37 #ifdef __STDC_MB_MIGHT_NEQ_WC__ 38 /* we really need wchar_t values to be proper Unicode */ 39 #error You are crazy. Go away. 40 #endif 41 42 #ifndef __IN_MKDEP 43 /* makedepend may not define the constants we are checking for */ 44 #if __WCHAR_MAX__ != 65535U 45 #error GCC __WCHAR_MAX__ does not indicate UCS-2 46 #endif 47 #ifndef __STDC_ISO_10646__ 48 #error This code assumes that wchar_t is UCS-2HE 49 #endif 50 #endif /* !__IN_MKDEP */ 51 52 #if !defined(_GCC_WCHAR_T) && !defined(__cplusplus) 53 #define _GCC_WCHAR_T 54 typedef __WCHAR_TYPE__ wchar_t; 55 #endif 56 57 #if !defined(_GCC_WINT_T) 58 #define _GCC_WINT_T 59 typedef __WINT_TYPE__ wint_t; 60 #endif 61 62 #if !defined(_GCC_MBSTATE_T) 63 #define _GCC_MBSTATE_T 64 typedef struct { 65 /*- 66 * 0: initial state 67 * 1: "value" contains one more octet worth of information 68 * 2: "value" contains two more octets worth of information 69 * 3: "value" contains the lower 6 bit of a rejected hibit-7 octet 70 * (possible future extension to two rejected octets) 71 */ 72 unsigned int count:2; 73 /*- 74 * 10 bits for mbstowcs(3) and optu8to16(3) 75 * 12 bits for wcstombs(3) and optu16to8(3) 76 * 14 bits available in total 77 */ 78 unsigned int value:12; 79 } __attribute__((__packed__)) mbstate_t; 80 #endif 81 82 #undef WCHAR_MIN 83 #define WCHAR_MIN 0 84 #undef WCHAR_MAX 85 #define WCHAR_MAX 0xFFFDU 86 #undef WEOF 87 #define WEOF 0xFFFFU 88 89 typedef unsigned int wctype_t; 90 91 __BEGIN_DECLS 92 wint_t btowc(int); 93 wint_t fgetwc(FILE *); 94 wchar_t *fgetws(wchar_t *, int, FILE *); 95 wint_t fputwc(wchar_t, FILE *); 96 int fputws(const wchar_t *, FILE *); 97 int fwide(FILE *, int); 98 wint_t getwc(FILE *); 99 wint_t getwchar(void); 100 size_t mbrlen(const char *, size_t, mbstate_t *); 101 size_t mbrtowc(wchar_t *, const char *, size_t, mbstate_t *) 102 __attribute__((__bounded__(__string__, 2, 3))); 103 int mbsinit(const mbstate_t *); 104 size_t mbslen(const char *); 105 #if __OPENBSD_VISIBLE 106 size_t mbsnrtowcs(wchar_t *, const char **, size_t, size_t, mbstate_t *); 107 #endif 108 size_t mbsrtowcs(wchar_t *, const char **, size_t, mbstate_t *); 109 #if __OPENBSD_VISIBLE 110 #undef optu16to8 111 #define optu16to8 optu16to8 112 size_t optu16to8(char *, wchar_t, mbstate_t *) 113 __attribute__((__bounded__(__minbytes__, 1, MB_CUR_MAX))); 114 #undef optu8to16 115 #define optu8to16 optu8to16 116 size_t optu8to16(wchar_t *, const char *, size_t, mbstate_t *) 117 __attribute__((__bounded__(__string__, 2, 3))); 118 #endif 119 wint_t putwc(wchar_t, FILE *); 120 wint_t putwchar(wchar_t); 121 wint_t ungetwc(wint_t, FILE *); 122 size_t wcrtomb(char *, wchar_t, mbstate_t *) 123 __attribute__((__bounded__(__minbytes__, 1, MB_CUR_MAX))); 124 int wcscasecmp(const wchar_t *, const wchar_t *); 125 wchar_t *wcscat(wchar_t *, const wchar_t *); 126 wchar_t *wcschr(const wchar_t *, wchar_t); 127 int wcscmp(const wchar_t *, const wchar_t *); 128 int wcscoll(const wchar_t *, const wchar_t *); 129 wchar_t *wcscpy(wchar_t *, const wchar_t *); 130 size_t wcscspn(const wchar_t *, const wchar_t *); 131 wchar_t *wcsdup(const wchar_t *); 132 size_t wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *); 133 size_t wcslcat(wchar_t *, const wchar_t *, size_t); 134 size_t wcslcpy(wchar_t *, const wchar_t *, size_t); 135 size_t wcslen(const wchar_t *); 136 int wcsncasecmp(const wchar_t *, const wchar_t *, size_t); 137 wchar_t *wcsncat(wchar_t *, const wchar_t *, size_t); 138 int wcsncmp(const wchar_t *, const wchar_t *, size_t); 139 wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t); 140 #if __OPENBSD_VISIBLE 141 wchar_t *wcsndup(const wchar_t *, size_t); 142 size_t wcsnrtombs(char *, const wchar_t **, size_t, size_t, mbstate_t *); 143 #endif 144 wchar_t *wcspbrk(const wchar_t *, const wchar_t *); 145 wchar_t *wcsrchr(const wchar_t *, wchar_t); 146 size_t wcsrtombs(char *, const wchar_t **, size_t, mbstate_t *); 147 size_t wcsspn(const wchar_t *, const wchar_t *); 148 wchar_t *wcsstr(const wchar_t *, const wchar_t *); 149 double wcstod(const wchar_t *, wchar_t **); 150 float wcstof(const wchar_t *, wchar_t **); 151 wchar_t *wcstok(wchar_t *, const wchar_t *, wchar_t **); 152 long wcstol(const wchar_t *, wchar_t **, int); 153 #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || \ 154 defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) > 199901L 155 /* LONGLONG */ 156 long long wcstoll(const wchar_t *, wchar_t **, int); 157 #endif 158 unsigned long wcstoul(const wchar_t *, wchar_t **, int); 159 #if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || \ 160 defined(_ISOC99_SOURCE) || (__STDC_VERSION__ - 0) > 199901L 161 /* LONGLONG */ 162 unsigned long long wcstoull(const wchar_t *, wchar_t **, int); 163 #endif 164 wchar_t *wcswcs(const wchar_t *, const wchar_t *); 165 int wcswidth(const wchar_t *, size_t); 166 size_t wcsxfrm(wchar_t *, const wchar_t *, size_t); 167 int wctob(wint_t); 168 wctype_t wctype(const char *); 169 int wcwidth(wchar_t); 170 wchar_t *wmemchr(const wchar_t *, wchar_t, size_t); 171 int wmemcmp(const wchar_t *, const wchar_t *, size_t); 172 wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t); 173 wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); 174 wchar_t *wmemset(wchar_t *, wchar_t, size_t); 175 176 /* these functions are currently not implemented in libc */ 177 #if 0 178 int fwprintf(FILE *, const wchar_t *, ...); 179 int fwscanf(FILE *, const wchar_t *, ...); 180 int swprintf(wchar_t *, size_t, const wchar_t *, ...); 181 int swscanf(const wchar_t *, const wchar_t *, ...); 182 int vfwprintf(FILE *, const wchar_t *, _BSD_VA_LIST_); 183 int vfwscanf(FILE *, const wchar_t *, _BSD_VA_LIST_); 184 int vswprintf(wchar_t *, const wchar_t *, _BSD_VA_LIST_); 185 int vswscanf(const wchar_t *, const wchar_t *, _BSD_VA_LIST_); 186 int vwprintf(const wchar_t *, _BSD_VA_LIST_); 187 int vwscanf(const wchar_t *, _BSD_VA_LIST_); 188 int wprintf(const wchar_t *, ...); 189 int wscanf(const wchar_t *, ...); 190 #endif 191 __END_DECLS 192 193 #define getwc(f) fgetwc(f) 194 #define getwchar() getwc(stdin) 195 #define putwc(wc, f) fputwc((wc), (f)) 196 #define putwchar(wc) putwc((wc), stdout) 197 198 #if __OPENBSD_VISIBLE && !defined(iswoctet) 199 #define iswoctet(wc) (((wchar_t)(wc) & 0xFF80) == 0xEF80) 200 #endif 201 202 #ifdef __GNUC__ 203 #if !defined(__cplusplus) 204 #define btowc(c) __extension__({ \ 205 wint_t __WC_tmp = (c); \ 206 \ 207 (__WC_tmp > 0x7F ? WEOF : __WC_tmp); \ 208 }) 209 #define mblen(s,n) __extension__({ \ 210 mbstate_t __WC_ps = { 0, 0 }; \ 211 int __WC_rv; \ 212 \ 213 (((__WC_rv = mbrtowc(NULL, (s), (n), \ 214 &__WC_ps)) < 0) ? -1 : __WC_rv); \ 215 }) 216 #define mbsinit(c) __extension__({ \ 217 const mbstate_t *__WC_ps = (c); \ 218 \ 219 (__WC_ps == NULL ? -1 : \ 220 __WC_ps->count == 0 ? 1 : 0); \ 221 }) 222 #define mbslen(c) __extension__({ \ 223 const uint8_t *__WC_s = (c); \ 224 size_t __WC_num = 0; \ 225 \ 226 while (*__WC_s) { \ 227 if ((*__WC_s & 0xC0) != 0x80) \ 228 ++__WC_num; \ 229 ++__WC_s; \ 230 } \ 231 (__WC_num); \ 232 }) 233 #define mbstowcs(pwcs,s,n) __extension__({ \ 234 mbstate_t __WC_ps = { 0, 0 }; \ 235 const char *__WC_sb = (s); \ 236 \ 237 (mbsrtowcs((pwcs), &__WC_sb, (n), &__WC_ps)); \ 238 }) 239 #define mbtowc(pwc,s,n) __extension__({ \ 240 mbstate_t __WC_ps = { 0, 0 }; \ 241 int __WC_rv; \ 242 \ 243 (((__WC_rv = mbrtowc((pwc), (s), (n), \ 244 &__WC_ps)) < 0) ? -1 : __WC_rv); \ 245 }) 246 #define wcstombs(s,pwcs,n) __extension__({ \ 247 mbstate_t __WC_ps = { 0, 0 }; \ 248 const wchar_t *__WC_sb = (pwcs); \ 249 \ 250 (wcsrtombs((s), &__WC_sb, (n), &__WC_ps)); \ 251 }) 252 #define wcswidth(s,n) __extension__({ \ 253 int __WC_width = 0, __WC_i, __WC_n = (n); \ 254 const wchar_t *__WC_s = (s); \ 255 \ 256 while (__WC_n--) { \ 257 if (*__WC_s == L'\0') \ 258 break; \ 259 if ((__WC_i = wcwidth(*__WC_s)) < 0) { \ 260 __WC_width = -1; \ 261 break; \ 262 } \ 263 __WC_width += __WC_i; \ 264 __WC_s++; \ 265 } \ 266 (__WC_width); \ 267 }) 268 #define wctob(c) __extension__({ \ 269 wint_t __WC_tmp = (c); \ 270 \ 271 (__WC_tmp > 0x7F ? EOF : (int)__WC_tmp); \ 272 }) 273 #define wctomb(s,c) __extension__({ \ 274 mbstate_t __WC_ps = { 0, 0 }; \ 275 char *__WC_s = (s); \ 276 \ 277 (__WC_s ? wcrtomb(__WC_s, (c), &__WC_ps) : 0); \ 278 }) 279 #endif /* !__cplusplus */ 280 281 /* roll back the middle char of a mis-done 3-byte mb->wc conversion */ 282 #define mbrtowc_rollback(ps) __extension__({ \ 283 const mbstate_t *__WC_s = (ps); \ 284 int __WC_rv = EOF; \ 285 \ 286 if (__WC_s->count == 1 && \ 287 __WC_s->value >= 0x20) \ 288 __WC_rv = 0x80 | \ 289 (__WC_s->value & 0x3F); \ 290 (__WC_rv); \ 291 }) 292 #endif 293 294 /* initialise/set/reset a mbstate_t to empty */ 295 #define mbsreset(ps) do { \ 296 mbstate_t *__WC_s = (ps); \ 297 \ 298 if (__WC_s != NULL) \ 299 __WC_s->count = 0; \ 300 } while (0) 301 302 #endif 303