summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-04-12 09:59:33 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-04-12 09:59:33 +0000
commit83627b120c902e79bbb8994a0679712d31695878 (patch)
tree56603e4c5e15a49065ba5d3a8f915ca9d183eafb
parent32e799db485107ba9d47fb4fb4cd44c9d6f57b8a (diff)
*** empty log message ***
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@416 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog2
-rw-r--r--eval.c68
-rw-r--r--ext/extmk.rb.nt2
-rw-r--r--node.h4
-rw-r--r--parse.c593
-rw-r--r--parse.y21
-rw-r--r--regex.c2721
-rw-r--r--sample/test.rb27
-rw-r--r--win32/ruby.def1
9 files changed, 1710 insertions, 1729 deletions
diff --git a/ChangeLog b/ChangeLog
index e5bbfaab80..9c509ce431 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
Fri Apr 9 17:45:11 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+ * parse.y (rb_compile_string): bug for nested eval().
+
* regex.c (re_match): should pop non-greedy stack items on
failure, after best_regs are fixed.
diff --git a/eval.c b/eval.c
index 00a0d6390e..e012f56226 100644
--- a/eval.c
+++ b/eval.c
@@ -416,7 +416,6 @@ struct BLOCK {
struct BLOCK *prev;
};
static struct BLOCK *ruby_block;
-static struct BLOCK *ruby_calling_block;
#define PUSH_BLOCK(v,b) { \
struct BLOCK _block; \
@@ -443,12 +442,9 @@ static struct BLOCK *ruby_calling_block;
struct BLOCK * volatile _old; \
struct BLOCK * volatile _old_call; \
_old = ruby_block; \
- _old_call = ruby_calling_block; \
- ruby_calling_block = b; \
ruby_block = b;
#define POP_BLOCK2() \
- ruby_calling_block = _old_call; \
ruby_block = _old; \
}
@@ -476,6 +472,14 @@ new_dvar(id, value)
return vars;
}
+static void
+mark_dvar(vars)
+ struct RVarmap *vars;
+{
+ ruby_dyna_vars = new_dvar(0, 0);
+ ruby_dyna_vars->next = vars;
+}
+
VALUE
rb_dvar_defined(id)
ID id;
@@ -512,14 +516,16 @@ rb_dvar_push(id, value)
ruby_dyna_vars = new_dvar(id, value);
}
-void
-rb_dvar_asgn(id, value)
+static void
+dvar_asgn(id, value, push)
ID id;
VALUE value;
+ int push;
{
struct RVarmap *vars = ruby_dyna_vars;
while (vars) {
+ if (push && vars->id == 0) break;
if (vars->id == id) {
vars->val = value;
return;
@@ -527,7 +533,14 @@ rb_dvar_asgn(id, value)
vars = vars->next;
}
rb_dvar_push(id, value);
- return;
+}
+
+void
+rb_dvar_asgn(id, value)
+ ID id;
+ VALUE value;
+{
+ dvar_asgn(id, value, 0);
}
static void
@@ -535,9 +548,16 @@ dvar_asgn_push(id, value)
ID id;
VALUE value;
{
- rb_dvar_asgn(id, value);
- if (ruby_calling_block) {
- ruby_calling_block->d_vars = ruby_dyna_vars;
+ struct RVarmap* vars = 0;
+
+ if (ruby_dyna_vars && ruby_dyna_vars->id == 0) {
+ vars = ruby_dyna_vars;
+ ruby_dyna_vars = ruby_dyna_vars->next;
+ }
+ dvar_asgn(id, value, 1);
+ if (vars) {
+ vars->next = ruby_dyna_vars;
+ ruby_dyna_vars = vars;
}
}
@@ -653,7 +673,7 @@ static VALUE ruby_wrapper; /* security wrapper */
static VALUE rb_eval _((VALUE,NODE*));
static VALUE eval _((VALUE,VALUE,VALUE,char*,int));
-static NODE *compile _((VALUE));
+static NODE *compile _((VALUE, char*, int));
static VALUE rb_yield_0 _((VALUE, VALUE, VALUE));
static VALUE rb_call _((VALUE,VALUE,ID,int,VALUE*,int));
@@ -2451,7 +2471,9 @@ rb_eval(self, node)
case NODE_EVSTR:
ruby_sourceline = nd_line(node);
ruby_in_eval++;
- list->nd_head = compile(list->nd_head->nd_lit);
+ list->nd_head = compile(list->nd_head->nd_lit,
+ ruby_sourcefile,
+ ruby_sourceline);
ruby_eval_tree = 0;
ruby_in_eval--;
if (ruby_nerrs > 0) {
@@ -3106,7 +3128,7 @@ rb_yield_0(val, self, klass)
old_scope = ruby_scope;
ruby_scope = block->scope;
ruby_block = block->prev;
- ruby_dyna_vars = block->d_vars;
+ mark_dvar(block->d_vars);
ruby_class = klass?klass:block->klass;
if (!self) self = block->self;
node = block->body;
@@ -4086,13 +4108,15 @@ rb_frame_last_func()
}
static NODE*
-compile(src)
+compile(src, file, line)
VALUE src;
+ char *file;
+ int line;
{
NODE *node;
Check_Type(src, T_STRING);
- node = rb_compile_string("(eval)", src);
+ node = rb_compile_string(file, src, line);
if (ruby_nerrs == 0) return node;
return 0;
@@ -4135,8 +4159,6 @@ eval(self, src, scope, file, line)
ruby_frame = &(frame);
old_scope = ruby_scope;
ruby_scope = data->scope;
- old_call_block = ruby_calling_block;
- ruby_calling_block = data;
old_block = ruby_block;
ruby_block = data->prev;
old_d_vars = ruby_dyna_vars;
@@ -4161,9 +4183,7 @@ eval(self, src, scope, file, line)
}
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
- ruby_sourcefile = file;
- ruby_sourceline = line - 1;
- compile(src);
+ compile(src, file, line);
if (ruby_nerrs > 0) {
compile_error(0);
}
@@ -4178,9 +4198,6 @@ eval(self, src, scope, file, line)
FL_SET(old_scope, SCOPE_DONT_RECYCLE);
ruby_scope = old_scope;
ruby_block = old_block;
- ruby_calling_block = old_call_block;
- data->d_vars = ruby_dyna_vars;
- ruby_dyna_vars = old_d_vars;
data->vmode = scope_vmode; /* write back visibility mode */
scope_vmode = old_vmode;
}
@@ -4235,7 +4252,7 @@ rb_f_eval(argc, argv, self)
}
Check_SafeStr(src);
- return eval(self, src, scope, file, line);
+ return eval(self, src, scope, file, line-1);
}
static VALUE
@@ -5738,7 +5755,6 @@ struct thread {
struct SCOPE *scope;
struct RVarmap *dyna_vars;
struct BLOCK *block;
- struct BLOCK *cblock;
struct iter *iter;
struct tag *tag;
VALUE klass;
@@ -5899,7 +5915,6 @@ rb_thread_save_context(th)
th->wrapper = ruby_wrapper;
th->dyna_vars = ruby_dyna_vars;
th->block = ruby_block;
- th->cblock = ruby_calling_block;
th->misc = scope_vmode | (rb_trap_immediate<<8);
th->iter = ruby_iter;
th->tag = prot_tag;
@@ -5970,7 +5985,6 @@ rb_thread_restore_context(th, exit)
ruby_wrapper = th->wrapper;
ruby_dyna_vars = th->dyna_vars;
ruby_block = th->block;
- ruby_calling_block = th->cblock;
scope_vmode = th->misc&SCOPE_MASK;
rb_trap_immediate = th->misc>>8;
ruby_iter = th->iter;
diff --git a/ext/extmk.rb.nt b/ext/extmk.rb.nt
index 5836e5c681..dd979a45a3 100644
--- a/ext/extmk.rb.nt
+++ b/ext/extmk.rb.nt
@@ -451,7 +451,7 @@ if $extlist.size > 0
if File.exist?(l)
$extinit += format("\
\tInit_%s();\n\
-\trb_provide(\"%s.o\");\n\
+\trb_provide(\"%s.so\");\n\
", s, s)
$extobjs += "ext/"
#$extobjs += f # *.obj
diff --git a/node.h b/node.h
index cf114cf804..3d6002f8c9 100644
--- a/node.h
+++ b/node.h
@@ -331,8 +331,8 @@ VALUE rb_method_booundp();
#define NOEX_PRIVATE 2
#define NOEX_PROTECTED 4
-NODE *rb_compile_cstr _((const char*, const char*, int));
-NODE *rb_compile_string _((const char*, VALUE));
+NODE *rb_compile_cstr _((const char*, const char*, int, int));
+NODE *rb_compile_string _((const char*, VALUE, int));
NODE *rb_compile_file _((const char*, VALUE, int));
void rb_add_method _((VALUE, ID, NODE *, int));
diff --git a/parse.c b/parse.c
index 4623005327..c93f781faa 100644
--- a/parse.c
+++ b/parse.c
@@ -418,43 +418,43 @@ static const short yyrhs[] = { -1,
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 238, 247, 265, 271, 272, 276, 280, 285, 286, 287,
- 292, 298, 307, 312, 318, 324, 330, 340, 350, 357,
- 364, 372, 377, 379, 385, 392, 397, 398, 402, 406,
- 411, 416, 418, 423, 429, 435, 443, 444, 449, 450,
- 455, 459, 463, 467, 471, 476, 477, 482, 487, 491,
- 496, 500, 504, 508, 514, 518, 522, 526, 532, 536,
- 538, 539, 540, 541, 546, 552, 556, 557, 561, 562,
- 563, 564, 565, 566, 567, 568, 569, 570, 571, 572,
- 573, 574, 575, 576, 577, 578, 579, 580, 581, 582,
- 583, 584, 585, 586, 587, 589, 589, 589, 589, 590,
- 590, 590, 590, 590, 590, 590, 591, 591, 591, 591,
- 591, 591, 591, 592, 592, 592, 592, 592, 592, 592,
- 593, 593, 593, 593, 593, 593, 593, 594, 594, 594,
- 594, 594, 594, 595, 595, 597, 602, 603, 618, 633,
- 644, 655, 660, 664, 668, 672, 676, 680, 684, 688,
- 692, 696, 700, 704, 708, 712, 716, 720, 724, 728,
- 732, 736, 740, 744, 748, 752, 757, 761, 765, 769,
- 773, 777, 778, 782, 788, 793, 801, 802, 804, 809,
- 813, 817, 822, 826, 831, 836, 841, 845, 850, 855,
- 857, 863, 867, 869, 870, 872, 877, 883, 895, 900,
- 906, 920, 921, 923, 927, 932, 936, 940, 941, 945,
- 946, 947, 948, 949, 954, 962, 966, 973, 979, 985,
- 990, 994, 998, 998, 1003, 1007, 1012, 1013, 1022, 1031,
- 1040, 1048, 1056, 1064, 1072, 1092, 1096, 1106, 1114, 1121,
- 1129, 1138, 1146, 1154, 1163, 1164, 1171, 1179, 1183, 1187,
- 1191, 1196, 1197, 1198, 1200, 1201, 1203, 1204, 1213, 1214,
- 1219, 1220, 1222, 1223, 1227, 1231, 1236, 1241, 1249, 1254,
- 1261, 1265, 1269, 1273, 1274, 1276, 1286, 1291, 1297, 1303,
- 1309, 1314, 1321, 1330, 1331, 1333, 1340, 1341, 1346, 1352,
- 1353, 1355, 1362, 1364, 1365, 1370, 1371, 1375, 1377, 1378,
- 1379, 1381, 1382, 1384, 1385, 1386, 1387, 1388, 1389, 1390,
- 1391, 1392, 1393, 1395, 1400, 1401, 1403, 1407, 1411, 1415,
- 1417, 1422, 1427, 1431, 1435, 1439, 1443, 1447, 1451, 1455,
- 1459, 1464, 1471, 1479, 1486, 1491, 1496, 1503, 1508, 1512,
- 1514, 1527, 1545, 1546, 1550, 1558, 1559, 1564, 1569, 1570,
- 1571, 1573, 1574, 1576, 1577, 1579, 1580, 1582, 1583, 1585,
- 1586, 1587, 1589, 1590, 1592, 1593, 1595
+ 238, 247, 266, 272, 273, 277, 281, 286, 287, 288,
+ 293, 299, 308, 313, 319, 325, 331, 341, 351, 358,
+ 365, 373, 378, 380, 386, 393, 398, 399, 403, 407,
+ 412, 417, 419, 424, 430, 436, 444, 445, 450, 451,
+ 456, 460, 464, 468, 472, 477, 478, 483, 488, 492,
+ 497, 501, 505, 509, 515, 519, 523, 527, 533, 537,
+ 539, 540, 541, 542, 547, 553, 557, 558, 562, 563,
+ 564, 565, 566, 567, 568, 569, 570, 571, 572, 573,
+ 574, 575, 576, 577, 578, 579, 580, 581, 582, 583,
+ 584, 585, 586, 587, 588, 590, 590, 590, 590, 591,
+ 591, 591, 591, 591, 591, 591, 592, 592, 592, 592,
+ 592, 592, 592, 593, 593, 593, 593, 593, 593, 593,
+ 594, 594, 594, 594, 594, 594, 594, 595, 595, 595,
+ 595, 595, 595, 596, 596, 598, 603, 604, 619, 634,
+ 645, 656, 661, 665, 669, 673, 677, 681, 685, 689,
+ 693, 697, 701, 705, 709, 713, 717, 721, 725, 729,
+ 733, 737, 741, 745, 749, 753, 758, 762, 766, 770,
+ 774, 778, 779, 783, 789, 794, 802, 803, 805, 810,
+ 814, 818, 823, 827, 832, 837, 842, 846, 851, 856,
+ 858, 864, 868, 870, 871, 873, 878, 884, 896, 901,
+ 907, 921, 922, 924, 928, 933, 937, 941, 942, 946,
+ 947, 948, 949, 950, 955, 963, 967, 974, 980, 986,
+ 991, 995, 999, 999, 1004, 1008, 1013, 1014, 1023, 1032,
+ 1041, 1049, 1057, 1065, 1073, 1093, 1097, 1107, 1115, 1122,
+ 1130, 1139, 1147, 1155, 1164, 1165, 1172, 1180, 1184, 1188,
+ 1192, 1197, 1198, 1199, 1201, 1202, 1204, 1205, 1214, 1215,
+ 1220, 1221, 1223, 1224, 1228, 1232, 1237, 1242, 1250, 1255,
+ 1262, 1266, 1270, 1274, 1275, 1277, 1287, 1292, 1298, 1304,
+ 1310, 1315, 1322, 1331, 1332, 1334, 1341, 1342, 1347, 1353,
+ 1354, 1356, 1363, 1365, 1366, 1371, 1372, 1376, 1378, 1379,
+ 1380, 1382, 1383, 1385, 1386, 1387, 1388, 1389, 1390, 1391,
+ 1392, 1393, 1394, 1396, 1401, 1402, 1404, 1408, 1412, 1416,
+ 1418, 1423, 1428, 1432, 1436, 1440, 1444, 1448, 1452, 1456,
+ 1460, 1465, 1472, 1480, 1487, 1492, 1497, 1504, 1509, 1513,
+ 1515, 1528, 1546, 1547, 1551, 1559, 1560, 1565, 1570, 1571,
+ 1572, 1574, 1575, 1577, 1578, 1580, 1581, 1583, 1584, 1586,
+ 1587, 1588, 1590, 1591, 1593, 1594, 1596
};
#endif
@@ -2632,7 +2632,8 @@ case 1:
case 2:
#line 247 "parse.y"
{
- if (yyvsp[0].node) { /* last expression is void */
+ if (yyvsp[0].node && !compile_for_eval) {
+ /* last expression should not be void */
if (nd_type(yyvsp[0].node) != NODE_BLOCK) void_expr(yyvsp[0].node);
else {
NODE *node = yyvsp[0].node;
@@ -2650,36 +2651,36 @@ case 2:
;
break;}
case 3:
-#line 266 "parse.y"
+#line 267 "parse.y"
{
void_stmts(yyvsp[-1].node);
yyval.node = yyvsp[-1].node;
;
break;}
case 5:
-#line 273 "parse.y"
+#line 274 "parse.y"
{
yyval.node = newline_node(yyvsp[0].node);
;
break;}
case 6:
-#line 277 "parse.y"
+#line 278 "parse.y"
{
yyval.node = block_append(yyvsp[-2].node, newline_node(yyvsp[0].node));
;
break;}
case 7:
-#line 281 "parse.y"
+#line 282 "parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 9:
-#line 286 "parse.y"
+#line 287 "parse.y"
{lex_state = EXPR_FNAME;;
break;}
case 10:
-#line 287 "parse.y"
+#line 288 "parse.y"
{
if (cur_mid || in_single)
yyerror("alias within method");
@@ -2687,7 +2688,7 @@ case 10:
;
break;}
case 11:
-#line 293 "parse.y"
+#line 294 "parse.y"
{
if (cur_mid || in_single)
yyerror("alias within method");
@@ -2695,7 +2696,7 @@ case 11:
;
break;}
case 12:
-#line 299 "parse.y"
+#line 300 "parse.y"
{
char buf[3];
@@ -2706,14 +2707,14 @@ case 12:
;
break;}
case 13:
-#line 308 "parse.y"
+#line 309 "parse.y"
{
yyerror("can't make alias for the number variables");
yyval.node = 0;
;
break;}
case 14:
-#line 313 "parse.y"
+#line 314 "parse.y"
{
if (cur_mid || in_single)
yyerror("undef within method");
@@ -2721,7 +2722,7 @@ case 14:
;
break;}
case 15:
-#line 319 "parse.y"
+#line 320 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_IF(cond(yyvsp[0].node), yyvsp[-2].node, 0);
@@ -2729,7 +2730,7 @@ case 15:
;
break;}
case 16:
-#line 325 "parse.y"
+#line 326 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_UNLESS(cond(yyvsp[0].node), yyvsp[-2].node, 0);
@@ -2737,7 +2738,7 @@ case 16:
;
break;}
case 17:
-#line 331 "parse.y"
+#line 332 "parse.y"
{
value_expr(yyvsp[0].node);
if (nd_type(yyvsp[-2].node) == NODE_BEGIN) {
@@ -2749,7 +2750,7 @@ case 17:
;
break;}
case 18:
-#line 341 "parse.y"
+#line 342 "parse.y"
{
value_expr(yyvsp[0].node);
if (nd_type(yyvsp[-2].node) == NODE_BEGIN) {
@@ -2761,7 +2762,7 @@ case 18:
;
break;}
case 19:
-#line 351 "parse.y"
+#line 352 "parse.y"
{
if (cur_mid || in_single) {
yyerror("BEGIN in method");
@@ -2770,7 +2771,7 @@ case 19:
;
break;}
case 20:
-#line 358 "parse.y"
+#line 359 "parse.y"
{
ruby_eval_tree_begin = block_append(ruby_eval_tree_begin,
NEW_PREEXE(yyvsp[-1].node));
@@ -2779,7 +2780,7 @@ case 20:
;
break;}
case 21:
-#line 365 "parse.y"
+#line 366 "parse.y"
{
if (compile_for_eval && (cur_mid || in_single)) {
yyerror("END in method; use at_exit");
@@ -2789,14 +2790,14 @@ case 21:
;
break;}
case 22:
-#line 373 "parse.y"
+#line 374 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = node_assign(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 24:
-#line 380 "parse.y"
+#line 381 "parse.y"
{
value_expr(yyvsp[0].node);
yyvsp[-2].node->nd_value = yyvsp[0].node;
@@ -2804,7 +2805,7 @@ case 24:
;
break;}
case 25:
-#line 386 "parse.y"
+#line 387 "parse.y"
{
value_expr(yyvsp[0].node);
if (!compile_for_eval && !cur_mid && !in_single)
@@ -2813,47 +2814,47 @@ case 25:
;
break;}
case 26:
-#line 393 "parse.y"
+#line 394 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_YIELD(yyvsp[0].node);
;
break;}
case 28:
-#line 399 "parse.y"
+#line 400 "parse.y"
{
yyval.node = logop(NODE_AND, yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 29:
-#line 403 "parse.y"
+#line 404 "parse.y"
{
yyval.node = logop(NODE_OR, yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 30:
-#line 407 "parse.y"
+#line 408 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_NOT(cond(yyvsp[0].node));
;
break;}
case 31:
-#line 412 "parse.y"
+#line 413 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_NOT(cond(yyvsp[0].node));
;
break;}
case 33:
-#line 419 "parse.y"
+#line 420 "parse.y"
{
yyval.node = new_fcall(yyvsp[-1].id, yyvsp[0].node);
fixpos(yyval.node, yyvsp[0].node);
;
break;}
case 34:
-#line 424 "parse.y"
+#line 425 "parse.y"
{
value_expr(yyvsp[-3].node);
yyval.node = new_call(yyvsp[-3].node, yyvsp[-1].id, yyvsp[0].node);
@@ -2861,7 +2862,7 @@ case 34:
;
break;}
case 35:
-#line 430 "parse.y"
+#line 431 "parse.y"
{
value_expr(yyvsp[-3].node);
yyval.node = new_call(yyvsp[-3].node, yyvsp[-1].id, yyvsp[0].node);
@@ -2869,7 +2870,7 @@ case 35:
;
break;}
case 36:
-#line 436 "parse.y"
+#line 437 "parse.y"
{
if (!compile_for_eval && !cur_mid && !in_single)
yyerror("super called outside of method");
@@ -2878,278 +2879,278 @@ case 36:
;
break;}
case 38:
-#line 445 "parse.y"
+#line 446 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 40:
-#line 451 "parse.y"
+#line 452 "parse.y"
{
yyval.node = NEW_MASGN(NEW_LIST(yyvsp[-1].node), 0);
;
break;}
case 41:
-#line 456 "parse.y"
+#line 457 "parse.y"
{
yyval.node = NEW_MASGN(NEW_LIST(yyvsp[0].node), 0);
;
break;}
case 42:
-#line 460 "parse.y"
+#line 461 "parse.y"
{
yyval.node = NEW_MASGN(NEW_LIST(yyvsp[-2].node), yyvsp[0].node);
;
break;}
case 43:
-#line 464 "parse.y"
+#line 465 "parse.y"
{
yyval.node = NEW_MASGN(list_concat(NEW_LIST(yyvsp[-1].node),yyvsp[0].node), 0);
;
break;}
case 44:
-#line 468 "parse.y"
+#line 469 "parse.y"
{
yyval.node = NEW_MASGN(list_concat(NEW_LIST(yyvsp[-4].node),yyvsp[-3].node),yyvsp[0].node);
;
break;}
case 45:
-#line 472 "parse.y"
+#line 473 "parse.y"
{
yyval.node = NEW_MASGN(0, yyvsp[0].node);
;
break;}
case 47:
-#line 478 "parse.y"
+#line 479 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 48:
-#line 483 "parse.y"
+#line 484 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 49:
-#line 488 "parse.y"
+#line 489 "parse.y"
{
yyval.node = NEW_LIST(yyvsp[0].node);
;
break;}
case 50:
-#line 492 "parse.y"
+#line 493 "parse.y"
{
yyval.node = list_append(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 51:
-#line 497 "parse.y"
+#line 498 "parse.y"
{
yyval.node = assignable(yyvsp[0].id, 0);
;
break;}
case 52:
-#line 501 "parse.y"
+#line 502 "parse.y"
{
yyval.node = aryset(yyvsp[-3].node, yyvsp[-1].node);
;
break;}
case 53:
-#line 505 "parse.y"
+#line 506 "parse.y"
{
yyval.node = attrset(yyvsp[-2].node, yyvsp[0].id);
;
break;}
case 54:
-#line 509 "parse.y"
+#line 510 "parse.y"
{
rb_backref_error(yyvsp[0].node);
yyval.node = 0;
;
break;}
case 55:
-#line 515 "parse.y"
+#line 516 "parse.y"
{
yyval.node = assignable(yyvsp[0].id, 0);
;
break;}
case 56:
-#line 519 "parse.y"
+#line 520 "parse.y"
{
yyval.node = aryset(yyvsp[-3].node, yyvsp[-1].node);
;
break;}
case 57:
-#line 523 "parse.y"
+#line 524 "parse.y"
{
yyval.node = attrset(yyvsp[-2].node, yyvsp[0].id);
;
break;}
case 58:
-#line 527 "parse.y"
+#line 528 "parse.y"
{
rb_backref_error(yyvsp[0].node);
yyval.node = 0;
;
break;}
case 59:
-#line 533 "parse.y"
+#line 534 "parse.y"
{
yyerror("class/module name must be CONSTANT");
;
break;}
case 64:
-#line 542 "parse.y"
+#line 543 "parse.y"
{
lex_state = EXPR_END;
yyval.id = yyvsp[0].id;
;
break;}
case 65:
-#line 547 "parse.y"
+#line 548 "parse.y"
{
lex_state = EXPR_END;
yyval.id = yyvsp[0].id;
;
break;}
case 66:
-#line 553 "parse.y"
+#line 554 "parse.y"
{
yyval.node = NEW_UNDEF(yyvsp[0].id);
;
break;}
case 67:
-#line 556 "parse.y"
+#line 557 "parse.y"
{lex_state = EXPR_FNAME;;
break;}
case 68:
-#line 557 "parse.y"
+#line 558 "parse.y"
{
yyval.node = block_append(yyvsp[-3].node, NEW_UNDEF(yyvsp[0].id));
;
break;}
case 69:
-#line 561 "parse.y"
+#line 562 "parse.y"
{ yyval.id = tDOT2; ;
break;}
case 70:
-#line 562 "parse.y"
+#line 563 "parse.y"
{ yyval.id = '|'; ;
break;}
case 71:
-#line 563 "parse.y"
+#line 564 "parse.y"
{ yyval.id = '^'; ;
break;}
case 72:
-#line 564 "parse.y"
+#line 565 "parse.y"
{ yyval.id = '&'; ;
break;}
case 73:
-#line 565 "parse.y"
+#line 566 "parse.y"
{ yyval.id = tCMP; ;
break;}
case 74:
-#line 566 "parse.y"
+#line 567 "parse.y"
{ yyval.id = tEQ; ;
break;}
case 75:
-#line 567 "parse.y"
+#line 568 "parse.y"
{ yyval.id = tEQQ; ;
break;}
case 76:
-#line 568 "parse.y"
+#line 569 "parse.y"
{ yyval.id = tMATCH; ;
break;}
case 77:
-#line 569 "parse.y"
+#line 570 "parse.y"
{ yyval.id = '>'; ;
break;}
case 78:
-#line 570 "parse.y"
+#line 571 "parse.y"
{ yyval.id = tGEQ; ;
break;}
case 79:
-#line 571 "parse.y"
+#line 572 "parse.y"
{ yyval.id = '<'; ;
break;}
case 80:
-#line 572 "parse.y"
+#line 573 "parse.y"
{ yyval.id = tLEQ; ;
break;}
case 81:
-#line 573 "parse.y"
+#line 574 "parse.y"
{ yyval.id = tLSHFT; ;
break;}
case 82:
-#line 574 "parse.y"
+#line 575 "parse.y"
{ yyval.id = tRSHFT; ;
break;}
case 83:
-#line 575 "parse.y"
+#line 576 "parse.y"
{ yyval.id = '+'; ;
break;}
case 84:
-#line 576 "parse.y"
+#line 577 "parse.y"
{ yyval.id = '-'; ;
break;}
case 85:
-#line 577 "parse.y"
+#line 578 "parse.y"
{ yyval.id = '*'; ;
break;}
case 86:
-#line 578 "parse.y"
+#line 579 "parse.y"
{ yyval.id = '*'; ;
break;}
case 87:
-#line 579 "parse.y"
+#line 580 "parse.y"
{ yyval.id = '/'; ;
break;}
case 88:
-#line 580 "parse.y"
+#line 581 "parse.y"
{ yyval.id = '%'; ;
break;}
case 89:
-#line 581 "parse.y"
+#line 582 "parse.y"
{ yyval.id = tPOW; ;
break;}
case 90:
-#line 582 "parse.y"
+#line 583 "parse.y"
{ yyval.id = '~'; ;
break;}
case 91:
-#line 583 "parse.y"
+#line 584 "parse.y"
{ yyval.id = tUPLUS; ;
break;}
case 92:
-#line 584 "parse.y"
+#line 585 "parse.y"
{ yyval.id = tUMINUS; ;
break;}
case 93:
-#line 585 "parse.y"
+#line 586 "parse.y"
{ yyval.id = tAREF; ;
break;}
case 94:
-#line 586 "parse.y"
+#line 587 "parse.y"
{ yyval.id = tASET; ;
break;}
case 95:
-#line 587 "parse.y"
+#line 588 "parse.y"
{ yyval.id = '`'; ;
break;}
case 136:
-#line 598 "parse.y"
+#line 599 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = node_assign(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 137:
-#line 602 "parse.y"
+#line 603 "parse.y"
{yyval.node = assignable(yyvsp[-1].id, 0);;
break;}
case 138:
-#line 603 "parse.y"
+#line 604 "parse.y"
{
if (yyvsp[-2].id == tOROP) {
yyvsp[-1].node->nd_value = yyvsp[0].node;
@@ -3167,7 +3168,7 @@ case 138:
;
break;}
case 139:
-#line 619 "parse.y"
+#line 620 "parse.y"
{
NODE *args = NEW_LIST(yyvsp[0].node);
@@ -3184,7 +3185,7 @@ case 139:
;
break;}
case 140:
-#line 634 "parse.y"
+#line 635 "parse.y"
{
if (yyvsp[-1].id == tOROP) {
yyvsp[-1].id = 0;
@@ -3197,7 +3198,7 @@ case 140:
;
break;}
case 141:
-#line 645 "parse.y"
+#line 646 "parse.y"
{
if (yyvsp[-1].id == tOROP) {
yyvsp[-1].id = 0;
@@ -3210,200 +3211,200 @@ case 141:
;
break;}
case 142:
-#line 656 "parse.y"
+#line 657 "parse.y"
{
rb_backref_error(yyvsp[-2].node);
yyval.node = 0;
;
break;}
case 143:
-#line 661 "parse.y"
+#line 662 "parse.y"
{
yyval.node = NEW_DOT2(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 144:
-#line 665 "parse.y"
+#line 666 "parse.y"
{
yyval.node = NEW_DOT3(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 145:
-#line 669 "parse.y"
+#line 670 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '+', 1, yyvsp[0].node);
;
break;}
case 146:
-#line 673 "parse.y"
+#line 674 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '-', 1, yyvsp[0].node);
;
break;}
case 147:
-#line 677 "parse.y"
+#line 678 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '*', 1, yyvsp[0].node);
;
break;}
case 148:
-#line 681 "parse.y"
+#line 682 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '/', 1, yyvsp[0].node);
;
break;}
case 149:
-#line 685 "parse.y"
+#line 686 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '%', 1, yyvsp[0].node);
;
break;}
case 150:
-#line 689 "parse.y"
+#line 690 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tPOW, 1, yyvsp[0].node);
;
break;}
case 151:
-#line 693 "parse.y"
+#line 694 "parse.y"
{
yyval.node = call_op(yyvsp[0].node, tUPLUS, 0);
;
break;}
case 152:
-#line 697 "parse.y"
+#line 698 "parse.y"
{
yyval.node = call_op(yyvsp[0].node, tUMINUS, 0);
;
break;}
case 153:
-#line 701 "parse.y"
+#line 702 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '|', 1, yyvsp[0].node);
;
break;}
case 154:
-#line 705 "parse.y"
+#line 706 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '^', 1, yyvsp[0].node);
;
break;}
case 155:
-#line 709 "parse.y"
+#line 710 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '&', 1, yyvsp[0].node);
;
break;}
case 156:
-#line 713 "parse.y"
+#line 714 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tCMP, 1, yyvsp[0].node);
;
break;}
case 157:
-#line 717 "parse.y"
+#line 718 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '>', 1, yyvsp[0].node);
;
break;}
case 158:
-#line 721 "parse.y"
+#line 722 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tGEQ, 1, yyvsp[0].node);
;
break;}
case 159:
-#line 725 "parse.y"
+#line 726 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, '<', 1, yyvsp[0].node);
;
break;}
case 160:
-#line 729 "parse.y"
+#line 730 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tLEQ, 1, yyvsp[0].node);
;
break;}
case 161:
-#line 733 "parse.y"
+#line 734 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tEQ, 1, yyvsp[0].node);
;
break;}
case 162:
-#line 737 "parse.y"
+#line 738 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tEQQ, 1, yyvsp[0].node);
;
break;}
case 163:
-#line 741 "parse.y"
+#line 742 "parse.y"
{
yyval.node = NEW_NOT(call_op(yyvsp[-2].node, tEQ, 1, yyvsp[0].node));
;
break;}
case 164:
-#line 745 "parse.y"
+#line 746 "parse.y"
{
yyval.node = match_gen(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 165:
-#line 749 "parse.y"
+#line 750 "parse.y"
{
yyval.node = NEW_NOT(match_gen(yyvsp[-2].node, yyvsp[0].node));
;
break;}
case 166:
-#line 753 "parse.y"
+#line 754 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_NOT(cond(yyvsp[0].node));
;
break;}
case 167:
-#line 758 "parse.y"
+#line 759 "parse.y"
{
yyval.node = call_op(yyvsp[0].node, '~', 0);
;
break;}
case 168:
-#line 762 "parse.y"
+#line 763 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tLSHFT, 1, yyvsp[0].node);
;
break;}
case 169:
-#line 766 "parse.y"
+#line 767 "parse.y"
{
yyval.node = call_op(yyvsp[-2].node, tRSHFT, 1, yyvsp[0].node);
;
break;}
case 170:
-#line 770 "parse.y"
+#line 771 "parse.y"
{
yyval.node = logop(NODE_AND, yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 171:
-#line 774 "parse.y"
+#line 775 "parse.y"
{
yyval.node = logop(NODE_OR, yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 172:
-#line 777 "parse.y"
+#line 778 "parse.y"
{in_defined = 1;;
break;}
case 173:
-#line 778 "parse.y"
+#line 779 "parse.y"
{
in_defined = 0;
yyval.node = NEW_DEFINED(yyvsp[0].node);
;
break;}
case 174:
-#line 783 "parse.y"
+#line 784 "parse.y"
{
value_expr(yyvsp[-4].node);
yyval.node = NEW_IF(cond(yyvsp[-4].node), yyvsp[-2].node, yyvsp[0].node);
@@ -3411,13 +3412,13 @@ case 174:
;
break;}
case 175:
-#line 789 "parse.y"
+#line 790 "parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 176:
-#line 794 "parse.y"
+#line 795 "parse.y"
{
if (yyvsp[0].node && nd_type(yyvsp[0].node) == NODE_BLOCK_PASS) {
rb_compile_error("block argument should not be given");
@@ -3426,107 +3427,107 @@ case 176:
;
break;}
case 179:
-#line 805 "parse.y"
+#line 806 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_LIST(yyvsp[0].node);
;
break;}
case 180:
-#line 810 "parse.y"
+#line 811 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 181:
-#line 814 "parse.y"
+#line 815 "parse.y"
{
yyval.node = arg_blk_pass(yyvsp[-1].node, yyvsp[0].node);
;
break;}
case 182:
-#line 818 "parse.y"
+#line 819 "parse.y"
{
yyval.node = arg_concat(yyvsp[-4].node, yyvsp[-1].node);
yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node);
;
break;}
case 183:
-#line 823 "parse.y"
+#line 824 "parse.y"
{
yyval.node = NEW_LIST(NEW_HASH(yyvsp[-1].node));
;
break;}
case 184:
-#line 827 "parse.y"
+#line 828 "parse.y"
{
yyval.node = NEW_LIST(NEW_HASH(yyvsp[-1].node));
yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node);
;
break;}
case 185:
-#line 832 "parse.y"
+#line 833 "parse.y"
{
yyval.node = arg_concat(NEW_LIST(NEW_HASH(yyvsp[-4].node)), yyvsp[-1].node);
yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node);
;
break;}
case 186:
-#line 837 "parse.y"
+#line 838 "parse.y"
{
yyval.node = list_append(yyvsp[-3].node, NEW_HASH(yyvsp[-1].node));
yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node);
;
break;}
case 187:
-#line 842 "parse.y"
+#line 843 "parse.y"
{
yyval.node = list_append(yyvsp[-3].node, NEW_HASH(yyvsp[-1].node));
;
break;}
case 188:
-#line 846 "parse.y"
+#line 847 "parse.y"
{
yyval.node = arg_concat(list_append(yyvsp[-6].node, NEW_HASH(yyvsp[-4].node)), yyvsp[-1].node);
yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node);
;
break;}
case 189:
-#line 851 "parse.y"
+#line 852 "parse.y"
{
value_expr(yyvsp[-1].node);
yyval.node = arg_blk_pass(NEW_RESTARGS(yyvsp[-1].node), yyvsp[0].node);
;
break;}
case 191:
-#line 858 "parse.y"
+#line 859 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_BLOCK_PASS(yyvsp[0].node);
;
break;}
case 192:
-#line 864 "parse.y"
+#line 865 "parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 196:
-#line 873 "parse.y"
+#line 874 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_LIST(yyvsp[0].node);
;
break;}
case 197:
-#line 878 "parse.y"
+#line 879 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = list_append(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 198:
-#line 884 "parse.y"
+#line 885 "parse.y"
{
if (yyvsp[0].node &&
nd_type(yyvsp[0].node) == NODE_ARRAY &&
@@ -3540,21 +3541,21 @@ case 198:
;
break;}
case 199:
-#line 896 "parse.y"
+#line 897 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = arg_concat(yyvsp[-3].node, yyvsp[0].node);
;
break;}
case 200:
-#line 901 "parse.y"
+#line 902 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = yyvsp[0].node;
;
break;}
case 201:
-#line 907 "parse.y"
+#line 908 "parse.y"
{
yyval.node = yyvsp[0].node;
if (yyvsp[0].node) {
@@ -3569,45 +3570,45 @@ case 201:
;
break;}
case 204:
-#line 924 "parse.y"
+#line 925 "parse.y"
{
yyval.node = NEW_LIT(yyvsp[0].val);
;
break;}
case 205:
-#line 928 "parse.y"
+#line 929 "parse.y"
{
value_expr(yyvsp[-2].node);
yyval.node = NEW_COLON2(yyvsp[-2].node, yyvsp[0].id);
;
break;}
case 206:
-#line 933 "parse.y"
+#line 934 "parse.y"
{
yyval.node = NEW_COLON3(yyvsp[0].id);
;
break;}
case 207:
-#line 937 "parse.y"
+#line 938 "parse.y"
{
yyval.node = NEW_STR(yyvsp[0].val);
;
break;}
case 209:
-#line 942 "parse.y"
+#line 943 "parse.y"
{
yyval.node = NEW_XSTR(yyvsp[0].val);
;
break;}
case 214:
-#line 950 "parse.y"
+#line 951 "parse.y"
{
value_expr(yyvsp[-3].node);
yyval.node = NEW_CALL(yyvsp[-3].node, tAREF, yyvsp[-1].node);
;
break;}
case 215:
-#line 955 "parse.y"
+#line 956 "parse.y"
{
if (yyvsp[-1].node == 0)
yyval.node = NEW_ZARRAY(); /* zero length array*/
@@ -3617,13 +3618,13 @@ case 215:
;
break;}
case 216:
-#line 963 "parse.y"
+#line 964 "parse.y"
{
yyval.node = NEW_HASH(yyvsp[-1].node);
;
break;}
case 217:
-#line 967 "parse.y"
+#line 968 "parse.y"
{
if (!compile_for_eval && !cur_mid && !in_single)
yyerror("return appeared outside of method");
@@ -3632,7 +3633,7 @@ case 217:
;
break;}
case 218:
-#line 974 "parse.y"
+#line 975 "parse.y"
{
if (!compile_for_eval && !cur_mid && !in_single)
yyerror("return appeared outside of method");
@@ -3640,7 +3641,7 @@ case 218:
;
break;}
case 219:
-#line 980 "parse.y"
+#line 981 "parse.y"
{
if (!compile_for_eval && !cur_mid && !in_single)
yyerror("return appeared outside of method");
@@ -3648,50 +3649,50 @@ case 219:
;
break;}
case 220:
-#line 986 "parse.y"
+#line 987 "parse.y"
{
value_expr(yyvsp[-1].node);
yyval.node = NEW_YIELD(yyvsp[-1].node);
;
break;}
case 221:
-#line 991 "parse.y"
+#line 992 "parse.y"
{
yyval.node = NEW_YIELD(0);
;
break;}
case 222:
-#line 995 "parse.y"
+#line 996 "parse.y"
{
yyval.node = NEW_YIELD(0);
;
break;}
case 223:
-#line 998 "parse.y"
+#line 999 "parse.y"
{in_defined = 1;;
break;}
case 224:
-#line 999 "parse.y"
+#line 1000 "parse.y"
{
in_defined = 0;
yyval.node = NEW_DEFINED(yyvsp[-1].node);
;
break;}
case 225:
-#line 1004 "parse.y"
+#line 1005 "parse.y"
{
yyval.node = NEW_VCALL(yyvsp[0].id);
;
break;}
case 226:
-#line 1008 "parse.y"
+#line 1009 "parse.y"
{
yyvsp[0].node->nd_iter = NEW_FCALL(yyvsp[-1].id, 0);
yyval.node = yyvsp[0].node;
;
break;}
case 228:
-#line 1014 "parse.y"
+#line 1015 "parse.y"
{
if (yyvsp[-1].node && nd_type(yyvsp[-1].node) == NODE_BLOCK_PASS) {
rb_compile_error("both block arg and actual block given");
@@ -3702,7 +3703,7 @@ case 228:
;
break;}
case 229:
-#line 1026 "parse.y"
+#line 1027 "parse.y"
{
value_expr(yyvsp[-4].node);
yyval.node = NEW_IF(cond(yyvsp[-4].node), yyvsp[-2].node, yyvsp[-1].node);
@@ -3710,7 +3711,7 @@ case 229:
;
break;}
case 230:
-#line 1035 "parse.y"
+#line 1036 "parse.y"
{
value_expr(yyvsp[-4].node);
yyval.node = NEW_UNLESS(cond(yyvsp[-4].node), yyvsp[-2].node, yyvsp[-1].node);
@@ -3718,7 +3719,7 @@ case 230:
;
break;}
case 231:
-#line 1043 "parse.y"
+#line 1044 "parse.y"
{
value_expr(yyvsp[-3].node);
yyval.node = NEW_WHILE(cond(yyvsp[-3].node), yyvsp[-1].node, 1);
@@ -3726,7 +3727,7 @@ case 231:
;
break;}
case 232:
-#line 1051 "parse.y"
+#line 1052 "parse.y"
{
value_expr(yyvsp[-3].node);
yyval.node = NEW_UNTIL(cond(yyvsp[-3].node), yyvsp[-1].node, 1);
@@ -3734,7 +3735,7 @@ case 232:
;
break;}
case 233:
-#line 1059 "parse.y"
+#line 1060 "parse.y"
{
value_expr(yyvsp[-2].node);
yyval.node = NEW_CASE(yyvsp[-2].node, yyvsp[-1].node);
@@ -3742,7 +3743,7 @@ case 233:
;
break;}
case 234:
-#line 1067 "parse.y"
+#line 1068 "parse.y"
{
value_expr(yyvsp[-5].node);
yyval.node = NEW_FOR(yyvsp[-5].node, yyvsp[-3].node, yyvsp[-1].node);
@@ -3750,7 +3751,7 @@ case 234:
;
break;}
case 235:
-#line 1078 "parse.y"
+#line 1079 "parse.y"
{
if (!yyvsp[-3].node && !yyvsp[-2].node && !yyvsp[-1].node)
yyval.node = NEW_BEGIN(yyvsp[-4].node);
@@ -3767,13 +3768,13 @@ case 235:
;
break;}
case 236:
-#line 1093 "parse.y"
+#line 1094 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 237:
-#line 1097 "parse.y"
+#line 1098 "parse.y"
{
if (cur_mid || in_single)
yyerror("class definition in method body");
@@ -3784,7 +3785,7 @@ case 237:
;
break;}
case 238:
-#line 1107 "parse.y"
+#line 1108 "parse.y"
{
yyval.node = NEW_CLASS(yyvsp[-4].id, yyvsp[-1].node, yyvsp[-3].node);
fixpos(yyval.node, yyvsp[-3].node);
@@ -3794,7 +3795,7 @@ case 238:
;
break;}
case 239:
-#line 1115 "parse.y"
+#line 1116 "parse.y"
{
class_nest++;
cref_push();
@@ -3802,7 +3803,7 @@ case 239:
;
break;}
case 240:
-#line 1122 "parse.y"
+#line 1123 "parse.y"
{
yyval.node = NEW_SCLASS(yyvsp[-4].node, yyvsp[-1].node);
fixpos(yyval.node, yyvsp[-4].node);
@@ -3812,7 +3813,7 @@ case 240:
;
break;}
case 241:
-#line 1130 "parse.y"
+#line 1131 "parse.y"
{
if (cur_mid || in_single)
yyerror("module definition in method body");
@@ -3822,7 +3823,7 @@ case 241:
;
break;}
case 242:
-#line 1139 "parse.y"
+#line 1140 "parse.y"
{
yyval.node = NEW_MODULE(yyvsp[-3].id, yyvsp[-1].node);
fixpos(yyval.node, yyvsp[-1].node);
@@ -3832,7 +3833,7 @@ case 242:
;
break;}
case 243:
-#line 1147 "parse.y"
+#line 1148 "parse.y"
{
if (cur_mid || in_single)
yyerror("nested method definition");
@@ -3841,7 +3842,7 @@ case 243:
;
break;}
case 244:
-#line 1156 "parse.y"
+#line 1157 "parse.y"
{
/* NOEX_PRIVATE for toplevel */
yyval.node = NEW_DEFN(yyvsp[-4].id, yyvsp[-2].node, yyvsp[-1].node, class_nest?0:1);
@@ -3851,11 +3852,11 @@ case 244:
;
break;}
case 245:
-#line 1163 "parse.y"
+#line 1164 "parse.y"
{lex_state = EXPR_FNAME;;
break;}
case 246:
-#line 1164 "parse.y"
+#line 1165 "parse.y"
{
value_expr(yyvsp[-3].node);
in_single++;
@@ -3864,7 +3865,7 @@ case 246:
;
break;}
case 247:
-#line 1173 "parse.y"
+#line 1174 "parse.y"
{
yyval.node = NEW_DEFS(yyvsp[-7].node, yyvsp[-4].id, yyvsp[-2].node, yyvsp[-1].node);
fixpos(yyval.node, yyvsp[-7].node);
@@ -3873,31 +3874,31 @@ case 247:
;
break;}
case 248:
-#line 1180 "parse.y"
+#line 1181 "parse.y"
{
yyval.node = NEW_BREAK();
;
break;}
case 249:
-#line 1184 "parse.y"
+#line 1185 "parse.y"
{
yyval.node = NEW_NEXT();
;
break;}
case 250:
-#line 1188 "parse.y"
+#line 1189 "parse.y"
{
yyval.node = NEW_REDO();
;
break;}
case 251:
-#line 1192 "parse.y"
+#line 1193 "parse.y"
{
yyval.node = NEW_RETRY();
;
break;}
case 258:
-#line 1207 "parse.y"
+#line 1208 "parse.y"
{
value_expr(yyvsp[-3].node);
yyval.node = NEW_IF(cond(yyvsp[-3].node), yyvsp[-1].node, yyvsp[0].node);
@@ -3905,37 +3906,37 @@ case 258:
;
break;}
case 260:
-#line 1215 "parse.y"
+#line 1216 "parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 264:
-#line 1224 "parse.y"
+#line 1225 "parse.y"
{
yyval.node = 0;
;
break;}
case 265:
-#line 1228 "parse.y"
+#line 1229 "parse.y"
{
yyval.node = 0;
;
break;}
case 266:
-#line 1232 "parse.y"
+#line 1233 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 267:
-#line 1237 "parse.y"
+#line 1238 "parse.y"
{
yyval.vars = dyna_push();
;
break;}
case 268:
-#line 1243 "parse.y"
+#line 1244 "parse.y"
{
yyval.node = NEW_ITER(yyvsp[-2].node, 0, yyvsp[-1].node);
fixpos(yyval.node, yyvsp[-2].node?yyvsp[-2].node:yyvsp[-1].node);
@@ -3943,13 +3944,13 @@ case 268:
;
break;}
case 269:
-#line 1250 "parse.y"
+#line 1251 "parse.y"
{
yyval.vars = dyna_push();
;
break;}
case 270:
-#line 1255 "parse.y"
+#line 1256 "parse.y"
{
yyval.node = NEW_ITER(yyvsp[-2].node, 0, yyvsp[-1].node);
fixpos(yyval.node, yyvsp[-2].node?yyvsp[-2].node:yyvsp[-1].node);
@@ -3957,25 +3958,25 @@ case 270:
;
break;}
case 271:
-#line 1262 "parse.y"
+#line 1263 "parse.y"
{
yyval.node = NEW_VCALL(yyvsp[0].id);
;
break;}
case 272:
-#line 1266 "parse.y"
+#line 1267 "parse.y"
{
yyval.node = NEW_VCALL(yyvsp[0].id);
;
break;}
case 273:
-#line 1270 "parse.y"
+#line 1271 "parse.y"
{
yyval.node = NEW_VCALL(yyvsp[0].id);
;
break;}
case 276:
-#line 1277 "parse.y"
+#line 1278 "parse.y"
{
if (yyvsp[-1].node && nd_type(yyvsp[-1].node) == NODE_BLOCK_PASS) {
rb_compile_error("both block arg and actual block given");
@@ -3986,14 +3987,14 @@ case 276:
;
break;}
case 277:
-#line 1287 "parse.y"
+#line 1288 "parse.y"
{
yyval.node = new_fcall(yyvsp[-3].id, yyvsp[-1].node);
fixpos(yyval.node, yyvsp[-1].node);
;
break;}
case 278:
-#line 1292 "parse.y"
+#line 1293 "parse.y"
{
value_expr(yyvsp[-5].node);
yyval.node = new_call(yyvsp[-5].node, yyvsp[-3].id, yyvsp[-1].node);
@@ -4001,7 +4002,7 @@ case 278:
;
break;}
case 279:
-#line 1298 "parse.y"
+#line 1299 "parse.y"
{
value_expr(yyvsp[-2].node);
yyval.node = new_call(yyvsp[-2].node, yyvsp[0].id, 0);
@@ -4009,7 +4010,7 @@ case 279:
;
break;}
case 280:
-#line 1304 "parse.y"
+#line 1305 "parse.y"
{
value_expr(yyvsp[-5].node);
yyval.node = new_call(yyvsp[-5].node, yyvsp[-3].id, yyvsp[-1].node);
@@ -4017,14 +4018,14 @@ case 280:
;
break;}
case 281:
-#line 1310 "parse.y"
+#line 1311 "parse.y"
{
value_expr(yyvsp[-2].node);
yyval.node = new_call(yyvsp[-2].node, yyvsp[0].id, 0);
;
break;}
case 282:
-#line 1315 "parse.y"
+#line 1316 "parse.y"
{
if (!compile_for_eval && !cur_mid &&
!in_single && !in_defined)
@@ -4033,7 +4034,7 @@ case 282:
;
break;}
case 283:
-#line 1322 "parse.y"
+#line 1323 "parse.y"
{
if (!compile_for_eval && !cur_mid &&
!in_single && !in_defined)
@@ -4042,165 +4043,165 @@ case 283:
;
break;}
case 286:
-#line 1336 "parse.y"
+#line 1337 "parse.y"
{
yyval.node = NEW_WHEN(yyvsp[-3].node, yyvsp[-1].node, yyvsp[0].node);
;
break;}
case 288:
-#line 1342 "parse.y"
+#line 1343 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = list_append(yyvsp[-3].node, NEW_WHEN(yyvsp[0].node, 0, 0));
;
break;}
case 289:
-#line 1347 "parse.y"
+#line 1348 "parse.y"
{
value_expr(yyvsp[0].node);
yyval.node = NEW_LIST(NEW_WHEN(yyvsp[0].node, 0, 0));
;
break;}
case 292:
-#line 1358 "parse.y"
+#line 1359 "parse.y"
{
yyval.node = NEW_RESBODY(yyvsp[-3].node, yyvsp[-1].node, yyvsp[0].node);
fixpos(yyval.node, yyvsp[-3].node?yyvsp[-3].node:yyvsp[-1].node);
;
break;}
case 295:
-#line 1366 "parse.y"
+#line 1367 "parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 297:
-#line 1372 "parse.y"
+#line 1373 "parse.y"
{
yyval.val = INT2FIX(yyvsp[0].id);
;
break;}
case 308:
-#line 1388 "parse.y"
+#line 1389 "parse.y"
{yyval.id = kNIL;;
break;}
case 309:
-#line 1389 "parse.y"
+#line 1390 "parse.y"
{yyval.id = kSELF;;
break;}
case 310:
-#line 1390 "parse.y"
+#line 1391 "parse.y"
{yyval.id = kTRUE;;
break;}
case 311:
-#line 1391 "parse.y"
+#line 1392 "parse.y"
{yyval.id = kFALSE;;
break;}
case 312:
-#line 1392 "parse.y"
+#line 1393 "parse.y"
{yyval.id = k__FILE__;;
break;}
case 313:
-#line 1393 "parse.y"
+#line 1394 "parse.y"
{yyval.id = k__LINE__;;
break;}
case 314:
-#line 1396 "parse.y"
+#line 1397 "parse.y"
{
yyval.node = gettable(yyvsp[0].id);
;
break;}
case 317:
-#line 1404 "parse.y"
+#line 1405 "parse.y"
{
yyval.node = 0;
;
break;}
case 318:
-#line 1408 "parse.y"
+#line 1409 "parse.y"
{
lex_state = EXPR_BEG;
;
break;}
case 319:
-#line 1412 "parse.y"
+#line 1413 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 320:
-#line 1415 "parse.y"
+#line 1416 "parse.y"
{yyerrok; yyval.node = 0;;
break;}
case 321:
-#line 1418 "parse.y"
+#line 1419 "parse.y"
{
yyval.node = yyvsp[-2].node;
lex_state = EXPR_BEG;
;
break;}
case 322:
-#line 1423 "parse.y"
+#line 1424 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 323:
-#line 1428 "parse.y"
+#line 1429 "parse.y"
{
yyval.node = block_append(NEW_ARGS(yyvsp[-5].num, yyvsp[-3].node, yyvsp[-1].id), yyvsp[0].node);
;
break;}
case 324:
-#line 1432 "parse.y"
+#line 1433 "parse.y"
{
yyval.node = block_append(NEW_ARGS(yyvsp[-3].num, yyvsp[-1].node, -1), yyvsp[0].node);
;
break;}
case 325:
-#line 1436 "parse.y"
+#line 1437 "parse.y"
{
yyval.node = block_append(NEW_ARGS(yyvsp[-3].num, 0, yyvsp[-1].id), yyvsp[0].node);
;
break;}
case 326:
-#line 1440 "parse.y"
+#line 1441 "parse.y"
{
yyval.node = block_append(NEW_ARGS(yyvsp[-1].num, 0, -1), yyvsp[0].node);
;
break;}
case 327:
-#line 1444 "parse.y"
+#line 1445 "parse.y"
{
yyval.node = block_append(NEW_ARGS(0, yyvsp[-3].node, yyvsp[-1].id), yyvsp[0].node);
;
break;}
case 328:
-#line 1448 "parse.y"
+#line 1449 "parse.y"
{
yyval.node = block_append(NEW_ARGS(0, yyvsp[-1].node, -1), yyvsp[0].node);
;
break;}
case 329:
-#line 1452 "parse.y"
+#line 1453 "parse.y"
{
yyval.node = block_append(NEW_ARGS(0, 0, yyvsp[-1].id), yyvsp[0].node);
;
break;}
case 330:
-#line 1456 "parse.y"
+#line 1457 "parse.y"
{
yyval.node = block_append(NEW_ARGS(0, 0, -1), yyvsp[0].node);
;
break;}
case 331:
-#line 1460 "parse.y"
+#line 1461 "parse.y"
{
yyval.node = NEW_ARGS(0, 0, -1);
;
break;}
case 332:
-#line 1465 "parse.y"
+#line 1466 "parse.y"
{
if (!is_local_id(yyvsp[0].id))
yyerror("formal argument must be local variable");
@@ -4209,7 +4210,7 @@ case 332:
;
break;}
case 333:
-#line 1472 "parse.y"
+#line 1473 "parse.y"
{
if (!is_local_id(yyvsp[0].id))
yyerror("formal argument must be local variable");
@@ -4218,7 +4219,7 @@ case 333:
;
break;}
case 334:
-#line 1480 "parse.y"
+#line 1481 "parse.y"
{
if (!is_local_id(yyvsp[-2].id))
yyerror("formal argument must be local variable");
@@ -4226,20 +4227,20 @@ case 334:
;
break;}
case 335:
-#line 1487 "parse.y"
+#line 1488 "parse.y"
{
yyval.node = NEW_BLOCK(yyvsp[0].node);
yyval.node->nd_end = yyval.node;
;
break;}
case 336:
-#line 1492 "parse.y"
+#line 1493 "parse.y"
{
yyval.node = block_append(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 337:
-#line 1497 "parse.y"
+#line 1498 "parse.y"
{
if (!is_local_id(yyvsp[0].id))
yyerror("rest argument must be local variable");
@@ -4247,19 +4248,19 @@ case 337:
;
break;}
case 338:
-#line 1504 "parse.y"
+#line 1505 "parse.y"
{
yyval.node = NEW_BLOCK_ARG(yyvsp[0].id);
;
break;}
case 339:
-#line 1509 "parse.y"
+#line 1510 "parse.y"
{
yyval.node = yyvsp[0].node;
;
break;}
case 341:
-#line 1515 "parse.y"
+#line 1516 "parse.y"
{
if (nd_type(yyvsp[0].node) == NODE_SELF) {
yyval.node = NEW_SELF();
@@ -4274,7 +4275,7 @@ case 341:
;
break;}
case 342:
-#line 1528 "parse.y"
+#line 1529 "parse.y"
{
switch (nd_type(yyvsp[-2].node)) {
case NODE_STR:
@@ -4293,13 +4294,13 @@ case 342:
;
break;}
case 344:
-#line 1547 "parse.y"
+#line 1548 "parse.y"
{
yyval.node = yyvsp[-1].node;
;
break;}
case 345:
-#line 1551 "parse.y"
+#line 1552 "parse.y"
{
if (yyvsp[-1].node->nd_alen%2 != 0) {
yyerror("odd number list for Hash");
@@ -4308,27 +4309,27 @@ case 345:
;
break;}
case 347:
-#line 1560 "parse.y"
+#line 1561 "parse.y"
{
yyval.node = list_concat(yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 348:
-#line 1565 "parse.y"
+#line 1566 "parse.y"
{
yyval.node = list_append(NEW_LIST(yyvsp[-2].node), yyvsp[0].node);
;
break;}
case 363:
-#line 1589 "parse.y"
+#line 1590 "parse.y"
{yyerrok;;
break;}
case 366:
-#line 1593 "parse.y"
+#line 1594 "parse.y"
{yyerrok;;
break;}
case 367:
-#line 1596 "parse.y"
+#line 1597 "parse.y"
{
yyval.node = 0;
;
@@ -4555,7 +4556,7 @@ yyerrhandle:
}
return 1;
}
-#line 1599 "parse.y"
+#line 1600 "parse.y"
#include <ctype.h>
#include <sys/types.h>
@@ -4672,28 +4673,27 @@ lex_get_str(s)
}
NODE*
-rb_compile_string(f, s)
+rb_compile_string(f, s, line)
const char *f;
VALUE s;
+ int line;
{
lex_gets = lex_get_str;
lex_gets_ptr = 0;
lex_input = s;
lex_pbeg = lex_p = lex_pend = 0;
- if (!ruby_sourcefile || strcmp(f, ruby_sourcefile)) /* not in eval() */
- ruby_sourceline = 0;
- else /* in eval() */
- compile_for_eval = 1;
+ ruby_sourceline = line;
+ compile_for_eval = 1;
return yycompile(f);
}
NODE*
-rb_compile_cstr(f, s, len)
+rb_compile_cstr(f, s, len, line)
const char *f, *s;
- int len;
+ int len, line;
{
- return rb_compile_string(f, rb_str_new(s, len));
+ return rb_compile_string(f, rb_str_new(s, len), line);
}
NODE*
@@ -6758,10 +6758,7 @@ void_expr(node)
case '<':
case tLEQ:
case tEQ:
- case tEQQ:
case tNEQ:
- case tMATCH:
- case tNMATCH:
case tAREF:
case tRSHFT:
case tCOLON2:
diff --git a/parse.y b/parse.y
index 8ec3489633..ca6d833a92 100644
--- a/parse.y
+++ b/parse.y
@@ -245,7 +245,8 @@ program : {
}
compstmt
{
- if ($2) { /* last expression is void */
+ if ($2 && !compile_for_eval) {
+ /* last expression should not be void */
if (nd_type($2) != NODE_BLOCK) void_expr($2);
else {
NODE *node = $2;
@@ -1712,28 +1713,27 @@ lex_get_str(s)
}
NODE*
-rb_compile_string(f, s)
+rb_compile_string(f, s, line)
const char *f;
VALUE s;
+ int line;
{
lex_gets = lex_get_str;
lex_gets_ptr = 0;
lex_input = s;
lex_pbeg = lex_p = lex_pend = 0;
- if (!ruby_sourcefile || strcmp(f, ruby_sourcefile)) /* not in eval() */
- ruby_sourceline = 0;
- else /* in eval() */
- compile_for_eval = 1;
+ ruby_sourceline = line;
+ compile_for_eval = 1;
return yycompile(f);
}
NODE*
-rb_compile_cstr(f, s, len)
+rb_compile_cstr(f, s, len, line)
const char *f, *s;
- int len;
+ int len, line;
{
- return rb_compile_string(f, rb_str_new(s, len));
+ return rb_compile_string(f, rb_str_new(s, len), line);
}
NODE*
@@ -3798,10 +3798,7 @@ void_expr(node)
case '<':
case tLEQ:
case tEQ:
- case tEQQ:
case tNEQ:
- case tMATCH:
- case tNMATCH:
case tAREF:
case tRSHFT:
case tCOLON2:
diff --git a/regex.c b/regex.c
index 27f1b56878..6c3e83b3fd 100644
--- a/regex.c
+++ b/regex.c
@@ -141,8 +141,8 @@ char *alloca();
#define TMALLOC(n,t) ((t*)xmalloc((n)*sizeof(t)))
#define TREALLOC(s,n,t) (s=((t*)xrealloc(s,(n)*sizeof(t))))
-#define EXPAND_FAIL_STACK(stackx,stackb,len) \
- do {\
+#define EXPAND_FAIL_STACK(stackx,stackb,len) \
+ do { \
/* Roughly double the size of the stack. */ \
stackx = DOUBLE_STACK(stackx,stackb,len,unsigned char*); \
/* Rearrange the pointers. */ \
@@ -401,7 +401,7 @@ enum regexpcode
such as p, not, e.g., p + 1. */
#define EXTRACT_NUMBER_AND_INCR(destination, source) \
do { EXTRACT_NUMBER(destination, source); \
- (source) += 2; } while (0)
+ (source) += 2; } while (0)
/* Specify the precise syntax of regexps for compilation. This provides
@@ -443,29 +443,29 @@ re_set_syntax(syntax)
/* Go backwards one character in the pattern. */
#define PATUNFETCH p--
-#define MBC2WC(c, p)\
- do {\
- if (current_mbctype == MBCTYPE_UTF8) {\
- int n = mbclen(c) - 1;\
- int c1;\
- c &= (1<<(BYTEWIDTH-2-n)) - 1;\
- while (n--) {\
- c = c << 6 | *p++ & ((1<<6)-1);\
- }\
- }\
- else {\
- c <<= 8;\
- c |= (unsigned char)*(p)++;\
- }\
+#define MBC2WC(c, p) \
+ do { \
+ if (current_mbctype == MBCTYPE_UTF8) { \
+ int n = mbclen(c) - 1; \
+ int c1; \
+ c &= (1<<(BYTEWIDTH-2-n)) - 1; \
+ while (n--) { \
+ c = c << 6 | *p++ & ((1<<6)-1); \
+ } \
+ } \
+ else { \
+ c <<= 8; \
+ c |= (unsigned char)*(p)++; \
+ } \
} while (0)
-#define PATFETCH_MBC(c) \
- do {\
- if (p + mbclen(c) - 1 >= pend) goto end_of_pattern;\
- MBC2WC(c, p);\
+#define PATFETCH_MBC(c) \
+ do { \
+ if (p + mbclen(c) - 1 >= pend) goto end_of_pattern; \
+ MBC2WC(c, p); \
} while(0)
-#define WC2MBC1ST(c) \
+#define WC2MBC1ST(c) \
((current_mbctype != MBCTYPE_UTF8)?(((c)>>8)&0xff):utf8_firstbyte(c))
static unsigned int
@@ -1181,14 +1181,13 @@ re_compile_pattern(pattern, size, bufp)
/* When testing what follows the $,
look past the \-constructs that don't consume anything. */
- while (p0 != pend)
- {
- if (*p0 == '\\' && p0 + 1 != pend
- && (p0[1] == 'b' || p0[1] == 'B'))
- p0 += 2;
- else
- break;
- }
+ while (p0 != pend) {
+ if (*p0 == '\\' && p0 + 1 != pend
+ && (p0[1] == 'b' || p0[1] == 'B'))
+ p0 += 2;
+ else
+ break;
+ }
BUFPUSH(endline);
break;
}
@@ -1279,11 +1278,10 @@ re_compile_pattern(pattern, size, bufp)
EXTEND_BUFFER;
laststart = b;
- if (*p == '^')
- {
- BUFPUSH(charset_not);
- p++;
- }
+ if (*p == '^') {
+ BUFPUSH(charset_not);
+ p++;
+ }
else
BUFPUSH(charset);
p0 = p;
@@ -1304,225 +1302,222 @@ re_compile_pattern(pattern, size, bufp)
}
/* Read in characters and ranges, setting map bits. */
- for (;;)
- {
- int size;
- unsigned last = (unsigned)-1;
-
- if ((size = EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH]))
- || current_mbctype) {
- /* Ensure the space is enough to hold another interval
- of multi-byte chars in charset(_not)?. */
- size = (1 << BYTEWIDTH) / BYTEWIDTH + 2 + size*8 + 8;
- while (b + size + 1 > bufp->buffer + bufp->allocated)
- EXTEND_BUFFER;
+ for (;;) {
+ int size;
+ unsigned last = (unsigned)-1;
+
+ if ((size = EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH]))
+ || current_mbctype) {
+ /* Ensure the space is enough to hold another interval
+ of multi-byte chars in charset(_not)?. */
+ size = (1 << BYTEWIDTH) / BYTEWIDTH + 2 + size*8 + 8;
+ while (b + size + 1 > bufp->buffer + bufp->allocated)
+ EXTEND_BUFFER;
+ }
+ range_retry:
+ PATFETCH(c);
+
+ if (c == ']') {
+ if (p == p0 + 1) {
+ if (p == pend)
+ goto invalid_pattern;
}
- range_retry:
- PATFETCH(c);
+ else
+ /* Stop if this isn't merely a ] inside a bracket
+ expression, but rather the end of a bracket
+ expression. */
+ break;
+ }
+ /* Look ahead to see if it's a range when the last thing
+ was a character class. */
+ if (had_char_class && c == '-' && *p != ']')
+ goto invalid_pattern;
+ if (ismbchar(c)) {
+ PATFETCH_MBC(c);
+ had_mbchar++;
+ }
- if (c == ']') {
- if (p == p0 + 1) {
- if (p == pend)
- goto invalid_pattern;
+ /* \ escapes characters when inside [...]. */
+ if (c == '\\') {
+ PATFETCH(c);
+ switch (c) {
+ case 'w':
+ for (c = 0; c < (1 << BYTEWIDTH); c++) {
+ if (SYNTAX(c) == Sword ||
+ (!current_mbctype && SYNTAX(c) == Sword2))
+ SET_LIST_BIT(c);
}
- else
- /* Stop if this isn't merely a ] inside a bracket
- expression, but rather the end of a bracket
- expression. */
- break;
- }
- /* Look ahead to see if it's a range when the last thing
- was a character class. */
- if (had_char_class && c == '-' && *p != ']')
- goto invalid_pattern;
- if (ismbchar(c)) {
- PATFETCH_MBC(c);
- had_mbchar++;
- }
+ if (current_mbctype) {
+ set_list_bits(0x80, 0xffffffff, b);
+ }
+ last = -1;
+ continue;
- /* \ escapes characters when inside [...]. */
- if (c == '\\') {
- PATFETCH(c);
- switch (c) {
- case 'w':
- for (c = 0; c < (1 << BYTEWIDTH); c++) {
- if (SYNTAX(c) == Sword ||
- (!current_mbctype && SYNTAX(c) == Sword2))
- SET_LIST_BIT(c);
- }
- if (current_mbctype) {
- set_list_bits(0x80, 0xffffffff, b);
- }
- last = -1;
- continue;
+ case 'W':
+ for (c = 0; c < (1 << BYTEWIDTH); c++) {
+ if (SYNTAX(c) != Sword &&
+ (current_mbctype || SYNTAX(c) != Sword2))
+ SET_LIST_BIT(c);
+ }
+ last = -1;
+ continue;
- case 'W':
- for (c = 0; c < (1 << BYTEWIDTH); c++) {
- if (SYNTAX(c) != Sword &&
- (current_mbctype || SYNTAX(c) != Sword2))
- SET_LIST_BIT(c);
- }
- last = -1;
- continue;
+ case 's':
+ for (c = 0; c < 256; c++)
+ if (ISSPACE(c))
+ SET_LIST_BIT(c);
+ last = -1;
+ continue;
- case 's':
- for (c = 0; c < 256; c++)
- if (ISSPACE(c))
- SET_LIST_BIT(c);
- last = -1;
- continue;
+ case 'S':
+ for (c = 0; c < 256; c++)
+ if (!ISSPACE(c))
+ SET_LIST_BIT(c);
+ if (current_mbctype)
+ set_list_bits(0x80, 0xffffffff, b);
+ last = -1;
+ continue;
- case 'S':
- for (c = 0; c < 256; c++)
- if (!ISSPACE(c))
- SET_LIST_BIT(c);
- if (current_mbctype) {
- set_list_bits(0x80, 0xffffffff, b);
- }
- last = -1;
- continue;
+ case 'd':
+ for (c = '0'; c <= '9'; c++)
+ SET_LIST_BIT(c);
+ last = -1;
+ continue;
- case 'd':
- for (c = '0'; c <= '9'; c++)
+ case 'D':
+ for (c = 0; c < 256; c++)
+ if (!ISDIGIT(c))
SET_LIST_BIT(c);
- last = -1;
- continue;
-
- case 'D':
- for (c = 0; c < 256; c++)
- if (!ISDIGIT(c))
- SET_LIST_BIT(c);
- if (current_mbctype) {
- set_list_bits(0x80, 0xffffffff, b);
- }
- last = -1;
- continue;
+ if (current_mbctype)
+ set_list_bits(0x80, 0xffffffff, b);
+ last = -1;
+ continue;
- case 'x':
- c = scan_hex(p, 2, &numlen);
- p += numlen;
- break;
+ case 'x':
+ c = scan_hex(p, 2, &numlen);
+ p += numlen;
+ break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- PATUNFETCH;
- c = scan_oct(p, 3, &numlen);
- p += numlen;
- break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ PATUNFETCH;
+ c = scan_oct(p, 3, &numlen);
+ p += numlen;
+ break;
- default:
- if (ismbchar(c)) {
- PATFETCH_MBC(c);
- had_mbchar++;
- }
- break;
+ default:
+ if (ismbchar(c)) {
+ PATFETCH_MBC(c);
+ had_mbchar++;
}
+ break;
}
+ }
- /* Get a range. */
- if (range) {
- if (last > c)
- goto invalid_pattern;
+ /* Get a range. */
+ if (range) {
+ if (last > c)
+ goto invalid_pattern;
- range = 0;
- if (had_mbchar == 0) {
- for (;last<=c;last++)
- SET_LIST_BIT(last);
- }
- else if (had_mbchar == 2) {
- set_list_bits(last, c, b);
- }
- else {
- /* restriction: range between sbc and mbc */
- goto invalid_pattern;
- }
+ range = 0;
+ if (had_mbchar == 0) {
+ for (;last<=c;last++)
+ SET_LIST_BIT(last);
}
- else if (p[0] == '-' && p[1] != ']') {
- last = c;
- PATFETCH(c1);
- range = 1;
- goto range_retry;
+ else if (had_mbchar == 2) {
+ set_list_bits(last, c, b);
}
- else if (c == '[' && *p == ':') {
- /* Leave room for the null. */
- char str[CHAR_CLASS_MAX_LENGTH + 1];
+ else {
+ /* restriction: range between sbc and mbc */
+ goto invalid_pattern;
+ }
+ }
+ else if (p[0] == '-' && p[1] != ']') {
+ last = c;
+ PATFETCH(c1);
+ range = 1;
+ goto range_retry;
+ }
+ else if (c == '[' && *p == ':') {
+ /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
- PATFETCH_RAW (c);
- c1 = 0;
+ PATFETCH_RAW (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend)
+ goto invalid_pattern;
+
+ for (;;) {
+ PATFETCH (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and:`]':
+ undo the ending character, the letters, and leave
+ the leading `:' and `[' (but set bits for them). */
+ if (c == ':' && *p == ']') {
+ int ch;
+ char is_alnum = STREQ(str, "alnum");
+ char is_alpha = STREQ(str, "alpha");
+ char is_blank = STREQ(str, "blank");
+ char is_cntrl = STREQ(str, "cntrl");
+ char is_digit = STREQ(str, "digit");
+ char is_graph = STREQ(str, "graph");
+ char is_lower = STREQ(str, "lower");
+ char is_print = STREQ(str, "print");
+ char is_punct = STREQ(str, "punct");
+ char is_space = STREQ(str, "space");
+ char is_upper = STREQ(str, "upper");
+ char is_xdigit = STREQ(str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str))
+ goto invalid_pattern;
+
+ /* Throw away the ] at the end of the character class. */
+ PATFETCH (c);
- /* If pattern is `[[:'. */
if (p == pend)
goto invalid_pattern;
- for (;;) {
- PATFETCH (c);
- if (c == ':' || c == ']' || p == pend
- || c1 == CHAR_CLASS_MAX_LENGTH)
- break;
- str[c1++] = c;
- }
- str[c1] = '\0';
-
- /* If isn't a word bracketed by `[:' and:`]':
- undo the ending character, the letters, and leave
- the leading `:' and `[' (but set bits for them). */
- if (c == ':' && *p == ']') {
- int ch;
- char is_alnum = STREQ(str, "alnum");
- char is_alpha = STREQ(str, "alpha");
- char is_blank = STREQ(str, "blank");
- char is_cntrl = STREQ(str, "cntrl");
- char is_digit = STREQ(str, "digit");
- char is_graph = STREQ(str, "graph");
- char is_lower = STREQ(str, "lower");
- char is_print = STREQ(str, "print");
- char is_punct = STREQ(str, "punct");
- char is_space = STREQ(str, "space");
- char is_upper = STREQ(str, "upper");
- char is_xdigit = STREQ(str, "xdigit");
-
- if (!IS_CHAR_CLASS (str))
- goto invalid_pattern;
-
- /* Throw away the ] at the end of the character class. */
- PATFETCH (c);
-
- if (p == pend)
- goto invalid_pattern;
-
- for (ch = 0; ch < 1 << BYTEWIDTH; ch++) {
- if ( (is_alnum && ISALNUM(ch))
- || (is_alpha && ISALPHA(ch))
- || (is_blank && ISBLANK(ch))
- || (is_cntrl && ISCNTRL(ch))
- || (is_digit && ISDIGIT(ch))
- || (is_graph && ISGRAPH(ch))
- || (is_lower && ISLOWER(ch))
- || (is_print && ISPRINT(ch))
- || (is_punct && ISPUNCT(ch))
- || (is_space && ISSPACE(ch))
- || (is_upper && ISUPPER(ch))
- || (is_xdigit && ISXDIGIT(ch)))
- SET_LIST_BIT (ch);
- }
- had_char_class = 1;
- }
- else {
- c1++;
- while (c1--)
- PATUNFETCH;
- SET_LIST_BIT(translate?translate['[']:'[');
- SET_LIST_BIT(translate?translate[':']:':');
- had_char_class = 0;
- last = ':';
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++) {
+ if ( (is_alnum && ISALNUM(ch))
+ || (is_alpha && ISALPHA(ch))
+ || (is_blank && ISBLANK(ch))
+ || (is_cntrl && ISCNTRL(ch))
+ || (is_digit && ISDIGIT(ch))
+ || (is_graph && ISGRAPH(ch))
+ || (is_lower && ISLOWER(ch))
+ || (is_print && ISPRINT(ch))
+ || (is_punct && ISPUNCT(ch))
+ || (is_space && ISSPACE(ch))
+ || (is_upper && ISUPPER(ch))
+ || (is_xdigit && ISXDIGIT(ch)))
+ SET_LIST_BIT (ch);
}
+ had_char_class = 1;
+ }
+ else {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT(TRANSLATE_P()?translate['[']:'[');
+ SET_LIST_BIT(TRANSLATE_P()?translate[':']:':');
+ had_char_class = 0;
+ last = ':';
}
- else if (had_mbchar == 0)
- SET_LIST_BIT(c);
- else
- set_list_bits(c, c, b);
- had_mbchar = 0;
}
+ else if (had_mbchar == 0)
+ SET_LIST_BIT(c);
+ else
+ set_list_bits(c, c, b);
+ had_mbchar = 0;
+ }
/* Discard any character set/class bitmap bytes that are all
0 at the end of the map. Decrement the map-length byte too. */
@@ -1680,17 +1675,17 @@ re_compile_pattern(pattern, size, bufp)
BUFPUSH((options&RE_OPTION_POSIX)?posix_off:posix_on);
}
pending_exact = 0;
- if (fixup_alt_jump)
- { /* Push a dummy failure point at the end of the
- alternative for a possible future
- `finalize_jump' to pop. See comments at
- `push_dummy_failure' in `re_match'. */
- BUFPUSH(push_dummy_failure);
-
- /* We allocated space for this jump when we assigned
- to `fixup_alt_jump', in the `handle_alt' case below. */
- store_jump(fixup_alt_jump, jump, b);
- }
+ if (fixup_alt_jump) {
+ /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `finalize_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match'. */
+ BUFPUSH(push_dummy_failure);
+
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ store_jump(fixup_alt_jump, jump, b);
+ }
options = *--stackp;
switch (c = *--stackp) {
case '(':
@@ -1772,10 +1767,9 @@ re_compile_pattern(pattern, size, bufp)
case '{':
/* If there is no previous pattern, this isn't an interval. */
- if (!laststart || p == pend)
- {
- goto normal_char;
- }
+ if (!laststart || p == pend) {
+ goto normal_char;
+ }
beg_interval = p - 1;
@@ -1872,37 +1866,37 @@ re_compile_pattern(pattern, size, bufp)
insert_op_2(set_number_at, laststart, b, 5, lower_bound);
b += 5;
- if (upper_bound > 1)
- { /* More than one repetition is allowed, so
- append a backward jump to the `succeed_n'
- that starts this interval.
-
- When we've reached this during matching,
- we'll have matched the interval once, so
- jump back only `upper_bound - 1' times. */
- GET_BUFFER_SPACE(5);
- store_jump_n(b, greedy?jump_n:finalize_push_n, laststart + 5,
- upper_bound - 1);
- b += 5;
-
- /* The location we want to set is the second
- parameter of the `jump_n'; that is `b-2' as
- an absolute address. `laststart' will be
- the `set_number_at' we're about to insert;
- `laststart+3' the number to set, the source
- for the relative address. But we are
- inserting into the middle of the pattern --
- so everything is getting moved up by 5.
- Conclusion: (b - 2) - (laststart + 3) + 5,
- i.e., b - laststart.
-
- We insert this at the beginning of the loop
- so that if we fail during matching, we'll
- reinitialize the bounds. */
- insert_op_2(set_number_at, laststart, b, b - laststart,
- upper_bound - 1);
- b += 5;
- }
+ if (upper_bound > 1) {
+ /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ GET_BUFFER_SPACE(5);
+ store_jump_n(b, greedy?jump_n:finalize_push_n, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op_2(set_number_at, laststart, b, b - laststart,
+ upper_bound - 1);
+ b += 5;
+ }
}
break;
@@ -1921,149 +1915,147 @@ re_compile_pattern(pattern, size, bufp)
distinguish, e.g., \B from \b, even if we normally would
translate, e.g., B to b. */
PATFETCH_RAW(c);
- switch (c)
- {
- case 's':
- case 'S':
- case 'd':
- case 'D':
- while (b - bufp->buffer + 9 + (1 << BYTEWIDTH) / BYTEWIDTH
- > bufp->allocated)
- EXTEND_BUFFER;
+ switch (c) {
+ case 's':
+ case 'S':
+ case 'd':
+ case 'D':
+ while (b - bufp->buffer + 9 + (1 << BYTEWIDTH) / BYTEWIDTH
+ > bufp->allocated)
+ EXTEND_BUFFER;
- laststart = b;
- if (c == 's' || c == 'd') {
- BUFPUSH(charset);
- }
- else {
- BUFPUSH(charset_not);
- }
+ laststart = b;
+ if (c == 's' || c == 'd') {
+ BUFPUSH(charset);
+ }
+ else {
+ BUFPUSH(charset_not);
+ }
- BUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH);
- memset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2);
- if (c == 's' || c == 'S') {
- SET_LIST_BIT(' ');
- SET_LIST_BIT('\t');
- SET_LIST_BIT('\n');
- SET_LIST_BIT('\r');
- SET_LIST_BIT('\f');
- }
- else {
- char cc;
+ BUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH);
+ memset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2);
+ if (c == 's' || c == 'S') {
+ SET_LIST_BIT(' ');
+ SET_LIST_BIT('\t');
+ SET_LIST_BIT('\n');
+ SET_LIST_BIT('\r');
+ SET_LIST_BIT('\f');
+ }
+ else {
+ char cc;
- for (cc = '0'; cc <= '9'; cc++) {
- SET_LIST_BIT(cc);
- }
+ for (cc = '0'; cc <= '9'; cc++) {
+ SET_LIST_BIT(cc);
}
+ }
- while ((int)b[-1] > 0 && b[b[-1] - 1] == 0)
- b[-1]--;
- if (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH)
- memmove(&b[b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH],
- 2 + EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH])*8);
- b += b[-1] + 2 + EXTRACT_UNSIGNED(&b[b[-1]])*8;
- break;
-
- case 'w':
- laststart = b;
- BUFPUSH(wordchar);
- break;
-
- case 'W':
- laststart = b;
- BUFPUSH(notwordchar);
- break;
+ while ((int)b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ if (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH)
+ memmove(&b[b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH],
+ 2 + EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH])*8);
+ b += b[-1] + 2 + EXTRACT_UNSIGNED(&b[b[-1]])*8;
+ break;
- case '<':
- BUFPUSH(wordbeg);
- break;
+ case 'w':
+ laststart = b;
+ BUFPUSH(wordchar);
+ break;
- case '>':
- BUFPUSH(wordend);
- break;
+ case 'W':
+ laststart = b;
+ BUFPUSH(notwordchar);
+ break;
- case 'b':
- BUFPUSH(wordbound);
- break;
+ case '<':
+ BUFPUSH(wordbeg);
+ break;
- case 'B':
- BUFPUSH(notwordbound);
- break;
+ case '>':
+ BUFPUSH(wordend);
+ break;
- case 'A':
- BUFPUSH(begbuf);
- break;
+ case 'b':
+ BUFPUSH(wordbound);
+ break;
- case 'Z':
- BUFPUSH(endbuf2);
- break;
+ case 'B':
+ BUFPUSH(notwordbound);
+ break;
- case 'z':
- BUFPUSH(endbuf);
- break;
+ case 'A':
+ BUFPUSH(begbuf);
+ break;
- /* hex */
- case 'x':
- had_mbchar = 0;
- c = scan_hex(p, 2, &numlen);
- p += numlen;
- goto numeric_char;
+ case 'Z':
+ BUFPUSH(endbuf2);
+ break;
- /* octal */
- case '0':
- had_mbchar = 0;
- c = scan_oct(p, 3, &numlen);
- p += numlen;
- goto numeric_char;
+ case 'z':
+ BUFPUSH(endbuf);
+ break;
- /* back-ref or octal */
- case '1': case '2': case '3':
- case '4': case '5': case '6':
- case '7': case '8': case '9':
- {
- const char *p_save;
+ /* hex */
+ case 'x':
+ had_mbchar = 0;
+ c = scan_hex(p, 2, &numlen);
+ p += numlen;
+ goto numeric_char;
+
+ /* octal */
+ case '0':
+ had_mbchar = 0;
+ c = scan_oct(p, 3, &numlen);
+ p += numlen;
+ goto numeric_char;
+
+ /* back-ref or octal */
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ {
+ const char *p_save;
- PATUNFETCH;
- p_save = p;
+ PATUNFETCH;
+ p_save = p;
- had_mbchar = 0;
+ had_mbchar = 0;
+ c1 = 0;
+ GET_UNSIGNED_NUMBER(c1);
+ if (!ISDIGIT(c)) PATUNFETCH;
+
+ if (c1 >= regnum) {
+ /* need to get octal */
+ p = p_save;
+ c = scan_oct(p_save, 3, &numlen) & 0xff;
+ p = p_save + numlen;
c1 = 0;
- GET_UNSIGNED_NUMBER(c1);
- if (!ISDIGIT(c)) PATUNFETCH;
-
- if (c1 >= regnum) {
- /* need to get octal */
- p = p_save;
- c = scan_oct(p_save, 3, &numlen) & 0xff;
- p = p_save + numlen;
- c1 = 0;
- goto numeric_char;
- }
+ goto numeric_char;
}
+ }
- /* Can't back reference to a subexpression if inside of it. */
- for (stackt = stackp - 2; stackt > stackb; stackt -= 5)
- if (*stackt == c1)
- goto normal_char;
- laststart = b;
- BUFPUSH(duplicate);
- BUFPUSH(c1);
- break;
+ /* Can't back reference to a subexpression if inside of it. */
+ for (stackt = stackp - 2; stackt > stackb; stackt -= 5)
+ if (*stackt == c1)
+ goto normal_char;
+ laststart = b;
+ BUFPUSH(duplicate);
+ BUFPUSH(c1);
+ break;
- default:
- goto normal_char;
- }
+ default:
+ goto normal_char;
+ }
break;
case '#':
- if (options & RE_OPTION_EXTENDED)
- {
- while (p != pend) {
- PATFETCH(c);
- if (c == '\n') break;
- }
- break;
+ if (options & RE_OPTION_EXTENDED) {
+ while (p != pend) {
+ PATFETCH(c);
+ if (c == '\n') break;
}
+ break;
+ }
goto normal_char;
case ' ':
@@ -2503,303 +2495,300 @@ re_compile_fastmap(bufp)
while (p) {
is_a_succeed_n = 0;
- if (p == pend)
- {
- bufp->can_be_null = 1;
- break;
- }
+ if (p == pend) {
+ bufp->can_be_null = 1;
+ break;
+ }
#ifdef SWITCH_ENUM_BUG
switch ((int)((enum regexpcode)*p++))
#else
- switch ((enum regexpcode)*p++)
+ switch ((enum regexpcode)*p++)
#endif
- {
- case exactn:
- if (p[1] == 0xff) {
- if (TRANSLATE_P())
- fastmap[translate[p[2]]] = 2;
- else
- fastmap[p[2]] = 2;
- }
- else if (TRANSLATE_P())
- fastmap[translate[p[1]]] = 1;
+ {
+ case exactn:
+ if (p[1] == 0xff) {
+ if (TRANSLATE_P())
+ fastmap[translate[p[2]]] = 2;
else
- fastmap[p[1]] = 1;
- break;
+ fastmap[p[2]] = 2;
+ }
+ else if (TRANSLATE_P())
+ fastmap[translate[p[1]]] = 1;
+ else
+ fastmap[p[1]] = 1;
+ break;
- case begline:
- case begbuf:
- case endbuf:
- case endbuf2:
- case wordbound:
- case notwordbound:
- case wordbeg:
- case wordend:
- case pop_and_fail:
- case push_dummy_failure:
- case stop_paren:
- continue;
+ case begline:
+ case begbuf:
+ case endbuf:
+ case endbuf2:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case pop_and_fail:
+ case push_dummy_failure:
+ case stop_paren:
+ continue;
- case casefold_on:
- bufp->options |= RE_MAY_IGNORECASE;
- case casefold_off:
- options ^= RE_OPTION_IGNORECASE;
- continue;
+ case casefold_on:
+ bufp->options |= RE_MAY_IGNORECASE;
+ case casefold_off:
+ options ^= RE_OPTION_IGNORECASE;
+ continue;
- case posix_on:
- case posix_off:
- options ^= RE_OPTION_POSIX;
- continue;
+ case posix_on:
+ case posix_off:
+ options ^= RE_OPTION_POSIX;
+ continue;
- case endline:
- if (TRANSLATE_P())
- fastmap[translate['\n']] = 1;
- else
- fastmap['\n'] = 1;
+ case endline:
+ if (TRANSLATE_P())
+ fastmap[translate['\n']] = 1;
+ else
+ fastmap['\n'] = 1;
- if (bufp->can_be_null == 0)
- bufp->can_be_null = 2;
- break;
+ if (bufp->can_be_null == 0)
+ bufp->can_be_null = 2;
+ break;
- case jump_n:
- case finalize_jump:
- case maybe_finalize_jump:
- case jump:
- case jump_past_alt:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR(j, p);
- p += j;
- if (j > 0)
- continue;
- /* Jump backward reached implies we just went through
- the body of a loop and matched nothing.
- Opcode jumped to should be an on_failure_jump.
- Just treat it like an ordinary jump.
- For a * loop, it has pushed its failure point already;
- If so, discard that as redundant. */
-
- if ((enum regexpcode)*p != on_failure_jump
- && (enum regexpcode)*p != try_next
- && (enum regexpcode)*p != succeed_n
- && (enum regexpcode)*p != finalize_push
- && (enum regexpcode)*p != finalize_push_n)
- continue;
- p++;
- EXTRACT_NUMBER_AND_INCR(j, p);
- p += j;
- if (stackp != stackb && *stackp == p)
- stackp--; /* pop */
+ case jump_n:
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case jump_past_alt:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR(j, p);
+ p += j;
+ if (j > 0)
continue;
-
- case start_nowidth:
- case stop_nowidth:
- case finalize_push:
- p += 2;
+ /* Jump backward reached implies we just went through
+ the body of a loop and matched nothing.
+ Opcode jumped to should be an on_failure_jump.
+ Just treat it like an ordinary jump.
+ For a * loop, it has pushed its failure point already;
+ If so, discard that as redundant. */
+
+ if ((enum regexpcode)*p != on_failure_jump
+ && (enum regexpcode)*p != try_next
+ && (enum regexpcode)*p != succeed_n
+ && (enum regexpcode)*p != finalize_push
+ && (enum regexpcode)*p != finalize_push_n)
continue;
+ p++;
+ EXTRACT_NUMBER_AND_INCR(j, p);
+ p += j;
+ if (stackp != stackb && *stackp == p)
+ stackp--; /* pop */
+ continue;
- case finalize_push_n:
- p += 4;
- continue;
+ case start_nowidth:
+ case stop_nowidth:
+ case finalize_push:
+ p += 2;
+ continue;
- case try_next:
- case on_failure_jump:
- handle_on_failure_jump:
- EXTRACT_NUMBER_AND_INCR(j, p);
- if (p + j < pend) {
- if (stackp == stacke) {
- unsigned char **stackx;
- unsigned int len = stacke - stackb;
+ case finalize_push_n:
+ p += 4;
+ continue;
- EXPAND_FAIL_STACK(stackx, stackb, len);
- }
- *++stackp = p + j; /* push */
+ case try_next:
+ case on_failure_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR(j, p);
+ if (p + j < pend) {
+ if (stackp == stacke) {
+ unsigned char **stackx;
+ unsigned int len = stacke - stackb;
+
+ EXPAND_FAIL_STACK(stackx, stackb, len);
+ }
+ *++stackp = p + j; /* push */
+ }
+ else {
+ bufp->can_be_null = 1;
+ }
+ if (is_a_succeed_n)
+ EXTRACT_NUMBER_AND_INCR(k, p); /* Skip the n. */
+ continue;
+
+ case succeed_n:
+ is_a_succeed_n = 1;
+ /* Get to the number of times to succeed. */
+ EXTRACT_NUMBER(k, p + 2);
+ /* Increment p past the n for when k != 0. */
+ if (k == 0) {
+ p += 4;
}
else {
- bufp->can_be_null = 1;
+ goto handle_on_failure_jump;
}
- if (is_a_succeed_n)
- EXTRACT_NUMBER_AND_INCR(k, p); /* Skip the n. */
continue;
- case succeed_n:
- is_a_succeed_n = 1;
- /* Get to the number of times to succeed. */
- EXTRACT_NUMBER(k, p + 2);
- /* Increment p past the n for when k != 0. */
- if (k == 0) {
- p += 4;
- }
- else {
- goto handle_on_failure_jump;
- }
- continue;
-
- case set_number_at:
- p += 4;
- continue;
+ case set_number_at:
+ p += 4;
+ continue;
- case start_memory:
- case stop_memory:
- p += 2;
- continue;
+ case start_memory:
+ case stop_memory:
+ p += 2;
+ continue;
- case duplicate:
- bufp->can_be_null = 1;
- fastmap['\n'] = 1;
- case anychar:
- {
- char ex = (options & RE_OPTION_POSIX)?'\0':'\n';
+ case duplicate:
+ bufp->can_be_null = 1;
+ fastmap['\n'] = 1;
+ case anychar:
+ {
+ char ex = (options & RE_OPTION_POSIX)?'\0':'\n';
- for (j = 0; j < (1 << BYTEWIDTH); j++) {
- if (j != ex) fastmap[j] = 1;
- }
- if (bufp->can_be_null) {
- FREE_AND_RETURN_VOID(stackb);
- }
+ for (j = 0; j < (1 << BYTEWIDTH); j++) {
+ if (j != ex) fastmap[j] = 1;
}
- /* Don't return; check the alternative paths
- so we can set can_be_null if appropriate. */
- break;
+ if (bufp->can_be_null) {
+ FREE_AND_RETURN_VOID(stackb);
+ }
+ }
+ /* Don't return; check the alternative paths
+ so we can set can_be_null if appropriate. */
+ break;
- case wordchar:
- for (j = 0; j < 0x80; j++) {
- if (SYNTAX(j) == Sword)
+ case wordchar:
+ for (j = 0; j < 0x80; j++) {
+ if (SYNTAX(j) == Sword)
+ fastmap[j] = 1;
+ }
+ switch (current_mbctype) {
+ case MBCTYPE_ASCII:
+ for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
+ if (SYNTAX(j) == Sword2)
fastmap[j] = 1;
}
- switch (current_mbctype) {
- case MBCTYPE_ASCII:
- for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
- if (SYNTAX(j) == Sword2)
- fastmap[j] = 1;
- }
- break;
- case MBCTYPE_EUC:
- case MBCTYPE_SJIS:
- case MBCTYPE_UTF8:
- for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
- if (re_mbctab[j])
- fastmap[j] = 1;
- }
- break;
+ break;
+ case MBCTYPE_EUC:
+ case MBCTYPE_SJIS:
+ case MBCTYPE_UTF8:
+ for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
+ if (re_mbctab[j])
+ fastmap[j] = 1;
}
break;
+ }
+ break;
- case notwordchar:
- for (j = 0; j < 0x80; j++)
- if (SYNTAX(j) != Sword)
+ case notwordchar:
+ for (j = 0; j < 0x80; j++)
+ if (SYNTAX(j) != Sword)
+ fastmap[j] = 1;
+ switch (current_mbctype) {
+ case MBCTYPE_ASCII:
+ for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
+ if (SYNTAX(j) != Sword2)
+ fastmap[j] = 1;
+ }
+ break;
+ case MBCTYPE_EUC:
+ case MBCTYPE_SJIS:
+ case MBCTYPE_UTF8:
+ for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
+ if (!re_mbctab[j])
fastmap[j] = 1;
- switch (current_mbctype) {
- case MBCTYPE_ASCII:
- for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
- if (SYNTAX(j) != Sword2)
- fastmap[j] = 1;
- }
- break;
- case MBCTYPE_EUC:
- case MBCTYPE_SJIS:
- case MBCTYPE_UTF8:
- for (j = 0x80; j < (1 << BYTEWIDTH); j++) {
- if (!re_mbctab[j])
- fastmap[j] = 1;
- }
- break;
}
break;
+ }
+ break;
- case charset:
- /* NOTE: Charset for single-byte chars never contain
- multi-byte char. See set_list_bits(). */
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
- if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
- {
- if (TRANSLATE_P())
- j = translate[j];
- fastmap[j] = (j>0x7f?(ismbchar(j)?0:2):1);
- }
- {
- unsigned short size;
- unsigned int c, beg, end;
-
- p += p[-1] + 2;
- size = EXTRACT_UNSIGNED(&p[-2]);
- for (j = 0; j < (int)size; j++) {
- c = EXTRACT_MBC(&p[j*8]);
- beg = WC2MBC1ST(c);
- c = EXTRACT_MBC(&p[j*8+4]);
- end = WC2MBC1ST(c);
- /* set bits for 1st bytes of multi-byte chars. */
- while (beg <= end) {
- /* NOTE: Charset for multi-byte chars might contain
- single-byte chars. We must reject them. */
- if (ismbchar(beg))
- fastmap[beg] = 1;
- beg++;
- }
+ case charset:
+ /* NOTE: Charset for single-byte chars never contain
+ multi-byte char. See set_list_bits(). */
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) {
+ if (TRANSLATE_P())
+ j = translate[j];
+ fastmap[j] = (j>0x7f?(ismbchar(j)?0:2):1);
+ }
+ {
+ unsigned short size;
+ unsigned int c, beg, end;
+
+ p += p[-1] + 2;
+ size = EXTRACT_UNSIGNED(&p[-2]);
+ for (j = 0; j < (int)size; j++) {
+ c = EXTRACT_MBC(&p[j*8]);
+ beg = WC2MBC1ST(c);
+ c = EXTRACT_MBC(&p[j*8+4]);
+ end = WC2MBC1ST(c);
+ /* set bits for 1st bytes of multi-byte chars. */
+ while (beg <= end) {
+ /* NOTE: Charset for multi-byte chars might contain
+ single-byte chars. We must reject them. */
+ if (ismbchar(beg))
+ fastmap[beg] = 1;
+ beg++;
}
}
- break;
+ }
+ break;
- case charset_not:
- /* S: set of all single-byte chars.
- M: set of all first bytes that can start multi-byte chars.
- s: any set of single-byte chars.
- m: any set of first bytes that can start multi-byte chars.
-
- We assume S+M = U.
- ___ _ _
- s+m = (S*s+M*m). */
- /* Chars beyond end of map must be allowed */
- /* NOTE: Charset_not for single-byte chars might contain
- multi-byte chars. See set_list_bits(). */
- for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ case charset_not:
+ /* S: set of all single-byte chars.
+ M: set of all first bytes that can start multi-byte chars.
+ s: any set of single-byte chars.
+ m: any set of first bytes that can start multi-byte chars.
+
+ We assume S+M = U.
+ ___ _ _
+ s+m = (S*s+M*m). */
+ /* Chars beyond end of map must be allowed */
+ /* NOTE: Charset_not for single-byte chars might contain
+ multi-byte chars. See set_list_bits(). */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ if (!ismbchar(j))
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) {
if (!ismbchar(j))
fastmap[j] = 1;
-
- for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ }
+ if (current_mbctype) {
+ for (j = 0x80; j < (1 << BYTEWIDTH); j++)
if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
- {
- if (!ismbchar(j))
- fastmap[j] = 1;
- }
- if (current_mbctype) {
+ fastmap[j] = 2;
+ }
+ {
+ unsigned short size;
+ unsigned int c, beg, end;
+
+ p += p[-1] + 2;
+ size = EXTRACT_UNSIGNED(&p[-2]);
+ if (size == 0) {
for (j = 0x80; j < (1 << BYTEWIDTH); j++)
- if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
- fastmap[j] = 2;
+ if (ismbchar(j))
+ fastmap[j] = 1;
+ break;
}
- {
- unsigned short size;
- unsigned int c, beg, end;
-
- p += p[-1] + 2;
- size = EXTRACT_UNSIGNED(&p[-2]);
- if (size == 0) {
- for (j = 0x80; j < (1 << BYTEWIDTH); j++)
- if (ismbchar(j))
- fastmap[j] = 1;
- break;
- }
- for (j = 0,c = 0x80;j < (int)size; j++) {
- int cc = EXTRACT_MBC(&p[j*8]);
- beg = WC2MBC1ST(cc);
- while (c < beg) {
- if (ismbchar(c))
- fastmap[c] = 1;
- c++;
- }
-
- cc = EXTRACT_MBC(&p[j*8+4]);
- c = WC2MBC1ST(cc) + 1;
+ for (j = 0,c = 0x80;j < (int)size; j++) {
+ int cc = EXTRACT_MBC(&p[j*8]);
+ beg = WC2MBC1ST(cc);
+ while (c < beg) {
+ if (ismbchar(c))
+ fastmap[c] = 1;
+ c++;
}
- for (j = c; j < (1 << BYTEWIDTH); j++)
- if (ismbchar(j))
- fastmap[j] = 1;
+ cc = EXTRACT_MBC(&p[j*8+4]);
+ c = WC2MBC1ST(cc) + 1;
}
- break;
- case unused: /* pacify gcc -Wall */
- break;
+ for (j = c; j < (1 << BYTEWIDTH); j++)
+ if (ismbchar(j))
+ fastmap[j] = 1;
}
+ break;
+
+ case unused: /* pacify gcc -Wall */
+ break;
+ }
/* Get here means we have successfully found the possible starting
characters of one path of the pattern. We need not follow this
@@ -2907,45 +2896,42 @@ re_search(bufp, string, size, startpos, range, regs)
string we get. */
if (fastmap && startpos < size
- && bufp->can_be_null != 1 && !(anchor && startpos == 0))
- {
- if (range > 0) /* Searching forwards. */
- {
- register unsigned char *p, c;
- int irange = range;
+ && bufp->can_be_null != 1 && !(anchor && startpos == 0)) {
+ if (range > 0) { /* Searching forwards. */
+ register unsigned char *p, c;
+ int irange = range;
- p = (unsigned char*)string+startpos;
+ p = (unsigned char*)string+startpos;
- while (range > 0) {
- c = *p++;
- if (ismbchar(c)) {
- int len = mbclen(c) - 1;
- if (fastmap[c])
- break;
- p += len;
- range -= len + 1;
- c = *p;
- if (fastmap[c] == 2)
- break;
- }
- else {
- if (fastmap[MAY_TRANSLATE() ? translate[c] : c])
- break;
- range--;
- }
- }
- startpos += irange - range;
+ while (range > 0) {
+ c = *p++;
+ if (ismbchar(c)) {
+ int len = mbclen(c) - 1;
+ if (fastmap[c])
+ break;
+ p += len;
+ range -= len + 1;
+ c = *p;
+ if (fastmap[c] == 2)
+ break;
}
- else /* Searching backwards. */
- {
- register unsigned char c;
-
- c = string[startpos];
- c &= 0xff;
- if (MAY_TRANSLATE() ? !fastmap[translate[c]] : !fastmap[c])
- goto advance;
+ else {
+ if (fastmap[MAY_TRANSLATE() ? translate[c] : c])
+ break;
+ range--;
}
+ }
+ startpos += irange - range;
}
+ else { /* Searching backwards. */
+ register unsigned char c;
+
+ c = string[startpos];
+ c &= 0xff;
+ if (MAY_TRANSLATE() ? !fastmap[translate[c]] : !fastmap[c])
+ goto advance;
+ }
+ }
if (startpos > size) return -1;
if (anchor && size > 0 && startpos == size) return -1;
@@ -3331,66 +3317,60 @@ re_match(bufp, string_arg, size, pos, regs)
*p);
#endif
/* End of pattern means we might have succeeded. */
- if (p == pend)
- {
- /* If not end of string, try backtracking. Otherwise done. */
- if (d != dend)
- {
- while (stackp != stackb && (int)stackp[-1] == 1) {
- if (best_regs_set) /* non-greedy, no need to backtrack */
- goto restore_best_regs;
- POP_FAILURE_POINT();
- }
- if (stackp != stackb) {
- /* More failure points to try. */
+ if (p == pend) {
+ /* If not end of string, try backtracking. Otherwise done. */
+ if (d != dend) {
+ while (stackp != stackb && (int)stackp[-1] == 1) {
+ if (best_regs_set) /* non-greedy, no need to backtrack */
+ goto restore_best_regs;
+ POP_FAILURE_POINT();
+ }
+ if (stackp != stackb) {
+ /* More failure points to try. */
- /* If exceeds best match so far, save it. */
- if (! best_regs_set || (d > best_regend[0])) {
- best_regs_set = 1;
- best_regend[0] = d; /* Never use regstart[0]. */
+ /* If exceeds best match so far, save it. */
+ if (! best_regs_set || (d > best_regend[0])) {
+ best_regs_set = 1;
+ best_regend[0] = d; /* Never use regstart[0]. */
- for (mcnt = 1; mcnt < num_regs; mcnt++) {
- best_regstart[mcnt] = regstart[mcnt];
- best_regend[mcnt] = regend[mcnt];
- }
- }
- goto fail;
- }
- /* If no failure points, don't restore garbage. */
- else if (best_regs_set) {
- restore_best_regs:
- /* Restore best match. */
- d = best_regend[0];
-
- for (mcnt = 0; mcnt < num_regs; mcnt++)
- {
- regstart[mcnt] = best_regstart[mcnt];
- regend[mcnt] = best_regend[mcnt];
- }
+ for (mcnt = 1; mcnt < num_regs; mcnt++) {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
}
}
+ goto fail;
+ }
+ /* If no failure points, don't restore garbage. */
+ else if (best_regs_set) {
+ restore_best_regs:
+ /* Restore best match. */
+ d = best_regend[0];
+
+ for (mcnt = 0; mcnt < num_regs; mcnt++) {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ }
- /* If caller wants register contents data back, convert it
- to indices. */
- if (regs)
- {
- regs->beg[0] = pos;
- regs->end[0] = d - string;
- for (mcnt = 1; mcnt < num_regs; mcnt++)
- {
- if (REG_UNSET(regend[mcnt]))
- {
- regs->beg[mcnt] = -1;
- regs->end[mcnt] = -1;
- continue;
- }
- regs->beg[mcnt] = regstart[mcnt] - string;
- regs->end[mcnt] = regend[mcnt] - string;
- }
+ /* If caller wants register contents data back, convert it
+ to indices. */
+ if (regs) {
+ regs->beg[0] = pos;
+ regs->end[0] = d - string;
+ for (mcnt = 1; mcnt < num_regs; mcnt++) {
+ if (REG_UNSET(regend[mcnt])) {
+ regs->beg[mcnt] = -1;
+ regs->end[mcnt] = -1;
+ continue;
}
- FREE_VARIABLES();
- FREE_AND_RETURN(stackb, (d - pos - string));
+ regs->beg[mcnt] = regstart[mcnt] - string;
+ regs->end[mcnt] = regend[mcnt] - string;
+ }
}
+ FREE_VARIABLES();
+ FREE_AND_RETURN(stackb, (d - pos - string));
+ }
/* Otherwise match next pattern command. */
#ifdef SWITCH_ENUM_BUG
@@ -3398,612 +3378,595 @@ re_match(bufp, string_arg, size, pos, regs)
#else
switch ((enum regexpcode)*p++)
#endif
+ {
+ /* ( [or `(', as appropriate] is represented by start_memory,
+ ) by stop_memory. Both of those commands are followed by
+ a register number in the next byte. The text matched
+ within the ( and ) is recorded under that number. */
+ case start_memory:
+ /* Find out if this group can match the empty string. */
+ p1 = p; /* To send to group_match_null_string_p. */
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
+ regstart[*p] = d;
+ IS_ACTIVE(reg_info[*p]) = 1;
+ MATCHED_SOMETHING(reg_info[*p]) = 0;
+ p += 2;
+ continue;
+
+ case stop_memory:
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ : regend[*p];
+
+ regend[*p] = d;
+ IS_ACTIVE(reg_info[*p]) = 0;
+
+ /* If just failed to match something this time around with a sub-
+ expression that's in a loop, try to force exit from the loop. */
+ if ((p + 1) != pend &&
+ (! MATCHED_SOMETHING(reg_info[*p])
+ || (enum regexpcode)p[-3] == start_memory)) {
+ p1 = p + 2;
+ mcnt = 0;
+ switch (*p1++) {
+ case jump_n:
+ case finalize_push_n:
+ case finalize_jump:
+ case maybe_finalize_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR(mcnt, p1);
+ break;
+ }
+ p1 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump, exit from the loop by forcing a
+ failure after pushing on the stack the on_failure_jump's
+ jump in the pattern, and d. */
+ if (mcnt < 0 && (enum regexpcode)*p1 == on_failure_jump
+ && (enum regexpcode)p1[3] == start_memory && p1[4] == *p) {
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
+
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
+
+ if (EVER_MATCHED_SOMETHING (reg_info[*p])) {
+ unsigned r;
+
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Restore this and inner groups' (if any) registers. */
+ for (r = *p; r < *p + *(p + 1); r++) {
+ regstart[r] = old_regstart[r];
+
+ /* xx why this test? */
+ if ((int)old_regend[r] >= (int)regstart[r])
+ regend[r] = old_regend[r];
+ }
+ }
+ p1++;
+ EXTRACT_NUMBER_AND_INCR(mcnt, p1);
+ PUSH_FAILURE_POINT(p1 + mcnt, d);
+ goto fail;
+ }
+ }
+ p += 2;
+ continue;
+
+ case stop_paren:
+ break;
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
{
+ int regno = *p++; /* Get which register to match against */
+ register unsigned char *d2, *dend2;
- /* ( [or `(', as appropriate] is represented by start_memory,
- ) by stop_memory. Both of those commands are followed by
- a register number in the next byte. The text matched
- within the ( and ) is recorded under that number. */
- case start_memory:
- /* Find out if this group can match the empty string. */
- p1 = p; /* To send to group_match_null_string_p. */
- if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
- REG_MATCH_NULL_STRING_P (reg_info[*p])
- = group_match_null_string_p (&p1, pend, reg_info);
-
- /* Save the position in the string where we were the last time
- we were at this open-group operator in case the group is
- operated upon by a repetition operator, e.g., with `(a*)*b'
- against `ab'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
- : regstart[*p];
- regstart[*p] = d;
- IS_ACTIVE(reg_info[*p]) = 1;
- MATCHED_SOMETHING(reg_info[*p]) = 0;
- p += 2;
- continue;
+ if (IS_ACTIVE(reg_info[regno])) break;
- case stop_memory:
- /* We need to save the string position the last time we were at
- this close-group operator in case the group is operated
- upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
- against `aba'; then we want to ignore where we are now in
- the string in case this attempt to match fails. */
- old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
- ? REG_UNSET (regend[*p]) ? d : regend[*p]
- : regend[*p];
-
- regend[*p] = d;
- IS_ACTIVE(reg_info[*p]) = 0;
-
- /* If just failed to match something this time around with a sub-
- expression that's in a loop, try to force exit from the loop. */
- if ((p + 1) != pend &&
- (! MATCHED_SOMETHING(reg_info[*p])
- || (enum regexpcode)p[-3] == start_memory))
- {
- p1 = p + 2;
- mcnt = 0;
- switch (*p1++)
- {
- case jump_n:
- case finalize_push_n:
- case finalize_jump:
- case maybe_finalize_jump:
- case jump:
- case dummy_failure_jump:
- EXTRACT_NUMBER_AND_INCR(mcnt, p1);
- break;
- }
- p1 += mcnt;
-
- /* If the next operation is a jump backwards in the pattern
- to an on_failure_jump, exit from the loop by forcing a
- failure after pushing on the stack the on_failure_jump's
- jump in the pattern, and d. */
- if (mcnt < 0 && (enum regexpcode)*p1 == on_failure_jump
- && (enum regexpcode)p1[3] == start_memory && p1[4] == *p)
- {
- /* If this group ever matched anything, then restore
- what its registers were before trying this last
- failed match, e.g., with `(a*)*b' against `ab' for
- regstart[1], and, e.g., with `((a*)*(b*)*)*'
- against `aba' for regend[3].
-
- Also restore the registers for inner groups for,
- e.g., `((a*)(b*))*' against `aba' (register 3 would
- otherwise get trashed). */
-
- if (EVER_MATCHED_SOMETHING (reg_info[*p]))
- {
- unsigned r;
-
- EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
-
- /* Restore this and inner groups' (if any) registers. */
- for (r = *p; r < *p + *(p + 1); r++)
- {
- regstart[r] = old_regstart[r];
-
- /* xx why this test? */
- if ((int)old_regend[r] >= (int)regstart[r])
- regend[r] = old_regend[r];
- }
- }
- p1++;
- EXTRACT_NUMBER_AND_INCR(mcnt, p1);
- PUSH_FAILURE_POINT(p1 + mcnt, d);
- goto fail;
- }
- }
- p += 2;
- continue;
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+ if (REG_UNSET(d2)) break;
- case stop_paren:
- break;
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
- /* \<digit> has been turned into a `duplicate' command which is
- followed by the numeric value of <digit> as the register number. */
- case duplicate:
- {
- int regno = *p++; /* Get which register to match against */
- register unsigned char *d2, *dend2;
-
- if (IS_ACTIVE(reg_info[regno])) break;
-
- /* Where in input to try to start matching. */
- d2 = regstart[regno];
- if (REG_UNSET(d2)) break;
-
- /* Where to stop matching; if both the place to start and
- the place to stop matching are in the same string, then
- set to the place to stop, otherwise, for now have to use
- the end of the first string. */
-
- dend2 = regend[regno];
- if (REG_UNSET(dend2)) break;
- for (;;)
- {
- /* At end of register contents => success */
- if (d2 == dend2) break;
-
- /* If necessary, advance to next segment in data. */
- PREFETCH;
-
- /* How many characters left in this segment to match. */
- mcnt = dend - d;
-
- /* Want how many consecutive characters we can match in
- one shot, so, if necessary, adjust the count. */
- if (mcnt > dend2 - d2)
- mcnt = dend2 - d2;
-
- /* Compare that many; failure if mismatch, else move
- past them. */
- if ((options & RE_OPTION_IGNORECASE)
- ? memcmp_translate(d, d2, mcnt)
- : memcmp((char*)d, (char*)d2, mcnt))
- goto fail;
- d += mcnt, d2 += mcnt;
- }
- }
- break;
+ dend2 = regend[regno];
+ if (REG_UNSET(dend2)) break;
+ for (;;) {
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
- case start_nowidth:
- PUSH_FAILURE_POINT(0, d);
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- STORE_NUMBER(p+mcnt, stackp - stackb);
- continue;
+ /* If necessary, advance to next segment in data. */
+ PREFETCH;
- case stop_nowidth:
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- stackp = stackb + mcnt;
- d = stackp[-2];
- POP_FAILURE_POINT();
- continue;
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
- case pop_and_fail:
- EXTRACT_NUMBER(mcnt, p+1);
- stackp = stackb + mcnt;
- POP_FAILURE_POINT();
- goto fail;
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
- case anychar:
- PREFETCH;
- if (ismbchar(*d)) {
- if (d + mbclen(*d) > dend)
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if ((options & RE_OPTION_IGNORECASE)
+ ? memcmp_translate(d, d2, mcnt)
+ : memcmp((char*)d, (char*)d2, mcnt))
goto fail;
- SET_REGS_MATCHED;
- d += mbclen(*d);
- break;
+ d += mcnt, d2 += mcnt;
}
- if (((TRANSLATE_P()) ? translate[*d] : *d) ==
- ((options&RE_OPTION_POSIX) ? '\0' : '\n'))
+ }
+ break;
+
+ case start_nowidth:
+ PUSH_FAILURE_POINT(0, d);
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ STORE_NUMBER(p+mcnt, stackp - stackb);
+ continue;
+
+ case stop_nowidth:
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ stackp = stackb + mcnt;
+ d = stackp[-2];
+ POP_FAILURE_POINT();
+ continue;
+
+ case pop_and_fail:
+ EXTRACT_NUMBER(mcnt, p+1);
+ stackp = stackb + mcnt;
+ POP_FAILURE_POINT();
+ goto fail;
+
+ case anychar:
+ PREFETCH;
+ if (ismbchar(*d)) {
+ if (d + mbclen(*d) > dend)
goto fail;
SET_REGS_MATCHED;
- d++;
+ d += mbclen(*d);
break;
+ }
+ if (((TRANSLATE_P()) ? translate[*d] : *d) ==
+ ((options&RE_OPTION_POSIX) ? '\0' : '\n'))
+ goto fail;
+ SET_REGS_MATCHED;
+ d++;
+ break;
- case charset:
- case charset_not:
- {
- int not; /* Nonzero for charset_not. */
- int part; /* 2 if matched part of mbc */
- unsigned char *dsave = d + 1;
- int cc, c;
-
- PREFETCH;
- cc = c = (unsigned char)*d++;
- if (ismbchar(c)) {
- if (d + mbclen(c) - 1 <= dend) {
- MBC2WC(c, d);
- }
- }
- else if (TRANSLATE_P())
- cc = c = (unsigned char)translate[c];
+ case charset:
+ case charset_not:
+ {
+ int not; /* Nonzero for charset_not. */
+ int part; /* 2 if matched part of mbc */
+ unsigned char *dsave = d + 1;
+ int cc, c;
- part = not = is_in_list(c, p);
- if (*(p - 1) == (unsigned char)charset_not) {
- not = !not;
+ PREFETCH;
+ cc = c = (unsigned char)*d++;
+ if (ismbchar(c)) {
+ if (d + mbclen(c) - 1 <= dend) {
+ MBC2WC(c, d);
}
- if (!not) goto fail;
-
- p += 1 + *p + 2 + EXTRACT_UNSIGNED(&p[1 + *p])*8;
- SET_REGS_MATCHED;
-
- if (part == 2) d = dsave;
- break;
}
+ else if (TRANSLATE_P())
+ cc = c = (unsigned char)translate[c];
- case begline:
- if (size == 0 || AT_STRINGS_BEG(d))
- break;
- if (d[-1] == '\n' && !AT_STRINGS_END(d))
- break;
- goto fail;
-
- case endline:
- if (AT_STRINGS_END(d)) {
- if (size == 0 || d[-1] != '\n')
- break;
+ part = not = is_in_list(c, p);
+ if (*(p - 1) == (unsigned char)charset_not) {
+ not = !not;
}
- else if (*d == '\n')
- break;
- goto fail;
+ if (!not) goto fail;
- /* Match at the very beginning of the string. */
- case begbuf:
- if (AT_STRINGS_BEG(d))
- break;
- goto fail;
+ p += 1 + *p + 2 + EXTRACT_UNSIGNED(&p[1 + *p])*8;
+ SET_REGS_MATCHED;
- /* Match at the very end of the data. */
- case endbuf:
- if (AT_STRINGS_END(d))
- break;
- goto fail;
+ if (part == 2) d = dsave;
+ break;
+ }
- /* Match at the very end of the data. */
- case endbuf2:
- if (AT_STRINGS_END(d))
- break;
- /* .. or newline just before the end of the data. */
- if (*d == '\n' && AT_STRINGS_END(d+1))
- break;
- goto fail;
+ case begline:
+ if (size == 0 || AT_STRINGS_BEG(d))
+ break;
+ if (d[-1] == '\n' && !AT_STRINGS_END(d))
+ break;
+ goto fail;
- /* `or' constructs are handled by starting each alternative with
- an on_failure_jump that points to the start of the next
- alternative. Each alternative except the last ends with a
- jump to the joining point. (Actually, each jump except for
- the last one really jumps to the following jump, because
- tensioning the jumps is a hassle.) */
+ case endline:
+ if (AT_STRINGS_END(d)) {
+ if (size == 0 || d[-1] != '\n')
+ break;
+ }
+ else if (*d == '\n')
+ break;
+ goto fail;
- /* The start of a stupid repeat has an on_failure_jump that points
- past the end of the repeat text. This makes a failure point so
- that on failure to match a repetition, matching restarts past
- as many repetitions have been found with no way to fail and
- look for another one. */
+ /* Match at the very beginning of the string. */
+ case begbuf:
+ if (AT_STRINGS_BEG(d))
+ break;
+ goto fail;
- /* A smart repeat is similar but loops back to the on_failure_jump
- so that each repetition makes another failure point. */
+ /* Match at the very end of the data. */
+ case endbuf:
+ if (AT_STRINGS_END(d))
+ break;
+ goto fail;
- case on_failure_jump:
- on_failure:
+ /* Match at the very end of the data. */
+ case endbuf2:
+ if (AT_STRINGS_END(d))
+ break;
+ /* .. or newline just before the end of the data. */
+ if (*d == '\n' && AT_STRINGS_END(d+1))
+ break;
+ goto fail;
+
+ /* `or' constructs are handled by starting each alternative with
+ an on_failure_jump that points to the start of the next
+ alternative. Each alternative except the last ends with a
+ jump to the joining point. (Actually, each jump except for
+ the last one really jumps to the following jump, because
+ tensioning the jumps is a hassle.) */
+
+ /* The start of a stupid repeat has an on_failure_jump that points
+ past the end of the repeat text. This makes a failure point so
+ that on failure to match a repetition, matching restarts past
+ as many repetitions have been found with no way to fail and
+ look for another one. */
+
+ /* A smart repeat is similar but loops back to the on_failure_jump
+ so that each repetition makes another failure point. */
+
+ case on_failure_jump:
+ on_failure:
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ PUSH_FAILURE_POINT(p + mcnt, d);
+ continue;
+
+ /* The end of a smart repeat has a maybe_finalize_jump back.
+ Change it either to a finalize_jump or an ordinary jump. */
+ case maybe_finalize_jump:
EXTRACT_NUMBER_AND_INCR(mcnt, p);
- PUSH_FAILURE_POINT(p + mcnt, d);
- continue;
-
- /* The end of a smart repeat has a maybe_finalize_jump back.
- Change it either to a finalize_jump or an ordinary jump. */
- case maybe_finalize_jump:
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- {
- register unsigned char *p2 = p;
-
- /* Compare the beginning of the repeat with what in the
- pattern follows its end. If we can establish that there
- is nothing that they would both match, i.e., that we
- would have to backtrack because of (as in, e.g., `a*a')
- then we can change to pop_failure_jump, because we'll
- never have to backtrack.
-
- This is not true in the case of alternatives: in
- `(a|ab)*' we do need to backtrack to the `ab' alternative
- (e.g., if the string was `ab'). But instead of trying to
- detect that here, the alternative has put on a dummy
- failure point which is what we will end up popping. */
-
- /* Skip over open/close-group commands. */
- while (p2 + 2 < pend) {
- if ((enum regexpcode)*p2 == stop_memory ||
- (enum regexpcode)*p2 == start_memory)
- p2 += 3; /* Skip over args, too. */
- else if ((enum regexpcode)*p2 == stop_paren)
- p2 += 1;
- else
- break;
- }
+ {
+ register unsigned char *p2 = p;
+
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands. */
+ while (p2 + 2 < pend) {
+ if ((enum regexpcode)*p2 == stop_memory ||
+ (enum regexpcode)*p2 == start_memory)
+ p2 += 3; /* Skip over args, too. */
+ else if ((enum regexpcode)*p2 == stop_paren)
+ p2 += 1;
+ else
+ break;
+ }
- if (p2 == pend)
+ if (p2 == pend)
+ p[-3] = (unsigned char)finalize_jump;
+ else if (*p2 == (unsigned char)exactn
+ || *p2 == (unsigned char)endline) {
+ register int c = *p2 == (unsigned char)endline ? '\n' : p2[2];
+ register unsigned char *p1 = p + mcnt;
+ /* p1[0] ... p1[2] are an on_failure_jump.
+ Examine what follows that. */
+ if (p1[3] == (unsigned char)exactn && p1[5] != c)
p[-3] = (unsigned char)finalize_jump;
- else if (*p2 == (unsigned char)exactn
- || *p2 == (unsigned char)endline)
- {
- register int c = *p2 == (unsigned char)endline ? '\n' : p2[2];
- register unsigned char *p1 = p + mcnt;
- /* p1[0] ... p1[2] are an on_failure_jump.
- Examine what follows that. */
- if (p1[3] == (unsigned char)exactn && p1[5] != c)
- p[-3] = (unsigned char)finalize_jump;
- else if (p1[3] == (unsigned char)charset
- || p1[3] == (unsigned char)charset_not) {
- int not;
- if (ismbchar(c)) {
- unsigned char *pp = p2+3;
- MBC2WC(c, pp);
- }
- /* `is_in_list()' is TRUE if c would match */
- /* That means it is not safe to finalize. */
- not = is_in_list(c, p1 + 4);
- if (p1[3] == (unsigned char)charset_not)
- not = !not;
- if (!not)
- p[-3] = (unsigned char)finalize_jump;
- }
+ else if (p1[3] == (unsigned char)charset
+ || p1[3] == (unsigned char)charset_not) {
+ int not;
+ if (ismbchar(c)) {
+ unsigned char *pp = p2+3;
+ MBC2WC(c, pp);
}
- }
- p -= 2; /* Point at relative address again. */
- if (p[-1] != (unsigned char)finalize_jump)
- {
- p[-1] = (unsigned char)jump;
- goto nofinalize;
+ /* `is_in_list()' is TRUE if c would match */
+ /* That means it is not safe to finalize. */
+ not = is_in_list(c, p1 + 4);
+ if (p1[3] == (unsigned char)charset_not)
+ not = !not;
+ if (!not)
+ p[-3] = (unsigned char)finalize_jump;
}
- /* Note fall through. */
-
- /* The end of a stupid repeat has a finalize_jump back to the
- start, where another failure point will be made which will
- point to after all the repetitions found so far. */
-
- /* Take off failure points put on by matching on_failure_jump
- because didn't fail. Also remove the register information
- put on by the on_failure_jump. */
- case finalize_jump:
- if (stackp[-2] == d) {
- p = stackp[-3];
- POP_FAILURE_POINT();
- continue;
}
- POP_FAILURE_POINT();
- /* Note fall through. */
-
- /* Jump without taking off any failure points. */
- case jump:
- nofinalize:
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- p += mcnt;
- continue;
-
- /* We need this opcode so we can detect where alternatives end
- in `group_match_null_string_p' et al. */
- case jump_past_alt:
+ }
+ p -= 2; /* Point at relative address again. */
+ if (p[-1] != (unsigned char)finalize_jump) {
+ p[-1] = (unsigned char)jump;
goto nofinalize;
+ }
+ /* Note fall through. */
+
+ /* The end of a stupid repeat has a finalize_jump back to the
+ start, where another failure point will be made which will
+ point to after all the repetitions found so far. */
+
+ /* Take off failure points put on by matching on_failure_jump
+ because didn't fail. Also remove the register information
+ put on by the on_failure_jump. */
+ case finalize_jump:
+ if (stackp[-2] == d) {
+ p = stackp[-3];
+ POP_FAILURE_POINT();
+ continue;
+ }
+ POP_FAILURE_POINT();
+ /* Note fall through. */
- case dummy_failure_jump:
- /* Normally, the on_failure_jump pushes a failure point, which
- then gets popped at finalize_jump. We will end up at
- finalize_jump, also, and with a pattern of, say, `a+', we
- are skipping over the on_failure_jump, so we have to push
- something meaningless for finalize_jump to pop. */
- PUSH_FAILURE_POINT(0, 0);
- goto nofinalize;
+ /* Jump without taking off any failure points. */
+ case jump:
+ nofinalize:
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ p += mcnt;
+ continue;
+
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ goto nofinalize;
+
+ case dummy_failure_jump:
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at finalize_jump. We will end up at
+ finalize_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for finalize_jump to pop. */
+ PUSH_FAILURE_POINT(0, 0);
+ goto nofinalize;
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `finalize_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT(0, 0);
+ break;
- /* At the end of an alternative, we need to push a dummy failure
- point in case we are followed by a `finalize_jump', because
- we don't want the failure point for the alternative to be
- popped. For example, matching `(a|ab)*' against `aab'
- requires that we match the `ab' alternative. */
- case push_dummy_failure:
- /* See comments just above at `dummy_failure_jump' about the
- two zeroes. */
+ /* Have to succeed matching what follows at least n times. Then
+ just handle like an on_failure_jump. */
+ case succeed_n:
+ EXTRACT_NUMBER(mcnt, p + 2);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0) {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR(p, mcnt);
PUSH_FAILURE_POINT(0, 0);
- break;
-
- /* Have to succeed matching what follows at least n times. Then
- just handle like an on_failure_jump. */
- case succeed_n:
- EXTRACT_NUMBER(mcnt, p + 2);
- /* Originally, this is how many times we HAVE to succeed. */
- if (mcnt > 0)
- {
- mcnt--;
- p += 2;
- STORE_NUMBER_AND_INCR(p, mcnt);
- PUSH_FAILURE_POINT(0, 0);
- }
- else if (mcnt == 0)
- {
- p[2] = unused;
- p[3] = unused;
- goto on_failure;
- }
- continue;
+ }
+ else if (mcnt == 0) {
+ p[2] = unused;
+ p[3] = unused;
+ goto on_failure;
+ }
+ continue;
- case jump_n:
- EXTRACT_NUMBER(mcnt, p + 2);
- /* Originally, this is how many times we CAN jump. */
- if (mcnt)
- {
- mcnt--;
- STORE_NUMBER(p + 2, mcnt);
- goto nofinalize; /* Do the jump without taking off
+ case jump_n:
+ EXTRACT_NUMBER(mcnt, p + 2);
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt) {
+ mcnt--;
+ STORE_NUMBER(p + 2, mcnt);
+ goto nofinalize; /* Do the jump without taking off
any failure points. */
- }
- /* If don't have to jump any more, skip over the rest of command. */
- else
- p += 4;
- continue;
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ continue;
- case set_number_at:
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- p1 = p + mcnt;
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- STORE_NUMBER(p1, mcnt);
- continue;
+ case set_number_at:
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ STORE_NUMBER(p1, mcnt);
+ continue;
- case try_next:
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- if (p + mcnt < pend) {
- PUSH_FAILURE_POINT(p, d);
- stackp[-1] = (unsigned char*)1;
- }
- p += mcnt;
- continue;
+ case try_next:
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ if (p + mcnt < pend) {
+ PUSH_FAILURE_POINT(p, d);
+ stackp[-1] = (unsigned char*)1;
+ }
+ p += mcnt;
+ continue;
- case finalize_push:
+ case finalize_push:
+ POP_FAILURE_POINT();
+ EXTRACT_NUMBER_AND_INCR(mcnt, p);
+ PUSH_FAILURE_POINT(p + mcnt, d);
+ stackp[-1] = (unsigned char*)1;
+ continue;
+
+ case finalize_push_n:
+ EXTRACT_NUMBER(mcnt, p + 2);
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt) {
+ int pos, i;
+
+ mcnt--;
+ STORE_NUMBER(p + 2, mcnt);
+ EXTRACT_NUMBER(pos, p);
+ EXTRACT_NUMBER(i, p+pos+5);
+ if (i > 0) goto nofinalize;
POP_FAILURE_POINT();
EXTRACT_NUMBER_AND_INCR(mcnt, p);
PUSH_FAILURE_POINT(p + mcnt, d);
stackp[-1] = (unsigned char*)1;
- continue;
+ p += 2; /* skip n */
+ }
+ /* If don't have to push any more, skip over the rest of command. */
+ else
+ p += 4;
+ continue;
- case finalize_push_n:
- EXTRACT_NUMBER(mcnt, p + 2);
- /* Originally, this is how many times we CAN jump. */
- if (mcnt) {
- int pos, i;
-
- mcnt--;
- STORE_NUMBER(p + 2, mcnt);
- EXTRACT_NUMBER(pos, p);
- EXTRACT_NUMBER(i, p+pos+5);
- if (i > 0) goto nofinalize;
- POP_FAILURE_POINT();
- EXTRACT_NUMBER_AND_INCR(mcnt, p);
- PUSH_FAILURE_POINT(p + mcnt, d);
- stackp[-1] = (unsigned char*)1;
- p += 2; /* skip n */
- }
- /* If don't have to push any more, skip over the rest of command. */
- else
- p += 4;
- continue;
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case unused:
+ continue;
- /* Ignore these. Used to ignore the n of succeed_n's which
- currently have n == 0. */
- case unused:
- continue;
+ case casefold_on:
+ options |= RE_OPTION_IGNORECASE;
+ continue;
- case casefold_on:
- options |= RE_OPTION_IGNORECASE;
- continue;
+ case casefold_off:
+ options &= ~RE_OPTION_IGNORECASE;
+ continue;
- case casefold_off:
- options &= ~RE_OPTION_IGNORECASE;
- continue;
+ case posix_on:
+ options |= RE_OPTION_POSIX;
+ continue;
- case posix_on:
- options |= RE_OPTION_POSIX;
- continue;
+ case posix_off:
+ options &= ~RE_OPTION_POSIX;
+ continue;
- case posix_off:
- options &= ~RE_OPTION_POSIX;
- continue;
+ case wordbound:
+ if (AT_STRINGS_BEG(d)) {
+ if (IS_A_LETTER(d)) break;
+ else goto fail;
+ }
+ if (AT_STRINGS_BEG(d)) {
+ if (PREV_IS_A_LETTER(d)) break;
+ else goto fail;
+ }
+ if (PREV_IS_A_LETTER(d) != IS_A_LETTER(d))
+ break;
+ goto fail;
- case wordbound:
- if (AT_STRINGS_BEG(d)) {
- if (IS_A_LETTER(d)) break;
- else goto fail;
- }
- if (AT_STRINGS_BEG(d)) {
- if (PREV_IS_A_LETTER(d)) break;
- else goto fail;
- }
- if (PREV_IS_A_LETTER(d) != IS_A_LETTER(d))
- break;
+ case notwordbound:
+ if (AT_STRINGS_BEG(d)) {
+ if (IS_A_LETTER(d)) goto fail;
+ else break;
+ }
+ if (AT_STRINGS_END(d)) {
+ if (PREV_IS_A_LETTER(d)) goto fail;
+ else break;
+ }
+ if (PREV_IS_A_LETTER(d) != IS_A_LETTER(d))
goto fail;
+ break;
- case notwordbound:
- if (AT_STRINGS_BEG(d)) {
- if (IS_A_LETTER(d)) goto fail;
- else break;
- }
- if (AT_STRINGS_END(d)) {
- if (PREV_IS_A_LETTER(d)) goto fail;
- else break;
- }
- if (PREV_IS_A_LETTER(d) != IS_A_LETTER(d))
- goto fail;
+ case wordbeg:
+ if (IS_A_LETTER(d) && (AT_STRINGS_BEG(d) || !PREV_IS_A_LETTER(d)))
break;
+ goto fail;
- case wordbeg:
- if (IS_A_LETTER(d) && (AT_STRINGS_BEG(d) || !PREV_IS_A_LETTER(d)))
- break;
- goto fail;
+ case wordend:
+ if (!AT_STRINGS_BEG(d) && PREV_IS_A_LETTER(d)
+ && (!IS_A_LETTER(d) || AT_STRINGS_END(d)))
+ break;
+ goto fail;
- case wordend:
- if (!AT_STRINGS_BEG(d) && PREV_IS_A_LETTER(d)
- && (!IS_A_LETTER(d) || AT_STRINGS_END(d)))
- break;
+ case wordchar:
+ PREFETCH;
+ if (!IS_A_LETTER(d))
goto fail;
+ if (ismbchar(*d) && d + mbclen(*d) - 1 < dend)
+ d += mbclen(*d) - 1;
+ d++;
+ SET_REGS_MATCHED;
+ break;
- case wordchar:
- PREFETCH;
- if (!IS_A_LETTER(d))
- goto fail;
- if (ismbchar(*d) && d + mbclen(*d) - 1 < dend)
- d += mbclen(*d) - 1;
- d++;
- SET_REGS_MATCHED;
- break;
+ case notwordchar:
+ PREFETCH;
+ if (IS_A_LETTER(d))
+ goto fail;
+ if (ismbchar(*d) && d + mbclen(*d) - 1 < dend)
+ d += mbclen(*d) - 1;
+ d++;
+ SET_REGS_MATCHED;
+ break;
- case notwordchar:
- PREFETCH;
- if (IS_A_LETTER(d))
- goto fail;
- if (ismbchar(*d) && d + mbclen(*d) - 1 < dend)
- d += mbclen(*d) - 1;
- d++;
- SET_REGS_MATCHED;
- break;
+ case exactn:
+ /* Match the next few pattern characters exactly.
+ mcnt is how many characters to match. */
+ mcnt = *p++;
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (TRANSLATE_P()) {
+ do {
+ unsigned char c;
- case exactn:
- /* Match the next few pattern characters exactly.
- mcnt is how many characters to match. */
- mcnt = *p++;
- /* This is written out as an if-else so we don't waste time
- testing `translate' inside the loop. */
- if (TRANSLATE_P())
- {
- do
- {
- unsigned char c;
-
- PREFETCH;
- c = *d++;
- if (*p == 0xff) {
- p++;
- if (!--mcnt
- || AT_STRINGS_END(d)
- || (unsigned char)*d++ != (unsigned char)*p++)
- goto fail;
- continue;
- }
- if (ismbchar(c)) {
- int n;
-
- if (c != (unsigned char)*p++)
- goto fail;
- for (n = mbclen(c) - 1; n > 0; n--)
- if (!--mcnt /* redundant check if pattern was
- compiled properly. */
- || AT_STRINGS_END(d)
- || (unsigned char)*d++ != (unsigned char)*p++)
- goto fail;
- continue;
- }
- /* compiled code translation needed for ruby */
- if ((unsigned char)translate[c]
- != (unsigned char)translate[*p++])
- goto fail;
- }
- while (--mcnt);
+ PREFETCH;
+ c = *d++;
+ if (*p == 0xff) {
+ p++;
+ if (!--mcnt
+ || AT_STRINGS_END(d)
+ || (unsigned char)*d++ != (unsigned char)*p++)
+ goto fail;
+ continue;
}
- else
- {
- do
- {
- PREFETCH;
- if (*p == 0xff) {p++; mcnt--;}
- if (*d++ != *p++) goto fail;
- }
- while (--mcnt);
+ if (ismbchar(c)) {
+ int n;
+
+ if (c != (unsigned char)*p++)
+ goto fail;
+ for (n = mbclen(c) - 1; n > 0; n--)
+ if (!--mcnt /* redundant check if pattern was
+ compiled properly. */
+ || AT_STRINGS_END(d)
+ || (unsigned char)*d++ != (unsigned char)*p++)
+ goto fail;
+ continue;
}
- SET_REGS_MATCHED;
- break;
+ /* compiled code translation needed for ruby */
+ if ((unsigned char)translate[c] != (unsigned char)translate[*p++])
+ goto fail;
+ }
+ while (--mcnt);
}
+ else {
+ do {
+ PREFETCH;
+ if (*p == 0xff) {p++; mcnt--;}
+ if (*d++ != *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED;
+ break;
+ }
#if 0
while (stackp != stackb && (int)stackp[-1] == 1)
POP_FAILURE_POINT();
@@ -4012,78 +3975,77 @@ re_match(bufp, string_arg, size, pos, regs)
/* Jump here if any matching operation fails. */
fail:
- if (stackp != stackb)
+ if (stackp != stackb) {
/* A restart point is known. Restart there and pop it. */
- {
- short last_used_reg, this_reg;
+ short last_used_reg, this_reg;
- /* If this failure point is from a dummy_failure_point, just
- skip it. */
- if (stackp[-3] == 0 || (best_regs_set && stackp[-1] == 1)) {
- POP_FAILURE_POINT();
- goto fail;
- }
- stackp--; /* discard flag */
- d = *--stackp;
- p = *--stackp;
- /* Restore register info. */
- last_used_reg = (long)*--stackp;
-
- /* Make the ones that weren't saved -1 or 0 again. */
- for (this_reg = num_regs - 1; this_reg > last_used_reg; this_reg--) {
- regend[this_reg] = REG_UNSET_VALUE;
- regstart[this_reg] = REG_UNSET_VALUE;
- IS_ACTIVE(reg_info[this_reg]) = 0;
- MATCHED_SOMETHING(reg_info[this_reg]) = 0;
- }
+ /* If this failure point is from a dummy_failure_point, just
+ skip it. */
+ if (stackp[-3] == 0 || (best_regs_set && (int)stackp[-1] == 1)) {
+ POP_FAILURE_POINT();
+ goto fail;
+ }
+ stackp--; /* discard flag */
+ d = *--stackp;
+ p = *--stackp;
+ /* Restore register info. */
+ last_used_reg = (long)*--stackp;
+
+ /* Make the ones that weren't saved -1 or 0 again. */
+ for (this_reg = num_regs - 1; this_reg > last_used_reg; this_reg--) {
+ regend[this_reg] = REG_UNSET_VALUE;
+ regstart[this_reg] = REG_UNSET_VALUE;
+ IS_ACTIVE(reg_info[this_reg]) = 0;
+ MATCHED_SOMETHING(reg_info[this_reg]) = 0;
+ }
- /* And restore the rest from the stack. */
- for ( ; this_reg > 0; this_reg--) {
- reg_info[this_reg].word = *--stackp;
- regend[this_reg] = *--stackp;
- regstart[this_reg] = *--stackp;
- }
- if (p < pend) {
- int is_a_jump_n = 0;
- int failed_paren = 0;
-
- p1 = p;
- /* If failed to a backwards jump that's part of a repetition
- loop, need to pop this failure point and use the next one. */
- pop_loop:
- switch ((enum regexpcode)*p1) {
- case stop_paren:
- failed_paren = 1;
- p1++;
- goto pop_loop;
+ /* And restore the rest from the stack. */
+ for ( ; this_reg > 0; this_reg--) {
+ reg_info[this_reg].word = *--stackp;
+ regend[this_reg] = *--stackp;
+ regstart[this_reg] = *--stackp;
+ }
+ if (p < pend) {
+ int is_a_jump_n = 0;
+ int failed_paren = 0;
+
+ p1 = p;
+ /* If failed to a backwards jump that's part of a repetition
+ loop, need to pop this failure point and use the next one. */
+ pop_loop:
+ switch ((enum regexpcode)*p1) {
+ case stop_paren:
+ failed_paren = 1;
+ p1++;
+ goto pop_loop;
- case jump_n:
- case finalize_push_n:
- is_a_jump_n = 1;
- case maybe_finalize_jump:
- case finalize_jump:
- case finalize_push:
- case jump:
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- p1 += mcnt;
-
- if (p1 >= pend) break;
- if (( is_a_jump_n && (enum regexpcode)*p1 == succeed_n) ||
- (!is_a_jump_n && (enum regexpcode)*p1 == on_failure_jump)) {
- if (failed_paren) {
- p1++;
- EXTRACT_NUMBER_AND_INCR(mcnt, p1);
- PUSH_FAILURE_POINT(p1 + mcnt, d);
- }
- goto fail;
+ case jump_n:
+ case finalize_push_n:
+ is_a_jump_n = 1;
+ case maybe_finalize_jump:
+ case finalize_jump:
+ case finalize_push:
+ case jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+
+ if (p1 >= pend) break;
+ if (( is_a_jump_n && (enum regexpcode)*p1 == succeed_n) ||
+ (!is_a_jump_n && (enum regexpcode)*p1 == on_failure_jump)) {
+ if (failed_paren) {
+ p1++;
+ EXTRACT_NUMBER_AND_INCR(mcnt, p1);
+ PUSH_FAILURE_POINT(p1 + mcnt, d);
}
- break;
- default:
- /* do nothing */ ;
+ goto fail;
}
+ break;
+ default:
+ /* do nothing */ ;
}
}
+ }
else
break; /* Matching at this starting point really fails. */
}
@@ -4128,65 +4090,64 @@ group_match_null_string_p (p, end, reg_info)
/* If the next operation is not a jump backwards in the
pattern. */
- if (mcnt >= 0)
- {
- /* Go through the on_failure_jumps of the alternatives,
- seeing if any of the alternatives cannot match nothing.
- The last alternative starts with only a jump,
- whereas the rest start with on_failure_jump and end
- with a jump, e.g., here is the pattern for `a|b|c':
+ if (mcnt >= 0) {
+ /* Go through the on_failure_jumps of the alternatives,
+ seeing if any of the alternatives cannot match nothing.
+ The last alternative starts with only a jump,
+ whereas the rest start with on_failure_jump and end
+ with a jump, e.g., here is the pattern for `a|b|c':
- /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
- /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
- /exactn/1/c
+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+ /exactn/1/c
- So, we have to first go through the first (n-1)
- alternatives and then deal with the last one separately. */
+ So, we have to first go through the first (n-1)
+ alternatives and then deal with the last one separately. */
- /* Deal with the first (n-1) alternatives, which start
- with an on_failure_jump (see above) that jumps to right
- past a jump_past_alt. */
+ /* Deal with the first (n-1) alternatives, which start
+ with an on_failure_jump (see above) that jumps to right
+ past a jump_past_alt. */
- while ((enum regexpcode)p1[mcnt-3] == jump_past_alt) {
- /* `mcnt' holds how many bytes long the alternative
- is, including the ending `jump_past_alt' and
- its number. */
+ while ((enum regexpcode)p1[mcnt-3] == jump_past_alt) {
+ /* `mcnt' holds how many bytes long the alternative
+ is, including the ending `jump_past_alt' and
+ its number. */
- if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
- reg_info))
- return 0;
+ if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
+ reg_info))
+ return 0;
- /* Move to right after this alternative, including the
- jump_past_alt. */
- p1 += mcnt;
+ /* Move to right after this alternative, including the
+ jump_past_alt. */
+ p1 += mcnt;
- /* Break if it's the beginning of an n-th alternative
- that doesn't begin with an on_failure_jump. */
- if ((enum regexpcode)*p1 != on_failure_jump)
- break;
-
- /* Still have to check that it's not an n-th
- alternative that starts with an on_failure_jump. */
- p1++;
- EXTRACT_NUMBER_AND_INCR (mcnt, p1);
- if ((enum regexpcode)p1[mcnt-3] != jump_past_alt) {
- /* Get to the beginning of the n-th alternative. */
- p1 -= 3;
- break;
- }
+ /* Break if it's the beginning of an n-th alternative
+ that doesn't begin with an on_failure_jump. */
+ if ((enum regexpcode)*p1 != on_failure_jump)
+ break;
+
+ /* Still have to check that it's not an n-th
+ alternative that starts with an on_failure_jump. */
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if ((enum regexpcode)p1[mcnt-3] != jump_past_alt) {
+ /* Get to the beginning of the n-th alternative. */
+ p1 -= 3;
+ break;
}
+ }
- /* Deal with the last alternative: go back and get number
- of the `jump_past_alt' just before it. `mcnt' contains
- the length of the alternative. */
- EXTRACT_NUMBER (mcnt, p1 - 2);
+ /* Deal with the last alternative: go back and get number
+ of the `jump_past_alt' just before it. `mcnt' contains
+ the length of the alternative. */
+ EXTRACT_NUMBER (mcnt, p1 - 2);
#if 0
- if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
- return 0;
+ if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+ return 0;
#endif
- p1 += mcnt; /* Get past the n-th alternative. */
- } /* if mcnt > 0 */
+ p1 += mcnt; /* Get past the n-th alternative. */
+ } /* if mcnt > 0 */
break;
diff --git a/sample/test.rb b/sample/test.rb
index 57641448ff..11fa499fd3 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -599,14 +599,21 @@ ok(("abc" =~ /d*$/) == 3)
ok("" =~ /^$/)
ok("\n" =~ /^$/)
ok("a\n\n" =~ /^$/)
-"abcabc" =~ /.*a/
-ok($& == "abca")
-"abcabc" =~ /.*c/
-ok($& == "abcabc")
-"abcabc" =~ /.*?a/
-ok($& == "a")
-"abcabc" =~ /.*?c/
-ok($& == "abc")
+ok("abcabc" =~ /.*a/ && $& == "abca")
+ok("abcabc" =~ /.*c/ && $& == "abcabc")
+ok("abcabc" =~ /.*?a/ && $& == "a")
+ok("abcabc" =~ /.*?c/ && $& == "abc")
+ok(/(.|\n)*?\n(b|\n)/ =~ "a\nb\n\n" && $& == "a\nb")
+$x = <<END;
+ABCD
+ABCD
+END
+
+$x.gsub!(/((.|\n)*?)B((.|\n)*?)D/){$1+$3}
+ok($x == "AC\nAC\n")
+
+ok("foobar" =~ /foo(?=(bar)|(baz))/)
+ok("foobaz" =~ /foo(?=(bar)|(baz))/)
$foo = "abc"
ok("#$foo = abc" == "abc = abc")
@@ -845,9 +852,13 @@ ok($x[4].call == 8)
proc {
p = binding
eval "foo11 = 1", p
+ foo22 = 5
proc{foo11=22}.call
+ proc{foo22=55}.call
ok(eval("foo11", p) == eval("foo11"))
ok(eval("foo11") == 1)
+ ok(eval("foo22", p) == eval("foo22"))
+ ok(eval("foo22") == 55)
}.call
p1 = proc{i6 = 0; proc{i6}}.call
diff --git a/win32/ruby.def b/win32/ruby.def
index 06820c8cf9..df8390b0be 100644
--- a/win32/ruby.def
+++ b/win32/ruby.def
@@ -197,7 +197,6 @@ EXPORTS
ruby_run
rb_eval_string
rb_eval_cmd
- rb_trap_eval
rb_test_false_or_nil
rb_respond_to
rb_exit