This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
utf8.h: Simplify UTF8_EIGHT_BIT_foo on EBCDIC
authorKarl Williamson <public@khwilliamson.com>
Fri, 1 Mar 2013 15:28:52 +0000 (08:28 -0700)
committerKarl Williamson <public@khwilliamson.com>
Thu, 29 Aug 2013 15:55:59 +0000 (09:55 -0600)
These macros were previously defined in terms of UTF8_TWO_BYTE_HI and
UTF8_TWO_BYTE_LO.  But the EIGHT_BIT versions can use the less general
and simpler NATIVE_TO_LATIN1 instead of NATIVE_TO_UNI because the input
domain is restricted in the EIGHT_BIT.  Note that on ASCII platforms,
these both expand to the same thing, so the difference matters only on
EBCDIC.

utf8.h

diff --git a/utf8.h b/utf8.h
index 1ecb3b8..3fb4fd2 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -348,11 +348,14 @@ Perl's extended UTF-8 means we can have start bytes up to FF.
 #define UTF8_TWO_BYTE_HI(c)    ((U8) (UTF8_TWO_BYTE_HI_nocast(c)))
 #define UTF8_TWO_BYTE_LO(c)    ((U8) (UTF8_TWO_BYTE_LO_nocast(c)))
 
-/* This name is used when the source is a single byte.  For EBCDIC these could
- * be more efficiently written; the reason is that things above 0xFF have to be
- * special-cased, which is done by the EBCDIC version of NATIVE_TO_UNI() */
-#define UTF8_EIGHT_BIT_HI(c)   UTF8_TWO_BYTE_HI((U8)(c))
-#define UTF8_EIGHT_BIT_LO(c)   UTF8_TWO_BYTE_LO((U8)(c))
+/* This name is used when the source is a single byte (input not checked).
+ * These expand identically to the TWO_BYTE versions on ASCII platforms, but
+ * use to/from LATIN1 instead of UNI, which on EBCDIC eliminates tests */
+#define UTF8_EIGHT_BIT_HI(c)   I8_TO_NATIVE_UTF8((NATIVE_TO_LATIN1(c)          \
+                        >> UTF_ACCUMULATION_SHIFT) | (0xFF & UTF_START_MARK(2)))
+#define UTF8_EIGHT_BIT_LO(c)   I8_TO_NATIVE_UTF8((NATIVE_TO_LATIN1(c)          \
+                                                  & UTF_CONTINUATION_MASK)      \
+                                                | UTF_CONTINUATION_MARK)
 
 /* This is illegal in any well-formed UTF-8 in both EBCDIC and ASCII
  * as it is only in overlongs. */