Browse Source

ctype: remove some trivial macros from ctype.h;
remove __tolower and __toupper (they existed only in SOME configs!);
remove usages of _tolower (some of them clearly buggy) from uclibc code;
add a few more -U<define> options to unifdef pass over installed headers;
document it on docs/wchar_and_locale.txt

text data bss dec hex filename
- 514963 2727 15396 533086 8225e lib/libuClibc-0.9.30-svn.so
+ 514888 2727 15396 533011 82213 lib/libuClibc-0.9.30-svn.so

Denis Vlasenko 15 years ago
parent
commit
cf578c75a5

+ 2 - 1
Rules.mak

@@ -46,7 +46,8 @@ AWK        = awk
 
 STRIP_FLAGS ?= -x -R .note -R .comment
 
-UNIFDEF := $(top_builddir)extra/scripts/unifdef -UUCLIBC_INTERNAL
+## unused? if yes, remove after 0.9.31
+## UNIFDEF := $(top_builddir)extra/scripts/unifdef -UUCLIBC_INTERNAL
 
 # Select the compiler needed to build binaries for your development system
 HOSTCC     = gcc

+ 39 - 40
docs/wchar_and_locale.txt

@@ -72,43 +72,42 @@ __WCHAR_REPLACEMENT_CHAR
 
 		Actual ctype macros are a bloody mess!
 
-ctype.h
-...
-...
-#define __isctype(c, type) \
-  ((__UCLIBC_CTYPE_B)[(int) (c)] & (__ctype_mask_t) type)
-
-#define __isascii(c)    (((c) & ~0x7f) == 0)    /* If C is a 7 bit value.  */
-#define __toascii(c)    ((c) & 0x7f)            /* Mask off high bits.  */
-#define __isdigit_char(C)    (((unsigned char)((C) - '0')) <= 9)
-#define __isdigit_int(C)     (((unsigned int)((C) - '0')) <= 9)
-
-# define isalnum(c)     __isctype((c), _ISalnum)
-# define isalpha(c)     __isctype((c), _ISalpha)
-
-# if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus
-#  define tolower(c)    __tobody (c, tolower, __UCLIBC_CTYPE_TOLOWER, (c))
-#  define toupper(c)    __tobody (c, toupper, __UCLIBC_CTYPE_TOUPPER, (c))
-# endif /* Optimizing gcc */
-
-# if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
-#  define isascii(c)    __isascii (c)
-#  define toascii(c)    __toascii (c)
-#  define _tolower(c)   ((int) (__UCLIBC_CTYPE_TOLOWER)[(int) (c)])
-#  define _toupper(c)   ((int) (__UCLIBC_CTYPE_TOUPPER)[(int) (c)])
-# endif
-...
-...
-
-bits/uClibc_ctype.h
-...
-...
-#define __tolower(c)            __body(tolower,c)
-#define __toupper(c)            __body(toupper,c)
-
-#define _toupper(c) ((c) ^ 0x20)
-#define _tolower(c) ((c) | 0x20)
-...
-...
-
-WTF?! We have (at least) TWO DIFFERENT _tolower's?
+__C_isspace(c), __C_tolower(c) et al
+	Defined in bits/uClibc_ctype.h. Non-locale-aware, unsafe
+	wrt multiple-evaluation, macros. Return unsigned int.
+
+__isspace(c), __tolower(c) et al
+	Defined in bits/uClibc_ctype.h. Non-locale-aware,
+	but safe wrt multiple-evaluation, macros. Return int.
+
+__isdigit_char, __isdigit_int
+	Visible only to uclibc code. ((unsigned char/int)((c) - '0') <= 9).
+
+_tolower(c), _toupper(c)
+	Even more unsafe versions (they just do | 0x20 or ^ 0x20). Sheesh.
+	They are mandated by POSIX so we must have them defined,
+	but I removed all uses in uclibc code. Half of them were buggy.
+
+isspace(c), tolower(c) et al
+	Declared as int isXXXX(int c) in bits/uClibc_ctype.h. Then,
+	if not C++ compile, defined as macros to __usXXXX(c)
+
+bits/uClibc_ctype.h is included by ctype.h only if !__UCLIBC_HAS_CTYPE_TABLES__.
+
+Otherwise, ctype.h declares int isXXXX(int c) functions,
+then defines macros for isXXXX(c), __isXXX(c), toXXXX(c).
+Surprisingly, there are no __toXXXX(c), but if __USE_EXTERN_INLINES,
+there are inlines (yes, not macros!) for toXXXX(c) functions,
+so those may have both inlines and macros!).
+It also defines "unsafe" _toXXXX macros.
+
+All in all, __isXXXX(c) and __toXXXXX(c) seem to be useless,
+they are full equivalents to non-underscored versions.
+Remove?
+
+Macro-ization of isXXX(c) for __UCLIBC_HAS_XLOCALE__ case is problematic:
+it is done by indexing: __UCLIBC_CTYPE_B[c], and in __UCLIBC_HAS_XLOCALE__
+case __UCLIBC_CTYPE_B is doing a __ctype_b_loc() call! We do not save
+function call! Thus, why not have dedicated optimized functions
+for each isXXXX() instead? Looking deeper, __ctype_b_loc() may have
+another lever of function calls inside! What a mess...

+ 6 - 1
extra/scripts/install_headers.sh

@@ -51,7 +51,12 @@ while read -r filename; do
 	# exactly the same as input. That's ok.
 	# Do not abort the script if unifdef "fails"!
 	# NB2: careful with sed command arguments, they contain tab character
-	"$top_builddir/extra/scripts/unifdef" -UUCLIBC_INTERNAL -U_LIBC "$1/$filename" \
+	"$top_builddir/extra/scripts/unifdef" \
+		-UUCLIBC_INTERNAL \
+		-U_LIBC \
+		-U__UCLIBC_GEN_LOCALE \
+		-U__NO_CTYPE \
+		"$1/$filename" \
 	| sed -e '/^rtld_hidden_proto[ 	]*([a-zA-Z0-9_]*)$/d' \
 	| sed -e '/^lib\(c\|m\|resolv\|dl\|intl\|rt\|nsl\|util\|crypt\|pthread\)_hidden_proto[ 	]*([a-zA-Z0-9_]*)$/d' \
 	>"$2/$filename"

+ 75 - 101
include/ctype.h

@@ -27,7 +27,13 @@
 #include <features.h>
 #include <bits/types.h>
 
-#ifdef __UCLIBC_HAS_CTYPE_TABLES__
+#ifndef __UCLIBC_HAS_CTYPE_TABLES__
+
+/* "Stub locale": we are permanently in C/POSIX locale.
+ * Using simple(r) ctype.h machinery in this header instead: */
+#include <bits/uClibc_ctype.h>
+
+#else
 
 __BEGIN_DECLS
 
@@ -51,13 +57,14 @@ enum
   _ISalnum  = 1 << 11,  /* Alphanumeric.  */
 };
 
+/* __ctype_XXX_t types and __UCLIBC_CTYPE_x_TBL_OFFSET constants */
 #include <bits/uClibc_touplow.h>
 
 #ifdef __UCLIBC_HAS_CTYPE_SIGNED__
 # define __UCLIBC_CTYPE_IN_TO_DOMAIN(c) (((unsigned int)((c) + 128)) < 384)
-#else  /* __UCLIBC_HAS_CTYPE_SIGNED__ */
+#else
 # define __UCLIBC_CTYPE_IN_TO_DOMAIN(c) (((unsigned int)(c)) < 256)
-#endif /* __UCLIBC_HAS_CTYPE_SIGNED__ */
+#endif
 
 /* In the thread-specific locale model (see `uselocale' in <locale.h>)
    we cannot use global variables for these as was done in the past.
@@ -101,16 +108,12 @@ libc_hidden_proto(__C_ctype_tolower)
 
 #ifdef __UCLIBC_HAS_XLOCALE__
 
-extern __const __ctype_mask_t **__ctype_b_loc (void)
-     __attribute__ ((__const));
+const __ctype_mask_t **__ctype_b_loc(void) __attribute__ ((const));
 libc_hidden_proto(__ctype_b_loc)
-extern __const __ctype_touplow_t **__ctype_tolower_loc (void)
-     __attribute__ ((__const));
+const __ctype_touplow_t **__ctype_tolower_loc(void) __attribute__ ((const));
 libc_hidden_proto(__ctype_tolower_loc)
-extern __const __ctype_touplow_t **__ctype_toupper_loc (void)
-     __attribute__ ((__const));
+const __ctype_touplow_t **__ctype_toupper_loc(void) __attribute__ ((const));
 libc_hidden_proto(__ctype_toupper_loc)
-
 #define __UCLIBC_CTYPE_B	(*__ctype_b_loc())
 #define __UCLIBC_CTYPE_TOLOWER	(*__ctype_tolower_loc())
 #define __UCLIBC_CTYPE_TOUPPER	(*__ctype_toupper_loc())
@@ -124,64 +127,58 @@ extern const __ctype_touplow_t *__ctype_toupper;
 libc_hidden_proto(__ctype_toupper)
 extern const __ctype_touplow_t *__ctype_tolower;
 libc_hidden_proto(__ctype_tolower)
-
 #define __UCLIBC_CTYPE_B	(__ctype_b)
 #define __UCLIBC_CTYPE_TOLOWER	(__ctype_tolower)
 #define __UCLIBC_CTYPE_TOUPPER	(__ctype_toupper)
 
 #endif /* __UCLIBC_HAS_XLOCALE__ */
 
-#define __isctype(c, type) \
-  ((__UCLIBC_CTYPE_B)[(int) (c)] & (__ctype_mask_t) type)
 
 #define	__isascii(c)	(((c) & ~0x7f) == 0)	/* If C is a 7 bit value.  */
 #define	__toascii(c)	((c) & 0x7f)		/* Mask off high bits.  */
 
 #if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc)
-/* isdigit() is really locale-invariant, so provide some small fast macros.
- * These are uClibc-specific. */
+/* These are uClibc-specific. */
 #define __isdigit_char(C)    (((unsigned char)((C) - '0')) <= 9)
 #define __isdigit_int(C)     (((unsigned int)((C) - '0')) <= 9)
 #endif
 
-#define	__exctype(name)	extern int name (int) __THROW
-
 __BEGIN_NAMESPACE_STD
 
 /* The following names are all functions:
      int isCHARACTERISTIC(int c);
    which return nonzero iff C has CHARACTERISTIC.
    For the meaning of the characteristic names, see the `enum' above.  */
-__exctype (isalnum);
+extern int isalnum(int __c) __THROW;
 libc_hidden_proto(isalnum)
-__exctype (isalpha);
+extern int isalpha(int __c) __THROW;
 libc_hidden_proto(isalpha)
-__exctype (iscntrl);
+extern int iscntrl(int __c) __THROW;
 libc_hidden_proto(iscntrl)
-__exctype (isdigit);
+extern int isdigit(int __c) __THROW;
 libc_hidden_proto(isdigit)
-__exctype (islower);
+extern int islower(int __c) __THROW;
 libc_hidden_proto(islower)
-__exctype (isgraph);
+extern int isgraph(int __c) __THROW;
 libc_hidden_proto(isgraph)
-__exctype (isprint);
+extern int isprint(int __c) __THROW;
 libc_hidden_proto(isprint)
-__exctype (ispunct);
+extern int ispunct(int __c) __THROW;
 libc_hidden_proto(ispunct)
-__exctype (isspace);
+extern int isspace(int __c) __THROW;
 libc_hidden_proto(isspace)
-__exctype (isupper);
+extern int isupper(int __c) __THROW;
 libc_hidden_proto(isupper)
-__exctype (isxdigit);
+extern int isxdigit(int __c) __THROW;
 libc_hidden_proto(isxdigit)
 
 
 /* Return the lowercase version of C.  */
-extern int tolower (int __c) __THROW;
+extern int tolower(int __c) __THROW;
 libc_hidden_proto(tolower)
 
 /* Return the uppercase version of C.  */
-extern int toupper (int __c) __THROW;
+extern int toupper(int __c) __THROW;
 libc_hidden_proto(toupper)
 
 __END_NAMESPACE_STD
@@ -191,7 +188,7 @@ __END_NAMESPACE_STD
 #ifdef	__USE_ISOC99
 __BEGIN_NAMESPACE_C99
 
-__exctype (isblank);
+extern int isblank(int __c) __THROW;
 libc_hidden_proto(isblank)
 
 __END_NAMESPACE_C99
@@ -199,44 +196,39 @@ __END_NAMESPACE_C99
 
 #ifdef __USE_GNU
 /* Test C for a set of character classes according to MASK.  */
-extern int isctype (int __c, int __mask) __THROW;
+extern int isctype(int __c, int __mask) __THROW;
 #endif
 
 #if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
-
 /* Return nonzero iff C is in the ASCII set
    (i.e., is no more than 7 bits wide).  */
-extern int isascii (int __c) __THROW;
+extern int isascii(int __c) __THROW;
 libc_hidden_proto(isascii)
-
 /* Return the part of C that is in the ASCII set
    (i.e., the low-order 7 bits of C).  */
-extern int toascii (int __c) __THROW;
-
+extern int toascii(int __c) __THROW;
 /* These are the same as `toupper' and `tolower' except that they do not
    check the argument for being in the range of a `char'.  */
-__exctype (_toupper);
-__exctype (_tolower);
+extern int _toupper(int __c) __THROW;
+extern int _tolower(int __c) __THROW;
 #endif /* Use SVID or use misc.  */
 
 /* This code is needed for the optimized mapping functions.  */
-#define __tobody(c, f, a, args) \
-  (__extension__							      \
-   ({ int __res;							      \
-      if (sizeof (c) > 1)						      \
-	{								      \
-	  if (__builtin_constant_p (c))					      \
-	    {								      \
-	      int __c = (c);						      \
-	      __res = __UCLIBC_CTYPE_IN_TO_DOMAIN(__c) ? (a)[__c] : __c;      \
-	    }								      \
-	  else								      \
-	    __res = f args;						      \
-	}								      \
-      else								      \
-	__res = (a)[(int) (c)];						      \
-      __res; }))
-
+#define __tobody(c, f, table, args) \
+(__extension__ ({ \
+	int __res; \
+	if (sizeof(c) > 1) { \
+		if (__builtin_constant_p(c)) { \
+			int __c = (c); \
+			__res = __UCLIBC_CTYPE_IN_TO_DOMAIN(__c) ? (table)[__c] : __c; \
+		} else \
+			__res = f args; \
+	} else \
+		__res = (table)[(int) (c)]; \
+	__res; \
+}))
+
+#define __isctype(c, type) ((__UCLIBC_CTYPE_B)[(int)(c)] & (__ctype_mask_t)type)
 #if !defined __NO_CTYPE && !defined __cplusplus
 # define isalnum(c)	__isctype((c), _ISalnum)
 # define isalpha(c)	__isctype((c), _ISalpha)
@@ -249,7 +241,6 @@ __exctype (_tolower);
 # define isspace(c)	__isctype((c), _ISspace)
 # define isupper(c)	__isctype((c), _ISupper)
 # define isxdigit(c)	__isctype((c), _ISxdigit)
-
 # ifdef __USE_ISOC99
 #  define isblank(c)	__isctype((c), _ISblank)
 # endif
@@ -260,7 +251,6 @@ __NTH (tolower (int __c))
 {
   return __UCLIBC_CTYPE_IN_TO_DOMAIN(__c) ? (__UCLIBC_CTYPE_TOLOWER)[__c] : __c;
 }
-
 __extern_inline int
 __NTH (toupper (int __c))
 {
@@ -269,14 +259,13 @@ __NTH (toupper (int __c))
 # endif
 
 # if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus
-#  define tolower(c)	__tobody (c, tolower, __UCLIBC_CTYPE_TOLOWER, (c))
-#  define toupper(c)	__tobody (c, toupper, __UCLIBC_CTYPE_TOUPPER, (c))
+#  define tolower(c)	__tobody(c, tolower, __UCLIBC_CTYPE_TOLOWER, (c))
+#  define toupper(c)	__tobody(c, toupper, __UCLIBC_CTYPE_TOUPPER, (c))
 # endif /* Optimizing gcc */
 
 # if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
 #  define isascii(c)	__isascii (c)
 #  define toascii(c)	__toascii (c)
-
 #  define _tolower(c)	((int) (__UCLIBC_CTYPE_TOLOWER)[(int) (c)])
 #  define _toupper(c)	((int) (__UCLIBC_CTYPE_TOUPPER)[(int) (c)])
 # endif
@@ -284,7 +273,7 @@ __NTH (toupper (int __c))
 #endif /* Not __NO_CTYPE.  */
 
 
-#if defined(__USE_GNU) && defined(__UCLIBC_HAS_XLOCALE__)
+#if defined __USE_GNU && defined __UCLIBC_HAS_XLOCALE__
 /* The concept of one static locale per category is not very well
    thought out.  Many applications will need to process its data using
    information from several different locales.  Another application is
@@ -302,70 +291,61 @@ __NTH (toupper (int __c))
 
 /* These definitions are similar to the ones above but all functions
    take as an argument a handle for the locale which shall be used.  */
-#  define __isctype_l(c, type, locale) \
-  ((locale)->__ctype_b[(int) (c)] & (__ctype_mask_t) type)
-
-# define __exctype_l(name) 						      \
-  extern int name (int, __locale_t) __THROW
-
-/* The following names are all functions:
-     int isCHARACTERISTIC(int c, locale_t *locale);
-   which return nonzero iff C has CHARACTERISTIC.
-   For the meaning of the characteristic names, see the `enum' above.  */
-__exctype_l (isalnum_l);
+extern int isalnum_l(int, __locale_t) __THROW;
 libc_hidden_proto(isalnum_l)
-__exctype_l (isalpha_l);
+extern int isalpha_l(int, __locale_t) __THROW;
 libc_hidden_proto(isalpha_l)
-__exctype_l (iscntrl_l);
+extern int iscntrl_l(int, __locale_t) __THROW;
 libc_hidden_proto(iscntrl_l)
-__exctype_l (isdigit_l);
+extern int isdigit_l(int, __locale_t) __THROW;
 libc_hidden_proto(isdigit_l)
-__exctype_l (islower_l);
+extern int islower_l(int, __locale_t) __THROW;
 libc_hidden_proto(islower_l)
-__exctype_l (isgraph_l);
+extern int isgraph_l(int, __locale_t) __THROW;
 libc_hidden_proto(isgraph_l)
-__exctype_l (isprint_l);
+extern int isprint_l(int, __locale_t) __THROW;
 libc_hidden_proto(isprint_l)
-__exctype_l (ispunct_l);
+extern int ispunct_l(int, __locale_t) __THROW;
 libc_hidden_proto(ispunct_l)
-__exctype_l (isspace_l);
+extern int isspace_l(int, __locale_t) __THROW;
 libc_hidden_proto(isspace_l)
-__exctype_l (isupper_l);
+extern int isupper_l(int, __locale_t) __THROW;
 libc_hidden_proto(isupper_l)
-__exctype_l (isxdigit_l);
+extern int isxdigit_l(int, __locale_t) __THROW;
 libc_hidden_proto(isxdigit_l)
-__exctype_l (isblank_l);
+extern int isblank_l(int, __locale_t) __THROW;
 libc_hidden_proto(isblank_l)
 
-#if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
+# if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
 
 /* Return nonzero iff C is in the ASCII set
    (i.e., is no more than 7 bits wide).  */
 extern int isascii_l (int __c) __THROW;
 libc_hidden_proto(isascii_l)
 
-#endif
+# endif
 
 /* Return the lowercase version of C in locale L.  */
-extern int __tolower_l (int __c, __locale_t __l) __THROW;
+// "ordinary" ctype.h has no __tolower, why we try to have it?
+// remove after 0.9.31
+//extern int __tolower_l (int __c, __locale_t __l) __THROW;
 extern int tolower_l (int __c, __locale_t __l) __THROW;
 libc_hidden_proto(tolower_l)
 
 /* Return the uppercase version of C.  */
-extern int __toupper_l (int __c, __locale_t __l) __THROW;
+//extern int __toupper_l (int __c, __locale_t __l) __THROW;
 extern int toupper_l (int __c, __locale_t __l) __THROW;
 libc_hidden_proto(toupper_l)
 
 # if __GNUC__ >= 2 && defined __OPTIMIZE__ && !defined __cplusplus
-#  define __tolower_l(c, locale) \
-  __tobody (c, __tolower_l, (locale)->__ctype_tolower, (c, locale))
-#  define __toupper_l(c, locale) \
-  __tobody (c, __toupper_l, (locale)->__ctype_toupper, (c, locale))
-#  define tolower_l(c, locale)	__tolower_l ((c), (locale))
-#  define toupper_l(c, locale)	__toupper_l ((c), (locale))
+#  define tolower_l(c, locale) __tobody(c, tolower_l, (locale)->__ctype_tolower, (c, locale))
+#  define toupper_l(c, locale) __tobody(c, toupper_l, (locale)->__ctype_toupper, (c, locale))
+//#  define __tolower_l(c, locale) tolower_l((c), (locale))
+//#  define __toupper_l(c, locale) toupper_l((c), (locale))
 # endif	/* Optimizing gcc */
 
 
+# define __isctype_l(c, type, locale) ((locale)->__ctype_b[(int) (c)] & (__ctype_mask_t) type)
 # ifndef __NO_CTYPE
 #  define __isalnum_l(c,l)	__isctype_l((c), _ISalnum, (l))
 #  define __isalpha_l(c,l)	__isctype_l((c), _ISalpha, (l))
@@ -378,7 +358,6 @@ libc_hidden_proto(toupper_l)
 #  define __isspace_l(c,l)	__isctype_l((c), _ISspace, (l))
 #  define __isupper_l(c,l)	__isctype_l((c), _ISupper, (l))
 #  define __isxdigit_l(c,l)	__isctype_l((c), _ISxdigit, (l))
-
 #  define __isblank_l(c,l)	__isctype_l((c), _ISblank, (l))
 
 #  if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
@@ -397,7 +376,6 @@ libc_hidden_proto(toupper_l)
 #  define isspace_l(c,l)	__isspace_l ((c), (l))
 #  define isupper_l(c,l)	__isupper_l ((c), (l))
 #  define isxdigit_l(c,l)	__isxdigit_l ((c), (l))
-
 #  define isblank_l(c,l)	__isblank_l ((c), (l))
 
 #  if defined __USE_SVID || defined __USE_MISC || defined __USE_XOPEN
@@ -411,10 +389,6 @@ libc_hidden_proto(toupper_l)
 
 __END_DECLS
 
-#else  /* __UCLIBC_HAS_CTYPE_TABLES__ */
-
-#include <bits/uClibc_ctype.h>
-
-#endif
+#endif /* __UCLIBC_HAS_CTYPE_TABLES__ */
 
 #endif /* ctype.h  */

+ 1 - 1
include/xlocale.h

@@ -25,7 +25,7 @@
 
 #ifndef __UCLIBC_HAS_XLOCALE__
 #error Attempted to include xlocale.h when uClibc built without extended locale support.
-#endif /* __UCLIBC_HAS_XLOCALE__ */
+#endif
 
 #include <bits/uClibc_locale.h>
 /* #include <bits/uClibc_touplow.h> */

+ 4 - 2
libc/misc/ctype/ctype.c

@@ -319,7 +319,8 @@ int tolower_l(int c, __locale_t l)
 	return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_tolower[c] : c;
 }
 libc_hidden_def(tolower_l)
-weak_alias (tolower_l, __tolower_l)
+//remove after 0.9.31. See ctype.h for why.
+//weak_alias (tolower_l, __tolower_l)
 
 #endif
 /**********************************************************************/
@@ -366,7 +367,8 @@ int toupper_l(int c, __locale_t l)
 	return __UCLIBC_CTYPE_IN_TO_DOMAIN(c) ? l->__ctype_toupper[c] : c;
 }
 libc_hidden_def(toupper_l)
-weak_alias (toupper_l, __toupper_l)
+//remove after 0.9.31. See ctype.h for why.
+//weak_alias (toupper_l, __toupper_l)
 
 #endif
 /**********************************************************************/

+ 1 - 1
libc/misc/regex/regcomp.c

@@ -281,7 +281,7 @@ re_set_fastmap (char *fastmap, int icase, int ch)
 {
   fastmap[ch] = 1;
   if (icase)
-    fastmap[__tolower (ch)] = 1;
+    fastmap[tolower (ch)] = 1;
 }
 
 /* Helper function for re_compile_fastmap.

+ 0 - 4
libc/misc/regex/regex.c

@@ -38,10 +38,6 @@
 #  define __wctype wctype
 # endif
 # include <ctype.h>
-# ifdef __UCLIBC_HAS_CTYPE_TABLES__
-#  define __toupper toupper
-#  define __tolower tolower
-# endif
 #endif
 
 /* Make sure noone compiles this code with a C++ compiler.  */

+ 2 - 2
libc/misc/regex/regex_internal.c

@@ -289,7 +289,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
 	    {
 	      /* In case of a singlebyte character.  */
 	      pstr->mbs[byte_idx]
-		= __toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
+		= toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
 	      /* The next step uses the assumption that wchar_t is encoded
 		 ASCII-safe: all ASCII values can be converted like this.  */
 	      pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
@@ -523,7 +523,7 @@ build_upper_buffer (re_string_t *pstr)
       if (BE (pstr->trans != NULL, 0))
 	ch = pstr->trans[ch];
       if (islower (ch))
-	pstr->mbs[char_idx] = __toupper (ch);
+	pstr->mbs[char_idx] = toupper (ch);
       else
 	pstr->mbs[char_idx] = ch;
     }

+ 1 - 1
libc/misc/regex/regex_old.c

@@ -226,7 +226,7 @@ char *realloc ();
 # ifdef _tolower
 #  define TOLOWER(c) _tolower(c)
 # else
-#  define TOLOWER(c) __tolower(c)
+#  define TOLOWER(c) tolower(c)
 # endif
 
 # ifndef NULL

+ 11 - 14
libc/misc/wctype/_wctype.c

@@ -701,23 +701,20 @@ libc_hidden_def(iswctype)
 
 /* Minimal support for C/POSIX locale. */
 
-#ifndef _tolower
-#warning _tolower is undefined!
-#define _tolower(c)    tolower(c)
-#endif
-#ifndef _toupper
-#warning _toupper is undefined!
-#define _toupper(c)    toupper(c)
-#endif
-
 wint_t towctrans(wint_t wc, wctrans_t desc)
 {
-	if (((unsigned int)(desc - _CTYPE_tolower))
-		<= (_CTYPE_toupper - _CTYPE_tolower)
-		) {
+	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);
+// I think it's wrong: _toupper(c) assumes that c is a *lowercase* *letter* -
+// it is defined as ((c) ^ 0x20)!
+//		if ((__uwchar_t) wc <= 0x7f) {
+//			return (desc == _CTYPE_tolower) ? _tolower(wc) : _toupper(wc);
+//		}
+		__uwchar_t c = wc | 0x20; /* lowercase if it's a letter */
+		if (c >= 'a' && c <= 'z') {
+			if (desc == _CTYPE_toupper)
+				c &= ~0x20; /* uppercase */
+			return c;
 		}
 	} else {
 		__set_errno(EINVAL);	/* Invalid transliteration. */

+ 11 - 17
libc/stdlib/_strtod.c

@@ -36,7 +36,7 @@
  */
 
 /**********************************************************************/
-/*							OPTIONS									  */
+/*                      OPTIONS                                       */
 /**********************************************************************/
 
 /* Defined if we want to recognize "nan", "inf", and "infinity". (C99) */
@@ -79,7 +79,7 @@
 #define _STRTOD_ZERO_CHECK	   1
 
 /**********************************************************************/
-/* Don't change anything that follows.									   */
+/* Don't change anything that follows.                                */
 /**********************************************************************/
 
 #ifdef _STRTOD_ERRNO
@@ -107,23 +107,22 @@
 #include <locale.h>
 
 #ifdef __UCLIBC_HAS_WCHAR__
-
-#include <wchar.h>
-#include <wctype.h>
-#include <bits/uClibc_uwchar.h>
+# include <wchar.h>
+# include <wctype.h>
+# include <bits/uClibc_uwchar.h>
 /* libc_hidden_proto(iswspace) */
 #endif
 
 #ifdef __UCLIBC_HAS_XLOCALE__
-#include <xlocale.h>
+# include <xlocale.h>
 /* libc_hidden_proto(iswspace_l) */
-#endif /* __UCLIBC_HAS_XLOCALE__ */
+#endif
 
 /* Handle _STRTOD_HEXADECIMAL_FLOATS via uClibc config now. */
 #undef _STRTOD_HEXADECIMAL_FLOATS
 #ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
-#define _STRTOD_HEXADECIMAL_FLOATS 1
-#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
+# define _STRTOD_HEXADECIMAL_FLOATS 1
+#endif
 
 /**********************************************************************/
 
@@ -348,16 +347,11 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp
 			static const char nan_inf_str[] = "\05nan\0\012infinity\0\05inf\0";
 			int i = 0;
 
-#ifdef __UCLIBC_HAS_LOCALE__
-			/* Avoid tolower problems for INFINITY in the tr_TR locale. (yuk)*/
-#undef _tolower
-#define _tolower(C)     ((C)|0x20)
-#endif /* __UCLIBC_HAS_LOCALE__ */
-
 			do {
 				/* Unfortunately, we have no memcasecmp(). */
 				int j = 0;
-				while (_tolower(pos[j]) == nan_inf_str[i+1+j]) {
+				/* | 0x20 is a cheap lowercasing (valid for ASCII letters and numbers only) */
+				while (pos[j] | 0x20 == nan_inf_str[i+1+j]) {
 					++j;
 					if (!nan_inf_str[i+1+j]) {
 						number = i / 0.;

+ 69 - 75
libc/sysdeps/linux/common/bits/uClibc_ctype.h

@@ -39,7 +39,7 @@
 
 #include "uClibc_charclass.h"
 
-#else /* !__UCLIBC_GEN_LOCALE */
+#else
 
 /* Define some ctype macros valid for the C/POSIX locale. */
 
@@ -86,7 +86,7 @@
 		 : (((unsigned int)((c) - 0x21)) <= (0x7e - 0x21))))
 #define __C_isgraph(c) \
 	((sizeof(c) == sizeof(char)) \
-	 ? (((unsigned int)((c) - 0x21)) <= (0x7e - 0x21)) \
+	 ? (((unsigned char)((c) - 0x21)) <= (0x7e - 0x21)) \
 	 : (((unsigned int)((c) - 0x21)) <= (0x7e - 0x21)))
 
 #define __C_tolower(c) (__C_isupper(c) ? ((c) | 0x20) : (c))
@@ -119,27 +119,18 @@ extern int toascii(int c) __THROW;
 #endif
 
 #if defined _LIBC && (defined NOT_IN_libc || defined IS_IN_libc)
-/* isdigit() is really locale-invariant, so provide some small fast macros.
- * These are uClibc-specific. */
-#define __isdigit_char(C)    (((unsigned char)((C) - '0')) <= 9)
-#define __isdigit_int(C)     (((unsigned int)((C) - '0')) <= 9)
+/* These are uClibc-specific. */
+# define __isdigit_char(c) ((unsigned char)((c) - '0') <= 9)
+# define __isdigit_int(c)  ((unsigned int)((c) - '0') <= 9)
 #endif
 
-/* Next, some ctype macros which are valid for all supported locales. */
-/* WARNING: isspace and isblank need to be reverified if more 8-bit codesets
- * are added!!!  But isdigit and isxdigit are always valid. */
-
-/* #define __isspace(c)	__C_isspace(c) */
-/* #define __isblank(c)	__C_isblank(c) */
-
-/* #define __isdigit(c)	__C_isdigit(c) */
-/* #define __isxdigit(c)	__C_isxdigit(c) */
-
 /* Now some non-ansi/iso c99 macros. */
 
 #define __isascii(c) (((c) & ~0x7f) == 0)
 #define __toascii(c) ((c) & 0x7f)
+/* Works correctly *only* on lowercase letters! */
 #define _toupper(c) ((c) ^ 0x20)
+/* Works correctly *only* on letters (of any case) and numbers */
 #define _tolower(c) ((c) | 0x20)
 
 __END_DECLS
@@ -147,70 +138,73 @@ __END_DECLS
 /**********************************************************************/
 #ifdef __GNUC__
 
-#define __body_C_macro(f,args)  __C_ ## f args
-
-#define __body(f,c) \
-	(__extension__ ({ \
-		int __res; \
-		if (sizeof(c) > sizeof(char)) { \
-			int __c = (c); \
-			__res = __body_C_macro(f,(__c)); \
-		} else { \
-			unsigned char __c = (c); \
-			__res = __body_C_macro(f,(__c)); \
-		} \
-		__res; \
-	}))
-
-#define __isspace(c)		__body(isspace,c)
-#define __isblank(c)		__body(isblank,c)
-#define __isdigit(c)		__body(isdigit,c)
-#define __isxdigit(c)		__body(isxdigit,c)
-#define __iscntrl(c)		__body(iscntrl,c)
-#define __isalpha(c)		__body(isalpha,c)
-#define __isalnum(c)		__body(isalnum,c)
-#define __isprint(c)		__body(isprint,c)
-#define __islower(c)		__body(islower,c)
-#define __isupper(c)		__body(isupper,c)
-#define __ispunct(c)		__body(ispunct,c)
-#define __isgraph(c)		__body(isgraph,c)
-
-#define __tolower(c)		__body(tolower,c)
-#define __toupper(c)		__body(toupper,c)
-
-#if !defined __NO_CTYPE && !defined __cplusplus
-
-#define isspace(c)			__isspace(c)
-#define isblank(c)			__isblank(c)
-#define isdigit(c)			__isdigit(c)
-#define isxdigit(c)			__isxdigit(c)
-#define iscntrl(c)			__iscntrl(c)
-#define isalpha(c)			__isalpha(c)
-#define isalnum(c)			__isalnum(c)
-#define isprint(c)			__isprint(c)
-#define islower(c)			__islower(c)
-#define isupper(c)			__isupper(c)
-#define ispunct(c)			__ispunct(c)
-#define isgraph(c)			__isgraph(c)
-
-#define tolower(c)			__tolower(c)
-#define toupper(c)			__toupper(c)
-
-#endif
+# define __body_C_macro(f,args)  __C_ ## f args
+
+# define __body(f,c) \
+(__extension__ ({ \
+	int __res; \
+	if (sizeof(c) > sizeof(char)) { \
+		int __c = (c); \
+		__res = __body_C_macro(f,(__c)); \
+	} else { \
+		unsigned char __c = (c); \
+		__res = __body_C_macro(f,(__c)); \
+	} \
+	__res; \
+}))
+
+# define __isspace(c)   __body(isspace,c)
+# define __isblank(c)   __body(isblank,c)
+# define __isdigit(c)   __body(isdigit,c)
+# define __isxdigit(c)  __body(isxdigit,c)
+# define __iscntrl(c)   __body(iscntrl,c)
+# define __isalpha(c)   __body(isalpha,c)
+# define __isalnum(c)   __body(isalnum,c)
+# define __isprint(c)   __body(isprint,c)
+# define __islower(c)   __body(islower,c)
+# define __isupper(c)   __body(isupper,c)
+# define __ispunct(c)   __body(ispunct,c)
+# define __isgraph(c)   __body(isgraph,c)
+
+//locale-aware ctype.h has no __tolower, why stub locale
+//tries to have it? remove after 0.9.31
+//# define __tolower(c) __body(tolower,c)
+//# define __toupper(c) __body(toupper,c)
+
+# if !defined __NO_CTYPE && !defined __cplusplus
+
+#  define isspace(c)    __isspace(c)
+#  define isblank(c)    __isblank(c)
+#  define isdigit(c)    __isdigit(c)
+#  define isxdigit(c)   __isxdigit(c)
+#  define iscntrl(c)    __iscntrl(c)
+#  define isalpha(c)    __isalpha(c)
+#  define isalnum(c)    __isalnum(c)
+#  define isprint(c)    __isprint(c)
+#  define islower(c)    __islower(c)
+#  define isupper(c)    __isupper(c)
+#  define ispunct(c)    __ispunct(c)
+#  define isgraph(c)    __isgraph(c)
+
+#  define tolower(c)    __body(tolower,c)
+#  define toupper(c)    __body(toupper,c)
+
+# endif
 
 #else  /* !_GNUC__ */
 
-#if !defined __NO_CTYPE && !defined __cplusplus
+# if !defined __NO_CTYPE && !defined __cplusplus
 
-/* These macros should be safe from side effects. */
-#define isdigit(c)			__C_isdigit(c)
-#define isalpha(c)			__C_isalpha(c)
-#define isprint(c)			__C_isprint(c)
-#define islower(c)			__C_islower(c)
-#define isupper(c)			__C_isupper(c)
-#define isgraph(c)			__C_isgraph(c)
+/* These macros should be safe from side effects!
+ * (not all __C_xxx macros are) */
+#  define isdigit(c)    __C_isdigit(c)
+#  define isalpha(c)    __C_isalpha(c)
+#  define isprint(c)    __C_isprint(c)
+#  define islower(c)    __C_islower(c)
+#  define isupper(c)    __C_isupper(c)
+#  define isgraph(c)    __C_isgraph(c)
 
-#endif
+# endif
 
 #endif /* __GNUC__ */
 /**********************************************************************/

+ 19 - 19
libc/sysdeps/linux/common/bits/uClibc_locale.h

@@ -334,42 +334,42 @@ extern int __locale_mbrtowc_l(wchar_t *__restrict dst,
 
 extern __locale_t __curlocale_var;
 
-#ifdef __UCLIBC_HAS_THREADS__
+# ifdef __UCLIBC_HAS_THREADS__
 
 extern __locale_t __curlocale(void)  __THROW __attribute__ ((__const__));
 extern __locale_t __curlocale_set(__locale_t newloc);
-#define __UCLIBC_CURLOCALE           (__curlocale())
-#define __UCLIBC_CURLOCALE_DATA      (*__curlocale())
+#  define __UCLIBC_CURLOCALE           (__curlocale())
+#  define __UCLIBC_CURLOCALE_DATA      (*__curlocale())
 
-#else  /* __UCLIBC_HAS_THREADS__ */
+# else
 
-#define __UCLIBC_CURLOCALE           (__curlocale_var)
-#define __UCLIBC_CURLOCALE_DATA      (*__curlocale_var)
+#  define __UCLIBC_CURLOCALE           (__curlocale_var)
+#  define __UCLIBC_CURLOCALE_DATA      (*__curlocale_var)
 
-#endif /* __UCLIBC_HAS_THREADS__ */
+# endif
 
 #elif defined(__UCLIBC_HAS_LOCALE__)
 
-#define __UCLIBC_CURLOCALE           (__global_locale)
-#define __UCLIBC_CURLOCALE_DATA      (*__global_locale)
+# define __UCLIBC_CURLOCALE           (__global_locale)
+# define __UCLIBC_CURLOCALE_DATA      (*__global_locale)
 
 #endif
 /**********************************************************************/
 #if defined(__UCLIBC_HAS_XLOCALE__) && defined(__UCLIBC_DO_XLOCALE)
 
-#define __XL_NPP(N) N ## _l
-#define __LOCALE_PARAM    , __locale_t locale_arg
-#define __LOCALE_ARG      , locale_arg
-#define __LOCALE_PTR      locale_arg
+# define __XL_NPP(N) N ## _l
+# define __LOCALE_PARAM    , __locale_t locale_arg
+# define __LOCALE_ARG      , locale_arg
+# define __LOCALE_PTR      locale_arg
 
-#else  /* defined(__UCLIBC_HAS_XLOCALE__) && defined(__UCLIBC_DO_XLOCALE) */
+#else
 
-#define __XL_NPP(N) N
-#define __LOCALE_PARAM
-#define __LOCALE_ARG
-#define __LOCALE_PTR      __UCLIBC_CURLOCALE
+# define __XL_NPP(N) N
+# define __LOCALE_PARAM
+# define __LOCALE_ARG
+# define __LOCALE_PTR      __UCLIBC_CURLOCALE
 
-#endif /* defined(__UCLIBC_HAS_XLOCALE__) && defined(__UCLIBC_DO_XLOCALE) */
+#endif
 /**********************************************************************/
 
 #endif /* !defined(__LOCALE_C_ONLY) */

+ 2 - 2
libc/sysdeps/linux/common/bits/uClibc_touplow.h

@@ -43,13 +43,13 @@ typedef __int16_t __ctype_touplow_t;
 #define __UCLIBC_CTYPE_B_TBL_OFFSET       128
 #define __UCLIBC_CTYPE_TO_TBL_OFFSET      128
 
-#else  /* __UCLIBC_HAS_CTYPE_SIGNED__ */
+#else
 
 typedef unsigned char __ctype_touplow_t;
 #define __UCLIBC_CTYPE_B_TBL_OFFSET       1
 #define __UCLIBC_CTYPE_TO_TBL_OFFSET      0
 
-#endif /* __UCLIBC_HAS_CTYPE_SIGNED__ */
+#endif
 
 #endif /* _UCLIBC_TOUPLOW_H */