[前][次][番号順一覧][スレッド一覧]

ruby-changes:45884

From: naruse <ko1@a...>
Date: Mon, 13 Mar 2017 18:05:51 +0900 (JST)
Subject: [ruby-changes:45884] naruse:r57957 (ruby_2_4): merge revision(s) 57603: [Backport #12997]

naruse	2017-03-13 18:05:46 +0900 (Mon, 13 Mar 2017)

  New Revision: 57957

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57957

  Log:
    merge revision(s) 57603: [Backport #12997]
    
    Merge Onigmo 6.1.1
    
    * Support absent operator https://github.com/k-takata/Onigmo/issues/82
    * https://github.com/k-takata/Onigmo/blob/Onigmo-6.1.1/HISTORY

  Modified directories:
    branches/ruby_2_4/
  Modified files:
    branches/ruby_2_4/NEWS
    branches/ruby_2_4/include/ruby/onigmo.h
    branches/ruby_2_4/regcomp.c
    branches/ruby_2_4/regenc.c
    branches/ruby_2_4/regexec.c
    branches/ruby_2_4/regint.h
    branches/ruby_2_4/regparse.c
    branches/ruby_2_4/regparse.h
    branches/ruby_2_4/version.h
Index: ruby_2_4/NEWS
===================================================================
--- ruby_2_4/NEWS	(revision 57956)
+++ ruby_2_4/NEWS	(revision 57957)
@@ -140,7 +140,8 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/ruby_2_4/NEWS#L140
   * Regexp#match? [Feature #8110]
     This returns bool and doesn't save backref.
 
-  * Update Onigmo 6.0.0.
+  * Update Onigmo 6.1.1.
+    * Support absent operator https://github.com/k-takata/Onigmo/issues/82
 
 * Regexp/String: Updated Unicode version from 8.0.0 to 9.0.0 [Feature #12513]
 
Index: ruby_2_4/regenc.c
===================================================================
--- ruby_2_4/regenc.c	(revision 57956)
+++ ruby_2_4/regenc.c	(revision 57957)
@@ -54,11 +54,11 @@ onigenc_set_default_encoding(OnigEncodin https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regenc.c#L54
 extern int
 onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, OnigEncoding enc)
 {
-  int ret = ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e);
+  int ret = ONIGENC_PRECISE_MBC_ENC_LEN(enc, p, e);
   if (ONIGENC_MBCLEN_CHARFOUND_P(ret))
     return ONIGENC_MBCLEN_CHARFOUND_LEN(ret);
   else if (ONIGENC_MBCLEN_NEEDMORE_P(ret))
-    return (int)(e-p)+ONIGENC_MBCLEN_NEEDMORE_LEN(ret);
+    return (int )(e - p) + ONIGENC_MBCLEN_NEEDMORE_LEN(ret);
   return 1;
 }
 
Index: ruby_2_4/regcomp.c
===================================================================
--- ruby_2_4/regcomp.c	(revision 57956)
+++ ruby_2_4/regcomp.c	(revision 57957)
@@ -1286,6 +1286,10 @@ compile_length_enclose_node(EncloseNode* https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L1286
     }
     break;
 
+  case ENCLOSE_ABSENT:
+    len = SIZE_OP_PUSH_ABSENT_POS + SIZE_OP_ABSENT + tlen + SIZE_OP_ABSENT_END;
+    break;
+
   default:
     return ONIGERR_TYPE_BUG;
     break;
@@ -1430,6 +1434,19 @@ compile_enclose_node(EncloseNode* node, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L1434
     }
     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;
     break;
@@ -1484,9 +1501,6 @@ compile_anchor_node(AnchorNode* node, re https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L1501
   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:
     if (node->ascii_range)    r = add_opcode(reg, OP_ASCII_WORD_BOUND);
     else                      r = add_opcode(reg, OP_WORD_BOUND);
@@ -2112,6 +2126,7 @@ quantifiers_memory_node_info(Node* node) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L2126
       case ENCLOSE_OPTION:
       case ENCLOSE_STOP_BACKTRACK:
       case ENCLOSE_CONDITION:
+      case ENCLOSE_ABSENT:
 	r = quantifiers_memory_node_info(en->target);
 	break;
       default:
@@ -2251,6 +2266,9 @@ get_min_match_length(Node* node, OnigDis https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L2266
       case ENCLOSE_CONDITION:
 	r = get_min_match_length(en->target, min, env);
 	break;
+
+      case ENCLOSE_ABSENT:
+	break;
       }
     }
     break;
@@ -2374,6 +2392,9 @@ get_max_match_length(Node* node, OnigDis https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L2392
       case ENCLOSE_CONDITION:
 	r = get_max_match_length(en->target, max, env);
 	break;
+
+      case ENCLOSE_ABSENT:
+	break;
       }
     }
     break;
@@ -2497,6 +2518,7 @@ get_char_length_tree1(Node* node, regex_ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L2518
       case ENCLOSE_CONDITION:
 	r = get_char_length_tree1(en->target, reg, len, level);
 	break;
+      case ENCLOSE_ABSENT:
       default:
 	break;
       }
@@ -2790,6 +2812,9 @@ get_head_value_node(Node* node, int exac https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L2812
       case ENCLOSE_CONDITION:
 	n = get_head_value_node(en->target, exact, reg);
 	break;
+
+      case ENCLOSE_ABSENT:
+	break;
       }
     }
     break;
@@ -3295,7 +3320,7 @@ setup_look_behind(Node* node, regex_t* r https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L3320
 }
 
 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;
 
@@ -3329,32 +3354,10 @@ next_setup(Node* node, Node* next_node, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L3354
 	  }
 	}
       }
-
-#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;
       goto retry;
@@ -3852,9 +3855,8 @@ setup_comb_exp_check(Node* node, int sta https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L3855
 #define IN_NOT        (1<<1)
 #define IN_REPEAT     (1<<2)
 #define IN_VAR_REPEAT (1<<3)
-#define IN_ROOT       (1<<4)
-#define IN_CALL       (1<<5)
-#define IN_RECCALL    (1<<6)
+#define IN_CALL       (1<<4)
+#define IN_RECCALL    (1<<5)
 
 /* setup_tree does the following work.
  1. check empty loop. (set qn->target_empty_info)
@@ -3869,25 +3871,19 @@ setup_tree(Node* node, regex_t* reg, int https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L3871
 {
   int type;
   int r = 0;
-  int in_root = state & IN_ROOT;
 
-  state &= ~IN_ROOT;
 restart:
   type = NTYPE(node);
   switch (type) {
   case NT_LIST:
     {
       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)));
     }
     break;
@@ -4051,7 +4047,6 @@ restart: https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L4047
       case ENCLOSE_OPTION:
 	{
 	  OnigOptionType options = reg->options;
-	  state |= in_root;
 	  reg->options = NENCLOSE(node)->option;
 	  r = setup_tree(NENCLOSE(node)->target, reg, state, env);
 	  reg->options = options;
@@ -4101,6 +4096,10 @@ restart: https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L4096
 	  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;
       }
     }
     break;
@@ -4195,6 +4194,8 @@ set_bm_skip(UChar* s, UChar* end, regex_ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L4194
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
       clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
 	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
@@ -4229,6 +4230,8 @@ set_bm_skip(UChar* s, UChar* end, regex_ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L4230
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
       clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
 	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
@@ -4273,6 +4276,8 @@ set_bm_skip(UChar* s, UChar* end, regex_ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L4276
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
       clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
 	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
@@ -4307,6 +4312,8 @@ set_bm_skip(UChar* s, UChar* end, regex_ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L4312
 	n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, reg->case_fold_flag,
 					       p, end, items);
       clen = enclen(enc, p, end);
+      if (p + clen > end)
+	clen = (int )(end - p);
 
       for (j = 0; j < n; j++) {
 	if ((items[j].code_len != 1) || (items[j].byte_len != clen))
@@ -5274,6 +5281,10 @@ optimize_node_left(Node* node, NodeOptIn https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L5281
       case ENCLOSE_CONDITION:
 	r = optimize_node_left(en->target, opt, env);
 	break;
+
+      case ENCLOSE_ABSENT:
+	set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
+	break;
       }
     }
     break;
@@ -5782,7 +5793,7 @@ onig_compile(regex_t* reg, const UChar* https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L5793
     reg->num_call = 0;
 #endif
 
-  r = setup_tree(root, reg, IN_ROOT, &scan_env);
+  r = setup_tree(root, reg, 0, &scan_env);
   if (r != 0) goto err_unset;
 
 #ifdef ONIG_DEBUG_PARSE_TREE
@@ -5944,7 +5955,7 @@ onig_reg_init(regex_t* reg, OnigOptionTy https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L5955
 extern int
 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;
 
@@ -6173,7 +6184,6 @@ OnigOpInfoType OnigOpInfo[] = { https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L6184
   { OP_END_LINE,            "end-line",        ARG_NON },
   { 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 },
   { OP_BACKREFN,            "backrefn",             ARG_MEMNUM  },
@@ -6215,6 +6225,9 @@ OnigOpInfoType OnigOpInfo[] = { https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L6225
   { OP_LOOK_BEHIND,          "look-behind",          ARG_SPECIAL },
   { 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 },
   { OP_CONDITION,            "condition",            ARG_SPECIAL },
@@ -6509,7 +6522,7 @@ onig_print_compiled_byte_code(FILE* f, U https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L6522
 
     default:
       fprintf(stderr, "onig_print_compiled_byte_code: undefined code %d\n",
-	      *--bp);
+	      bp[-1]);
     }
   }
   fputs("]", f);
@@ -6629,7 +6642,6 @@ print_indent_tree(FILE* f, Node* node, i https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L6642
     case ANCHOR_END_LINE:       fputs("end line",       f); break;
     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;
@@ -6694,6 +6706,9 @@ print_indent_tree(FILE* f, Node* node, i https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regcomp.c#L6706
     case ENCLOSE_CONDITION:
       fprintf(f, "condition:%d", NENCLOSE(node)->regnum);
       break;
+    case ENCLOSE_ABSENT:
+      fprintf(f, "absent");
+      break;
 
     default:
       break;
Index: ruby_2_4/regparse.c
===================================================================
--- ruby_2_4/regparse.c	(revision 57956)
+++ ruby_2_4/regparse.c	(revision 57957)
@@ -58,7 +58,8 @@ const OnigSyntaxType OnigSyntaxRuby = { https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L58
       ONIG_SYN_OP2_ESC_CAPITAL_X_EXTENDED_GRAPHEME_CLUSTER |
       ONIG_SYN_OP2_QMARK_LPAREN_CONDITION |
       ONIG_SYN_OP2_ESC_CAPITAL_R_LINEBREAK |
-      ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP )
+      ONIG_SYN_OP2_ESC_CAPITAL_K_KEEP |
+      ONIG_SYN_OP2_QMARK_TILDE_ABSENT )
   , ( SYN_GNU_REGEX_BV |
       ONIG_SYN_ALLOW_INTERVAL_LOW_ABBREV |
       ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND |
@@ -1024,14 +1025,15 @@ scan_env_add_mem_entry(ScanEnv* env) https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L1025
       if (IS_NULL(env->mem_nodes_dynamic)) {
 	alloc = INIT_SCANENV_MEMNODES_ALLOC_SIZE;
 	p = (Node** )xmalloc(sizeof(Node*) * alloc);
+	CHECK_NULL_RETURN_MEMERR(p);
 	xmemcpy(p, env->mem_nodes_static,
 		sizeof(Node*) * SCANENV_MEMNODES_SIZE);
       }
       else {
 	alloc = env->mem_alloc * 2;
 	p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
+	CHECK_NULL_RETURN_MEMERR(p);
       }
-      CHECK_NULL_RETURN_MEMERR(p);
 
       for (i = env->num_mem + 1; i < alloc; i++)
 	p[i] = NULL_NODE;
@@ -3176,7 +3178,7 @@ fetch_token_in_cc(OnigToken* tok, UChar* https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L3178
       PUNFETCH;
       num = fetch_escaped_value(&p, end, env, &c2);
       if (num < 0) return num;
-      if ((OnigCodePoint)tok->u.c != c2) {
+      if ((OnigCodePoint )tok->u.c != c2) {
 	tok->u.code = (OnigCodePoint )c2;
 	tok->type   = TK_CODE_POINT;
       }
@@ -3780,7 +3782,7 @@ fetch_token(OnigToken* tok, UChar** src, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L3782
 	num = fetch_escaped_value(&p, end, env, &c2);
 	if (num < 0) return num;
 	/* set_raw: */
-	if ((OnigCodePoint)tok->u.c != c2) {
+	if ((OnigCodePoint )tok->u.c != c2) {
 	  tok->type = TK_CODE_POINT;
 	  tok->u.code = (OnigCodePoint )c2;
 	}
@@ -4989,6 +4991,14 @@ parse_enclose(Node** np, OnigToken* tok, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L4991
     case '>':   /* (?>...) stop backtrack */
       *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
       break;
+    case '~':   /* (?~...) absent operator */
+      if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_TILDE_ABSENT)) {
+	*np = node_new_enclose(ENCLOSE_ABSENT);
+      }
+      else {
+	return ONIGERR_UNDEFINED_GROUP_OPTION;
+      }
+      break;
 
 #ifdef USE_NAMED_GROUP
     case '\'':
@@ -5030,7 +5040,9 @@ parse_enclose(Node** np, OnigToken* tok, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L5040
 	named_group1:
 	  list_capture = 0;
 
+# ifdef USE_CAPTURE_HISTORY
 	named_group2:
+# endif
 	  name = p;
 	  r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
 	  if (r < 0) return r;
@@ -5060,9 +5072,10 @@ parse_enclose(Node** np, OnigToken* tok, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L5072
 #endif
       break;
 
+#ifdef USE_CAPTURE_HISTORY
     case '@':
       if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ATMARK_CAPTURE_HISTORY)) {
-#ifdef USE_NAMED_GROUP
+# ifdef USE_NAMED_GROUP
 	if (!PEND &&
 	    IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
 	  PFETCH(c);
@@ -5072,7 +5085,7 @@ parse_enclose(Node** np, OnigToken* tok, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L5085
 	  }
 	  PUNFETCH;
 	}
-#endif
+# endif
 	*np = node_new_enclose_memory(env->option, 0);
 	CHECK_NULL_RETURN_MEMERR(*np);
 	num = scan_env_add_mem_entry(env);
@@ -5087,6 +5100,7 @@ parse_enclose(Node** np, OnigToken* tok, https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.c#L5100
 	return ONIGERR_UNDEFINED_GROUP_OPTION;
       }
       break;
+#endif /* USE_CAPTURE_HISTORY */
 
     case '(':   /* conditional expression: (?(cond)yes), (?(cond)yes|no) */
       if (!PEND &&
Index: ruby_2_4/regparse.h
===================================================================
--- ruby_2_4/regparse.h	(revision 57956)
+++ ruby_2_4/regparse.h	(revision 57957)
@@ -95,6 +95,7 @@ RUBY_SYMBOL_EXPORT_BEGIN https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regparse.h#L95
 #define ENCLOSE_OPTION           (1<<1)
 #define ENCLOSE_STOP_BACKTRACK   (1<<2)
 #define ENCLOSE_CONDITION        (1<<3)
+#define ENCLOSE_ABSENT           (1<<4)
 
 #define NODE_STR_MARGIN         16
 #define NODE_STR_BUF_SIZE       24  /* sizeof(CClassNode) - sizeof(int)*4 */
Index: ruby_2_4/regint.h
===================================================================
--- ruby_2_4/regint.h	(revision 57956)
+++ ruby_2_4/regint.h	(revision 57957)
@@ -202,7 +202,9 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regint.h#L202
 #define xmemcpy     memcpy
 #define xmemmove    memmove
 
-#if defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 90 && !defined(__GNUC__)
+#if ((defined(RUBY_MSVCRT_VERSION) && RUBY_MSVCRT_VERSION >= 90) \
+        || (!defined(RUBY_MSVCRT_VERSION) && defined(_WIN32))) \
+    && !defined(__GNUC__)
 # define xalloca     _alloca
 # define xvsnprintf(buf,size,fmt,args)  _vsnprintf_s(buf,size,_TRUNCATE,fmt,args)
 # define xsnprintf   sprintf_s
@@ -598,7 +600,6 @@ enum OpCode { https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regint.h#L600
   OP_END_LINE,
   OP_SEMI_END_BUF,
   OP_BEGIN_POSITION,
-  OP_BEGIN_POS_OR_LINE,   /* used for implicit anchor optimization */
 
   OP_BACKREF1,
   OP_BACKREF2,
@@ -643,6 +644,9 @@ enum OpCode { https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regint.h#L644
   OP_LOOK_BEHIND,          /* (?<=...) start (no needs end opcode) */
   OP_PUSH_LOOK_BEHIND_NOT, /* (?<!...) start */
   OP_FAIL_LOOK_BEHIND_NOT, /* (?<!...) end   */
+  OP_PUSH_ABSENT_POS,      /* (?~...)  start */
+  OP_ABSENT,               /* (?~...)  start of inner loop */
+  OP_ABSENT_END,           /* (?~...)  end   */
 
   OP_CALL,                 /* \g<name> */
   OP_RETURN,
@@ -730,6 +734,9 @@ typedef void* PointerType; https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regint.h#L734
 #define SIZE_OP_CALL                   (SIZE_OPCODE + SIZE_ABSADDR)
 #define SIZE_OP_RETURN                  SIZE_OPCODE
 #define SIZE_OP_CONDITION              (SIZE_OPCODE + SIZE_MEMNUM + SIZE_RELADDR)
+#define SIZE_OP_PUSH_ABSENT_POS         SIZE_OPCODE
+#define SIZE_OP_ABSENT                 (SIZE_OPCODE + SIZE_RELADDR)
+#define SIZE_OP_ABSENT_END              SIZE_OPCODE
 
 #ifdef USE_COMBINATION_EXPLOSION_CHECK
 # define SIZE_OP_STATE_CHECK           (SIZE_OPCODE + SIZE_STATE_CHECK_NUM)
@@ -841,6 +848,10 @@ typedef struct _OnigStackType { https://github.com/ruby/ruby/blob/trunk/ruby_2_4/regint.h#L848
       UChar *pstr;       /* string position */
     } call_frame;
 #endif
+    struct {
+      UChar *abs_pstr;        /* absent start position */
+      const UChar *end_pstr;  /* end position */
+    } absent_pos;
   } u;
 } OnigStackType;
 
Index: ruby_2_4/regexec.c
===================================================================
--- ruby_2_4/regexec.c	(revision 57956)
+++ ruby_2_4/regexec.c	(revision 57957)
@@ -403,6 +403,8 @@ onig_region_copy(OnigRegion*  (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]