+/* Compile */
+#define RE_DEBUG_COMPILE_MASK 0x0000FF
+#define RE_DEBUG_COMPILE_PARSE 0x000001
+#define RE_DEBUG_COMPILE_OPTIMISE 0x000002
+#define RE_DEBUG_COMPILE_TRIE 0x000004
+#define RE_DEBUG_COMPILE_DUMP 0x000008
+#define RE_DEBUG_COMPILE_FLAGS 0x000010
+
+/* Execute */
+#define RE_DEBUG_EXECUTE_MASK 0x00FF00
+#define RE_DEBUG_EXECUTE_INTUIT 0x000100
+#define RE_DEBUG_EXECUTE_MATCH 0x000200
+#define RE_DEBUG_EXECUTE_TRIE 0x000400
+
+/* Extra */
+#define RE_DEBUG_EXTRA_MASK 0xFF0000
+#define RE_DEBUG_EXTRA_TRIE 0x010000
+#define RE_DEBUG_EXTRA_OFFSETS 0x020000
+#define RE_DEBUG_EXTRA_OFFDEBUG 0x040000
+#define RE_DEBUG_EXTRA_STATE 0x080000
+#define RE_DEBUG_EXTRA_OPTIMISE 0x100000
+#define RE_DEBUG_EXTRA_BUFFERS 0x400000
+#define RE_DEBUG_EXTRA_GPOS 0x800000
+/* combined */
+#define RE_DEBUG_EXTRA_STACK 0x280000
+
+#define RE_DEBUG_FLAG(x) (re_debug_flags & x)
+/* Compile */
+#define DEBUG_COMPILE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_COMPILE_MASK) x )
+#define DEBUG_PARSE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_COMPILE_PARSE) x )
+#define DEBUG_OPTIMISE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_COMPILE_OPTIMISE) x )
+#define DEBUG_PARSE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_COMPILE_PARSE) x )
+#define DEBUG_DUMP_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_COMPILE_DUMP) x )
+#define DEBUG_TRIE_COMPILE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_COMPILE_TRIE) x )
+#define DEBUG_FLAGS_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_COMPILE_FLAGS) x )
+/* Execute */
+#define DEBUG_EXECUTE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXECUTE_MASK) x )
+#define DEBUG_INTUIT_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXECUTE_INTUIT) x )
+#define DEBUG_MATCH_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXECUTE_MATCH) x )
+#define DEBUG_TRIE_EXECUTE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXECUTE_TRIE) x )
+
+/* Extra */
+#define DEBUG_EXTRA_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_MASK) x )
+#define DEBUG_OFFSETS_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_OFFSETS) x )
+#define DEBUG_STATE_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_STATE) x )
+#define DEBUG_STACK_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_STACK) x )
+#define DEBUG_BUFFERS_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_BUFFERS) x )
+
+#define DEBUG_OPTIMISE_MORE_r(x) DEBUG_r( \
+ if ((RE_DEBUG_EXTRA_OPTIMISE|RE_DEBUG_COMPILE_OPTIMISE) == \
+ (re_debug_flags & (RE_DEBUG_EXTRA_OPTIMISE|RE_DEBUG_COMPILE_OPTIMISE)) ) x )
+#define MJD_OFFSET_DEBUG(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_OFFDEBUG) \
+ Perl_warn_nocontext x )
+#define DEBUG_TRIE_COMPILE_MORE_r(x) DEBUG_TRIE_COMPILE_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_TRIE) x )
+#define DEBUG_TRIE_EXECUTE_MORE_r(x) DEBUG_TRIE_EXECUTE_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_TRIE) x )
+
+#define DEBUG_TRIE_r(x) DEBUG_r( \
+ if (re_debug_flags & (RE_DEBUG_COMPILE_TRIE \
+ | RE_DEBUG_EXECUTE_TRIE )) x )
+#define DEBUG_GPOS_r(x) DEBUG_r( \
+ if (re_debug_flags & RE_DEBUG_EXTRA_GPOS) x )
+
+/* initialization */
+/* get_sv() can return NULL during global destruction. re_debug_flags can get
+ * clobbered by a longjmp, so must be initialized */
+#define GET_RE_DEBUG_FLAGS DEBUG_r({ \
+ SV * re_debug_flags_sv = NULL; \
+ re_debug_flags = 0; \
+ re_debug_flags_sv = get_sv(RE_DEBUG_FLAGS, 1); \
+ if (re_debug_flags_sv) { \
+ if (!SvIOK(re_debug_flags_sv)) \
+ sv_setuv(re_debug_flags_sv, RE_DEBUG_COMPILE_DUMP | RE_DEBUG_EXECUTE_MASK ); \
+ re_debug_flags=SvIV(re_debug_flags_sv); \
+ }\
+})
+