This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
handy.h: Use some common macros for ASCII/EBCDIC
[perl5.git] / utf8.h
diff --git a/utf8.h b/utf8.h
index 5880aa3..f0e9d56 100644 (file)
--- a/utf8.h
+++ b/utf8.h
                                     ckWARN_d(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY)
 
 #define to_uni_fold(c, p, lenp) _to_uni_fold_flags(c, p, lenp, FOLD_FLAGS_FULL)
-#define to_utf8_fold(c, p, lenp) _to_utf8_fold_flags(c, p, lenp, \
-                    FOLD_FLAGS_FULL, NULL)
-#define to_utf8_lower(a,b,c) _to_utf8_lower_flags(a,b,c,0, NULL)
-#define to_utf8_upper(a,b,c) _to_utf8_upper_flags(a,b,c,0, NULL)
-#define to_utf8_title(a,b,c) _to_utf8_title_flags(a,b,c,0, NULL)
+#define to_utf8_fold(c, p, lenp) _to_utf8_fold_flags(c, p, lenp, FOLD_FLAGS_FULL)
+#define to_utf8_lower(a,b,c) _to_utf8_lower_flags(a,b,c,0)
+#define to_utf8_upper(a,b,c) _to_utf8_upper_flags(a,b,c,0)
+#define to_utf8_title(a,b,c) _to_utf8_title_flags(a,b,c,0)
 
 /* Source backward compatibility. */
 #define is_utf8_string_loc(s, len, ep) is_utf8_string_loclen(s, len, ep, 0)
 
 #define foldEQ_utf8(s1, pe1, l1, u1, s2, pe2, l2, u2) \
                    foldEQ_utf8_flags(s1, pe1, l1, u1, s2, pe2, l2, u2, 0)
-#define FOLDEQ_UTF8_NOMIX_ASCII (1 << 0)
-#define FOLDEQ_UTF8_LOCALE      (1 << 1)
+#define FOLDEQ_UTF8_NOMIX_ASCII   (1 << 0)
+#define FOLDEQ_LOCALE             (1 << 1)
 #define FOLDEQ_S1_ALREADY_FOLDED  (1 << 2)
 #define FOLDEQ_S2_ALREADY_FOLDED  (1 << 3)
 
@@ -233,7 +232,9 @@ Perl's extended UTF-8 means we can have start bytes up to FF.
     (((UV) UTF_CONTINUATION_MASK) << ((sizeof(UV) * CHARBITS)           \
            - UTF_ACCUMULATION_SHIFT))
 
-#ifdef HAS_QUAD
+#if UVSIZE >= 8
+#  define UTF8_QUAD_MAX UINT64_C(0x1000000000)
+
 /* Input is a true Unicode (not-native) code point */
 #define OFFUNISKIP(uv) ( (uv) < 0x80        ? 1 : \
                      (uv) < 0x800          ? 2 : \
@@ -347,29 +348,48 @@ Perl's extended UTF-8 means we can have start bytes up to FF.
 
 #define MAX_PORTABLE_UTF8_TWO_BYTE 0x3FF    /* constrained by EBCDIC */
 
-/* The macros in the next sets are used to generate the two utf8 or utfebcdic
- * bytes from an ordinal that is known to fit into two bytes; it must be less
- * than 0x3FF to work across both encodings. */
-/* Nocast allows these to be used in the case label of a switch statement;
- * however this doesn't won't work for ebcdic, and should be avoided.  Use
- * regen/unicode_constants instead */
-#define UTF8_TWO_BYTE_HI_nocast(c)     I8_TO_NATIVE_UTF8((NATIVE_TO_UNI(c)     \
-                        >> UTF_ACCUMULATION_SHIFT) | UTF_START_MARK(2))
-#define UTF8_TWO_BYTE_LO_nocast(c)  I8_TO_NATIVE_UTF8((NATIVE_TO_UNI(c)         \
-                                                  & UTF_CONTINUATION_MASK)      \
-                                                | UTF_CONTINUATION_MARK)
-
-#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 (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) | UTF_START_MARK(2))
-#define UTF8_EIGHT_BIT_LO(c)   I8_TO_NATIVE_UTF8((NATIVE_TO_LATIN1(c)          \
-                                                  & UTF_CONTINUATION_MASK)      \
-                                                | UTF_CONTINUATION_MARK)
+/* The macros in the next 4 sets are used to generate the two utf8 or utfebcdic
+ * bytes from an ordinal that is known to fit into exactly two (not one) bytes;
+ * it must be less than 0x3FF to work across both encodings. */
+
+/* These two are helper macros for the other three sets, and should not be used
+ * directly anywhere else.  'translate_function' is either NATIVE_TO_LATIN1
+ * (which works for code points up to 0xFF) or NATIVE_TO_UNI which works for any
+ * code point */
+#define __BASE_TWO_BYTE_HI(c, translate_function)                               \
+            I8_TO_NATIVE_UTF8((translate_function(c) >> UTF_ACCUMULATION_SHIFT) \
+                              | UTF_START_MARK(2))
+#define __BASE_TWO_BYTE_LO(c, translate_function)                               \
+              I8_TO_NATIVE_UTF8((translate_function(c) & UTF_CONTINUATION_MASK) \
+                                 | UTF_CONTINUATION_MARK)
+
+/* The next two macros should not be used.  They were designed to be usable as
+ * the case label of a switch statement, but this doesn't work for EBCDIC.  Use
+ * regen/unicode_constants.pl instead */
+#define UTF8_TWO_BYTE_HI_nocast(c)  __BASE_TWO_BYTE_HI(c, NATIVE_TO_UNI)
+#define UTF8_TWO_BYTE_LO_nocast(c)  __BASE_TWO_BYTE_LO(c, NATIVE_TO_UNI)
+
+/* The next two macros are used when the source should be a single byte
+ * character; checked for under DEBUGGING */
+#define UTF8_EIGHT_BIT_HI(c) (__ASSERT_(FITS_IN_8_BITS(c))                    \
+                             ((U8) __BASE_TWO_BYTE_HI(c, NATIVE_TO_LATIN1)))
+#define UTF8_EIGHT_BIT_LO(c) (__ASSERT_(FITS_IN_8_BITS(c))                    \
+                             ((U8) __BASE_TWO_BYTE_LO(c, NATIVE_TO_LATIN1)))
+
+/* These final two macros in the series are used when the source can be any
+ * code point whose UTF-8 is known to occupy 2 bytes; they are less efficient
+ * than the EIGHT_BIT versions on EBCDIC platforms.  We use the logical '~'
+ * operator instead of "<=" to avoid getting compiler warnings.
+ * MAX_PORTABLE_UTF8_TWO_BYTE should be exactly all one bits in the lower few
+ * places, so the ~ works */
+#define UTF8_TWO_BYTE_HI(c)                                                    \
+       (__ASSERT_((sizeof(c) ==  1)                                            \
+                  || !(((WIDEST_UTYPE)(c)) & ~MAX_PORTABLE_UTF8_TWO_BYTE))     \
+        ((U8) __BASE_TWO_BYTE_HI(c, NATIVE_TO_LATIN1)))
+#define UTF8_TWO_BYTE_LO(c)                                                    \
+       (__ASSERT_((sizeof(c) ==  1)                                            \
+                  || !(((WIDEST_UTYPE)(c)) & ~MAX_PORTABLE_UTF8_TWO_BYTE))     \
+        ((U8) __BASE_TWO_BYTE_LO(c, NATIVE_TO_LATIN1)))
 
 /* This is illegal in any well-formed UTF-8 in both EBCDIC and ASCII
  * as it is only in overlongs. */
@@ -426,7 +446,9 @@ Perl's extended UTF-8 means we can have start bytes up to FF.
 #define UTF8_WARN_SUPER                        0x0400  /* points above the legal max */
 
 /* Code points which never were part of the original UTF-8 standard, the first
- * byte of which is a FE or FF on ASCII platforms. */
+ * byte of which is a FE or FF on ASCII platforms. If the first byte is FF, it
+ * will overflow a 32-bit word.  If the first byte is FE, it will overflow a
+ * signed 32-bit word. */
 #define UTF8_DISALLOW_FE_FF            0x0800
 #define UTF8_WARN_FE_FF                        0x1000
 
@@ -521,10 +543,6 @@ Perl's extended UTF-8 means we can have start bytes up to FF.
 #define UNICODE_IS_SUPER(c)            ((c) > PERL_UNICODE_MAX)
 #define UNICODE_IS_FE_FF(c)            ((c) > 0x7FFFFFFF)
 
-#ifdef HAS_QUAD
-#    define UTF8_QUAD_MAX      UINT64_C(0x1000000000)
-#endif
-
 #define LATIN_SMALL_LETTER_SHARP_S      LATIN_SMALL_LETTER_SHARP_S_NATIVE
 #define LATIN_SMALL_LETTER_Y_WITH_DIAERESIS                                  \
                                 LATIN_SMALL_LETTER_Y_WITH_DIAERESIS_NATIVE