Index: EcnlProtoTool/trunk/onigmo-6.1.3/src/regcomp.c
===================================================================
--- EcnlProtoTool/trunk/onigmo-5.15.0/src/regcomp.c	(revision 321)
+++ EcnlProtoTool/trunk/onigmo-6.1.3/src/regcomp.c	(revision 331)
@@ -4,5 +4,5 @@
 /*-
  * Copyright (c) 2002-2013  K.Kosako  <sndgk393 AT ybb DOT ne DOT jp>
- * Copyright (c) 2011-2014  K.Takata  <kentkt AT csc DOT jp>
+ * Copyright (c) 2011-2016  K.Takata  <kentkt AT csc DOT jp>
  * All rights reserved.
  *
@@ -31,13 +31,4 @@
 #include "regparse.h"
 
-#if defined(USE_MULTI_THREAD_SYSTEM) \
-  && defined(USE_DEFAULT_MULTI_THREAD_SYSTEM)
-#ifdef _WIN32
-CRITICAL_SECTION gOnigMutex;
-#else
-pthread_mutex_t gOnigMutex;
-#endif
-#endif
-
 OnigCaseFoldType OnigDefaultCaseFoldFlag = ONIGENC_CASE_FOLD_MIN;
 
@@ -264,4 +255,5 @@
 }
 
+#if 0
 static int
 add_pointer(regex_t* reg, void* addr)
@@ -272,4 +264,5 @@
   return 0;
 }
+#endif
 
 static int
@@ -483,5 +476,5 @@
 
   p = prev = sn->s;
-  prev_len = enclen(enc, p);
+  prev_len = enclen(enc, p, sn->end);
   p += prev_len;
   blen = prev_len;
@@ -489,5 +482,5 @@
 
   for (; p < sn->end; ) {
-    len = enclen(enc, p);
+    len = enclen(enc, p, sn->end);
     if (len == prev_len || ambig) {
       blen += len;
@@ -532,10 +525,10 @@
 
   p = prev = sn->s;
-  prev_len = enclen(enc, p);
+  prev_len = enclen(enc, p, end);
   p += prev_len;
   blen = prev_len;
 
   for (; p < end; ) {
-    len = enclen(enc, p);
+    len = enclen(enc, p, end);
     if (len == prev_len || ambig) {
       blen += len;
@@ -592,9 +585,4 @@
   int len;
 
-  if (IS_NCCLASS_SHARE(cc)) {
-    len = SIZE_OPCODE + SIZE_POINTER;
-    return len;
-  }
-
   if (IS_NULL(cc->mbuf)) {
     len = SIZE_OPCODE + SIZE_BITSET;
@@ -621,10 +609,4 @@
 {
   int r;
-
-  if (IS_NCCLASS_SHARE(cc)) {
-    add_opcode(reg, OP_CCLASS_NODE);
-    r = add_pointer(reg, cc);
-    return r;
-  }
 
   if (IS_NULL(cc->mbuf)) {
@@ -639,7 +621,7 @@
     if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
       if (IS_NCCLASS_NOT(cc))
-        add_opcode(reg, OP_CCLASS_MB_NOT);
+	add_opcode(reg, OP_CCLASS_MB_NOT);
       else
-        add_opcode(reg, OP_CCLASS_MB);
+	add_opcode(reg, OP_CCLASS_MB);
 
       r = add_multi_byte_cclass(cc->mbuf, reg);
@@ -647,7 +629,7 @@
     else {
       if (IS_NCCLASS_NOT(cc))
-        add_opcode(reg, OP_CCLASS_MIX_NOT);
+	add_opcode(reg, OP_CCLASS_MIX_NOT);
       else
-        add_opcode(reg, OP_CCLASS_MIX);
+	add_opcode(reg, OP_CCLASS_MIX);
 
       r = add_bitset(reg, cc->bs);
@@ -761,7 +743,7 @@
     if (qn->greedy && infinite) {
       if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON)
-        return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower + cklen;
+	return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower + cklen;
       else
-        return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower + cklen;
+	return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower + cklen;
     }
   }
@@ -990,7 +972,7 @@
     if (qn->greedy && infinite) {
       if (IS_NOT_NULL(qn->next_head_exact))
-        return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower;
+	return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower;
       else
-        return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower;
+	return SIZE_OP_ANYCHAR_STAR + tlen * qn->lower;
     }
   }
@@ -1011,7 +993,10 @@
 
     if (qn->greedy) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
       if (IS_NOT_NULL(qn->head_exact))
 	len += SIZE_OP_PUSH_OR_JUMP_EXACT1 + mod_tlen + SIZE_OP_JUMP;
-      else if (IS_NOT_NULL(qn->next_head_exact))
+      else
+#endif
+      if (IS_NOT_NULL(qn->next_head_exact))
 	len += SIZE_OP_PUSH_IF_PEEK_NEXT + mod_tlen + SIZE_OP_JUMP;
       else
@@ -1079,7 +1064,10 @@
     if (qn->lower == 1 && tlen > QUANTIFIER_EXPAND_LIMIT_SIZE) {
       if (qn->greedy) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
 	if (IS_NOT_NULL(qn->head_exact))
 	  r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_OR_JUMP_EXACT1);
-	else if (IS_NOT_NULL(qn->next_head_exact))
+	else
+#endif
+	if (IS_NOT_NULL(qn->next_head_exact))
 	  r = add_opcode_rel_addr(reg, OP_JUMP, SIZE_OP_PUSH_IF_PEEK_NEXT);
 	else
@@ -1097,4 +1085,5 @@
 
     if (qn->greedy) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
       if (IS_NOT_NULL(qn->head_exact)) {
 	r = add_opcode_rel_addr(reg, OP_PUSH_OR_JUMP_EXACT1,
@@ -1107,5 +1096,7 @@
 	-(mod_tlen + (int )SIZE_OP_JUMP + (int )SIZE_OP_PUSH_OR_JUMP_EXACT1));
       }
-      else if (IS_NOT_NULL(qn->next_head_exact)) {
+      else
+#endif
+      if (IS_NOT_NULL(qn->next_head_exact)) {
 	r = add_opcode_rel_addr(reg, OP_PUSH_IF_PEEK_NEXT,
 				mod_tlen + SIZE_OP_JUMP);
@@ -1244,4 +1235,9 @@
 		? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
     }
+    else if (IS_ENCLOSE_RECURSION(node)) {
+      len = SIZE_OP_MEMORY_START_PUSH;
+      len += tlen + (BIT_STATUS_AT(reg->bt_mem_end, node->regnum)
+		     ? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_REC);
+    }
     else
 #endif
@@ -1289,4 +1285,8 @@
       return ONIGERR_PARSER_BUG;
     }
+    break;
+
+  case ENCLOSE_ABSENT:
+    len = SIZE_OP_PUSH_ABSENT_POS + SIZE_OP_ABSENT + tlen + SIZE_OP_ABSENT_END;
     break;
 
@@ -1355,4 +1355,12 @@
       r = add_opcode(reg, OP_RETURN);
     }
+    else if (IS_ENCLOSE_RECURSION(node)) {
+      if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
+	r = add_opcode(reg, OP_MEMORY_END_PUSH_REC);
+      else
+	r = add_opcode(reg, OP_MEMORY_END_REC);
+      if (r) return r;
+      r = add_mem_num(reg, node->regnum);
+    }
     else
 #endif
@@ -1427,4 +1435,17 @@
     break;
 
+  case ENCLOSE_ABSENT:
+    len = compile_length_tree(node->target, reg);
+    if (len < 0) return len;
+
+    r = add_opcode(reg, OP_PUSH_ABSENT_POS);
+    if (r) return r;
+    r = add_opcode_rel_addr(reg, OP_ABSENT, len + SIZE_OP_ABSENT_END);
+    if (r) return r;
+    r = compile_tree(node->target, reg);
+    if (r) return r;
+    r = add_opcode(reg, OP_ABSENT_END);
+    break;
+
   default:
     return ONIGERR_TYPE_BUG;
@@ -1480,7 +1501,4 @@
   case ANCHOR_SEMI_END_BUF:   r = add_opcode(reg, OP_SEMI_END_BUF);   break;
   case ANCHOR_BEGIN_POSITION: r = add_opcode(reg, OP_BEGIN_POSITION); break;
-
-  /* used for implicit anchor optimization: /.*a/ ==> /(?:^|\G).*a/ */
-  case ANCHOR_ANYCHAR_STAR:   r = add_opcode(reg, OP_BEGIN_POS_OR_LINE); break;
 
   case ANCHOR_WORD_BOUND:
@@ -1590,8 +1608,8 @@
       len = 0;
       do {
-        r = compile_length_tree(NCAR(node), reg);
-        if (r < 0) return r;
-        len += r;
-        n++;
+	r = compile_length_tree(NCAR(node), reg);
+	if (r < 0) return r;
+	len += r;
+	n++;
       } while (IS_NOT_NULL(node = NCDR(node)));
       r = len;
@@ -1622,5 +1640,5 @@
 #ifdef USE_BACKREF_WITH_LEVEL
       if (IS_BACKREF_NEST_LEVEL(br)) {
-        r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
+	r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
             SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
       }
@@ -1786,10 +1804,10 @@
 	int* p;
 
-        if (IS_IGNORECASE(reg->options)) {
-          r = add_opcode(reg, OP_BACKREF_MULTI_IC);
-        }
-        else {
-          r = add_opcode(reg, OP_BACKREF_MULTI);
-        }
+	if (IS_IGNORECASE(reg->options)) {
+	  r = add_opcode(reg, OP_BACKREF_MULTI_IC);
+	}
+	else {
+	  r = add_opcode(reg, OP_BACKREF_MULTI);
+	}
 	if (r) return r;
 
@@ -1885,15 +1903,6 @@
 
   case NT_ANCHOR:
-    {
-      AnchorNode* an = NANCHOR(node);
-      switch (an->type) {
-      case ANCHOR_PREC_READ:
-      case ANCHOR_PREC_READ_NOT:
-      case ANCHOR_LOOK_BEHIND:
-      case ANCHOR_LOOK_BEHIND_NOT:
-	r = noname_disable_map(&(an->target), map, counter);
-	break;
-      }
-    }
+    if (NANCHOR(node)->target)
+      r = noname_disable_map(&(NANCHOR(node)->target), map, counter);
     break;
 
@@ -1952,5 +1961,5 @@
       EncloseNode* en = NENCLOSE(node);
       if (en->type == ENCLOSE_CONDITION)
-        en->regnum = map[en->regnum].new_val;
+	en->regnum = map[en->regnum].new_val;
       r = renumber_by_map(en->target, map);
     }
@@ -1962,15 +1971,6 @@
 
   case NT_ANCHOR:
-    {
-      AnchorNode* an = NANCHOR(node);
-      switch (an->type) {
-      case ANCHOR_PREC_READ:
-      case ANCHOR_PREC_READ_NOT:
-      case ANCHOR_LOOK_BEHIND:
-      case ANCHOR_LOOK_BEHIND_NOT:
-	r = renumber_by_map(an->target, map);
-	break;
-      }
-    }
+    if (NANCHOR(node)->target)
+      r = renumber_by_map(NANCHOR(node)->target, map);
     break;
 
@@ -2006,4 +2006,9 @@
     break;
 
+  case NT_ANCHOR:
+    if (NANCHOR(node)->target)
+      r = numbered_ref_check(NANCHOR(node)->target);
+    break;
+
   default:
     break;
@@ -2014,9 +2019,11 @@
 
 static int
-disable_noname_group_capture_(Node** root, regex_t* reg, ScanEnv* env, GroupNumRemap* map)
+disable_noname_group_capture(Node** root, regex_t* reg, ScanEnv* env)
 {
   int r, i, pos, counter;
   BitStatusType loc;
-
+  GroupNumRemap* map;
+
+  map = (GroupNumRemap* )xalloca(sizeof(GroupNumRemap) * (env->num_mem + 1));
   CHECK_NULL_RETURN_MEMERR(map);
   for (i = 1; i <= env->num_mem; i++) {
@@ -2049,13 +2056,4 @@
 
   return onig_renumber_name_table(reg, map);
-}
-
-static int
-disable_noname_group_capture(Node** root, regex_t* reg, ScanEnv* env)
-{
-	GroupNumRemap* map = (GroupNumRemap*)xmalloc(sizeof(GroupNumRemap) * (env->num_mem + 1));
-	int ret = disable_noname_group_capture_(root, reg, env, map);
-	xfree(map);
-	return ret;
 }
 #endif /* USE_NAMED_GROUP */
@@ -2099,5 +2097,5 @@
     break;
 
-#ifdef USE_SUBEXP_CALL
+# ifdef USE_SUBEXP_CALL
   case NT_CALL:
     if (IS_CALL_RECURSION(NCALL(node))) {
@@ -2107,5 +2105,5 @@
       r = quantifiers_memory_node_info(NCALL(node)->target);
     break;
-#endif
+# endif
 
   case NT_QTFR:
@@ -2129,4 +2127,5 @@
       case ENCLOSE_STOP_BACKTRACK:
       case ENCLOSE_CONDITION:
+      case ENCLOSE_ABSENT:
 	r = quantifiers_memory_node_info(en->target);
 	break;
@@ -2246,20 +2245,28 @@
       switch (en->type) {
       case ENCLOSE_MEMORY:
-#ifdef USE_SUBEXP_CALL
-	if (IS_ENCLOSE_MIN_FIXED(en))
-	  *min = en->min_len;
-	else {
-	  r = get_min_match_length(en->target, min, env);
-	  if (r == 0) {
-	    en->min_len = *min;
-	    SET_ENCLOSE_STATUS(node, NST_MIN_FIXED);
+        if (IS_ENCLOSE_MIN_FIXED(en))
+          *min = en->min_len;
+        else {
+	  if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
+	    *min = 0;  /* recursive */
+	  else {
+	    SET_ENCLOSE_STATUS(node, NST_MARK1);
+	    r = get_min_match_length(en->target, min, env);
+	    CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
+	    if (r == 0) {
+	      en->min_len = *min;
+	      SET_ENCLOSE_STATUS(node, NST_MIN_FIXED);
+	    }
 	  }
-	}
-	break;
-#endif
+        }
+        break;
+
       case ENCLOSE_OPTION:
       case ENCLOSE_STOP_BACKTRACK:
       case ENCLOSE_CONDITION:
 	r = get_min_match_length(en->target, min, env);
+	break;
+
+      case ENCLOSE_ABSENT:
 	break;
       }
@@ -2364,20 +2371,28 @@
       switch (en->type) {
       case ENCLOSE_MEMORY:
-#ifdef USE_SUBEXP_CALL
 	if (IS_ENCLOSE_MAX_FIXED(en))
 	  *max = en->max_len;
 	else {
-	  r = get_max_match_length(en->target, max, env);
-	  if (r == 0) {
-	    en->max_len = *max;
-	    SET_ENCLOSE_STATUS(node, NST_MAX_FIXED);
+	  if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
+	    *max = ONIG_INFINITE_DISTANCE;
+	  else {
+	    SET_ENCLOSE_STATUS(node, NST_MARK1);
+	    r = get_max_match_length(en->target, max, env);
+	    CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
+	    if (r == 0) {
+	      en->max_len = *max;
+	      SET_ENCLOSE_STATUS(node, NST_MAX_FIXED);
+	    }
 	  }
 	}
 	break;
-#endif
+
       case ENCLOSE_OPTION:
       case ENCLOSE_STOP_BACKTRACK:
       case ENCLOSE_CONDITION:
 	r = get_max_match_length(en->target, max, env);
+	break;
+
+      case ENCLOSE_ABSENT:
 	break;
       }
@@ -2445,5 +2460,5 @@
       UChar *s = sn->s;
       while (s < sn->end) {
-	s += enclen(reg->enc, s);
+	s += enclen(reg->enc, s, sn->end);
 	(*len)++;
       }
@@ -2504,4 +2519,5 @@
 	r = get_char_length_tree1(en->target, reg, len, level);
 	break;
+      case ENCLOSE_ABSENT:
       default:
 	break;
@@ -2630,8 +2646,8 @@
 	    v = BITSET_AT(xc->bs, i);
 	    if ((v != 0 && !IS_NCCLASS_NOT(xc)) ||
-                (v == 0 && IS_NCCLASS_NOT(xc))) {
+		(v == 0 && IS_NCCLASS_NOT(xc))) {
 	      v = BITSET_AT(yc->bs, i);
 	      if ((v != 0 && !IS_NCCLASS_NOT(yc)) ||
-                  (v == 0 && IS_NCCLASS_NOT(yc)))
+		  (v == 0 && IS_NCCLASS_NOT(yc)))
 		return 0;
 	    }
@@ -2683,22 +2699,22 @@
 
       case NT_CCLASS:
-        {
-          CClassNode* cc = NCCLASS(y);
-
-          code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
-                                     xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
-          return (onig_is_code_in_cc(reg->enc, code, cc) != 0 ? 0 : 1);
-        }
-        break;
+	{
+	  CClassNode* cc = NCCLASS(y);
+
+	  code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
+				     xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
+	  return (onig_is_code_in_cc(reg->enc, code, cc) != 0 ? 0 : 1);
+	}
+	break;
 
       case NT_STR:
-        {
-          UChar *q;
-          StrNode* ys = NSTR(y);
-          len = NSTRING_LEN(x);
-          if (len > NSTRING_LEN(y)) len = NSTRING_LEN(y);
-          if (NSTRING_IS_AMBIG(x) || NSTRING_IS_AMBIG(y)) {
-            /* tiny version */
-            return 0;
+	{
+	  UChar *q;
+	  StrNode* ys = NSTR(y);
+	  len = NSTRING_LEN(x);
+	  if (len > NSTRING_LEN(y)) len = NSTRING_LEN(y);
+	  if (NSTRING_IS_AMBIG(x) || NSTRING_IS_AMBIG(y)) {
+	    /* tiny version */
+	    return 0;
 	  }
 	  else {
@@ -2711,5 +2727,5 @@
 
       default:
-        break;
+	break;
       }
     }
@@ -2768,7 +2784,9 @@
       QtfrNode* qn = NQTFR(node);
       if (qn->lower > 0) {
+#ifdef USE_OP_PUSH_OR_JUMP_EXACT
 	if (IS_NOT_NULL(qn->head_exact))
 	  n = qn->head_exact;
 	else
+#endif
 	  n = get_head_value_node(qn->target, exact, reg);
       }
@@ -2795,4 +2813,7 @@
 	n = get_head_value_node(en->target, exact, reg);
 	break;
+
+      case ENCLOSE_ABSENT:
+	break;
       }
     }
@@ -2862,6 +2883,6 @@
 #ifdef USE_SUBEXP_CALL
 
-#define RECURSION_EXIST       1
-#define RECURSION_INFINITE    2
+# define RECURSION_EXIST       1
+# define RECURSION_INFINITE    2
 
 static int
@@ -3063,5 +3084,5 @@
 subexp_recursive_check_trav(Node* node, ScanEnv* env)
 {
-#define FOUND_CALLED_NODE    1
+# define FOUND_CALLED_NODE    1
 
   int type;
@@ -3164,5 +3185,5 @@
 	int gnum = cn->group_num;
 
-#ifdef USE_NAMED_GROUP
+# ifdef USE_NAMED_GROUP
 	if (env->num_named > 0 &&
 	    IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
@@ -3170,5 +3191,5 @@
 	  return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
 	}
-#endif
+# endif
 	if (gnum > env->num_mem) {
 	  onig_scan_env_set_error_string(env,
@@ -3177,7 +3198,7 @@
 	}
 
-#ifdef USE_NAMED_GROUP
+# ifdef USE_NAMED_GROUP
       set_call_attr:
-#endif
+# endif
 	cn->target = nodes[cn->group_num];
 	if (IS_NULL(cn->target)) {
@@ -3190,10 +3211,10 @@
 	cn->unset_addr_list = env->unset_addr_list;
       }
-#ifdef USE_NAMED_GROUP
-#ifdef USE_PERL_SUBEXP_CALL
+# ifdef USE_NAMED_GROUP
+#  ifdef USE_PERL_SUBEXP_CALL
       else if (cn->name == cn->name_end) {
 	goto set_call_attr;
       }
-#endif
+#  endif
       else {
 	int *refs;
@@ -3217,5 +3238,5 @@
 	}
       }
-#endif
+# endif
     }
     break;
@@ -3300,5 +3321,5 @@
 
 static int
-next_setup(Node* node, Node* next_node, int in_root, regex_t* reg)
+next_setup(Node* node, Node* next_node, regex_t* reg)
 {
   int type;
@@ -3334,30 +3355,8 @@
 	}
       }
-
-#ifndef ONIG_DONT_OPTIMIZE
-      if (NTYPE(node) == NT_QTFR && /* the type may be changed by above block */
-	  in_root && /* qn->lower == 0 && */
-	  NTYPE(qn->target) == NT_CANY &&
-	  ! IS_MULTILINE(reg->options)) {
-	/* implicit anchor: /.*a/ ==> /(?:^|\G).*a/ */
-	Node *np;
-	np = onig_node_new_list(NULL_NODE, NULL_NODE);
-	CHECK_NULL_RETURN_MEMERR(np);
-	swap_node(node, np);
-	NCDR(node) = onig_node_new_list(np, NULL_NODE);
-	if (IS_NULL(NCDR(node))) {
-	  onig_node_free(np);
-	  return ONIGERR_MEMORY;
-	}
-	np = onig_node_new_anchor(ANCHOR_ANYCHAR_STAR);   /* (?:^|\G) */
-	CHECK_NULL_RETURN_MEMERR(np);
-	NCAR(node) = np;
-      }
-#endif
     }
   }
   else if (type == NT_ENCLOSE) {
     EncloseNode* en = NENCLOSE(node);
-    in_root = 0;
     if (en->type == ENCLOSE_MEMORY) {
       node = en->target;
@@ -3516,27 +3515,27 @@
 
       if (q < end) {
-        r = expand_case_fold_make_rem_string(&rem, q, end, reg);
-        if (r != 0) {
-          onig_node_free(an);
-          goto mem_err2;
-        }
-
-        xnode = onig_node_list_add(NULL_NODE, snode);
-        if (IS_NULL(xnode)) {
-          onig_node_free(an);
-          onig_node_free(rem);
-          goto mem_err2;
-        }
-        if (IS_NULL(onig_node_list_add(xnode, rem))) {
-          onig_node_free(an);
-          onig_node_free(xnode);
-          onig_node_free(rem);
-          goto mem_err;
-        }
-
-        NCAR(an) = xnode;
+	r = expand_case_fold_make_rem_string(&rem, q, end, reg);
+	if (r != 0) {
+	  onig_node_free(an);
+	  goto mem_err2;
+	}
+
+	xnode = onig_node_list_add(NULL_NODE, snode);
+	if (IS_NULL(xnode)) {
+	  onig_node_free(an);
+	  onig_node_free(rem);
+	  goto mem_err2;
+	}
+	if (IS_NULL(onig_node_list_add(xnode, rem))) {
+	  onig_node_free(an);
+	  onig_node_free(xnode);
+	  onig_node_free(rem);
+	  goto mem_err;
+	}
+
+	NCAR(an) = xnode;
       }
       else {
-        NCAR(an) = snode;
+	NCAR(an) = snode;
       }
 
@@ -3592,5 +3591,5 @@
     }
 
-    len = enclen(reg->enc, p);
+    len = enclen(reg->enc, p, end);
 
     varlen = is_case_fold_variable_len(n, items, len);
@@ -3715,10 +3714,10 @@
 #ifdef USE_COMBINATION_EXPLOSION_CHECK
 
-#define CEC_THRES_NUM_BIG_REPEAT         512
-#define CEC_INFINITE_NUM          0x7fffffff
-
-#define CEC_IN_INFINITE_REPEAT    (1<<0)
-#define CEC_IN_FINITE_REPEAT      (1<<1)
-#define CEC_CONT_BIG_REPEAT       (1<<2)
+# define CEC_THRES_NUM_BIG_REPEAT         512
+# define CEC_INFINITE_NUM          0x7fffffff
+
+# define CEC_IN_INFINITE_REPEAT    (1<<0)
+# define CEC_IN_FINITE_REPEAT      (1<<1)
+# define CEC_CONT_BIG_REPEAT       (1<<2)
 
 static int
@@ -3836,5 +3835,5 @@
     break;
 
-#ifdef USE_SUBEXP_CALL
+# ifdef USE_SUBEXP_CALL
   case NT_CALL:
     if (IS_CALL_RECURSION(NCALL(node)))
@@ -3843,5 +3842,5 @@
       r = setup_comb_exp_check(NCALL(node)->target, state, env);
     break;
-#endif
+# endif
 
   default:
@@ -3857,5 +3856,6 @@
 #define IN_REPEAT     (1<<2)
 #define IN_VAR_REPEAT (1<<3)
-#define IN_ROOT       (1<<4)
+#define IN_CALL       (1<<4)
+#define IN_RECCALL    (1<<5)
 
 /* setup_tree does the following work.
@@ -3872,7 +3872,5 @@
   int type;
   int r = 0;
-  int in_root = state & IN_ROOT;
-
-  state &= ~IN_ROOT;
+
 restart:
   type = NTYPE(node);
@@ -3881,14 +3879,10 @@
     {
       Node* prev = NULL_NODE;
-      int prev_in_root = 0;
-      state |= in_root;
       do {
 	r = setup_tree(NCAR(node), reg, state, env);
 	if (IS_NOT_NULL(prev) && r == 0) {
-	  r = next_setup(prev, NCAR(node), prev_in_root, reg);
+	  r = next_setup(prev, NCAR(node), reg);
 	}
 	prev = NCAR(node);
-	prev_in_root = state & IN_ROOT;
-	state &= ~IN_ROOT;
       } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
     }
@@ -3947,5 +3941,5 @@
 
       if ((state & IN_REPEAT) != 0) {
-        qn->state |= NST_IN_REPEAT;
+	qn->state |= NST_IN_REPEAT;
       }
 
@@ -4054,5 +4048,4 @@
 	{
 	  OnigOptionType options = reg->options;
-	  state |= in_root;
 	  reg->options = NENCLOSE(node)->option;
 	  r = setup_tree(NENCLOSE(node)->target, reg, state, env);
@@ -4062,10 +4055,16 @@
 
       case ENCLOSE_MEMORY:
-	if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT)) != 0) {
+	if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT | IN_CALL)) != 0) {
 	  BIT_STATUS_ON_AT(env->bt_mem_start, en->regnum);
 	  /* SET_ENCLOSE_STATUS(node, NST_MEM_IN_ALT_NOT); */
 	}
-        r = setup_tree(en->target, reg, state, env);
-        break;
+	if (IS_ENCLOSE_CALLED(en))
+	  state |= IN_CALL;
+	if (IS_ENCLOSE_RECURSION(en))
+	  state |= IN_RECCALL;
+	else if ((state & IN_RECCALL) != 0)
+	  SET_CALL_RECURSION(node);
+	r = setup_tree(en->target, reg, state, env);
+	break;
 
       case ENCLOSE_STOP_BACKTRACK:
@@ -4094,4 +4093,10 @@
 	}
 #endif
+	if (NENCLOSE(node)->regnum > env->num_mem)
+	  return ONIGERR_INVALID_BACKREF;
+	r = setup_tree(NENCLOSE(node)->target, reg, state, env);
+	break;
+
+      case ENCLOSE_ABSENT:
 	r = setup_tree(NENCLOSE(node)->target, reg, state, env);
 	break;
@@ -4137,8 +4142,8 @@
 	  if (r < 0) return r;
 	  if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
-	  r = setup_look_behind(node, reg, env);
-	  if (r != 0) return r;
 	  if (NTYPE(node) != NT_ANCHOR) goto restart;
 	  r = setup_tree(an->target, reg, state, env);
+	  if (r != 0) return r;
+	  r = setup_look_behind(node, reg, env);
 	}
 	break;
@@ -4150,8 +4155,8 @@
 	  if (r < 0) return r;
 	  if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
-	  r = setup_look_behind(node, reg, env);
-	  if (r != 0) return r;
 	  if (NTYPE(node) != NT_ANCHOR) goto restart;
 	  r = setup_tree(an->target, reg, (state | IN_NOT), env);
+	  if (r != 0) return r;
+	  r = setup_look_behind(node, reg, env);
 	}
 	break;
@@ -4189,5 +4194,7 @@
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
-      clen = enclen(enc, p);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
@@ -4207,4 +4214,8 @@
   }
   else {
+# if OPT_EXACT_MAXLEN < ONIG_CHAR_TABLE_SIZE
+    /* This should not happen. */
+    return ONIGERR_TYPE_BUG;
+# else
     if (IS_NULL(*int_skip)) {
       *int_skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
@@ -4219,5 +4230,7 @@
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
-      clen = enclen(enc, p);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
@@ -4235,4 +4248,5 @@
       }
     }
+# endif
   }
   return 0;
@@ -4262,5 +4276,7 @@
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
-      clen = enclen(enc, p);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
@@ -4280,4 +4296,8 @@
   }
   else {
+# if OPT_EXACT_MAXLEN < ONIG_CHAR_TABLE_SIZE
+    /* This should not happen. */
+    return ONIGERR_TYPE_BUG;
+# else
     if (IS_NULL(*int_skip)) {
       *int_skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
@@ -4292,5 +4312,7 @@
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
-      clen = enclen(enc, p);
+      clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
@@ -4308,10 +4330,9 @@
       }
     }
+# endif
   }
   return 0;
 }
 #endif /* USE_SUNDAY_QUICK_SEARCH */
-
-#define OPT_EXACT_MAXLEN   24
 
 typedef struct {
@@ -4604,5 +4625,5 @@
   end = p + add->len;
   for (i = to->len; p < end; ) {
-    len = enclen(enc, p);
+    len = enclen(enc, p, end);
     if (i + len > OPT_EXACT_MAXLEN) break;
     for (j = 0; j < len && p < end; j++)
@@ -4626,5 +4647,5 @@
 
   for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
-    len = enclen(enc, p);
+    len = enclen(enc, p, end);
     if (i + len > OPT_EXACT_MAXLEN) break;
     for (j = 0; j < len && p < end; j++)
@@ -4652,5 +4673,5 @@
   for (i = 0; i < to->len && i < add->len; ) {
     if (to->s[i] != add->s[i]) break;
-    len = enclen(env->enc, to->s + i);
+    len = enclen(env->enc, to->s + i, to->s + to->len);
 
     for (j = 1; j < len; j++) {
@@ -4984,12 +5005,12 @@
 	  add_char_opt_map_info(&opt->map, *(sn->s), env->enc);
 	}
-        set_mml(&opt->len, slen, slen);
+	set_mml(&opt->len, slen, slen);
       }
       else {
-        OnigDistance max;
+	OnigDistance max;
 
 	if (NSTRING_IS_DONT_GET_OPT_INFO(node)) {
-          int n = onigenc_strlen(env->enc, sn->s, sn->end);
-          max = ONIGENC_MBC_MAXLEN_DIST(env->enc) * n;
+	  int n = onigenc_strlen(env->enc, sn->s, sn->end);
+	  max = ONIGENC_MBC_MAXLEN_DIST(env->enc) * n;
 	}
 	else {
@@ -5007,5 +5028,5 @@
 	}
 
-        set_mml(&opt->len, slen, max);
+	set_mml(&opt->len, slen, max);
       }
 
@@ -5023,5 +5044,5 @@
 
       if (IS_NOT_NULL(cc->mbuf) || IS_NCCLASS_NOT(cc)) {
-        OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
+	OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
 	OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
 
@@ -5029,10 +5050,10 @@
       }
       else {
-        for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
-          z = BITSET_AT(cc->bs, i);
-          if ((z && !IS_NCCLASS_NOT(cc)) || (!z && IS_NCCLASS_NOT(cc))) {
-            add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
-          }
-        }
+	for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+	  z = BITSET_AT(cc->bs, i);
+	  if ((z && !IS_NCCLASS_NOT(cc)) || (!z && IS_NCCLASS_NOT(cc))) {
+	    add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
+	  }
+	}
 	set_mml(&opt->len, 1, 1);
       }
@@ -5048,5 +5069,5 @@
 
       if (max == 1) {
-        min = 1;
+	min = 1;
 
 	maxcode = NCTYPE(node)->ascii_range ? 0x80 : SINGLE_BYTE_SIZE;
@@ -5071,5 +5092,5 @@
       }
       else {
-        min = ONIGENC_MBC_MINLEN(env->enc);
+	min = ONIGENC_MBC_MINLEN(env->enc);
       }
       set_mml(&opt->len, min, max);
@@ -5190,5 +5211,5 @@
 	    if (nopt.exb.reach_end) {
 	      for (i = 2; i <= qn->lower &&
-		          ! is_full_opt_exact_info(&opt->exb); i++) {
+			  ! is_full_opt_exact_info(&opt->exb); i++) {
 		concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
 	      }
@@ -5261,4 +5282,8 @@
 	r = optimize_node_left(en->target, opt, env);
 	break;
+
+      case ENCLOSE_ABSENT:
+	set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
+	break;
       }
     }
@@ -5312,9 +5337,12 @@
     if (e->len >= 3 || (e->len >= 2 && allow_reverse)) {
       r = set_bm_skip(reg->exact, reg->exact_end, reg,
-	              reg->map, &(reg->int_map), 0);
-      if (r) return r;
-
-      reg->optimize = (allow_reverse != 0
+		      reg->map, &(reg->int_map), 0);
+      if (r == 0) {
+	reg->optimize = (allow_reverse != 0
 		       ? ONIG_OPTIMIZE_EXACT_BM : ONIG_OPTIMIZE_EXACT_BM_NOT_REV);
+      }
+      else {
+	reg->optimize = ONIG_OPTIMIZE_EXACT;
+      }
     }
     else {
@@ -5381,4 +5409,7 @@
         ANCHOR_BEGIN_POSITION | ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML |
         ANCHOR_LOOK_BEHIND);
+
+  if ((opt.anc.left_anchor & (ANCHOR_LOOK_BEHIND | ANCHOR_PREC_READ_NOT)) != 0)
+    reg->anchor &= ~ANCHOR_ANYCHAR_STAR_ML;
 
   reg->anchor |= opt.anc.right_anchor & (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF |
@@ -5455,5 +5486,5 @@
       }
 
-      p += enclen(enc, p);
+      p += enclen(enc, p, end);
     }
   }
@@ -5574,12 +5605,12 @@
       for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++) {
 	if (reg->map[i] != 0) {
-          if (c > 0)  fputs(", ", f);
-          c++;
-          if (ONIGENC_MBC_MAXLEN(reg->enc) == 1 &&
-              ONIGENC_IS_CODE_PRINT(reg->enc, (OnigCodePoint )i))
-            fputc(i, f);
-          else
-            fprintf(f, "%d", i);
-        }
+	  if (c > 0)  fputs(", ", f);
+	  c++;
+	  if (ONIGENC_MBC_MAXLEN(reg->enc) == 1 &&
+	      ONIGENC_IS_CODE_PRINT(reg->enc, (OnigCodePoint )i))
+	    fputc(i, f);
+	  else
+	    fprintf(f, "%d", i);
+	}
       }
       fprintf(f, "]\n");
@@ -5616,4 +5647,5 @@
 }
 
+#ifdef RUBY
 size_t
 onig_memsize(const regex_t *reg)
@@ -5639,7 +5671,7 @@
     return size;
 }
+#endif
 
 #define REGEX_TRANSFER(to,from) do {\
-  (to)->state = ONIG_STATE_MODIFY;\
   onig_free_body(to);\
   xmemcpy(to, from, sizeof(regex_t));\
@@ -5647,55 +5679,37 @@
 } while (0)
 
+#if 0
 extern void
 onig_transfer(regex_t* to, regex_t* from)
 {
-  THREAD_ATOMIC_START;
   REGEX_TRANSFER(to, from);
-  THREAD_ATOMIC_END;
-}
-
-#define REGEX_CHAIN_HEAD(reg) do {\
-  while (IS_NOT_NULL((reg)->chain)) {\
-    (reg) = (reg)->chain;\
-  }\
-} while (0)
-
-extern void
-onig_chain_link_add(regex_t* to, regex_t* add)
-{
-  THREAD_ATOMIC_START;
-  REGEX_CHAIN_HEAD(to);
-  to->chain = add;
-  THREAD_ATOMIC_END;
-}
-
-extern void
-onig_chain_reduce(regex_t* reg)
-{
-  regex_t *head, *prev;
-
-  prev = reg;
-  head = prev->chain;
-  if (IS_NOT_NULL(head)) {
-    reg->state = ONIG_STATE_MODIFY;
-    while (IS_NOT_NULL(head->chain)) {
-      prev = head;
-      head = head->chain;
-    }
-    prev->chain = (regex_t* )NULL;
-    REGEX_TRANSFER(reg, head);
-  }
-}
+}
+#endif
 
 #ifdef ONIG_DEBUG_COMPILE
-static void print_compiled_byte_code_list P_((FILE* f, regex_t* reg));
+static void print_compiled_byte_code_list(FILE* f, regex_t* reg);
 #endif
 #ifdef ONIG_DEBUG_PARSE_TREE
-static void print_tree P_((FILE* f, Node* node));
-#endif
-
+static void print_tree(FILE* f, Node* node);
+#endif
+
+#ifdef RUBY
 extern int
 onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
-	      OnigErrorInfo* einfo)
+	     OnigErrorInfo* einfo)
+{
+  return onig_compile_ruby(reg, pattern, pattern_end, einfo, NULL, 0);
+}
+#endif
+
+#ifdef RUBY
+extern int
+onig_compile_ruby(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
+	      OnigErrorInfo* einfo, const char *sourcefile, int sourceline)
+#else
+extern int
+onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
+	     OnigErrorInfo* einfo)
+#endif
 {
 #define COMPILE_INIT_SIZE  20
@@ -5711,5 +5725,8 @@
   if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
 
-  reg->state = ONIG_STATE_COMPILING;
+#ifdef RUBY
+  scan_env.sourcefile = sourcefile;
+  scan_env.sourceline = sourceline;
+#endif
 
 #ifdef ONIG_DEBUG
@@ -5737,4 +5754,11 @@
   r = onig_parse_make_tree(&root, pattern, pattern_end, reg, &scan_env);
   if (r != 0) goto err;
+
+#ifdef ONIG_DEBUG_PARSE_TREE
+# if 0
+  fprintf(stderr, "ORIGINAL PARSE TREE:\n");
+  print_tree(stderr, root);
+# endif
+#endif
 
 #ifdef USE_NAMED_GROUP
@@ -5770,5 +5794,5 @@
 #endif
 
-  r = setup_tree(root, reg, IN_ROOT, &scan_env);
+  r = setup_tree(root, reg, 0, &scan_env);
   if (r != 0) goto err_unset;
 
@@ -5789,15 +5813,15 @@
 #ifdef USE_COMBINATION_EXPLOSION_CHECK
   if (scan_env.backrefed_mem == 0
-#ifdef USE_SUBEXP_CALL
+# ifdef USE_SUBEXP_CALL
       || scan_env.num_call == 0
-#endif
+# endif
       ) {
     setup_comb_exp_check(root, 0, &scan_env);
-#ifdef USE_SUBEXP_CALL
+# ifdef USE_SUBEXP_CALL
     if (scan_env.has_recursion != 0) {
       scan_env.num_comb_exp_check = 0;
     }
     else
-#endif
+# endif
     if (scan_env.comb_exp_max_regnum > 0) {
       int i;
@@ -5853,12 +5877,11 @@
 
 #ifdef ONIG_DEBUG_COMPILE
-#ifdef USE_NAMED_GROUP
+# ifdef USE_NAMED_GROUP
   onig_print_names(stderr, reg);
-#endif
+# endif
   print_compiled_byte_code_list(stderr, reg);
 #endif
 
  end:
-  reg->state = ONIG_STATE_NORMAL;
   return r;
 
@@ -5884,25 +5907,4 @@
 }
 
-#ifdef USE_RECOMPILE_API
-extern int
-onig_recompile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
-	    OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax,
-	    OnigErrorInfo* einfo)
-{
-  int r;
-  regex_t *new_reg;
-
-  r = onig_new(&new_reg, pattern, pattern_end, option, enc, syntax, einfo);
-  if (r) return r;
-  if (ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
-    onig_transfer(reg, new_reg);
-  }
-  else {
-    onig_chain_link_add(reg, new_reg);
-  }
-  return 0;
-}
-#endif
-
 static int onig_inited = 0;
 
@@ -5910,5 +5912,5 @@
 onig_reg_init(regex_t* reg, OnigOptionType option,
 	      OnigCaseFoldType case_fold_flag,
-	      OnigEncoding enc, OnigSyntaxType* syntax)
+	      OnigEncoding enc, const OnigSyntaxType* syntax)
 {
   if (! onig_inited)
@@ -5925,6 +5927,4 @@
     return ONIGERR_INVALID_COMBINATION_OF_OPTIONS;
   }
-
-  (reg)->state = ONIG_STATE_MODIFY;
 
   if ((option & ONIG_OPTION_NEGATE_SINGLELINE) != 0) {
@@ -5956,5 +5956,5 @@
 onig_new_without_alloc(regex_t* reg, const UChar* pattern,
           const UChar* pattern_end, OnigOptionType option, OnigEncoding enc,
-          OnigSyntaxType* syntax, OnigErrorInfo* einfo)
+          const OnigSyntaxType* syntax, OnigErrorInfo* einfo)
 {
   int r;
@@ -5969,5 +5969,5 @@
 extern int
 onig_new(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
-	  OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax,
+	  OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax,
 	  OnigErrorInfo* einfo)
 {
@@ -5989,4 +5989,9 @@
 }
 
+extern int
+onig_initialize(OnigEncoding encodings[] ARG_UNUSED, int n ARG_UNUSED)
+{
+  return onig_init();
+}
 
 extern int
@@ -5996,8 +6001,9 @@
     return 0;
 
-  THREAD_SYSTEM_INIT;
-  THREAD_ATOMIC_START;
-
   onig_inited = 1;
+
+#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
+  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
 
   onigenc_init();
@@ -6008,5 +6014,4 @@
 #endif
 
-  THREAD_ATOMIC_END;
   return 0;
 }
@@ -6047,6 +6052,4 @@
 onig_end(void)
 {
-  THREAD_ATOMIC_START;
-
   exec_end_call_list();
 
@@ -6055,16 +6058,10 @@
 #endif
 
-#ifdef USE_SHARED_CCLASS_TABLE
-  onig_free_shared_cclass_table();
-#endif
-
-#ifdef USE_PARSE_TREE_NODE_RECYCLE
-  onig_free_node_list();
+#if defined(ONIG_DEBUG_MEMLEAK) && defined(_MSC_VER)
+  _CrtDumpMemoryLeaks();
 #endif
 
   onig_inited = 0;
 
-  THREAD_ATOMIC_END;
-  THREAD_SYSTEM_END;
   return 0;
 }
@@ -6132,12 +6129,12 @@
 
 /* arguments type */
-#define ARG_SPECIAL     -1
-#define ARG_NON          0
-#define ARG_RELADDR      1
-#define ARG_ABSADDR      2
-#define ARG_LENGTH       3
-#define ARG_MEMNUM       4
-#define ARG_OPTION       5
-#define ARG_STATE_CHECK  6
+# define ARG_SPECIAL     -1
+# define ARG_NON          0
+# define ARG_RELADDR      1
+# define ARG_ABSADDR      2
+# define ARG_LENGTH       3
+# define ARG_MEMNUM       4
+# define ARG_OPTION       5
+# define ARG_STATE_CHECK  6
 
 OnigOpInfoType OnigOpInfo[] = {
@@ -6164,5 +6161,4 @@
   { OP_CCLASS_MB_NOT,     "cclass-mb-not",   ARG_SPECIAL },
   { OP_CCLASS_MIX_NOT,    "cclass-mix-not",  ARG_SPECIAL },
-  { OP_CCLASS_NODE,       "cclass-node",     ARG_SPECIAL },
   { OP_ANYCHAR,           "anychar",         ARG_NON },
   { OP_ANYCHAR_ML,        "anychar-ml",      ARG_NON },
@@ -6189,5 +6185,4 @@
   { OP_SEMI_END_BUF,        "semi-end-buf",    ARG_NON },
   { OP_BEGIN_POSITION,      "begin-position",  ARG_NON },
-  { OP_BEGIN_POS_OR_LINE,   "begin-pos-or-line",    ARG_NON },
   { OP_BACKREF1,            "backref1",             ARG_NON },
   { OP_BACKREF2,            "backref2",             ARG_NON },
@@ -6231,4 +6226,7 @@
   { OP_PUSH_LOOK_BEHIND_NOT, "push-look-behind-not", ARG_SPECIAL },
   { OP_FAIL_LOOK_BEHIND_NOT, "fail-look-behind-not", ARG_NON },
+  { OP_PUSH_ABSENT_POS,      "push-absent-pos",      ARG_NON },
+  { OP_ABSENT,               "absent",               ARG_RELADDR },
+  { OP_ABSENT_END,           "absent-end",           ARG_NON },
   { OP_CALL,                 "call",                 ARG_ABSADDR },
   { OP_RETURN,               "return",               ARG_NON },
@@ -6267,5 +6265,5 @@
 }
 
-#ifdef ONIG_DEBUG_PARSE_TREE
+# ifdef ONIG_DEBUG_PARSE_TREE
 static void
 Indent(FILE* f, int indent)
@@ -6274,5 +6272,5 @@
   for (i = 0; i < indent; i++) putc(' ', f);
 }
-#endif /* ONIG_DEBUG_PARSE_TREE */
+# endif /* ONIG_DEBUG_PARSE_TREE */
 
 static void
@@ -6293,5 +6291,5 @@
 
 extern void
-onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp,
+onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar* bpend, UChar** nextp,
                               OnigEncoding enc)
 {
@@ -6313,5 +6311,5 @@
     case ARG_RELADDR:
       GET_RELADDR_INC(addr, bp);
-      fprintf(f, ":(+%d)", addr);
+      fprintf(f, ":(%s%d)", (addr >= 0) ? "+" : "", addr);
       break;
     case ARG_ABSADDR:
@@ -6392,5 +6390,5 @@
 
     case OP_EXACT1_IC:
-      len = enclen(enc, bp);
+      len = enclen(enc, bp, bpend);
       p_string(f, len, bp);
       bp += len;
@@ -6418,7 +6416,7 @@
       GET_LENGTH_INC(len, bp);
       q = bp;
-#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
+# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
       ALIGNMENT_RIGHT(q);
-#endif
+# endif
       GET_CODE_POINT(code, q);
       bp += len;
@@ -6432,20 +6430,10 @@
       GET_LENGTH_INC(len, bp);
       q = bp;
-#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
+# ifndef PLATFORM_UNALIGNED_WORD_ACCESS
       ALIGNMENT_RIGHT(q);
-#endif
+# endif
       GET_CODE_POINT(code, q);
       bp += len;
       fprintf(f, ":%d:%d:%d", n, (int )code, len);
-      break;
-
-    case OP_CCLASS_NODE:
-      {
-        CClassNode *cc;
-
-        GET_POINTER_INC(cc, bp);
-        n = bitset_on_num(cc->bs);
-        fprintf(f, ":%"PRIuPTR":%d", (uintptr_t )cc, n);
-      }
       break;
 
@@ -6502,5 +6490,5 @@
       addr = *((RelAddrType* )bp);
       bp += SIZE_RELADDR;
-      fprintf(f, ":(%d)", addr);
+      fprintf(f, ":(%s%d)", (addr >= 0) ? "+" : "", addr);
       p_string(f, 1, bp);
       bp += 1;
@@ -6515,5 +6503,5 @@
       GET_RELADDR_INC(addr, bp);
       GET_LENGTH_INC(len, bp);
-      fprintf(f, ":%d:(%d)", len, addr);
+      fprintf(f, ":%d:(%s%d)", len, (addr >= 0) ? "+" : "", addr);
       break;
 
@@ -6524,5 +6512,5 @@
       addr = *((RelAddrType* )bp);
       bp += SIZE_RELADDR;
-      fprintf(f, ":%d:(%d)", scn, addr);
+      fprintf(f, ":%d:(%s%d)", scn, (addr >= 0) ? "+" : "", addr);
       break;
 
@@ -6530,10 +6518,10 @@
       GET_MEMNUM_INC(mem, bp);
       GET_RELADDR_INC(addr, bp);
-      fprintf(f, ":%d:(%d)", mem, addr);
+      fprintf(f, ":%d:(%s%d)", mem, (addr >= 0) ? "+" : "", addr);
       break;
 
     default:
       fprintf(stderr, "onig_print_compiled_byte_code: undefined code %d\n",
-	      *--bp);
+	      bp[-1]);
     }
   }
@@ -6542,5 +6530,5 @@
 }
 
-#ifdef ONIG_DEBUG_COMPILE
+# ifdef ONIG_DEBUG_COMPILE
 static void
 print_compiled_byte_code_list(FILE* f, regex_t* reg)
@@ -6559,12 +6547,12 @@
     else
       fprintf(f, " %ld:", bp - reg->p);
-    onig_print_compiled_byte_code(f, bp, &bp, reg->enc);
+    onig_print_compiled_byte_code(f, bp, end, &bp, reg->enc);
   }
 
   fprintf(f, "\n");
 }
-#endif /* ONIG_DEBUG_COMPILE */
-
-#ifdef ONIG_DEBUG_PARSE_TREE
+# endif /* ONIG_DEBUG_COMPILE */
+
+# ifdef ONIG_DEBUG_PARSE_TREE
 static void
 print_indent_tree(FILE* f, Node* node, int indent)
@@ -6613,10 +6601,13 @@
   case NT_CCLASS:
     fprintf(f, "<cclass:%"PRIxPTR">", (intptr_t )node);
-    if (IS_NCCLASS_NOT(NCCLASS(node))) fputs(" not", f);
+    if (IS_NCCLASS_NOT(NCCLASS(node))) fputs("not ", f);
     if (NCCLASS(node)->mbuf) {
       BBuf* bbuf = NCCLASS(node)->mbuf;
-      for (i = 0; i < (int )bbuf->used; i++) {
-	if (i > 0) fprintf(f, ",");
-	fprintf(f, "%0x", bbuf->p[i]);
+      OnigCodePoint* data = (OnigCodePoint* )bbuf->p;
+      OnigCodePoint* end = (OnigCodePoint* )(bbuf->p + bbuf->used);
+      fprintf(f, "%d", *data++);
+      for (; data < end; data+=2) {
+	fprintf(f, ",");
+	fprintf(f, "%04x-%04x", data[0], data[1]);
       }
     }
@@ -6652,12 +6643,11 @@
     case ANCHOR_SEMI_END_BUF:   fputs("semi end buf",   f); break;
     case ANCHOR_BEGIN_POSITION: fputs("begin position", f); break;
-    case ANCHOR_ANYCHAR_STAR:   fputs("begin position/line", f); break;
 
     case ANCHOR_WORD_BOUND:      fputs("word bound",     f); break;
     case ANCHOR_NOT_WORD_BOUND:  fputs("not word bound", f); break;
-#ifdef USE_WORD_BEGIN_END
+#  ifdef USE_WORD_BEGIN_END
     case ANCHOR_WORD_BEGIN:      fputs("word begin", f);     break;
     case ANCHOR_WORD_END:        fputs("word end", f);       break;
-#endif
+#  endif
     case ANCHOR_PREC_READ:       fputs("prec read",      f); container_p = TRUE; break;
     case ANCHOR_PREC_READ_NOT:   fputs("prec read not",  f); container_p = TRUE; break;
@@ -6685,5 +6675,5 @@
     break;
 
-#ifdef USE_SUBEXP_CALL
+#  ifdef USE_SUBEXP_CALL
   case NT_CALL:
     {
@@ -6693,5 +6683,5 @@
     }
     break;
-#endif
+#  endif
 
   case NT_QTFR:
@@ -6717,4 +6707,7 @@
       fprintf(f, "condition:%d", NENCLOSE(node)->regnum);
       break;
+    case ENCLOSE_ABSENT:
+      fprintf(f, "absent");
+      break;
 
     default:
@@ -6744,4 +6737,4 @@
   print_indent_tree(f, node, 0);
 }
-#endif /* ONIG_DEBUG_PARSE_TREE */
+# endif /* ONIG_DEBUG_PARSE_TREE */
 #endif /* ONIG_DEBUG */
