[PATCH 4/6] generated character data for libc/ctype
Thomas Wolff
towo@towo.net
Wed Mar 7 23:21:00 GMT 2018
-------------- next part --------------
From 58a9cfcb253165d7073a9ed25e143daa2e979c10 Mon Sep 17 00:00:00 2001
From: Thomas Wolff <towo@towo.net>
Date: Sun, 25 Feb 2018 17:22:34 +0100
Subject: [PATCH 4/6] use generated character data
---
newlib/libc/ctype/categories.c | 39 +++
newlib/libc/ctype/categories.h | 7 +
newlib/libc/ctype/iswalnum.c | 2 +-
newlib/libc/ctype/iswalnum_l.c | 19 +-
newlib/libc/ctype/iswalpha.c | 73 ++++++
newlib/libc/ctype/iswalpha_l.c | 17 +-
newlib/libc/ctype/iswblank.c | 19 +-
newlib/libc/ctype/iswblank_l.c | 16 +-
newlib/libc/ctype/iswcntrl.c | 17 +-
newlib/libc/ctype/iswcntrl_l.c | 16 +-
newlib/libc/ctype/iswctype_l.c | 37 ++-
newlib/libc/ctype/iswdigit.c | 3 +-
newlib/libc/ctype/iswdigit_l.c | 2 +-
newlib/libc/ctype/iswgraph.c | 3 +-
newlib/libc/ctype/iswgraph_l.c | 19 +-
newlib/libc/ctype/iswlower.c | 4 +-
newlib/libc/ctype/iswlower_l.c | 16 +-
newlib/libc/ctype/iswprint.c | 72 ++++++
newlib/libc/ctype/iswprint_l.c | 17 +-
newlib/libc/ctype/iswpunct.c | 7 +-
newlib/libc/ctype/iswpunct_l.c | 22 +-
newlib/libc/ctype/iswspace.c | 20 +-
newlib/libc/ctype/iswspace_l.c | 17 +-
newlib/libc/ctype/iswupper.c | 6 +-
newlib/libc/ctype/iswupper_l.c | 16 +-
newlib/libc/ctype/iswxdigit.c | 6 +-
newlib/libc/ctype/jp2uc.c | 51 +++-
newlib/libc/ctype/local.h | 19 +-
newlib/libc/ctype/towctrans.c | 16 +-
newlib/libc/ctype/towctrans_l.c | 97 +++++++-
newlib/libc/ctype/towlower.c | 81 +++++++
newlib/libc/ctype/towlower_l.c | 7 +-
newlib/libc/ctype/towupper.c | 515 +---------------------------------------
newlib/libc/ctype/towupper_l.c | 8 +-
34 files changed, 650 insertions(+), 639 deletions(-)
create mode 100644 newlib/libc/ctype/categories.c
create mode 100644 newlib/libc/ctype/categories.h
create mode 100644 newlib/libc/ctype/iswalpha.c
create mode 100644 newlib/libc/ctype/iswprint.c
create mode 100644 newlib/libc/ctype/towlower.c
diff --git a/newlib/libc/ctype/categories.c b/newlib/libc/ctype/categories.c
new file mode 100644
index 0000000..db285d7
--- /dev/null
+++ b/newlib/libc/ctype/categories.c
@@ -0,0 +1,39 @@
+#include <wctype.h>
+#include "categories.h"
+
+struct _category {
+ enum category cat: 11;
+ unsigned int first: 21;
+ unsigned short delta;
+} __attribute__((packed));
+
+static const struct _category categories[] = {
+#include "categories.t"
+};
+
+static enum category
+bisearch_cat(wint_t ucs, const struct _category *table, int max)
+{
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].first + table[max].delta)
+ return 0;
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].first + table[mid].delta)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return table[mid].cat;
+ }
+ return -1;
+}
+
+enum category category(wint_t ucs)
+{
+ return bisearch_cat(ucs, categories,
+ sizeof(categories) / sizeof(*categories) - 1);
+}
diff --git a/newlib/libc/ctype/categories.h b/newlib/libc/ctype/categories.h
new file mode 100644
index 0000000..271038e
--- /dev/null
+++ b/newlib/libc/ctype/categories.h
@@ -0,0 +1,7 @@
+/* category data */
+
+enum category {
+#include "categories.cat"
+};
+
+extern enum category category(wint_t ucs);
diff --git a/newlib/libc/ctype/iswalnum.c b/newlib/libc/ctype/iswalnum.c
index 45273a8..7b2cac7 100644
--- a/newlib/libc/ctype/iswalnum.c
+++ b/newlib/libc/ctype/iswalnum.c
@@ -39,5 +39,5 @@ No supporting OS subroutines are required.
int
iswalnum (wint_t c)
{
- return (iswalpha (c) || iswdigit (c));
+ return iswalnum_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswalnum_l.c b/newlib/libc/ctype/iswalnum_l.c
index e4ab3dd..8802273 100644
--- a/newlib/libc/ctype/iswalnum_l.c
+++ b/newlib/libc/ctype/iswalnum_l.c
@@ -1,10 +1,23 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswalnum_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswalpha (c) || iswdigit (c);
+#ifdef _MB_CAPABLE
+ //return iswalpha (c) || iswdigit (c);
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ return cat == CAT_LC || cat == CAT_Lu || cat == CAT_Ll || cat == CAT_Lt
+ || cat == CAT_Lm || cat == CAT_Lo
+ || cat == CAT_Nl // Letter_Number
+ || cat == CAT_Nd // Decimal_Number
+ ;
+#else
+ return c < (wint_t)0x100 ? isalnum (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswalpha.c b/newlib/libc/ctype/iswalpha.c
new file mode 100644
index 0000000..3928772
--- /dev/null
+++ b/newlib/libc/ctype/iswalpha.c
@@ -0,0 +1,73 @@
+/* Copyright (c) 2002 Red Hat Incorporated.
+ All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ The name of Red Hat Incorporated may not be used to endorse
+ or promote products derived from this software without specific
+ prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+FUNCTION
+ <<iswalpha>>, <<iswalpha_l>>---alphabetic wide character test
+
+INDEX
+ iswalpha
+
+INDEX
+ iswalpha_l
+
+SYNOPSIS
+ #include <wctype.h>
+ int iswalpha(wint_t <[c]>);
+
+ #include <wctype.h>
+ int iswalpha_l(wint_t <[c]>, locale_t <[locale]>);
+
+DESCRIPTION
+<<iswalpha>> is a function which classifies wide-character values that
+are alphabetic.
+
+<<iswalpha_l>> is like <<iswalpha>> but performs the check based on the
+locale specified by the locale object locale. If <[locale]> is
+LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined.
+
+RETURNS
+<<iswalpha>>, <<iswalpha_l>> return non-zero if <[c]> is an alphabetic
+wide character.
+
+PORTABILITY
+<<iswalpha>> is C99.
+<<iswalpha_l>> is POSIX-1.2008.
+
+No supporting OS subroutines are required.
+*/
+#include <_ansi.h>
+#include <wctype.h>
+
+int
+iswalpha (wint_t c)
+{
+ return iswalpha_l (c, 0);
+}
diff --git a/newlib/libc/ctype/iswalpha_l.c b/newlib/libc/ctype/iswalpha_l.c
index efcb95a..922983e 100644
--- a/newlib/libc/ctype/iswalpha_l.c
+++ b/newlib/libc/ctype/iswalpha_l.c
@@ -1,10 +1,21 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswalpha_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswalpha (c);
+#ifdef _MB_CAPABLE
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ return cat == CAT_LC || cat == CAT_Lu || cat == CAT_Ll || cat == CAT_Lt
+ || cat == CAT_Lm || cat == CAT_Lo
+ || cat == CAT_Nl // Letter_Number
+ ;
+#else
+ return c < (wint_t)0x100 ? isalpha (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswblank.c b/newlib/libc/ctype/iswblank.c
index ef91572..31779d2 100644
--- a/newlib/libc/ctype/iswblank.c
+++ b/newlib/libc/ctype/iswblank.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -62,26 +63,10 @@ PORTABILITY
No supporting OS subroutines are required.
*/
#include <_ansi.h>
-#include <newlib.h>
#include <wctype.h>
-#include <ctype.h>
-#include <string.h>
-#include "local.h"
int
iswblank (wint_t c)
{
-#ifdef _MB_CAPABLE
- c = _jp2uc (c);
- /* Based on Unicode 5.2. Control char 09, plus all characters
- from general category "Zs", which are not marked as decomposition
- type "noBreak". */
- return (c == 0x0009 || c == 0x0020 ||
- c == 0x1680 || c == 0x180e ||
- (c >= 0x2000 && c <= 0x2006) ||
- (c >= 0x2008 && c <= 0x200a) ||
- c == 0x205f || c == 0x3000);
-#else
- return (c < 0x100 ? isblank (c) : 0);
-#endif /* _MB_CAPABLE */
+ return iswblank_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswblank_l.c b/newlib/libc/ctype/iswblank_l.c
index 6960693..b27ed82 100644
--- a/newlib/libc/ctype/iswblank_l.c
+++ b/newlib/libc/ctype/iswblank_l.c
@@ -1,10 +1,20 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswblank_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswblank (c);
+#ifdef _MB_CAPABLE
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ // exclude "<noBreak>"?
+ return cat == CAT_Zs
+ || c == '\t';
+#else
+ return c < 0x100 ? isblank (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswcntrl.c b/newlib/libc/ctype/iswcntrl.c
index 249a0a8..d4b0147 100644
--- a/newlib/libc/ctype/iswcntrl.c
+++ b/newlib/libc/ctype/iswcntrl.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -62,24 +63,10 @@ PORTABILITY
No supporting OS subroutines are required.
*/
#include <_ansi.h>
-#include <newlib.h>
#include <wctype.h>
-#include <ctype.h>
-#include <string.h>
-#include "local.h"
int
iswcntrl (wint_t c)
{
-#ifdef _MB_CAPABLE
- c = _jp2uc (c);
-
- /* Based on Unicode 5.2. All characters from general category "Cc", "Zl",
- and "Zp". */
- return ((c >= 0x0000 && c <= 0x001f) ||
- (c >= 0x007f && c <= 0x009f) ||
- c == 0x2028 || c == 0x2029);
-#else
- return (c < 0x100 ? iscntrl (c) : 0);
-#endif /* _MB_CAPABLE */
+ return iswcntrl_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswcntrl_l.c b/newlib/libc/ctype/iswcntrl_l.c
index 37caba8..6a900a7 100644
--- a/newlib/libc/ctype/iswcntrl_l.c
+++ b/newlib/libc/ctype/iswcntrl_l.c
@@ -1,10 +1,20 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswcntrl_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswcntrl (c);
+#ifdef _MB_CAPABLE
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ return cat == CAT_Cc
+ || cat == CAT_Zl || cat == CAT_Zp // Line/Paragraph Separator
+ ;
+#else
+ return c < 0x100 ? iscntrl (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswctype_l.c b/newlib/libc/ctype/iswctype_l.c
index d9e7b2e..506972d 100644
--- a/newlib/libc/ctype/iswctype_l.c
+++ b/newlib/libc/ctype/iswctype_l.c
@@ -1,10 +1,41 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
#include <wctype.h>
+#include "local.h"
int
iswctype_l (wint_t c, wctype_t desc, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswctype (c, desc);
+ switch (desc)
+ {
+ case WC_ALNUM:
+ return iswalnum_l (c, locale);
+ case WC_ALPHA:
+ return iswalpha_l (c, locale);
+ case WC_BLANK:
+ return iswblank_l (c, locale);
+ case WC_CNTRL:
+ return iswcntrl_l (c, locale);
+ case WC_DIGIT:
+ return iswdigit_l (c, locale);
+ case WC_GRAPH:
+ return iswgraph_l (c, locale);
+ case WC_LOWER:
+ return iswlower_l (c, locale);
+ case WC_PRINT:
+ return iswprint_l (c, locale);
+ case WC_PUNCT:
+ return iswpunct_l (c, locale);
+ case WC_SPACE:
+ return iswspace_l (c, locale);
+ case WC_UPPER:
+ return iswupper_l (c, locale);
+ case WC_XDIGIT:
+ return iswxdigit_l (c, locale);
+ default:
+ return 0; /* eliminate warning */
+ }
+
+ /* otherwise unknown */
+ return 0;
}
diff --git a/newlib/libc/ctype/iswdigit.c b/newlib/libc/ctype/iswdigit.c
index 2b26141..d3562f8 100644
--- a/newlib/libc/ctype/iswdigit.c
+++ b/newlib/libc/ctype/iswdigit.c
@@ -38,5 +38,6 @@ No supporting OS subroutines are required.
int
iswdigit (wint_t c)
{
- return (c >= (wint_t)'0' && c <= (wint_t)'9');
+ return c >= (wint_t)'0' && c <= (wint_t)'9';
+ // category (c) == CAT_Nd not to be included as of C-99
}
diff --git a/newlib/libc/ctype/iswdigit_l.c b/newlib/libc/ctype/iswdigit_l.c
index 98dd94e..29de9d3 100644
--- a/newlib/libc/ctype/iswdigit_l.c
+++ b/newlib/libc/ctype/iswdigit_l.c
@@ -4,5 +4,5 @@
int
iswdigit_l (wint_t c, struct __locale_t *locale)
{
- return (c >= (wint_t)'0' && c <= (wint_t)'9');
+ return c >= (wint_t)'0' && c <= (wint_t)'9';
}
diff --git a/newlib/libc/ctype/iswgraph.c b/newlib/libc/ctype/iswgraph.c
index e0df4aa..bb21c21 100644
--- a/newlib/libc/ctype/iswgraph.c
+++ b/newlib/libc/ctype/iswgraph.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -67,5 +68,5 @@ No supporting OS subroutines are required.
int
iswgraph (wint_t c)
{
- return (iswprint (c) && !iswspace (c));
+ return iswgraph_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswgraph_l.c b/newlib/libc/ctype/iswgraph_l.c
index 9803c18..b8a5866 100644
--- a/newlib/libc/ctype/iswgraph_l.c
+++ b/newlib/libc/ctype/iswgraph_l.c
@@ -1,10 +1,23 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswgraph_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswprint (c) && !iswspace (c);
+#ifdef _MB_CAPABLE
+ //return iswprint (c, locale) && !iswspace (c, locale);
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ return cat != -1
+ && cat != CAT_Cc && cat != CAT_Cf
+ && cat != CAT_Cs // Surrogate
+ && cat != CAT_Zs
+ && cat != CAT_Zl && cat != CAT_Zp // Line/Paragraph Separator
+ ;
+#else
+ return iswprint_l (c, locale) && !iswspace_l (c, locale);
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswlower.c b/newlib/libc/ctype/iswlower.c
index 8b38835..e1d926b 100644
--- a/newlib/libc/ctype/iswlower.c
+++ b/newlib/libc/ctype/iswlower.c
@@ -17,7 +17,7 @@ SYNOPSIS
DESCRIPTION
<<iswlower>> is a function which classifies wide-character values that
-have uppercase translations.
+are categorized as lowercase.
<<iswlower_l>> is like <<iswlower>> but performs the check based on the
locale specified by the locale object locale. If <[locale]> is
@@ -38,5 +38,5 @@ No supporting OS subroutines are required.
int
iswlower (wint_t c)
{
- return (towupper (c) != c);
+ return iswlower_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswlower_l.c b/newlib/libc/ctype/iswlower_l.c
index d69615b..64f77a3 100644
--- a/newlib/libc/ctype/iswlower_l.c
+++ b/newlib/libc/ctype/iswlower_l.c
@@ -1,10 +1,20 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswlower_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return (towupper (c) != c);
+#ifdef _MB_CAPABLE
+ c = _jp2uc_l (c, locale);
+ // The wide-character class "lower" contains at least those characters wc
+ // which are equal to towlower(wc) and different from towupper(wc).
+ enum category cat = category (c);
+ return cat == CAT_Ll || (cat == CAT_LC && towlower (c) == c);
+#else
+ return c < 0x100 ? islower (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswprint.c b/newlib/libc/ctype/iswprint.c
new file mode 100644
index 0000000..5e468fe
--- /dev/null
+++ b/newlib/libc/ctype/iswprint.c
@@ -0,0 +1,72 @@
+/* Copyright (c) 2002 Red Hat Incorporated.
+ All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ The name of Red Hat Incorporated may not be used to endorse
+ or promote products derived from this software without specific
+ prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+FUNCTION
+ <<iswprint>>, <<iswprint_l>>---printable wide character test
+
+INDEX
+ iswprint
+
+INDEX
+ iswprint_l
+
+SYNOPSIS
+ #include <wctype.h>
+ int iswprint(wint_t <[c]>);
+
+ #include <wctype.h>
+ int iswprint_l(wint_t <[c]>, locale_t <[locale]>);
+
+DESCRIPTION
+<<iswprint>> is a function which classifies wide-character values that
+are printable.
+
+<<iswprint_l>> is like <<iswprint>> but performs the check based on the
+locale specified by the locale object locale. If <[locale]> is
+LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined.
+
+RETURNS
+<<iswprint>>, <<iswprint_l>> return non-zero if <[c]> is a printable wide character.
+
+PORTABILITY
+<<iswprint>> is C99.
+<<iswprint_l>> is POSIX-1.2008.
+
+No supporting OS subroutines are required.
+*/
+#include <_ansi.h>
+#include <wctype.h>
+
+int
+iswprint (wint_t c)
+{
+ return iswprint_l (c, 0);
+}
diff --git a/newlib/libc/ctype/iswprint_l.c b/newlib/libc/ctype/iswprint_l.c
index a8d8686..cdf027b 100644
--- a/newlib/libc/ctype/iswprint_l.c
+++ b/newlib/libc/ctype/iswprint_l.c
@@ -1,10 +1,21 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswprint_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswprint (c);
+#ifdef _MB_CAPABLE
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ return cat != -1
+ && cat != CAT_Cc && cat != CAT_Cf
+ && cat != CAT_Cs // Surrogate
+ ;
+#else
+ return c < (wint_t)0x100 ? isprint (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswpunct.c b/newlib/libc/ctype/iswpunct.c
index 8ab7038..27a6d65 100644
--- a/newlib/libc/ctype/iswpunct.c
+++ b/newlib/libc/ctype/iswpunct.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -62,14 +63,10 @@ PORTABILITY
No supporting OS subroutines are required.
*/
#include <_ansi.h>
-#include <newlib.h>
#include <wctype.h>
-#include <string.h>
-#include <ctype.h>
-#include "local.h"
int
iswpunct (wint_t c)
{
- return (!iswalnum (c) && iswgraph (c));
+ return iswpunct_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswpunct_l.c b/newlib/libc/ctype/iswpunct_l.c
index c7acc4e..4adc1ed 100644
--- a/newlib/libc/ctype/iswpunct_l.c
+++ b/newlib/libc/ctype/iswpunct_l.c
@@ -1,10 +1,26 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswpunct_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return !iswalnum (c) && iswgraph (c);
+#ifdef _MB_CAPABLE
+ //return !iswalnum (c) && iswgraph (c);
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ return cat == CAT_Pc || cat == CAT_Pd || cat == CAT_Pe || cat == CAT_Pf || cat == CAT_Pi || cat == CAT_Po || cat == CAT_Ps
+ || cat == CAT_Sm // Math Symbols
+ // the following are included for backwards consistency:
+ || cat == CAT_Sc // Currency Symbols
+ || cat == CAT_Sk // Modifier_Symbol
+ || cat == CAT_So // Other_Symbol
+ || cat == CAT_No // Other_Number
+ ;
+#else
+ return c < (wint_t)0x100 ? ispunct (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswspace.c b/newlib/libc/ctype/iswspace.c
index ae3841a..ca6a887 100644
--- a/newlib/libc/ctype/iswspace.c
+++ b/newlib/libc/ctype/iswspace.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -62,27 +63,10 @@ PORTABILITY
No supporting OS subroutines are required.
*/
#include <_ansi.h>
-#include <newlib.h>
#include <wctype.h>
-#include <ctype.h>
-#include <string.h>
-#include "local.h"
int
iswspace (wint_t c)
{
-#ifdef _MB_CAPABLE
- c = _jp2uc (c);
- /* Based on Unicode 5.2. Control chars 09-0D, plus all characters
- from general category "Zs", which are not marked as decomposition
- type "noBreak". */
- return ((c >= 0x0009 && c <= 0x000d) || c == 0x0020 ||
- c == 0x1680 || c == 0x180e ||
- (c >= 0x2000 && c <= 0x2006) ||
- (c >= 0x2008 && c <= 0x200a) ||
- c == 0x2028 || c == 0x2029 ||
- c == 0x205f || c == 0x3000);
-#else
- return (c < 0x100 ? isspace (c) : 0);
-#endif /* _MB_CAPABLE */
+ return iswspace_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswspace_l.c b/newlib/libc/ctype/iswspace_l.c
index 0c30242..e7f47ee 100644
--- a/newlib/libc/ctype/iswspace_l.c
+++ b/newlib/libc/ctype/iswspace_l.c
@@ -1,10 +1,21 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswspace_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return iswspace (c);
+#ifdef _MB_CAPABLE
+ c = _jp2uc_l (c, locale);
+ enum category cat = category (c);
+ // exclude "<noBreak>"?
+ return cat == CAT_Zs
+ || cat == CAT_Zl || cat == CAT_Zp // Line/Paragraph Separator
+ || (c >= 0x9 && c <= 0xD);
+#else
+ return c < 0x100 ? isspace (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswupper.c b/newlib/libc/ctype/iswupper.c
index c4969a3..96b5a0c 100644
--- a/newlib/libc/ctype/iswupper.c
+++ b/newlib/libc/ctype/iswupper.c
@@ -17,14 +17,14 @@ SYNOPSIS
DESCRIPTION
<<iswupper>> is a function which classifies wide-character values that
-have uppercase translations.
+are categorized as uppercase.
<<iswupper_l>> is like <<iswupper>> but performs the check based on the
locale specified by the locale object locale. If <[locale]> is
LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined.
RETURNS
-<<iswupper>>, <<iswupper_l>> return non-zero if <[c]> is a uppercase wide character.
+<<iswupper>>, <<iswupper_l>> return non-zero if <[c]> is an uppercase wide character.
PORTABILITY
<<iswupper>> is C99.
@@ -38,5 +38,5 @@ No supporting OS subroutines are required.
int
iswupper (wint_t c)
{
- return (towlower (c) != c);
+ return iswupper_l (c, 0);
}
diff --git a/newlib/libc/ctype/iswupper_l.c b/newlib/libc/ctype/iswupper_l.c
index 2555cd0..7ce8b5e 100644
--- a/newlib/libc/ctype/iswupper_l.c
+++ b/newlib/libc/ctype/iswupper_l.c
@@ -1,10 +1,20 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
+#include <ctype.h>
#include <wctype.h>
+#include "local.h"
+#include "categories.h"
int
iswupper_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return towlower (c) != c;
+#ifdef _MB_CAPABLE
+ c = _jp2uc_l (c, locale);
+ // The wide-character class "upper" contains at least those characters wc
+ // which are equal to towupper(wc) and different from towlower(wc).
+ enum category cat = category (c);
+ return cat == CAT_Lu || (cat == CAT_LC && towupper (c) == c);
+#else
+ return c < 0x100 ? islower (c) : 0;
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/iswxdigit.c b/newlib/libc/ctype/iswxdigit.c
index 4367186..fce2a4d 100644
--- a/newlib/libc/ctype/iswxdigit.c
+++ b/newlib/libc/ctype/iswxdigit.c
@@ -38,7 +38,7 @@ No supporting OS subroutines are required.
int
iswxdigit (wint_t c)
{
- return ((c >= (wint_t)'0' && c <= (wint_t)'9') ||
- (c >= (wint_t)'a' && c <= (wint_t)'f') ||
- (c >= (wint_t)'A' && c <= (wint_t)'F'));
+ return (c >= (wint_t)'0' && c <= (wint_t)'9')
+ || (c >= (wint_t)'a' && c <= (wint_t)'f')
+ || (c >= (wint_t)'A' && c <= (wint_t)'F');
}
diff --git a/newlib/libc/ctype/jp2uc.c b/newlib/libc/ctype/jp2uc.c
index 29eec0f..b89b5ea 100644
--- a/newlib/libc/ctype/jp2uc.c
+++ b/newlib/libc/ctype/jp2uc.c
@@ -1,7 +1,8 @@
-/* Routine to translate from Japanese characters to Unicode */
+/* Routine to translate between Japanese characters and Unicode */
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff: consider locale, add dummy uc2jp
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -25,7 +26,7 @@
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
@@ -40,13 +41,15 @@
#include <string.h>
#include <wctype.h>
#include "local.h"
-#include "jp2uc.h"
/* Japanese encoding types supported */
#define JP_JIS 1
#define JP_SJIS 2
#define JP_EUCJP 3
+/* Japanese to Unicode conversion routine */
+#include "jp2uc.h"
+
static wint_t
__jp2uc (wint_t c, int type)
{
@@ -104,7 +107,7 @@ __jp2uc (wint_t c, int type)
return d02f4[index];
}
- /* handle smaller ranges here */
+ /* handle smaller ranges here */
switch (byte1)
{
case 0xA1:
@@ -148,20 +151,50 @@ __jp2uc (wint_t c, int type)
return WEOF;
}
- return WEOF;
+ return WEOF;
+}
+
+/* Unicode to Japanese conversion routine */
+static wint_t
+__uc2jp (wint_t c, int type)
+{
+#warning back-conversion Unicode to Japanese not implemented; needed for towupper/towlower
+ return c;
}
+/* Japanese to Unicode conversion interface */
wint_t
-_jp2uc (wint_t c)
+_jp2uc_l (wint_t c, struct __locale_t * l)
{
- if (!strcmp (__current_locale_charset (), "JIS"))
+ char * cs = l ? __locale_charset(l) : __current_locale_charset();
+ if (0 == strcmp (cs, "JIS"))
c = __jp2uc (c, JP_JIS);
- else if (!strcmp (__current_locale_charset (), "SJIS"))
+ else if (0 == strcmp (cs, "SJIS"))
c = __jp2uc (c, JP_SJIS);
- else if (!strcmp (__current_locale_charset (), "EUCJP"))
+ else if (0 == strcmp (cs, "EUCJP"))
c = __jp2uc (c, JP_EUCJP);
return c;
}
+wint_t
+_jp2uc (wint_t c)
+{
+ return _jp2uc_l (c, 0);
+}
+
+/* Unicode to Japanese conversion interface */
+wint_t
+_uc2jp_l (wint_t c, struct __locale_t * l)
+{
+ char * cs = l ? __locale_charset(l) : __current_locale_charset();
+ if (0 == strcmp (cs, "JIS"))
+ c = __uc2jp (c, JP_JIS);
+ else if (0 == strcmp (cs, "SJIS"))
+ c = __uc2jp (c, JP_SJIS);
+ else if (0 == strcmp (cs, "EUCJP"))
+ c = __uc2jp (c, JP_EUCJP);
+ return c;
+}
+
#endif /* !__CYGWIN__ */
#endif /* _MB_CAPABLE */
diff --git a/newlib/libc/ctype/local.h b/newlib/libc/ctype/local.h
index 62d2b15..aa8f533 100644
--- a/newlib/libc/ctype/local.h
+++ b/newlib/libc/ctype/local.h
@@ -1,3 +1,5 @@
+/* Modified (m) 2017 Thomas Wolff: fixed locale/wchar handling */
+
/* wctrans constants */
#include <_ansi.h>
@@ -21,11 +23,22 @@
#define WC_UPPER 11
#define WC_XDIGIT 12
-/* internal function to translate JP to Unicode */
+/* internal functions to translate between JP and Unicode */
+/* note this is not applicable to Cygwin, where wchar_t is always Unicode,
+ and should not be applicable to most other platforms either;
+ * platforms for which wchar_t is not Unicode should be explicitly listed
+ * the transformation should be applied to all non-Unicode locales
+ (also Chinese, Korean, and even 8-bit locales such as *.CP1252)
+ * for towupper and towlower, the result must be back-transformed
+ into the respective locale encoding; currently NOT IMPLEMENTED
+*/
#ifdef __CYGWIN__
-/* Under Cygwin, the incoming wide character is already given in UTF due
- to the requirements of the underlying OS. */
+/* Under Cygwin, wchar_t (or its extension wint_t) is Unicode */
#define _jp2uc(c) (c)
+#define _jp2uc_l(c, l) (c)
+#define _uc2jp_l(c, l) (c)
#else
wint_t _jp2uc (wint_t);
+wint_t _jp2uc_l (wint_t, struct __locale_t *);
+wint_t _uc2jp_l (wint_t, struct __locale_t *);
#endif
diff --git a/newlib/libc/ctype/towctrans.c b/newlib/libc/ctype/towctrans.c
index edbdfce..176aa3d 100644
--- a/newlib/libc/ctype/towctrans.c
+++ b/newlib/libc/ctype/towctrans.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -69,10 +70,9 @@ No supporting OS subroutines are required.
*/
#include <_ansi.h>
-#include <string.h>
#include <reent.h>
#include <wctype.h>
-#include <errno.h>
+//#include <errno.h>
#include "local.h"
wint_t
@@ -80,13 +80,13 @@ _towctrans_r (struct _reent *r,
wint_t c,
wctrans_t w)
{
- if (w == WCT_TOLOWER)
- return towlower (c);
- else if (w == WCT_TOUPPER)
- return towupper (c);
+ if (w == WCT_TOLOWER || w == WCT_TOUPPER)
+ return towctrans_l (c, w, 0);
else
{
- r->_errno = EINVAL;
+ // skipping this because it was causing trouble (cygwin crash)
+ // and there is no errno specified for towctrans
+ //r->_errno = EINVAL;
return c;
}
}
@@ -94,7 +94,7 @@ _towctrans_r (struct _reent *r,
#ifndef _REENT_ONLY
wint_t
towctrans (wint_t c,
- wctrans_t w)
+ wctrans_t w)
{
return _towctrans_r (_REENT, c, w);
}
diff --git a/newlib/libc/ctype/towctrans_l.c b/newlib/libc/ctype/towctrans_l.c
index d7369e1..8da372f 100644
--- a/newlib/libc/ctype/towctrans_l.c
+++ b/newlib/libc/ctype/towctrans_l.c
@@ -1,10 +1,101 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
#include <wctype.h>
+//#include <errno.h>
+#include "local.h"
+
+enum {EVENCAP, ODDCAP};
+enum {TO1, TOLO, TOUP, TOBOTH};
+static struct caseconv_entry {
+ unsigned int first: 21;
+ unsigned short diff: 8;
+ unsigned char mode: 2;
+ int delta: 17;
+} __attribute__ ((packed))
+caseconv_table [] = {
+#include "caseconv.t"
+};
+#define first(ce) ce.first
+#define last(ce) (ce.first + ce.diff)
+
+/* auxiliary function for binary search in interval properties table */
+static const struct caseconv_entry *
+bisearch(wint_t ucs, const struct caseconv_entry *table, int max)
+{
+ int min = 0;
+ int mid;
+
+ if (ucs < first(table[0]) || ucs > last(table[max]))
+ return 0;
+ while (max >= min)
+ {
+ mid = (min + max) / 2;
+ if (ucs > last(table[mid]))
+ min = mid + 1;
+ else if (ucs < first(table[mid]))
+ max = mid - 1;
+ else
+ return &table[mid];
+ }
+ return 0;
+}
+
+static wint_t
+toulower (wint_t c)
+{
+ const struct caseconv_entry * cce =
+ bisearch(c, caseconv_table,
+ sizeof(caseconv_table) / sizeof(*caseconv_table) - 1);
+ if (cce)
+ switch (cce->mode) {
+ case TOLO: return c + cce->delta;
+ case TOBOTH: return c + 1;
+ case TO1: switch (cce->delta) {
+ case EVENCAP: if (!(c & 1)) return c + 1; break;
+ case ODDCAP: if (c & 1) return c + 1; break;
+ }
+ }
+ else
+ return c;
+}
+
+static wint_t
+touupper (wint_t c)
+{
+ const struct caseconv_entry * cce =
+ bisearch(c, caseconv_table,
+ sizeof(caseconv_table) / sizeof(*caseconv_table) - 1);
+ if (cce)
+ switch (cce->mode) {
+ case TOUP: return c + cce->delta;
+ case TOBOTH: return c - 1;
+ case TO1: switch (cce->delta) {
+ case EVENCAP: if (c & 1) return c - 1; break;
+ case ODDCAP: if (!(c & 1)) return c - 1; break;
+ }
+ }
+ else
+ return c;
+}
wint_t
towctrans_l (wint_t c, wctrans_t w, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
- return towctrans (c, w);
+ wint_t u = _jp2uc_l (c, locale);
+ wint_t res;
+ if (w == WCT_TOLOWER)
+ res = toulower (u);
+ else if (w == WCT_TOUPPER)
+ res = touupper (u);
+ else
+ {
+ // skipping the errno setting that was previously involved
+ // by delegating to towctrans; it was causing trouble (cygwin crash)
+ // and there is no errno specified for towctrans
+ return c;
+ }
+ if (res != u)
+ return _uc2jp_l (res, locale);
+ else
+ return c;
}
diff --git a/newlib/libc/ctype/towlower.c b/newlib/libc/ctype/towlower.c
new file mode 100644
index 0000000..01de1bd
--- /dev/null
+++ b/newlib/libc/ctype/towlower.c
@@ -0,0 +1,81 @@
+/* Copyright (c) 2002 Red Hat Incorporated.
+ All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ The name of Red Hat Incorporated may not be used to endorse
+ or promote products derived from this software without specific
+ prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL RED HAT INCORPORATED BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+FUNCTION
+ <<towlower>>, <<towlower_l>>---translate wide characters to lowercase
+
+INDEX
+ towlower
+
+INDEX
+ towlower_l
+
+SYNOPSIS
+ #include <wctype.h>
+ wint_t towlower(wint_t <[c]>);
+
+ #include <wctype.h>
+ wint_t towlower_l(wint_t <[c]>, locale_t <[locale]>);
+
+
+DESCRIPTION
+<<towlower>> is a function which converts uppercase wide characters to
+lowercase, leaving all other characters unchanged.
+
+<<towlower_l>> is like <<towlower>> but performs the function based on the
+locale specified by the locale object locale. If <[locale]> is
+LC_GLOBAL_LOCALE or not a valid locale object, the behaviour is undefined.
+
+RETURNS
+<<towlower>>, <<towlower_l>> return the lowercase equivalent of <[c]> when it is a
+uppercase wide character; otherwise, it returns the input character.
+
+PORTABILITY
+<<towlower>> is C99.
+<<towlower_l>> is POSIX-1.2008.
+
+No supporting OS subroutines are required.
+*/
+
+#include <_ansi.h>
+#include <ctype.h>
+#include <wctype.h>
+#include "local.h"
+
+wint_t
+towlower (wint_t c)
+{
+#ifdef _MB_CAPABLE
+ return towctrans (c, WCT_TOLOWER);
+#else
+ return c < 0x00ff ? (wint_t)(tolower ((int)c)) : c;
+#endif /* _MB_CAPABLE */
+}
diff --git a/newlib/libc/ctype/towlower_l.c b/newlib/libc/ctype/towlower_l.c
index 2e89ec9..46e024d 100644
--- a/newlib/libc/ctype/towlower_l.c
+++ b/newlib/libc/ctype/towlower_l.c
@@ -1,3 +1,4 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
#include <newlib.h>
#include <wctype.h>
@@ -6,7 +7,9 @@
wint_t
towlower_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
+#ifdef _MB_CAPABLE
+ return towctrans_l (c, WCT_TOLOWER, locale);
+#else
return towlower (c);
+#endif /* _MB_CAPABLE */
}
diff --git a/newlib/libc/ctype/towupper.c b/newlib/libc/ctype/towupper.c
index 306f72b..a60e62b 100644
--- a/newlib/libc/ctype/towupper.c
+++ b/newlib/libc/ctype/towupper.c
@@ -1,5 +1,6 @@
/* Copyright (c) 2002 Red Hat Incorporated.
All rights reserved.
+ Modified (m) 2017 Thomas Wolff to refer to generated Unicode data tables.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -76,518 +77,8 @@ wint_t
towupper (wint_t c)
{
#ifdef _MB_CAPABLE
- c = _jp2uc (c);
- /* Based on and tested against Unicode 5.2 */
-
- /* Expression used to filter out the characters for the below code:
-
- awk -F\; '{ if ( $13 != "" ) print $1; }' UnicodeData.txt
- */
- if (c < 0x100)
- {
- if (c == 0x00b5)
- return 0x039c;
-
- if ((c >= 0x00e0 && c <= 0x00fe && c != 0x00f7) ||
- (c >= 0x0061 && c <= 0x007a))
- return (c - 0x20);
-
- if (c == 0xff)
- return 0x0178;
-
- return c;
- }
- else if (c < 0x300)
- {
- if ((c >= 0x0101 && c <= 0x012f) ||
- (c >= 0x0133 && c <= 0x0137) ||
- (c >= 0x014b && c <= 0x0177) ||
- (c >= 0x01df && c <= 0x01ef) ||
- (c >= 0x01f9 && c <= 0x021f) ||
- (c >= 0x0223 && c <= 0x0233) ||
- (c >= 0x0247 && c <= 0x024f))
- {
- if (c & 0x01)
- return (c - 1);
- return c;
- }
-
- if ((c >= 0x013a && c <= 0x0148) ||
- (c >= 0x01ce && c <= 0x01dc) ||
- c == 0x023c || c == 0x0242)
- {
- if (!(c & 0x01))
- return (c - 1);
- return c;
- }
-
- if (c == 0x0131)
- return 0x0049;
-
- if (c == 0x017a || c == 0x017c || c == 0x017e)
- return (c - 1);
-
- if (c >= 0x017f && c <= 0x0292)
- {
- wint_t k;
- switch (c)
- {
- case 0x017f:
- k = 0x0053;
- break;
- case 0x0180:
- k = 0x0243;
- break;
- case 0x0183:
- k = 0x0182;
- break;
- case 0x0185:
- k = 0x0184;
- break;
- case 0x0188:
- k = 0x0187;
- break;
- case 0x018c:
- k = 0x018b;
- break;
- case 0x0192:
- k = 0x0191;
- break;
- case 0x0195:
- k = 0x01f6;
- break;
- case 0x0199:
- k = 0x0198;
- break;
- case 0x019a:
- k = 0x023d;
- break;
- case 0x019e:
- k = 0x0220;
- break;
- case 0x01a1:
- case 0x01a3:
- case 0x01a5:
- case 0x01a8:
- case 0x01ad:
- case 0x01b0:
- case 0x01b4:
- case 0x01b6:
- case 0x01b9:
- case 0x01bd:
- case 0x01c5:
- case 0x01c8:
- case 0x01cb:
- case 0x01f2:
- case 0x01f5:
- k = c - 1;
- break;
- case 0x01bf:
- k = 0x01f7;
- break;
- case 0x01c6:
- case 0x01c9:
- case 0x01cc:
- k = c - 2;
- break;
- case 0x01dd:
- k = 0x018e;
- break;
- case 0x01f3:
- k = 0x01f1;
- break;
- case 0x023f:
- k = 0x2c7e;
- break;
- case 0x0240:
- k = 0x2c7f;
- break;
- case 0x0250:
- k = 0x2c6f;
- break;
- case 0x0251:
- k = 0x2c6d;
- break;
- case 0x0252:
- k = 0x2c70;
- break;
- case 0x0253:
- k = 0x0181;
- break;
- case 0x0254:
- k = 0x0186;
- break;
- case 0x0256:
- k = 0x0189;
- break;
- case 0x0257:
- k = 0x018a;
- break;
- case 0x0259:
- k = 0x018f;
- break;
- case 0x025b:
- k = 0x0190;
- break;
- case 0x0260:
- k = 0x0193;
- break;
- case 0x0263:
- k = 0x0194;
- break;
- case 0x0268:
- k = 0x0197;
- break;
- case 0x0269:
- k = 0x0196;
- break;
- case 0x026b:
- k = 0x2c62;
- break;
- case 0x026f:
- k = 0x019c;
- break;
- case 0x0271:
- k = 0x2c6e;
- break;
- case 0x0272:
- k = 0x019d;
- break;
- case 0x0275:
- k = 0x019f;
- break;
- case 0x027d:
- k = 0x2c64;
- break;
- case 0x0280:
- k = 0x01a6;
- break;
- case 0x0283:
- k = 0x01a9;
- break;
- case 0x0288:
- k = 0x01ae;
- break;
- case 0x0289:
- k = 0x0244;
- break;
- case 0x028a:
- k = 0x01b1;
- break;
- case 0x028b:
- k = 0x01b2;
- break;
- case 0x028c:
- k = 0x0245;
- break;
- case 0x0292:
- k = 0x01b7;
- break;
- default:
- k = 0;
- }
- if (k != 0)
- return k;
- }
- }
- else if (c < 0x0400)
- {
- wint_t k;
-
- if (c >= 0x03ad && c <= 0x03af)
- return (c - 0x25);
-
- if (c >= 0x03b1 && c <= 0x03cb && c != 0x03c2)
- return (c - 0x20);
-
- if (c >= 0x03d9 && c <= 0x03ef && (c & 1))
- return (c - 1);
-
- switch (c)
- {
- case 0x0345:
- k = 0x0399;
- break;
- case 0x0371:
- case 0x0373:
- case 0x0377:
- case 0x03f8:
- case 0x03fb:
- k = c - 1;
- break;
- case 0x037b:
- case 0x037c:
- case 0x037d:
- k = c + 0x82;
- break;
- case 0x03ac:
- k = 0x0386;
- break;
- case 0x03c2:
- k = 0x03a3;
- break;
- case 0x03cc:
- k = 0x038c;
- break;
- case 0x03cd:
- case 0x03ce:
- k = c - 0x3f;
- break;
- case 0x03d0:
- k = 0x0392;
- break;
- case 0x03d1:
- k = 0x0398;
- break;
- case 0x03d5:
- k = 0x03a6;
- break;
- case 0x03d6:
- k = 0x03a0;
- break;
- case 0x03d7:
- k = 0x03cf;
- break;
- case 0x03f0:
- k = 0x039a;
- break;
- case 0x03f1:
- k = 0x03a1;
- break;
- case 0x03f2:
- k = 0x03f9;
- break;
- case 0x03f5:
- k = 0x0395;
- break;
- default:
- k = 0;
- }
- if (k != 0)
- return k;
- }
- else if (c < 0x500)
- {
- if (c >= 0x0430 && c <= 0x044f)
- return (c - 0x20);
-
- if (c >= 0x0450 && c <= 0x045f)
- return (c - 0x50);
-
- if ((c >= 0x0461 && c <= 0x0481) ||
- (c >= 0x048b && c <= 0x04bf) ||
- (c >= 0x04d1 && c <= 0x04ff))
- {
- if (c & 0x01)
- return (c - 1);
- return c;
- }
-
- if (c >= 0x04c2 && c <= 0x04ce)
- {
- if (!(c & 0x01))
- return (c - 1);
- return c;
- }
-
- if (c == 0x04cf)
- return 0x04c0;
- }
- else if (c < 0x0600)
- {
- if (c >= 0x0501 && c <= 0x0525 && (c & 1))
- return c - 1;
-
- if (c >= 0x0561 && c <= 0x0586)
- return (c - 0x30);
- }
- else if (c < 0x1f00)
- {
- if (c == 0x1d79)
- return 0xa77d;
-
- if (c == 0x1d7d)
- return 0x2c63;
-
- if ((c >= 0x1e01 && c <= 0x1e95) ||
- (c >= 0x1ea1 && c <= 0x1eff))
- {
- if (c & 0x01)
- return (c - 1);
- return c;
- }
-
- if (c == 0x1e9b)
- return 0x1e60;
- }
- else if (c < 0x2000)
- {
-
- if ((c >= 0x1f00 && c <= 0x1f07) ||
- (c >= 0x1f10 && c <= 0x1f15) ||
- (c >= 0x1f20 && c <= 0x1f27) ||
- (c >= 0x1f30 && c <= 0x1f37) ||
- (c >= 0x1f40 && c <= 0x1f45) ||
- (c >= 0x1f60 && c <= 0x1f67) ||
- (c >= 0x1f80 && c <= 0x1f87) ||
- (c >= 0x1f90 && c <= 0x1f97) ||
- (c >= 0x1fa0 && c <= 0x1fa7))
- return (c + 0x08);
-
- if (c >= 0x1f51 && c <= 0x1f57 && (c & 0x01))
- return (c + 0x08);
-
- if (c >= 0x1f70 && c <= 0x1ff3)
- {
- wint_t k;
- switch (c)
- {
- case 0x1fb0:
- k = 0x1fb8;
- break;
- case 0x1fb1:
- k = 0x1fb9;
- break;
- case 0x1f70:
- k = 0x1fba;
- break;
- case 0x1f71:
- k = 0x1fbb;
- break;
- case 0x1fb3:
- k = 0x1fbc;
- break;
- case 0x1fbe:
- k = 0x0399;
- break;
- case 0x1f72:
- k = 0x1fc8;
- break;
- case 0x1f73:
- k = 0x1fc9;
- break;
- case 0x1f74:
- k = 0x1fca;
- break;
- case 0x1f75:
- k = 0x1fcb;
- break;
- case 0x1fc3:
- k = 0x1fcc;
- break;
- case 0x1fd0:
- k = 0x1fd8;
- break;
- case 0x1fd1:
- k = 0x1fd9;
- break;
- case 0x1f76:
- k = 0x1fda;
- break;
- case 0x1f77:
- k = 0x1fdb;
- break;
- case 0x1fe0:
- k = 0x1fe8;
- break;
- case 0x1fe1:
- k = 0x1fe9;
- break;
- case 0x1f7a:
- k = 0x1fea;
- break;
- case 0x1f7b:
- k = 0x1feb;
- break;
- case 0x1fe5:
- k = 0x1fec;
- break;
- case 0x1f78:
- k = 0x1ff8;
- break;
- case 0x1f79:
- k = 0x1ff9;
- break;
- case 0x1f7c:
- k = 0x1ffa;
- break;
- case 0x1f7d:
- k = 0x1ffb;
- break;
- case 0x1ff3:
- k = 0x1ffc;
- break;
- default:
- k = 0;
- }
- if (k != 0)
- return k;
- }
- }
- else if (c < 0x3000)
- {
- if (c == 0x214e)
- return 0x2132;
-
- if (c == 0x2184)
- return 0x2183;
-
- if (c >= 0x2170 && c <= 0x217f)
- return (c - 0x10);
-
- if (c >= 0x24d0 && c <= 0x24e9)
- return (c - 0x1a);
-
- if (c >= 0x2c30 && c <= 0x2c5e)
- return (c - 0x30);
-
- if ((c >= 0x2c68 && c <= 0x2c6c && !(c & 1)) ||
- (c >= 0x2c81 && c <= 0x2ce3 && (c & 1)) ||
- c == 0x2c73 || c == 0x2c76 ||
- c == 0x2cec || c == 0x2cee)
- return (c - 1);
-
- if (c >= 0x2c81 && c <= 0x2ce3 && (c & 1))
- return (c - 1);
-
- if (c >= 0x2d00 && c <= 0x2d25)
- return (c - 0x1c60);
-
- switch (c)
- {
- case 0x2c61:
- return 0x2c60;
- case 0x2c65:
- return 0x023a;
- case 0x2c66:
- return 0x023e;
- }
- }
- else if (c >= 0xa000 && c < 0xb000)
- {
- if (((c >= 0xa641 && c <= 0xa65f) ||
- (c >= 0xa663 && c <= 0xa66d) ||
- (c >= 0xa681 && c <= 0xa697) ||
- (c >= 0xa723 && c <= 0xa72f) ||
- (c >= 0xa733 && c <= 0xa76f) ||
- (c >= 0xa77f && c <= 0xa787)) &&
- (c & 1))
- return (c - 1);
-
- if (c == 0xa77a || c == 0xa77c || c == 0xa78c)
- return (c - 1);
- }
- else
- {
- if (c >= 0xff41 && c <= 0xff5a)
- return (c - 0x20);
-
- if (c >= 0x10428 && c <= 0x1044f)
- return (c - 0x28);
- }
- return c;
+ return towctrans (c, WCT_TOUPPER);
#else
- return (c < 0x00ff ? (wint_t)(toupper ((int)c)) : c);
+ return c < 0x00ff ? (wint_t)(toupper ((int)c)) : c;
#endif /* _MB_CAPABLE */
}
-
diff --git a/newlib/libc/ctype/towupper_l.c b/newlib/libc/ctype/towupper_l.c
index 5a8384c..d7c1adb 100644
--- a/newlib/libc/ctype/towupper_l.c
+++ b/newlib/libc/ctype/towupper_l.c
@@ -1,10 +1,14 @@
+/* Modified (m) 2017 Thomas Wolff: revise Unicode and locale/wchar handling */
#include <_ansi.h>
#include <wctype.h>
+#include "local.h"
wint_t
towupper_l (wint_t c, struct __locale_t *locale)
{
- /* We're using a locale-independent representation of upper/lower case
- based on Unicode data. Thus, the locale doesn't matter. */
+#ifdef _MB_CAPABLE
+ return towctrans_l (c, WCT_TOUPPER, locale);
+#else
return towupper (c);
+#endif /* _MB_CAPABLE */
}
--
2.16.2
More information about the Newlib
mailing list