changeset 1540:1f2c3a031698

* cdl/i18n.cdl: Add newlib style ctype implementation. CYGSEM_LIBC_I18N_PER_THREAD_MB can be inactive when no kernel. * include/newlibctype.h: New file. * src/newlibctype.cxx: New file. * src/ctype.cxx: Don't define functions if newlib style ctype chosen instead. * src/wctomb.cxx (wctomb): Use correct thread data type. * src/mbtowc.cxx (mbtowc): Ditto. * src/mblen.cxx (mblen): Ditto.
author jlarmour
date Mon, 15 Mar 2004 15:21:14 +0000
parents 57cebf53b527
children 871b38a618f4
files packages/language/c/libc/i18n/current/ChangeLog packages/language/c/libc/i18n/current/cdl/i18n.cdl packages/language/c/libc/i18n/current/include/newlibctype.h packages/language/c/libc/i18n/current/src/ctype.cxx packages/language/c/libc/i18n/current/src/mblen.cxx packages/language/c/libc/i18n/current/src/mbtowc.cxx packages/language/c/libc/i18n/current/src/newlibctype.cxx packages/language/c/libc/i18n/current/src/wctomb.cxx
diffstat 8 files changed, 402 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/packages/language/c/libc/i18n/current/ChangeLog
+++ b/packages/language/c/libc/i18n/current/ChangeLog
@@ -1,3 +1,16 @@
+2004-02-17  Jonathan Larmour  <jifl@eCosCentric.com>
+
+	* cdl/i18n.cdl: Add newlib style ctype implementation.
+	CYGSEM_LIBC_I18N_PER_THREAD_MB can be inactive when no kernel.
+	* include/newlibctype.h: New file.
+	* src/newlibctype.cxx: New file.
+	* src/ctype.cxx: Don't define functions if newlib style ctype
+	chosen instead.
+
+	* src/wctomb.cxx (wctomb): Use correct thread data type.
+	* src/mbtowc.cxx (mbtowc): Ditto.
+	* src/mblen.cxx (mblen): Ditto.
+
 2003-02-24  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* cdl/i18n.cdl: Fix doc link.
--- a/packages/language/c/libc/i18n/current/cdl/i18n.cdl
+++ b/packages/language/c/libc/i18n/current/cdl/i18n.cdl
@@ -116,10 +116,26 @@ cdl_package CYGPKG_LIBC_I18N {
 
 # ====================================================================
 
+    cdl_option CYGPKG_LIBC_I18N_NEWLIB_CTYPE {
+        display       "Newlib's ctype implementation"
+        default_value 0
+        requires      { CYGBLD_ISO_CTYPE_HEADER == \
+                        "<cyg/libc/i18n/newlibctype.h>" }
+        description   "
+            This option enables the implementation of the ctype functions
+            that comes with newlib. It is table driven and therefore
+            exhibits different performance characteristics. It also offers
+            a limited amount of binary compatibility
+            with newlib so that programs linked against newlib ctype/locale
+            do not need to be recompiled when linked with eCos."
+        compile       newlibctype.cxx
+    }
+    
     cdl_option CYGSEM_LIBC_I18N_PER_THREAD_MB	 {
         display       "Per-thread multibyte state"
+        active_if     CYGPKG_KERNEL
         requires      CYGVAR_KERNEL_THREADS_DATA
-        default_value 0
+        default_value { CYGVAR_KERNEL_THREADS_DATA != 0 }
         description   "
             This option controls whether the multibyte character
             handling functions mblen(), mbtowc(), and wctomb(),
new file mode 100644
--- /dev/null
+++ b/packages/language/c/libc/i18n/current/include/newlibctype.h
@@ -0,0 +1,125 @@
+#ifndef CYGONCE_LIBC_I18N_NEWLIBCTYPE_H
+#define CYGONCE_LIBC_I18N_NEWLIBCTYPE_H
+/*===========================================================================
+//
+//      newlibctype.h
+//
+//      newlib's implementation of the ctype functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    jlarmour
+// Contributors: 
+// Date:         2004-02-16
+// Purpose:     
+// Description: 
+// Usage:        Do not include this file directly - use #include <ctype.h>
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/libc_i18n.h>   /* Configuration header */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int isalnum(int __c);
+extern int isalpha(int __c);
+extern int iscntrl(int __c);
+extern int isdigit(int __c);
+extern int isgraph(int __c);
+extern int islower(int __c);
+extern int isprint(int __c);
+extern int ispunct(int __c);
+extern int isspace(int __c);
+extern int isupper(int __c);
+extern int isxdigit(int __c);
+extern int tolower(int __c);
+extern int toupper(int __c);
+
+#ifndef __STRICT_ANSI__
+int isascii(int __c);
+int toascii(int __c);
+int _tolower(int __c);
+int _toupper(int __c);
+#endif
+
+#define _U      01
+#define _L      02
+#define _N      04
+#define _S      010
+#define _P      020
+#define _C      040
+#define _X      0100
+#define _B      0200
+
+extern  const char    _ctype_[];
+
+#ifndef __cplusplus
+#define isalpha(c)      ((_ctype_+1)[(unsigned)(c)]&(_U|_L))
+#define isupper(c)      ((_ctype_+1)[(unsigned)(c)]&_U)
+#define islower(c)      ((_ctype_+1)[(unsigned)(c)]&_L)
+#define isdigit(c)      ((_ctype_+1)[(unsigned)(c)]&_N)
+#define isxdigit(c)     ((_ctype_+1)[(unsigned)(c)]&(_X|_N))
+#define isspace(c)      ((_ctype_+1)[(unsigned)(c)]&_S)
+#define ispunct(c)      ((_ctype_+1)[(unsigned)(c)]&_P)
+#define isalnum(c)      ((_ctype_+1)[(unsigned)(c)]&(_U|_L|_N))
+#define isprint(c)      ((_ctype_+1)[(unsigned)(c)]&(_P|_U|_L|_N|_B))
+#define isgraph(c)      ((_ctype_+1)[(unsigned)(c)]&(_P|_U|_L|_N))
+#define iscntrl(c)      ((_ctype_+1)[(unsigned)(c)]&_C)
+/* Non-gcc versions will get the library versions, and will be
+   slightly slower */
+#ifdef __GNUC__
+# define toupper(c) \
+        __extension__ ({ int __x = (c); islower(__x) ? (__x - 'a' + 'A') : __x;})
+# define tolower(c) \
+        __extension__ ({ int __x = (c); isupper(__x) ? (__x - 'A' + 'a') : __x;})
+#endif
+#endif /* !__cplusplus */
+
+#ifndef __STRICT_ANSI__
+#define isascii(c)      ((unsigned)(c)<=0177)
+#define toascii(c)      ((c)&0177)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* CYGONCE_LIBC_I18N_NEWLIBCTYPE_H multiple inclusion protection */
+
+/* EOF newlibctype.h */
--- a/packages/language/c/libc/i18n/current/src/ctype.cxx
+++ b/packages/language/c/libc/i18n/current/src/ctype.cxx
@@ -53,12 +53,18 @@
 //
 //=========================================================================*/
 
+/* CONFIGURATION */
+
+#include <pkgconf/libc_i18n.h>   /* Configuration header */
+
 /* We don't want the inline versions of the ctype functions defined here */
 
 #define CYGPRI_LIBC_I18N_CTYPE_INLINE
 
 /* This means that including ctype.inl will make the outline functions */
 
-#include <cyg/libc/i18n/ctype.inl>
+#ifndef CYGPKG_LIBC_I18N_NEWLIB_CTYPE
+# include <cyg/libc/i18n/ctype.inl>
+#endif
 
 /* EOF ctype.cxx */
--- a/packages/language/c/libc/i18n/current/src/mblen.cxx
+++ b/packages/language/c/libc/i18n/current/src/mblen.cxx
@@ -132,7 +132,9 @@ static int mblen_trace = CYGNUM_LIBC_I18
 
 #ifdef CYGINT_LIBC_I18N_MB_REQUIRED
 # ifdef CYGSEM_LIBC_I18N_PER_THREAD_MB
-static volatile cyg_ucount32 mblen_data_index=CYGNUM_KERNEL_THREADS_DATA_MAX;
+static volatile Cyg_Thread::cyg_data_index 
+mblen_data_index=CYGNUM_KERNEL_THREADS_DATA_MAX;
+
 static Cyg_Mutex mblen_data_mutex CYG_INIT_PRIORITY(LIBC);
 # else
 static int cyg_libc_mblen_last;
@@ -167,11 +169,11 @@ mblen ( const char *s, size_t n )
     mblen_data_mutex.lock();
     if (CYGNUM_KERNEL_THREADS_DATA_MAX==mblen_data_index) {
       
-      // the kernel just throws an assert if this doesn't work
       // FIXME: Should use real CDL to pre-allocate a slot at compile
       // time to ensure there are enough slots
       mblen_data_index = self->new_data_index();
       
+      CYG_ASSERT(mblen_data_index >= 0, "failed to allocate data index" );
     }
     mblen_data_mutex.unlock();
   } // if
--- a/packages/language/c/libc/i18n/current/src/mbtowc.cxx
+++ b/packages/language/c/libc/i18n/current/src/mbtowc.cxx
@@ -141,7 +141,9 @@ static int mbtowc_trace = CYGNUM_LIBC_I1
 
 #ifdef CYGINT_LIBC_I18N_MB_REQUIRED
 # ifdef CYGSEM_LIBC_I18N_PER_THREAD_MB
-static volatile cyg_ucount32 mbtowc_data_index=CYGNUM_KERNEL_THREADS_DATA_MAX;
+static volatile Cyg_Thread::cyg_data_index
+mbtowc_data_index=CYGNUM_KERNEL_THREADS_DATA_MAX;
+
 static Cyg_Mutex mbtowc_data_mutex CYG_INIT_PRIORITY(LIBC);
 # else
 static int cyg_libc_mbtowc_last;
@@ -178,11 +180,11 @@ mbtowc ( wchar_t *pwc, const char *s, si
     mbtowc_data_mutex.lock();
     if (CYGNUM_KERNEL_THREADS_DATA_MAX==mbtowc_data_index) {
       
-      // the kernel just throws an assert if this doesn't work
       // FIXME: Should use real CDL to pre-allocate a slot at compile
       // time to ensure there are enough slots
       mbtowc_data_index = self->new_data_index();
       
+      CYG_ASSERT(mbtowc_data_index >= 0, "failed to allocate data index" );
     }
     mbtowc_data_mutex.unlock();
   } // if
new file mode 100644
--- /dev/null
+++ b/packages/language/c/libc/i18n/current/src/newlibctype.cxx
@@ -0,0 +1,229 @@
+/*===========================================================================
+//
+//      newlibctype.cxx
+//
+//      newlib's implementation of the ctype functions
+//
+//===========================================================================
+//####ECOSGPLCOPYRIGHTBEGIN####
+// -------------------------------------------
+// This file is part of eCos, the Embedded Configurable Operating System.
+// Copyright (C) 2004 eCosCentric Ltd.
+//
+// eCos is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 or (at your option) any later version.
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with eCos; if not, write to the Free Software Foundation, Inc.,
+// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+//
+// As a special exception, if other files instantiate templates or use macros
+// or inline functions from this file, or you compile this file and link it
+// with other works to produce a work based on this file, this file does not
+// by itself cause the resulting work to be covered by the GNU General Public
+// License. However the source code for this file must still be made available
+// in accordance with section (3) of the GNU General Public License.
+//
+// This exception does not invalidate any other reasons why a work based on
+// this file might be covered by the GNU General Public License.
+// -------------------------------------------
+//####ECOSGPLCOPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    jlarmour
+// Contributors: 
+// Date:         2004-02-16
+// Purpose:      Provides newlib's implementation of the ctype functions.
+// Description:  Also provides a degree of binary compatibility with newlib
+//               ctype functions, primarily for the benefit of libstdc++.
+// Usage:       
+//
+//####DESCRIPTIONEND####
+//
+//=========================================================================*/
+
+/* CONFIGURATION */
+
+#include <pkgconf/libc_i18n.h>   // Configuration header
+
+#ifdef CYGPKG_LIBC_I18N_NEWLIB_CTYPE
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/libc/i18n/newlibctype.h>
+
+#define _CONST  const    // just for compatibility
+
+#define _CTYPE_DATA_0_127 \
+        _C,     _C,     _C,     _C,     _C,     _C,     _C,     _C, \
+        _C,     _C|_S,  _C|_S,  _C|_S,  _C|_S,  _C|_S,  _C,     _C, \
+        _C,     _C,     _C,     _C,     _C,     _C,     _C,     _C, \
+        _C,     _C,     _C,     _C,     _C,     _C,     _C,     _C, \
+        _S|_B,  _P,     _P,     _P,     _P,     _P,     _P,     _P, \
+        _P,     _P,     _P,     _P,     _P,     _P,     _P,     _P, \
+        _N,     _N,     _N,     _N,     _N,     _N,     _N,     _N, \
+        _N,     _N,     _P,     _P,     _P,     _P,     _P,     _P, \
+        _P,     _U|_X,  _U|_X,  _U|_X,  _U|_X,  _U|_X,  _U|_X,  _U, \
+        _U,     _U,     _U,     _U,     _U,     _U,     _U,     _U, \
+        _U,     _U,     _U,     _U,     _U,     _U,     _U,     _U, \
+        _U,     _U,     _U,     _P,     _P,     _P,     _P,     _P, \
+        _P,     _L|_X,  _L|_X,  _L|_X,  _L|_X,  _L|_X,  _L|_X,  _L, \
+        _L,     _L,     _L,     _L,     _L,     _L,     _L,     _L, \
+        _L,     _L,     _L,     _L,     _L,     _L,     _L,     _L, \
+        _L,     _L,     _L,     _P,     _P,     _P,     _P,     _C
+
+#define _CTYPE_DATA_128_256 \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0, \
+        0,      0,      0,      0,      0,      0,      0,      0
+
+_CONST char _ctype_[1 + 256] = {
+        0,
+        _CTYPE_DATA_0_127,
+        _CTYPE_DATA_128_256
+};
+_CONST char *__ctype_ptr = _ctype_ + 1;
+
+#undef _tolower
+#undef tolower
+#undef _toupper
+#undef toupper
+
+int
+_tolower(int c)
+{
+    return isupper(c) ? (c) - 'A' + 'a' : c;
+}
+
+int
+tolower(int c)
+{
+    return isupper(c) ? (c) - 'A' + 'a' : c;
+}
+
+int
+_toupper(int c)
+{
+    return islower(c) ? c - 'a' + 'A' : c;
+}
+
+int
+toupper(int c)
+{
+    return islower(c) ? c - 'a' + 'A' : c;
+}
+
+#undef isalnum
+#undef isalpha
+#undef isascii
+#undef iscntrl
+#undef isdigit
+#undef islower
+#undef isgraph
+#undef isprint
+#undef ispunct
+#undef isspace
+#undef isupper
+#undef isxdigit
+#undef toascii
+
+int
+isalnum(int c)
+{
+    return((_ctype_ + 1)[c] & (_U|_L|_N));
+}
+
+int
+isalpha(int c)
+{
+    return((_ctype_ + 1)[c] & (_U|_L));
+}
+
+int 
+isascii(int c)
+{
+    return c >= 0 && c< 128;
+}
+
+int
+iscntrl(int c)
+{
+    return((_ctype_ + 1)[c] & _C);
+}
+
+int
+isdigit(int c)
+{
+    return((_ctype_ + 1)[c] & _N);
+}
+
+int
+islower(int c)
+{
+    return((_ctype_ + 1)[c] & _L);
+}
+
+int
+isgraph(int c)
+{
+    return((_ctype_ + 1)[c] & (_P|_U|_L|_N));
+}
+
+int
+isprint(int c)
+{
+    return((_ctype_ + 1)[c] & (_P|_U|_L|_N|_B));
+}
+
+int
+ispunct(int c)
+{
+    return((_ctype_ + 1)[c] & _P);
+}
+
+int
+isspace(int c)
+{
+    return((_ctype_ + 1)[c] & _S);
+}
+
+int
+isupper(int c)
+{
+    return((_ctype_ + 1)[c] & _U);
+}
+
+int
+isxdigit(int c)
+{
+    return((_ctype_ + 1)[c] & ((_X)|(_N)));
+}
+
+int
+toascii(int c)
+{
+    return (c)&0177;
+}
+
+#endif // ifdef CYGPKG_LIBC_I18N_NEWLIB_CTYPE
+
+/* EOF newlibctype.cxx */
--- a/packages/language/c/libc/i18n/current/src/wctomb.cxx
+++ b/packages/language/c/libc/i18n/current/src/wctomb.cxx
@@ -136,7 +136,8 @@ static int wctomb_trace = CYGNUM_LIBC_I1
 
 #ifdef CYGINT_LIBC_I18N_MB_REQUIRED
 # ifdef CYGSEM_LIBC_I18N_PER_THREAD_MB
-static volatile cyg_ucount32 wctomb_data_index=CYGNUM_KERNEL_THREADS_DATA_MAX;
+static volatile Cyg_Thread::cyg_data_index
+wctomb_data_index=CYGNUM_KERNEL_THREADS_DATA_MAX;
 static Cyg_Mutex wctomb_data_mutex CYG_INIT_PRIORITY(LIBC);
 # else
 static int cyg_libc_wctomb_last;
@@ -169,11 +170,11 @@ wctomb ( char *s, const wchar_t wchar )
     wctomb_data_mutex.lock();
     if (CYGNUM_KERNEL_THREADS_DATA_MAX==wctomb_data_index) {
       
-      // the kernel just throws an assert if this doesn't work
       // FIXME: Should use real CDL to pre-allocate a slot at compile
       // time to ensure there are enough slots
       wctomb_data_index = self->new_data_index();
       
+      CYG_ASSERT(wctomb_data_index >= 0, "failed to allocate data index" );
     }
     wctomb_data_mutex.unlock();
   } // if