summaryrefslogtreecommitdiff
path: root/libc/misc/wctype
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2002-07-03 17:24:17 +0000
committerManuel Novoa III <mjn3@codepoet.org>2002-07-03 17:24:17 +0000
commit599ad608ee3297bc1e2bb11656a97335e303877a (patch)
treec5b59cb5fa2c90f3b0c8b4d9831ae763f2825327 /libc/misc/wctype
parentab579e469c6787df9bd2252b3de8b1700d5097d8 (diff)
Enable WCHAR support for C/POSIX stub locales.
Implemented unformatted wide i/o functions. (ungetwc still needs testing) Fix a few bugs in wchar.c. Modifications for bcc/elks support.
Diffstat (limited to 'libc/misc/wctype')
-rw-r--r--libc/misc/wctype/wctype.c123
1 files changed, 121 insertions, 2 deletions
diff --git a/libc/misc/wctype/wctype.c b/libc/misc/wctype/wctype.c
index 39ed2cfd5..802e979f1 100644
--- a/libc/misc/wctype/wctype.c
+++ b/libc/misc/wctype/wctype.c
@@ -34,6 +34,7 @@
#include <string.h>
#include <errno.h>
#include <locale.h>
+#include <ctype.h>
/* We know wide char support is enabled. We wouldn't be here otherwise. */
@@ -41,7 +42,9 @@
* towctrans function. */
/* #define SMALL_UPLOW */
+#ifndef __LOCALE_C_ONLY
#define __WCTYPE_WITH_LOCALE
+#endif
/**********************************************************************/
@@ -292,6 +295,10 @@ wctype_t wctype(const char *property)
/**********************************************************************/
#ifdef L_iswctype
+#warning duh... replace the range-based classification with table lookup!
+
+#ifdef __WCTYPE_WITH_LOCALE
+
#warning TODO: need to fix locale ctype table lookup stuff
#if 0
extern const char ctype_range[];
@@ -346,6 +353,102 @@ int iswctype(wint_t wc, wctype_t desc)
return 0;
}
+#else
+
+static const unsigned char WCctype[] = {
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_space_blank << 4),
+ __CTYPE_cntrl_space_nonblank | (__CTYPE_cntrl_space_nonblank << 4),
+ __CTYPE_cntrl_space_nonblank | (__CTYPE_cntrl_space_nonblank << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_cntrl_nonspace | (__CTYPE_cntrl_nonspace << 4),
+ __CTYPE_print_space_blank | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_digit | (__CTYPE_digit << 4),
+ __CTYPE_digit | (__CTYPE_digit << 4),
+ __CTYPE_digit | (__CTYPE_digit << 4),
+ __CTYPE_digit | (__CTYPE_digit << 4),
+ __CTYPE_digit | (__CTYPE_digit << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_alpha_upper << 4),
+ __CTYPE_alpha_upper | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_alpha_lower << 4),
+ __CTYPE_alpha_lower | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_punct << 4),
+ __CTYPE_punct | (__CTYPE_cntrl_nonspace << 4),
+};
+
+static const char ctype_range[] = {
+ __CTYPE_RANGES
+};
+
+int iswctype(wint_t wc, wctype_t desc)
+{
+ unsigned char d = __CTYPE_unclassified;
+
+ if (((__uwchar_t) wc) <= 0x7f) {
+ if (desc < _CTYPE_iswxdigit) {
+ d = WCctype[wc >> 1];
+ d = (wc & 1) ? (d >> 4) : (d & 0xf);
+
+ return ( ((unsigned char)(d - ctype_range[2*desc]))
+ <= ctype_range[2*desc + 1] )
+ && ((desc != _CTYPE_iswblank) || (d & 1));
+ }
+
+ if (desc == _CTYPE_iswxdigit) {
+ return __C_isxdigit(((char) wc));
+ }
+ }
+ return 0;
+}
+
+#endif
+
#endif
/**********************************************************************/
#ifdef L_towctrans
@@ -446,10 +549,26 @@ wint_t towctrans(wint_t wc, wctrans_t desc)
#endif
-#else
+#else /* __WCTYPE_WITH_LOCALE */
+/* Minimal support for C/POSIX locale. */
-#endif
+wint_t towctrans(wint_t wc, wctrans_t desc)
+{
+ if (((unsigned int)(desc - _CTYPE_tolower))
+ <= (_CTYPE_toupper - _CTYPE_tolower)
+ ) {
+ /* Transliteration is either tolower or toupper. */
+ if (((__uwchar_t) wc) <= 0x7f) {
+ return (desc == _CTYPE_tolower) ? _tolower(wc) : _toupper(wc);
+ }
+ } else {
+ __set_errno(EINVAL); /* Invalid transliteration. */
+ }
+ return wc;
+}
+
+#endif /* __WCTYPE_WITH_LOCALE */
#endif
/**********************************************************************/