+#ifdef emacs
+
+/* Store characters in the range FROM to TO in the bitmap at B (for
+ ASCII and unibyte characters) and WORK_AREA (for multibyte
+ characters) while translating them and paying attention to the
+ continuity of translated characters.
+
+ Implementation note: It is better to implement these fairly big
+ macros by a function, but it's not that easy because macros called
+ in this macro assume various local variables already declared. */
+
+/* Both FROM and TO are ASCII characters. */
+
+#define SETUP_ASCII_RANGE(work_area, FROM, TO) \
+ do { \
+ int C0, C1; \
+ \
+ for (C0 = (FROM); C0 <= (TO); C0++) \
+ { \
+ C1 = TRANSLATE (C0); \
+ if (! ASCII_CHAR_P (C1)) \
+ { \
+ SET_RANGE_TABLE_WORK_AREA ((work_area), C1, C1); \
+ if ((C1 = RE_CHAR_TO_UNIBYTE (C1)) < 0) \
+ C1 = C0; \
+ } \
+ SET_LIST_BIT (C1); \
+ } \
+ } while (0)
+
+
+/* Both FROM and TO are unibyte characters (0x80..0xFF). */
+
+#define SETUP_UNIBYTE_RANGE(work_area, FROM, TO) \
+ do { \
+ int C0, C1, C2, I; \
+ int USED = RANGE_TABLE_WORK_USED (work_area); \
+ \
+ for (C0 = (FROM); C0 <= (TO); C0++) \
+ { \
+ C1 = RE_CHAR_TO_MULTIBYTE (C0); \
+ if (CHAR_BYTE8_P (C1)) \
+ SET_LIST_BIT (C0); \
+ else \
+ { \
+ C2 = TRANSLATE (C1); \
+ if (C2 == C1 \
+ || (C1 = RE_CHAR_TO_UNIBYTE (C2)) < 0) \
+ C1 = C0; \
+ SET_LIST_BIT (C1); \
+ for (I = RANGE_TABLE_WORK_USED (work_area) - 2; I >= USED; I -= 2) \
+ { \
+ int from = RANGE_TABLE_WORK_ELT (work_area, I); \
+ int to = RANGE_TABLE_WORK_ELT (work_area, I + 1); \
+ \
+ if (C2 >= from - 1 && C2 <= to + 1) \
+ { \
+ if (C2 == from - 1) \
+ RANGE_TABLE_WORK_ELT (work_area, I)--; \
+ else if (C2 == to + 1) \
+ RANGE_TABLE_WORK_ELT (work_area, I + 1)++; \
+ break; \
+ } \
+ } \
+ if (I < USED) \
+ SET_RANGE_TABLE_WORK_AREA ((work_area), C2, C2); \
+ } \
+ } \
+ } while (0)
+
+
+/* Both FROM and TO are mulitbyte characters. */
+
+#define SETUP_MULTIBYTE_RANGE(work_area, FROM, TO) \
+ do { \
+ int C0, C1, C2, I, USED = RANGE_TABLE_WORK_USED (work_area); \
+ \
+ SET_RANGE_TABLE_WORK_AREA ((work_area), (FROM), (TO)); \
+ for (C0 = (FROM); C0 <= (TO); C0++) \
+ { \
+ C1 = TRANSLATE (C0); \
+ if ((C2 = RE_CHAR_TO_UNIBYTE (C1)) >= 0 \
+ || (C1 != C0 && (C2 = RE_CHAR_TO_UNIBYTE (C0)) >= 0)) \
+ SET_LIST_BIT (C2); \
+ if (C1 >= (FROM) && C1 <= (TO)) \
+ continue; \
+ for (I = RANGE_TABLE_WORK_USED (work_area) - 2; I >= USED; I -= 2) \
+ { \
+ int from = RANGE_TABLE_WORK_ELT (work_area, I); \
+ int to = RANGE_TABLE_WORK_ELT (work_area, I + 1); \
+ \
+ if (C1 >= from - 1 && C1 <= to + 1) \
+ { \
+ if (C1 == from - 1) \
+ RANGE_TABLE_WORK_ELT (work_area, I)--; \
+ else if (C1 == to + 1) \
+ RANGE_TABLE_WORK_ELT (work_area, I + 1)++; \
+ break; \
+ } \
+ } \
+ if (I < USED) \
+ SET_RANGE_TABLE_WORK_AREA ((work_area), C1, C1); \
+ } \
+ } while (0)
+
+#endif /* emacs */
+