diff --git a/Zend/tests/flexible-heredoc-complex-test1.phpt b/Zend/tests/flexible-heredoc-complex-test1.phpt new file mode 100644 index 0000000000000..3e148d065243b --- /dev/null +++ b/Zend/tests/flexible-heredoc-complex-test1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Flexible heredoc syntax complex test 1: interpolated nested heredocs +with different delimiter names +--FILE-- + +--EXPECT-- +string(5) "a +b +c" diff --git a/Zend/tests/flexible-heredoc-complex-test2.phpt b/Zend/tests/flexible-heredoc-complex-test2.phpt new file mode 100644 index 0000000000000..d585e4b476b48 --- /dev/null +++ b/Zend/tests/flexible-heredoc-complex-test2.phpt @@ -0,0 +1,27 @@ +--TEST-- +Flexible heredoc syntax complex test 2: interpolated nested heredocs +with the same delimiter name +--FILE-- + +--EXPECT-- +string(5) "a +b +c" diff --git a/Zend/tests/flexible-heredoc-complex-test3.phpt b/Zend/tests/flexible-heredoc-complex-test3.phpt new file mode 100644 index 0000000000000..cf68f123163b2 --- /dev/null +++ b/Zend/tests/flexible-heredoc-complex-test3.phpt @@ -0,0 +1,27 @@ +--TEST-- +Flexible heredoc syntax complex test 3: interpolated nested heredocs +with the same delimiter name with different levels of indentation +--FILE-- + +--EXPECT-- +string(8) " a + b +c" diff --git a/Zend/tests/flexible-heredoc-complex-test4.phpt b/Zend/tests/flexible-heredoc-complex-test4.phpt new file mode 100644 index 0000000000000..5be0f442f62fe --- /dev/null +++ b/Zend/tests/flexible-heredoc-complex-test4.phpt @@ -0,0 +1,35 @@ +--TEST-- +Flexible heredoc syntax complex test 4: interpolated variable with +the same delimiter name as the heredoc +--FILE-- + +--EXPECT-- +string(8) "Test +FOO" +string(16) " Test + FOO" diff --git a/Zend/tests/flexible-heredoc-error1.phpt b/Zend/tests/flexible-heredoc-error1.phpt new file mode 100644 index 0000000000000..dc56d4f8ed40d --- /dev/null +++ b/Zend/tests/flexible-heredoc-error1.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible heredoc syntax 1: different indentation for body (spaces) ending marker (tabs) +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error10.phpt b/Zend/tests/flexible-heredoc-error10.phpt new file mode 100644 index 0000000000000..6b7fe9ee777d3 --- /dev/null +++ b/Zend/tests/flexible-heredoc-error10.phpt @@ -0,0 +1,13 @@ +--TEST-- +Flexible heredoc syntax error 10: unindented variable interpolation (as first value) +--FILE-- + +--EXPECTF-- +Parse error: Invalid body indentation level (expecting an indentation level of at least 1) in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error11.phpt b/Zend/tests/flexible-heredoc-error11.phpt new file mode 100644 index 0000000000000..3e71cbd684d26 --- /dev/null +++ b/Zend/tests/flexible-heredoc-error11.phpt @@ -0,0 +1,13 @@ +--TEST-- +Flexible heredoc syntax error 11: show erroneous line in error message (variable interpolation) +--FILE-- + +--EXPECTF-- +Parse error: Invalid body indentation level (expecting an indentation level of at least 1) in %s on line 5 \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error12.phpt b/Zend/tests/flexible-heredoc-error12.phpt new file mode 100644 index 0000000000000..022c0811aa3b0 --- /dev/null +++ b/Zend/tests/flexible-heredoc-error12.phpt @@ -0,0 +1,13 @@ +--TEST-- +Flexible heredoc syntax error 12: show erroneous line in error message (mixed indentation) +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line 5 \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error13.phpt b/Zend/tests/flexible-heredoc-error13.phpt new file mode 100644 index 0000000000000..f26b04e4602ca --- /dev/null +++ b/Zend/tests/flexible-heredoc-error13.phpt @@ -0,0 +1,13 @@ +--TEST-- +Flexible heredoc syntax error 12: show erroneous line in error message (lacking indentation) +--FILE-- + +--EXPECTF-- +Parse error: Invalid body indentation level (expecting an indentation level of at least 1) in %s on line 5 \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error2.phpt b/Zend/tests/flexible-heredoc-error2.phpt new file mode 100644 index 0000000000000..28e4d74a10302 --- /dev/null +++ b/Zend/tests/flexible-heredoc-error2.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible heredoc syntax 2: mixing spaces and tabs in body +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error3.phpt b/Zend/tests/flexible-heredoc-error3.phpt new file mode 100644 index 0000000000000..751f6b7926abc --- /dev/null +++ b/Zend/tests/flexible-heredoc-error3.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible heredoc syntax error 3: mixing spaces and tabs in ending marker +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error4.phpt b/Zend/tests/flexible-heredoc-error4.phpt new file mode 100644 index 0000000000000..4542b015b84c4 --- /dev/null +++ b/Zend/tests/flexible-heredoc-error4.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible heredoc syntax error 4: not enough body indentation +--FILE-- + +--EXPECTF-- +Parse error: Invalid body indentation level (expecting an indentation level of at least 5) in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error5.phpt b/Zend/tests/flexible-heredoc-error5.phpt new file mode 100644 index 0000000000000..fdd6e5c950a4f --- /dev/null +++ b/Zend/tests/flexible-heredoc-error5.phpt @@ -0,0 +1,11 @@ +--TEST-- +Flexible heredoc syntax error 5: mixing spaces and tabs in ending marker for 0 length body +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error6.phpt b/Zend/tests/flexible-heredoc-error6.phpt new file mode 100644 index 0000000000000..c2daa72207af3 --- /dev/null +++ b/Zend/tests/flexible-heredoc-error6.phpt @@ -0,0 +1,10 @@ +--TEST-- +Flexible heredoc syntax error 6: no ending token on 0 length body +--DESCRIPTION-- +Note: the closing ?> has been deliberately elided. +--FILE-- + has been deliberately elided. +--FILE-- + +--EXPECTF-- +Parse error: Invalid body indentation level (expecting an indentation level of at least 1) in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-error9.phpt b/Zend/tests/flexible-heredoc-error9.phpt new file mode 100644 index 0000000000000..70777f26d1cbc --- /dev/null +++ b/Zend/tests/flexible-heredoc-error9.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible heredoc syntax error 9: unindented variable interpolation +--FILE-- + +--EXPECTF-- +Parse error: Invalid body indentation level (expecting an indentation level of at least 2) in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-heredoc-nowdoc-lineno.phpt b/Zend/tests/flexible-heredoc-nowdoc-lineno.phpt new file mode 100644 index 0000000000000..8aeddbd10d07c --- /dev/null +++ b/Zend/tests/flexible-heredoc-nowdoc-lineno.phpt @@ -0,0 +1,30 @@ +--TEST-- +Flexible heredoc lineno: ensure the compiler globals line number is correct +--FILE-- +getLine()); +} + +?> +--EXPECT-- +int(20) diff --git a/Zend/tests/flexible-heredoc-nowdoc.phpt b/Zend/tests/flexible-heredoc-nowdoc.phpt new file mode 100644 index 0000000000000..175b9c6734487 --- /dev/null +++ b/Zend/tests/flexible-heredoc-nowdoc.phpt @@ -0,0 +1,128 @@ +--TEST-- +Flexible heredoc/nowdoc syntax +--FILE-- + +--EXPECT-- +string(0) "" +string(0) "" +string(0) "" + a + b + + c + + d +e + a + b + c + d +e + + a + + b + + c + + d + +e + + a + + a + + b + + c + + d + +e + + a + b + c + d +e +string(3) "Bar" +string(4) " +Bar" \ No newline at end of file diff --git a/Zend/tests/flexible-nowdoc-error1.phpt b/Zend/tests/flexible-nowdoc-error1.phpt new file mode 100644 index 0000000000000..5c086d2abd647 --- /dev/null +++ b/Zend/tests/flexible-nowdoc-error1.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible nowdoc syntax 1: different indentation for body (spaces) ending marker (tabs) +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-nowdoc-error2.phpt b/Zend/tests/flexible-nowdoc-error2.phpt new file mode 100644 index 0000000000000..e6bd544341df7 --- /dev/null +++ b/Zend/tests/flexible-nowdoc-error2.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible nowdoc syntax 2: mixing spaces and tabs in body +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-nowdoc-error3.phpt b/Zend/tests/flexible-nowdoc-error3.phpt new file mode 100644 index 0000000000000..c50dd4fa4a2dd --- /dev/null +++ b/Zend/tests/flexible-nowdoc-error3.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible nowdoc syntax error 3: mixing spaces and tabs in ending marker +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-nowdoc-error4.phpt b/Zend/tests/flexible-nowdoc-error4.phpt new file mode 100644 index 0000000000000..650a9a94f72c8 --- /dev/null +++ b/Zend/tests/flexible-nowdoc-error4.phpt @@ -0,0 +1,14 @@ +--TEST-- +Flexible nowdoc syntax error 4: not enough body indentation +--FILE-- + +--EXPECTF-- +Parse error: Invalid body indentation level (expecting an indentation level of at least 5) in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-nowdoc-error5.phpt b/Zend/tests/flexible-nowdoc-error5.phpt new file mode 100644 index 0000000000000..7579c10b72970 --- /dev/null +++ b/Zend/tests/flexible-nowdoc-error5.phpt @@ -0,0 +1,11 @@ +--TEST-- +Flexible nowdoc syntax error 5: mixing spaces and tabs in ending marker for 0 length body +--FILE-- + +--EXPECTF-- +Parse error: Invalid indentation - tabs and spaces cannot be mixed in %s on line %d \ No newline at end of file diff --git a/Zend/tests/flexible-nowdoc-error6.phpt b/Zend/tests/flexible-nowdoc-error6.phpt new file mode 100644 index 0000000000000..e4f9ded844a22 --- /dev/null +++ b/Zend/tests/flexible-nowdoc-error6.phpt @@ -0,0 +1,10 @@ +--TEST-- +Flexible nowdoc syntax error 6: no ending token on 0 length body +--DESCRIPTION-- +Note: the closing ?> has been deliberately elided. +--FILE-- + has been deliberately elided. +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected end of file, expecting variable (T_VARIABLE) or heredoc end (T_END_HEREDOC) or ${ (T_DOLLAR_OPEN_CURLY_BRACES) or {$ (T_CURLY_OPEN) in %s on line %d \ No newline at end of file diff --git a/Zend/tests/heredoc_009.phpt b/Zend/tests/heredoc_009.phpt deleted file mode 100644 index 38f5d282f0ae5..0000000000000 --- a/Zend/tests/heredoc_009.phpt +++ /dev/null @@ -1,42 +0,0 @@ ---TEST-- -Torture the T_END_HEREDOC rules (heredoc) ---FILE-- - ---EXPECTF-- -Notice: Undefined variable: ENDOFHEREDOC in %s on line %d -ENDOFHEREDOC ; - ENDOFHEREDOC; -ENDOFHEREDOC - ENDOFHEREDOC -; - -Notice: Undefined variable: ENDOFHEREDOC in %s on line %d -ENDOFHEREDOC ; - ENDOFHEREDOC; -ENDOFHEREDOC - ENDOFHEREDOC -; diff --git a/Zend/tests/heredoc_010.phpt b/Zend/tests/heredoc_010.phpt deleted file mode 100644 index 5aa0433bcff7a..0000000000000 --- a/Zend/tests/heredoc_010.phpt +++ /dev/null @@ -1,32 +0,0 @@ ---TEST-- -Torture the T_END_HEREDOC rules with variable expansions (heredoc) ---FILE-- - ---EXPECT-- -ENDOFHEREDOC -ENDOFHEREDOC -ENDOFHEREDOC -ENDOFHEREDOC -ENDOFHEREDOC -ENDOFHEREDOC diff --git a/Zend/tests/heredoc_017.phpt b/Zend/tests/heredoc_017.phpt deleted file mode 100644 index e0ffddf05f302..0000000000000 --- a/Zend/tests/heredoc_017.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Testinh heredoc syntax ---FILE-- - ---EXPECT-- -bool(true) diff --git a/Zend/tests/heredoc_018.phpt b/Zend/tests/heredoc_018.phpt deleted file mode 100644 index c10e9c1c4e296..0000000000000 --- a/Zend/tests/heredoc_018.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Testing heredoc with tabs before identifier ---FILE-- - ---EXPECT-- -bool(true) diff --git a/Zend/tests/nowdoc_009.phpt b/Zend/tests/nowdoc_009.phpt deleted file mode 100644 index ec8b78f010c8f..0000000000000 --- a/Zend/tests/nowdoc_009.phpt +++ /dev/null @@ -1,40 +0,0 @@ ---TEST-- -Torture the T_END_NOWDOC rules (nowdoc) ---FILE-- - ---EXPECT-- -ENDOFNOWDOC ; - ENDOFNOWDOC; -ENDOFNOWDOC - ENDOFNOWDOC -$ENDOFNOWDOC; -ENDOFNOWDOC ; - ENDOFNOWDOC; -ENDOFNOWDOC - ENDOFNOWDOC -$ENDOFNOWDOC; - diff --git a/Zend/tests/nowdoc_010.phpt b/Zend/tests/nowdoc_010.phpt deleted file mode 100644 index 6f288151ce937..0000000000000 --- a/Zend/tests/nowdoc_010.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -Torture the T_END_NOWDOC rules with variable expansions (nowdoc) ---FILE-- - ---EXPECT-- -{$fooledYou}ENDOFNOWDOC{$fooledYou} -ENDOFNOWDOC{$fooledYou} -{$fooledYou}ENDOFNOWDOC -{$fooledYou}ENDOFNOWDOC{$fooledYou} -ENDOFNOWDOC{$fooledYou} -{$fooledYou}ENDOFNOWDOC - diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 0db44016292a6..01b5583f0a18b 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -273,6 +273,9 @@ struct _zend_php_scanner_globals { int yy_state; zend_stack state_stack; zend_ptr_stack heredoc_label_stack; + zend_bool heredoc_scan_ahead; + int heredoc_indentation; + zend_bool heredoc_indentation_uses_spaces; /* original (unfiltered) script */ unsigned char *script_org; diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index 0ef393d6e9aee..42e209ab91bf9 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -183,6 +183,7 @@ void startup_scanner(void) CG(extra_fn_flags) = 0; zend_stack_init(&SCNG(state_stack), sizeof(int)); zend_ptr_stack_init(&SCNG(heredoc_label_stack)); + SCNG(heredoc_scan_ahead) = 0; } static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) { @@ -196,6 +197,7 @@ void shutdown_scanner(void) zend_stack_destroy(&SCNG(state_stack)); zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1); zend_ptr_stack_destroy(&SCNG(heredoc_label_stack)); + SCNG(heredoc_scan_ahead) = 0; SCNG(on_event) = NULL; } @@ -1106,6 +1108,88 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot return SUCCESS; } +#define HEREDOC_USING_SPACES 1 +#define HEREDOC_USING_TABS 2 + +static zend_bool strip_multiline_string_indentation(zval *zendlval, int newline, int indentation, zend_bool using_spaces) +{ + int len = Z_STRLEN_P(zendlval), new_len = len, i = 0, j = 0, skip, newline_count = 0; + char *copy = Z_STRVAL_P(zendlval); + zend_bool trailing_newline = 0; + + while (j < len) { + trailing_newline = 0; + + for (skip = 0; skip < indentation; ++skip, ++j, --new_len) { + if (copy[j] == '\r' || copy[j] == '\n') { + goto skip; + } + + if (copy[j] != ' ' && copy[j] != '\t') { + CG(zend_lineno) += newline_count; + zend_throw_exception_ex(zend_ce_parse_error, 0, "Invalid body indentation level (expecting an indentation level of at least %d)", indentation); + goto error; + } + + if ((!using_spaces && copy[j] == ' ') || (using_spaces && copy[j] == '\t')) { + CG(zend_lineno) += newline_count; + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); + goto error; + } + } + + while (j < len && copy[j] != '\r' && copy[j] != '\n') { + copy[i++] = copy[j++]; + } + + if (j == len) { + break; + } +skip: + if (copy[j] == '\r') { + copy[i++] = copy[j++]; + trailing_newline = 1; + } + + if (copy[j] == '\n') { + copy[i++] = copy[j++]; + trailing_newline = 1; + } + + if (trailing_newline) { + ++newline_count; + } + } + + if (YYSTATE != STATE(ST_END_HEREDOC) && trailing_newline && indentation) { + CG(zend_lineno) += newline_count; + zend_throw_exception_ex(zend_ce_parse_error, 0, "Invalid body indentation level (expecting an indentation level of at least %d)", indentation); + goto error; + } + + Z_STRVAL_P(zendlval)[new_len - newline] = '\0'; + Z_STRLEN_P(zendlval) = new_len - newline; + + return 1; + +error: + zval_dtor(zendlval); + ZVAL_UNDEF(zendlval); + + return 0; +} + +static void copy_heredoc_label_stack(void *void_heredoc_label) +{ + zend_heredoc_label *heredoc_label = void_heredoc_label; + zend_heredoc_label *new_heredoc_label = emalloc(sizeof(zend_heredoc_label)); + + *new_heredoc_label = *heredoc_label; + new_heredoc_label->label = estrndup(heredoc_label->label, heredoc_label->length); + + zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) new_heredoc_label); +} + #define PARSER_MODE() \ EXPECTED(elem != NULL) @@ -1141,7 +1225,7 @@ int start_line = CG(zend_lineno); SCNG(yy_text) = YYCURSOR; -#line 1145 "Zend/zend_language_scanner.c" +#line 1229 "Zend/zend_language_scanner.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -1193,7 +1277,7 @@ int start_line = CG(zend_lineno); yy4: YYDEBUG(4, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1854 "Zend/zend_language_scanner.l" +#line 1938 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1240,7 +1324,7 @@ int start_line = CG(zend_lineno); HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN_WITH_VAL(T_INLINE_HTML); } -#line 1244 "Zend/zend_language_scanner.c" +#line 1328 "Zend/zend_language_scanner.c" yy5: YYDEBUG(5, *YYCURSOR); yych = *++YYCURSOR; @@ -1256,7 +1340,7 @@ int start_line = CG(zend_lineno); yy7: YYDEBUG(7, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1842 "Zend/zend_language_scanner.l" +#line 1926 "Zend/zend_language_scanner.l" { if (CG(short_tags)) { BEGIN(ST_IN_SCRIPTING); @@ -1268,13 +1352,13 @@ int start_line = CG(zend_lineno); goto inline_char_handler; } } -#line 1272 "Zend/zend_language_scanner.c" +#line 1356 "Zend/zend_language_scanner.c" yy8: YYDEBUG(8, *YYCURSOR); ++YYCURSOR; YYDEBUG(9, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1823 "Zend/zend_language_scanner.l" +#line 1907 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); if (PARSER_MODE()) { @@ -1282,7 +1366,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_OPEN_TAG_WITH_ECHO); } -#line 1286 "Zend/zend_language_scanner.c" +#line 1370 "Zend/zend_language_scanner.c" yy10: YYDEBUG(10, *YYCURSOR); yych = *++YYCURSOR; @@ -1313,7 +1397,7 @@ int start_line = CG(zend_lineno); yy15: YYDEBUG(15, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1832 "Zend/zend_language_scanner.l" +#line 1916 "Zend/zend_language_scanner.l" { HANDLE_NEWLINE(yytext[yyleng-1]); BEGIN(ST_IN_SCRIPTING); @@ -1322,7 +1406,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_OPEN_TAG); } -#line 1326 "Zend/zend_language_scanner.c" +#line 1410 "Zend/zend_language_scanner.c" yy16: YYDEBUG(16, *YYCURSOR); ++YYCURSOR; @@ -1379,7 +1463,7 @@ int start_line = CG(zend_lineno); yy20: YYDEBUG(20, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2305 "Zend/zend_language_scanner.l" +#line 2472 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1424,7 +1508,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN(T_ERROR); } } -#line 1428 "Zend/zend_language_scanner.c" +#line 1512 "Zend/zend_language_scanner.c" yy21: YYDEBUG(21, *YYCURSOR); yych = *++YYCURSOR; @@ -1448,12 +1532,12 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(23, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2245 "Zend/zend_language_scanner.l" +#line 2412 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('`'); } -#line 1457 "Zend/zend_language_scanner.c" +#line 1541 "Zend/zend_language_scanner.c" yy24: YYDEBUG(24, *YYCURSOR); yych = *++YYCURSOR; @@ -1474,34 +1558,34 @@ int start_line = CG(zend_lineno); yy27: YYDEBUG(27, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1919 "Zend/zend_language_scanner.l" +#line 2003 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 1482 "Zend/zend_language_scanner.c" +#line 1566 "Zend/zend_language_scanner.c" yy28: YYDEBUG(28, *YYCURSOR); ++YYCURSOR; YYDEBUG(29, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1619 "Zend/zend_language_scanner.l" +#line 1703 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1493 "Zend/zend_language_scanner.c" +#line 1577 "Zend/zend_language_scanner.c" yy30: YYDEBUG(30, *YYCURSOR); ++YYCURSOR; YYDEBUG(31, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2233 "Zend/zend_language_scanner.l" +#line 2400 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 1505 "Zend/zend_language_scanner.c" +#line 1589 "Zend/zend_language_scanner.c" yy32: YYDEBUG(32, *YYCURSOR); yych = *++YYCURSOR; @@ -1515,13 +1599,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(35, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1913 "Zend/zend_language_scanner.l" +#line 1997 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 1525 "Zend/zend_language_scanner.c" +#line 1609 "Zend/zend_language_scanner.c" yy36: YYDEBUG(36, *YYCURSOR); yych = *++YYCURSOR; @@ -1539,13 +1623,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(38, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1905 "Zend/zend_language_scanner.l" +#line 1989 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 1549 "Zend/zend_language_scanner.c" +#line 1633 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_DOUBLE_QUOTES: @@ -1598,7 +1682,7 @@ int start_line = CG(zend_lineno); yy42: YYDEBUG(42, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2251 "Zend/zend_language_scanner.l" +#line 2418 "Zend/zend_language_scanner.l" { if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) { YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1; @@ -1651,18 +1735,18 @@ int start_line = CG(zend_lineno); RETURN_TOKEN(T_ERROR); } } -#line 1655 "Zend/zend_language_scanner.c" +#line 1739 "Zend/zend_language_scanner.c" yy43: YYDEBUG(43, *YYCURSOR); ++YYCURSOR; YYDEBUG(44, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2240 "Zend/zend_language_scanner.l" +#line 2407 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('"'); } -#line 1666 "Zend/zend_language_scanner.c" +#line 1750 "Zend/zend_language_scanner.c" yy45: YYDEBUG(45, *YYCURSOR); yych = *++YYCURSOR; @@ -1701,34 +1785,34 @@ int start_line = CG(zend_lineno); yy49: YYDEBUG(49, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1919 "Zend/zend_language_scanner.l" +#line 2003 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 1709 "Zend/zend_language_scanner.c" +#line 1793 "Zend/zend_language_scanner.c" yy50: YYDEBUG(50, *YYCURSOR); ++YYCURSOR; YYDEBUG(51, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1619 "Zend/zend_language_scanner.l" +#line 1703 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1720 "Zend/zend_language_scanner.c" +#line 1804 "Zend/zend_language_scanner.c" yy52: YYDEBUG(52, *YYCURSOR); ++YYCURSOR; YYDEBUG(53, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2233 "Zend/zend_language_scanner.l" +#line 2400 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 1732 "Zend/zend_language_scanner.c" +#line 1816 "Zend/zend_language_scanner.c" yy54: YYDEBUG(54, *YYCURSOR); yych = *++YYCURSOR; @@ -1742,13 +1826,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(57, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1913 "Zend/zend_language_scanner.l" +#line 1997 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 1752 "Zend/zend_language_scanner.c" +#line 1836 "Zend/zend_language_scanner.c" yy58: YYDEBUG(58, *YYCURSOR); yych = *++YYCURSOR; @@ -1766,13 +1850,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(60, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1905 "Zend/zend_language_scanner.l" +#line 1989 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 1776 "Zend/zend_language_scanner.c" +#line 1860 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_END_HEREDOC: @@ -1783,12 +1867,12 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(64, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2219 "Zend/zend_language_scanner.l" +#line 2386 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack)); - YYCURSOR += heredoc_label->length - 1; - yyleng = heredoc_label->length; + yyleng = heredoc_label->indentation + heredoc_label->length; + YYCURSOR += yyleng - 1; heredoc_label_dtor(heredoc_label); efree(heredoc_label); @@ -1796,7 +1880,7 @@ int start_line = CG(zend_lineno); BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_END_HEREDOC); } -#line 1800 "Zend/zend_language_scanner.c" +#line 1884 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_HEREDOC: { @@ -1844,11 +1928,10 @@ int start_line = CG(zend_lineno); yy68: YYDEBUG(68, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2351 "Zend/zend_language_scanner.l" +#line 2518 "Zend/zend_language_scanner.l" { - int newline = 0; - zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack)); + int newline = 0, indentation = 0, spacing = 0; if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1864,28 +1947,55 @@ int start_line = CG(zend_lineno); } /* fall through */ case '\n': + indentation = spacing = 0; + + while (YYCURSOR < YYLIMIT && (*YYCURSOR == ' ' || *YYCURSOR == '\t')) { + if (*YYCURSOR == '\t') { + spacing |= HEREDOC_USING_TABS; + } else { + spacing |= HEREDOC_USING_SPACES; + } + ++YYCURSOR; + ++indentation; + } + + if (YYCURSOR == YYLIMIT) { + yyleng = YYCURSOR - SCNG(yy_text); + HANDLE_NEWLINES(yytext, yyleng); + ZVAL_NULL(zendlval); + RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); + } + /* Check for ending label on the next line */ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) { - YYCTYPE *end = YYCURSOR + heredoc_label->length; + if (IS_LABEL_START(YYCURSOR[heredoc_label->length])) { + continue; + } - if (*end == ';') { - end++; + if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) { + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); } - if (*end == '\n' || *end == '\r') { - /* newline before label will be subtracted from returned text, but - * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ - if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') { - newline = 2; /* Windows newline */ - } else { - newline = 1; - } + /* newline before label will be subtracted from returned text, but + * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ + if (YYCURSOR[-indentation - 2] == '\r' && YYCURSOR[-indentation - 1] == '\n') { + newline = 2; /* Windows newline */ + } else { + newline = 1; + } - CG(increment_lineno) = 1; /* For newline before label */ - BEGIN(ST_END_HEREDOC); + CG(increment_lineno) = 1; /* For newline before label */ - goto heredoc_scan_done; + if (SCNG(heredoc_scan_ahead)) { + SCNG(heredoc_indentation) = indentation; + SCNG(heredoc_indentation_uses_spaces) = (spacing == HEREDOC_USING_SPACES); + } else { + YYCURSOR -= indentation; } + + BEGIN(ST_END_HEREDOC); + + goto heredoc_scan_done; } continue; case '$': @@ -1912,16 +2022,30 @@ int start_line = CG(zend_lineno); } heredoc_scan_done: + yyleng = YYCURSOR - SCNG(yy_text); + ZVAL_STRINGL(zendlval, yytext, yyleng); - if (EXPECTED(zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0) == SUCCESS) - || !PARSER_MODE()) { - RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); + if (!SCNG(heredoc_scan_ahead) && !EG(exception) && PARSER_MODE()) { + zend_string *copy = Z_STR_P(zendlval); + + if (!strip_multiline_string_indentation(zendlval, newline, heredoc_label->indentation, heredoc_label->indentation_uses_spaces)) { + RETURN_TOKEN(T_ERROR); + } + + if (UNEXPECTED(zend_scan_escape_string(zendlval, ZSTR_VAL(copy), ZSTR_LEN(copy), 0) != SUCCESS)) { + zend_string_free(copy); + RETURN_TOKEN(T_ERROR); + } + + zend_string_free(copy); } else { - RETURN_TOKEN(T_ERROR); + HANDLE_NEWLINES(yytext, yyleng - newline); } + + RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } -#line 1925 "Zend/zend_language_scanner.c" +#line 2049 "Zend/zend_language_scanner.c" yy69: YYDEBUG(69, *YYCURSOR); yych = *++YYCURSOR; @@ -1960,34 +2084,34 @@ int start_line = CG(zend_lineno); yy73: YYDEBUG(73, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1919 "Zend/zend_language_scanner.l" +#line 2003 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 1968 "Zend/zend_language_scanner.c" +#line 2092 "Zend/zend_language_scanner.c" yy74: YYDEBUG(74, *YYCURSOR); ++YYCURSOR; YYDEBUG(75, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1619 "Zend/zend_language_scanner.l" +#line 1703 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 1979 "Zend/zend_language_scanner.c" +#line 2103 "Zend/zend_language_scanner.c" yy76: YYDEBUG(76, *YYCURSOR); ++YYCURSOR; YYDEBUG(77, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2233 "Zend/zend_language_scanner.l" +#line 2400 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 1991 "Zend/zend_language_scanner.c" +#line 2115 "Zend/zend_language_scanner.c" yy78: YYDEBUG(78, *YYCURSOR); yych = *++YYCURSOR; @@ -2001,13 +2125,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(81, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1913 "Zend/zend_language_scanner.l" +#line 1997 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 2011 "Zend/zend_language_scanner.c" +#line 2135 "Zend/zend_language_scanner.c" yy82: YYDEBUG(82, *YYCURSOR); yych = *++YYCURSOR; @@ -2025,13 +2149,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(84, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1905 "Zend/zend_language_scanner.l" +#line 1989 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 2035 "Zend/zend_language_scanner.c" +#line 2159 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_IN_SCRIPTING: @@ -2200,7 +2324,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(88, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2486 "Zend/zend_language_scanner.l" +#line 2720 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -2209,7 +2333,7 @@ int start_line = CG(zend_lineno); zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 2213 "Zend/zend_language_scanner.c" +#line 2337 "Zend/zend_language_scanner.c" yy89: YYDEBUG(89, *YYCURSOR); ++YYCURSOR; @@ -2221,11 +2345,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(91, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1325 "Zend/zend_language_scanner.l" +#line 1409 "Zend/zend_language_scanner.l" { goto return_whitespace; } -#line 2229 "Zend/zend_language_scanner.c" +#line 2353 "Zend/zend_language_scanner.c" yy92: YYDEBUG(92, *YYCURSOR); ++YYCURSOR; @@ -2233,17 +2357,17 @@ int start_line = CG(zend_lineno); yy93: YYDEBUG(93, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1608 "Zend/zend_language_scanner.l" +#line 1692 "Zend/zend_language_scanner.l" { RETURN_TOKEN(yytext[0]); } -#line 2241 "Zend/zend_language_scanner.c" +#line 2365 "Zend/zend_language_scanner.c" yy94: YYDEBUG(94, *YYCURSOR); ++YYCURSOR; YYDEBUG(95, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2119 "Zend/zend_language_scanner.l" +#line 2203 "Zend/zend_language_scanner.l" { int bprefix = (yytext[0] != '"') ? 1 : 0; @@ -2288,13 +2412,13 @@ int start_line = CG(zend_lineno); BEGIN(ST_DOUBLE_QUOTES); RETURN_TOKEN('"'); } -#line 2292 "Zend/zend_language_scanner.c" +#line 2416 "Zend/zend_language_scanner.c" yy96: YYDEBUG(96, *YYCURSOR); ++YYCURSOR; YYDEBUG(97, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1946 "Zend/zend_language_scanner.l" +#line 2030 "Zend/zend_language_scanner.l" { while (YYCURSOR < YYLIMIT) { switch (*YYCURSOR++) { @@ -2326,7 +2450,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_COMMENT); } -#line 2330 "Zend/zend_language_scanner.c" +#line 2454 "Zend/zend_language_scanner.c" yy98: YYDEBUG(98, *YYCURSOR); yych = *++YYCURSOR; @@ -2357,7 +2481,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(102, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2029 "Zend/zend_language_scanner.l" +#line 2113 "Zend/zend_language_scanner.l" { register char *s, *t; char *end; @@ -2446,7 +2570,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN_WITH_VAL(T_CONSTANT_ENCAPSED_STRING); } -#line 2450 "Zend/zend_language_scanner.c" +#line 2574 "Zend/zend_language_scanner.c" yy103: YYDEBUG(103, *YYCURSOR); yyaccept = 0; @@ -2576,7 +2700,7 @@ int start_line = CG(zend_lineno); yy111: YYDEBUG(111, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1677 "Zend/zend_language_scanner.l" +#line 1761 "Zend/zend_language_scanner.l" { char *end; if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ @@ -2627,7 +2751,7 @@ int start_line = CG(zend_lineno); ZEND_ASSERT(!errno); RETURN_TOKEN_WITH_VAL(T_LNUMBER); } -#line 2631 "Zend/zend_language_scanner.c" +#line 2755 "Zend/zend_language_scanner.c" yy112: YYDEBUG(112, *YYCURSOR); yyaccept = 1; @@ -2708,11 +2832,11 @@ int start_line = CG(zend_lineno); yy120: YYDEBUG(120, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1941 "Zend/zend_language_scanner.l" +#line 2025 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_STRING, 0); } -#line 2716 "Zend/zend_language_scanner.c" +#line 2840 "Zend/zend_language_scanner.c" yy121: YYDEBUG(121, *YYCURSOR); yyaccept = 2; @@ -2997,11 +3121,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(143, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1348 "Zend/zend_language_scanner.l" +#line 1432 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_SEPARATOR); } -#line 3005 "Zend/zend_language_scanner.c" +#line 3129 "Zend/zend_language_scanner.c" yy144: YYDEBUG(144, *YYCURSOR); yych = *++YYCURSOR; @@ -3017,23 +3141,23 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(147, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2213 "Zend/zend_language_scanner.l" +#line 2380 "Zend/zend_language_scanner.l" { BEGIN(ST_BACKQUOTE); RETURN_TOKEN('`'); } -#line 3026 "Zend/zend_language_scanner.c" +#line 3150 "Zend/zend_language_scanner.c" yy148: YYDEBUG(148, *YYCURSOR); ++YYCURSOR; YYDEBUG(149, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1613 "Zend/zend_language_scanner.l" +#line 1697 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN('{'); } -#line 3037 "Zend/zend_language_scanner.c" +#line 3161 "Zend/zend_language_scanner.c" yy150: YYDEBUG(150, *YYCURSOR); yych = *++YYCURSOR; @@ -3045,7 +3169,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(152, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1625 "Zend/zend_language_scanner.l" +#line 1709 "Zend/zend_language_scanner.l" { RESET_DOC_COMMENT(); if (!zend_stack_is_empty(&SCNG(state_stack))) { @@ -3053,7 +3177,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN('}'); } -#line 3057 "Zend/zend_language_scanner.c" +#line 3181 "Zend/zend_language_scanner.c" yy153: YYDEBUG(153, *YYCURSOR); ++YYCURSOR; @@ -3061,11 +3185,11 @@ int start_line = CG(zend_lineno); yy154: YYDEBUG(154, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1512 "Zend/zend_language_scanner.l" +#line 1596 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_EQUAL); } -#line 3069 "Zend/zend_language_scanner.c" +#line 3193 "Zend/zend_language_scanner.c" yy155: YYDEBUG(155, *YYCURSOR); ++YYCURSOR; @@ -3090,41 +3214,41 @@ int start_line = CG(zend_lineno); yy157: YYDEBUG(157, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1919 "Zend/zend_language_scanner.l" +#line 2003 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 3098 "Zend/zend_language_scanner.c" +#line 3222 "Zend/zend_language_scanner.c" yy158: YYDEBUG(158, *YYCURSOR); ++YYCURSOR; YYDEBUG(159, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1556 "Zend/zend_language_scanner.l" +#line 1640 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MOD_EQUAL); } -#line 3108 "Zend/zend_language_scanner.c" +#line 3232 "Zend/zend_language_scanner.c" yy160: YYDEBUG(160, *YYCURSOR); ++YYCURSOR; YYDEBUG(161, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1584 "Zend/zend_language_scanner.l" +#line 1668 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_AND); } -#line 3118 "Zend/zend_language_scanner.c" +#line 3242 "Zend/zend_language_scanner.c" yy162: YYDEBUG(162, *YYCURSOR); ++YYCURSOR; YYDEBUG(163, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1568 "Zend/zend_language_scanner.l" +#line 1652 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AND_EQUAL); } -#line 3128 "Zend/zend_language_scanner.c" +#line 3252 "Zend/zend_language_scanner.c" yy164: YYDEBUG(164, *YYCURSOR); ++YYCURSOR; @@ -3254,72 +3378,72 @@ int start_line = CG(zend_lineno); if ((yych = *YYCURSOR) == '=') goto yy289; YYDEBUG(177, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1540 "Zend/zend_language_scanner.l" +#line 1624 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW); } -#line 3262 "Zend/zend_language_scanner.c" +#line 3386 "Zend/zend_language_scanner.c" yy178: YYDEBUG(178, *YYCURSOR); ++YYCURSOR; YYDEBUG(179, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1536 "Zend/zend_language_scanner.l" +#line 1620 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MUL_EQUAL); } -#line 3272 "Zend/zend_language_scanner.c" +#line 3396 "Zend/zend_language_scanner.c" yy180: YYDEBUG(180, *YYCURSOR); ++YYCURSOR; YYDEBUG(181, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1492 "Zend/zend_language_scanner.l" +#line 1576 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INC); } -#line 3282 "Zend/zend_language_scanner.c" +#line 3406 "Zend/zend_language_scanner.c" yy182: YYDEBUG(182, *YYCURSOR); ++YYCURSOR; YYDEBUG(183, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1528 "Zend/zend_language_scanner.l" +#line 1612 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PLUS_EQUAL); } -#line 3292 "Zend/zend_language_scanner.c" +#line 3416 "Zend/zend_language_scanner.c" yy184: YYDEBUG(184, *YYCURSOR); ++YYCURSOR; YYDEBUG(185, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1496 "Zend/zend_language_scanner.l" +#line 1580 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEC); } -#line 3302 "Zend/zend_language_scanner.c" +#line 3426 "Zend/zend_language_scanner.c" yy186: YYDEBUG(186, *YYCURSOR); ++YYCURSOR; YYDEBUG(187, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1532 "Zend/zend_language_scanner.l" +#line 1616 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MINUS_EQUAL); } -#line 3312 "Zend/zend_language_scanner.c" +#line 3436 "Zend/zend_language_scanner.c" yy188: YYDEBUG(188, *YYCURSOR); ++YYCURSOR; YYDEBUG(189, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1320 "Zend/zend_language_scanner.l" +#line 1404 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 3323 "Zend/zend_language_scanner.c" +#line 3447 "Zend/zend_language_scanner.c" yy190: YYDEBUG(190, *YYCURSOR); yych = *++YYCURSOR; @@ -3342,7 +3466,7 @@ int start_line = CG(zend_lineno); yy193: YYDEBUG(193, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1781 "Zend/zend_language_scanner.l" +#line 1865 "Zend/zend_language_scanner.l" { const char *end; @@ -3351,17 +3475,17 @@ int start_line = CG(zend_lineno); ZEND_ASSERT(end == yytext + yyleng); RETURN_TOKEN_WITH_VAL(T_DNUMBER); } -#line 3355 "Zend/zend_language_scanner.c" +#line 3479 "Zend/zend_language_scanner.c" yy194: YYDEBUG(194, *YYCURSOR); ++YYCURSOR; YYDEBUG(195, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1552 "Zend/zend_language_scanner.l" +#line 1636 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONCAT_EQUAL); } -#line 3365 "Zend/zend_language_scanner.c" +#line 3489 "Zend/zend_language_scanner.c" yy196: YYDEBUG(196, *YYCURSOR); yyaccept = 4; @@ -3370,7 +3494,7 @@ int start_line = CG(zend_lineno); yy197: YYDEBUG(197, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1978 "Zend/zend_language_scanner.l" +#line 2062 "Zend/zend_language_scanner.l" { int doc_com; @@ -3409,17 +3533,17 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_COMMENT); } -#line 3413 "Zend/zend_language_scanner.c" +#line 3537 "Zend/zend_language_scanner.c" yy198: YYDEBUG(198, *YYCURSOR); ++YYCURSOR; YYDEBUG(199, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1548 "Zend/zend_language_scanner.l" +#line 1632 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIV_EQUAL); } -#line 3423 "Zend/zend_language_scanner.c" +#line 3547 "Zend/zend_language_scanner.c" yy200: YYDEBUG(200, *YYCURSOR); yych = *++YYCURSOR; @@ -3451,11 +3575,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(204, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1344 "Zend/zend_language_scanner.l" +#line 1428 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM); } -#line 3459 "Zend/zend_language_scanner.c" +#line 3583 "Zend/zend_language_scanner.c" yy205: YYDEBUG(205, *YYCURSOR); yyaccept = 5; @@ -3466,22 +3590,22 @@ int start_line = CG(zend_lineno); yy206: YYDEBUG(206, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1600 "Zend/zend_language_scanner.l" +#line 1684 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL); } -#line 3474 "Zend/zend_language_scanner.c" +#line 3598 "Zend/zend_language_scanner.c" yy207: YYDEBUG(207, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '>') goto yy307; YYDEBUG(208, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1520 "Zend/zend_language_scanner.l" +#line 1604 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_SMALLER_OR_EQUAL); } -#line 3485 "Zend/zend_language_scanner.c" +#line 3609 "Zend/zend_language_scanner.c" yy209: YYDEBUG(209, *YYCURSOR); yych = *++YYCURSOR; @@ -3492,42 +3616,42 @@ int start_line = CG(zend_lineno); if ((yych = *YYCURSOR) == '=') goto yy309; YYDEBUG(211, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1508 "Zend/zend_language_scanner.l" +#line 1592 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_EQUAL); } -#line 3500 "Zend/zend_language_scanner.c" +#line 3624 "Zend/zend_language_scanner.c" yy212: YYDEBUG(212, *YYCURSOR); ++YYCURSOR; YYDEBUG(213, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1476 "Zend/zend_language_scanner.l" +#line 1560 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_ARROW); } -#line 3510 "Zend/zend_language_scanner.c" +#line 3634 "Zend/zend_language_scanner.c" yy214: YYDEBUG(214, *YYCURSOR); ++YYCURSOR; YYDEBUG(215, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1524 "Zend/zend_language_scanner.l" +#line 1608 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_GREATER_OR_EQUAL); } -#line 3520 "Zend/zend_language_scanner.c" +#line 3644 "Zend/zend_language_scanner.c" yy216: YYDEBUG(216, *YYCURSOR); ++YYCURSOR; if ((yych = *YYCURSOR) == '=') goto yy311; YYDEBUG(217, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1604 "Zend/zend_language_scanner.l" +#line 1688 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR); } -#line 3531 "Zend/zend_language_scanner.c" +#line 3655 "Zend/zend_language_scanner.c" yy218: YYDEBUG(218, *YYCURSOR); ++YYCURSOR; @@ -3536,7 +3660,7 @@ int start_line = CG(zend_lineno); yy219: YYDEBUG(219, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2017 "Zend/zend_language_scanner.l" +#line 2101 "Zend/zend_language_scanner.l" { BEGIN(INITIAL); if (yytext[yyleng-1] != '>') { @@ -3547,17 +3671,17 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_CLOSE_TAG); } -#line 3551 "Zend/zend_language_scanner.c" +#line 3675 "Zend/zend_language_scanner.c" yy220: YYDEBUG(220, *YYCURSOR); ++YYCURSOR; YYDEBUG(221, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1356 "Zend/zend_language_scanner.l" +#line 1440 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_COALESCE); } -#line 3561 "Zend/zend_language_scanner.c" +#line 3685 "Zend/zend_language_scanner.c" yy222: YYDEBUG(222, *YYCURSOR); yych = *++YYCURSOR; @@ -3584,11 +3708,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(226, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1260 "Zend/zend_language_scanner.l" +#line 1344 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AS); } -#line 3592 "Zend/zend_language_scanner.c" +#line 3716 "Zend/zend_language_scanner.c" yy227: YYDEBUG(227, *YYCURSOR); yych = *++YYCURSOR; @@ -3674,11 +3798,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(235, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1228 "Zend/zend_language_scanner.l" +#line 1312 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DO); } -#line 3682 "Zend/zend_language_scanner.c" +#line 3806 "Zend/zend_language_scanner.c" yy236: YYDEBUG(236, *YYCURSOR); yych = *++YYCURSOR; @@ -3763,11 +3887,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(248, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1204 "Zend/zend_language_scanner.l" +#line 1288 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IF); } -#line 3771 "Zend/zend_language_scanner.c" +#line 3895 "Zend/zend_language_scanner.c" yy249: YYDEBUG(249, *YYCURSOR); yych = *++YYCURSOR; @@ -3828,11 +3952,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(256, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1588 "Zend/zend_language_scanner.l" +#line 1672 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_OR); } -#line 3836 "Zend/zend_language_scanner.c" +#line 3960 "Zend/zend_language_scanner.c" yy257: YYDEBUG(257, *YYCURSOR); yych = *++YYCURSOR; @@ -3946,11 +4070,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(271, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1576 "Zend/zend_language_scanner.l" +#line 1660 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_XOR_EQUAL); } -#line 3954 "Zend/zend_language_scanner.c" +#line 4078 "Zend/zend_language_scanner.c" yy272: YYDEBUG(272, *YYCURSOR); yych = *++YYCURSOR; @@ -3978,31 +4102,31 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(274, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1572 "Zend/zend_language_scanner.l" +#line 1656 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OR_EQUAL); } -#line 3986 "Zend/zend_language_scanner.c" +#line 4110 "Zend/zend_language_scanner.c" yy275: YYDEBUG(275, *YYCURSOR); ++YYCURSOR; YYDEBUG(276, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1580 "Zend/zend_language_scanner.l" +#line 1664 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_OR); } -#line 3996 "Zend/zend_language_scanner.c" +#line 4120 "Zend/zend_language_scanner.c" yy277: YYDEBUG(277, *YYCURSOR); ++YYCURSOR; YYDEBUG(278, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1504 "Zend/zend_language_scanner.l" +#line 1588 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_IDENTICAL); } -#line 4006 "Zend/zend_language_scanner.c" +#line 4130 "Zend/zend_language_scanner.c" yy279: YYDEBUG(279, *YYCURSOR); yych = *++YYCURSOR; @@ -4068,21 +4192,21 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(290, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1544 "Zend/zend_language_scanner.l" +#line 1628 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW_EQUAL); } -#line 4076 "Zend/zend_language_scanner.c" +#line 4200 "Zend/zend_language_scanner.c" yy291: YYDEBUG(291, *YYCURSOR); ++YYCURSOR; YYDEBUG(292, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1352 "Zend/zend_language_scanner.l" +#line 1436 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELLIPSIS); } -#line 4086 "Zend/zend_language_scanner.c" +#line 4210 "Zend/zend_language_scanner.c" yy293: YYDEBUG(293, *YYCURSOR); yych = *++YYCURSOR; @@ -4106,7 +4230,7 @@ int start_line = CG(zend_lineno); } YYDEBUG(296, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1649 "Zend/zend_language_scanner.l" +#line 1733 "Zend/zend_language_scanner.l" { char *bin = yytext + 2; /* Skip "0b" */ int len = yyleng - 2; @@ -4134,7 +4258,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN_WITH_VAL(T_DNUMBER); } } -#line 4138 "Zend/zend_language_scanner.c" +#line 4262 "Zend/zend_language_scanner.c" yy297: YYDEBUG(297, *YYCURSOR); yych = *++YYCURSOR; @@ -4160,7 +4284,7 @@ int start_line = CG(zend_lineno); } YYDEBUG(302, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1728 "Zend/zend_language_scanner.l" +#line 1812 "Zend/zend_language_scanner.l" { char *hex = yytext + 2; /* Skip "0x" */ int len = yyleng - 2; @@ -4188,7 +4312,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN_WITH_VAL(T_DNUMBER); } } -#line 4192 "Zend/zend_language_scanner.c" +#line 4316 "Zend/zend_language_scanner.c" yy303: YYDEBUG(303, *YYCURSOR); ++YYCURSOR; @@ -4223,41 +4347,41 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(306, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1560 "Zend/zend_language_scanner.l" +#line 1644 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL_EQUAL); } -#line 4231 "Zend/zend_language_scanner.c" +#line 4355 "Zend/zend_language_scanner.c" yy307: YYDEBUG(307, *YYCURSOR); ++YYCURSOR; YYDEBUG(308, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1516 "Zend/zend_language_scanner.l" +#line 1600 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SPACESHIP); } -#line 4241 "Zend/zend_language_scanner.c" +#line 4365 "Zend/zend_language_scanner.c" yy309: YYDEBUG(309, *YYCURSOR); ++YYCURSOR; YYDEBUG(310, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1500 "Zend/zend_language_scanner.l" +#line 1584 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_IDENTICAL); } -#line 4251 "Zend/zend_language_scanner.c" +#line 4375 "Zend/zend_language_scanner.c" yy311: YYDEBUG(311, *YYCURSOR); ++YYCURSOR; YYDEBUG(312, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1564 "Zend/zend_language_scanner.l" +#line 1648 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR_EQUAL); } -#line 4261 "Zend/zend_language_scanner.c" +#line 4385 "Zend/zend_language_scanner.c" yy313: YYDEBUG(313, *YYCURSOR); yych = *++YYCURSOR; @@ -4281,11 +4405,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(317, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1592 "Zend/zend_language_scanner.l" +#line 1676 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_AND); } -#line 4289 "Zend/zend_language_scanner.c" +#line 4413 "Zend/zend_language_scanner.c" yy318: YYDEBUG(318, *YYCURSOR); yych = *++YYCURSOR; @@ -4366,11 +4490,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(330, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1162 "Zend/zend_language_scanner.l" +#line 1246 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 4374 "Zend/zend_language_scanner.c" +#line 4498 "Zend/zend_language_scanner.c" yy331: YYDEBUG(331, *YYCURSOR); yych = *++YYCURSOR; @@ -4452,11 +4576,11 @@ int start_line = CG(zend_lineno); yy340: YYDEBUG(340, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1232 "Zend/zend_language_scanner.l" +#line 1316 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOR); } -#line 4460 "Zend/zend_language_scanner.c" +#line 4584 "Zend/zend_language_scanner.c" yy341: YYDEBUG(341, *YYCURSOR); yych = *++YYCURSOR; @@ -4525,11 +4649,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(352, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1360 "Zend/zend_language_scanner.l" +#line 1444 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NEW); } -#line 4533 "Zend/zend_language_scanner.c" +#line 4657 "Zend/zend_language_scanner.c" yy353: YYDEBUG(353, *YYCURSOR); yych = *++YYCURSOR; @@ -4602,11 +4726,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(363, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1188 "Zend/zend_language_scanner.l" +#line 1272 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRY); } -#line 4610 "Zend/zend_language_scanner.c" +#line 4734 "Zend/zend_language_scanner.c" yy364: YYDEBUG(364, *YYCURSOR); yych = *++YYCURSOR; @@ -4621,11 +4745,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(366, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1424 "Zend/zend_language_scanner.l" +#line 1508 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_USE); } -#line 4629 "Zend/zend_language_scanner.c" +#line 4753 "Zend/zend_language_scanner.c" yy367: YYDEBUG(367, *YYCURSOR); ++YYCURSOR; @@ -4634,11 +4758,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(368, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1368 "Zend/zend_language_scanner.l" +#line 1452 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_VAR); } -#line 4642 "Zend/zend_language_scanner.c" +#line 4766 "Zend/zend_language_scanner.c" yy369: YYDEBUG(369, *YYCURSOR); yych = *++YYCURSOR; @@ -4653,11 +4777,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(371, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1596 "Zend/zend_language_scanner.l" +#line 1680 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_XOR); } -#line 4661 "Zend/zend_language_scanner.c" +#line 4785 "Zend/zend_language_scanner.c" yy372: YYDEBUG(372, *YYCURSOR); yych = *++YYCURSOR; @@ -4871,11 +4995,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(402, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1272 "Zend/zend_language_scanner.l" +#line 1356 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CASE); } -#line 4879 "Zend/zend_language_scanner.c" +#line 5003 "Zend/zend_language_scanner.c" yy403: YYDEBUG(403, *YYCURSOR); yych = *++YYCURSOR; @@ -4926,11 +5050,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(411, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1292 "Zend/zend_language_scanner.l" +#line 1376 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ECHO); } -#line 4934 "Zend/zend_language_scanner.c" +#line 5058 "Zend/zend_language_scanner.c" yy412: YYDEBUG(412, *YYCURSOR); ++YYCURSOR; @@ -4954,11 +5078,11 @@ int start_line = CG(zend_lineno); yy413: YYDEBUG(413, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1216 "Zend/zend_language_scanner.l" +#line 1300 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSE); } -#line 4962 "Zend/zend_language_scanner.c" +#line 5086 "Zend/zend_language_scanner.c" yy414: YYDEBUG(414, *YYCURSOR); yych = *++YYCURSOR; @@ -5003,11 +5127,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(421, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1400 "Zend/zend_language_scanner.l" +#line 1484 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EVAL); } -#line 5011 "Zend/zend_language_scanner.c" +#line 5135 "Zend/zend_language_scanner.c" yy422: YYDEBUG(422, *YYCURSOR); ++YYCURSOR; @@ -5016,11 +5140,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(423, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1158 "Zend/zend_language_scanner.l" +#line 1242 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 5024 "Zend/zend_language_scanner.c" +#line 5148 "Zend/zend_language_scanner.c" yy424: YYDEBUG(424, *YYCURSOR); yych = *++YYCURSOR; @@ -5059,11 +5183,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(430, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1288 "Zend/zend_language_scanner.l" +#line 1372 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GOTO); } -#line 5067 "Zend/zend_language_scanner.c" +#line 5191 "Zend/zend_language_scanner.c" yy431: YYDEBUG(431, *YYCURSOR); yych = *++YYCURSOR; @@ -5112,11 +5236,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(437, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1480 "Zend/zend_language_scanner.l" +#line 1564 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LIST); } -#line 5120 "Zend/zend_language_scanner.c" +#line 5244 "Zend/zend_language_scanner.c" yy438: YYDEBUG(438, *YYCURSOR); yych = *++YYCURSOR; @@ -5303,11 +5427,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(469, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1372 "Zend/zend_language_scanner.l" +#line 1456 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INT_CAST); } -#line 5311 "Zend/zend_language_scanner.c" +#line 5435 "Zend/zend_language_scanner.c" yy470: YYDEBUG(470, *YYCURSOR); yych = *++YYCURSOR; @@ -5404,11 +5528,13 @@ int start_line = CG(zend_lineno); yy481: YYDEBUG(481, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2165 "Zend/zend_language_scanner.l" +#line 2249 "Zend/zend_language_scanner.l" { char *s; - int bprefix = (yytext[0] != '<') ? 1 : 0; + unsigned char *saved_cursor; + int bprefix = (yytext[0] != '<') ? 1 : 0, spacing = 0, indentation = 0; zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label)); + zend_bool is_heredoc = 1; CG(zend_lineno)++; heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0); @@ -5421,6 +5547,7 @@ int start_line = CG(zend_lineno); if (*s == '\'') { s++; heredoc_label->length -= 2; + is_heredoc = 0; BEGIN(ST_NOWDOC); } else { @@ -5433,25 +5560,105 @@ int start_line = CG(zend_lineno); } heredoc_label->label = estrndup(s, heredoc_label->length); + heredoc_label->indentation = 0; + saved_cursor = YYCURSOR; + + zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label); + + while (YYCURSOR < YYLIMIT && (*YYCURSOR == ' ' || *YYCURSOR == '\t')) { + if (*YYCURSOR == '\t') { + spacing |= HEREDOC_USING_TABS; + } else { + spacing |= HEREDOC_USING_SPACES; + } + ++YYCURSOR; + ++indentation; + } + + if (YYCURSOR == YYLIMIT) { + YYCURSOR = saved_cursor; + RETURN_TOKEN(T_START_HEREDOC); + } /* Check for ending label on the next line */ if (heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, heredoc_label->length)) { - YYCTYPE *end = YYCURSOR + heredoc_label->length; + if (!IS_LABEL_START(YYCURSOR[heredoc_label->length])) { + if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) { + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); + } - if (*end == ';') { - end++; - } + YYCURSOR = saved_cursor; + heredoc_label->indentation = indentation; - if (*end == '\n' || *end == '\r') { BEGIN(ST_END_HEREDOC); + RETURN_TOKEN(T_START_HEREDOC); } } - zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label); + YYCURSOR = saved_cursor; + + if (is_heredoc && !SCNG(heredoc_scan_ahead)) { + zend_lex_state current_state; + int heredoc_nesting_level = 1; + int first_token = 0; + + zend_save_lexical_state(¤t_state); + + SCNG(heredoc_scan_ahead) = 1; + SCNG(heredoc_indentation) = 0; + SCNG(heredoc_indentation_uses_spaces) = 0; + LANG_SCNG(on_event) = NULL; + + zend_ptr_stack_reverse_apply(¤t_state.heredoc_label_stack, copy_heredoc_label_stack); + + while (heredoc_nesting_level) { + zval zv; + int retval; + + ZVAL_UNDEF(&zv); + retval = lex_scan(&zv, NULL); + zval_dtor(&zv); + + if (EG(exception)) { + zend_clear_exception(); + break; + } + + if (!first_token) { + first_token = retval; + } + + switch (retval) { + case T_START_HEREDOC: + ++heredoc_nesting_level; + break; + case T_END_HEREDOC: + --heredoc_nesting_level; + break; + case END: + heredoc_nesting_level = 0; + } + } + + if ( + (first_token == T_VARIABLE + || first_token == T_DOLLAR_OPEN_CURLY_BRACES + || first_token == T_CURLY_OPEN + ) && SCNG(heredoc_indentation)) { + zend_throw_exception_ex(zend_ce_parse_error, 0, "Invalid body indentation level (expecting an indentation level of at least %d)", SCNG(heredoc_indentation)); + } + + heredoc_label->indentation = SCNG(heredoc_indentation); + heredoc_label->indentation_uses_spaces = SCNG(heredoc_indentation_uses_spaces); + + zend_restore_lexical_state(¤t_state); + SCNG(heredoc_scan_ahead) = 0; + CG(increment_lineno) = 0; + } RETURN_TOKEN(T_START_HEREDOC); } -#line 5455 "Zend/zend_language_scanner.c" +#line 5662 "Zend/zend_language_scanner.c" yy482: YYDEBUG(482, *YYCURSOR); yych = *++YYCURSOR; @@ -5471,11 +5678,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(485, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1484 "Zend/zend_language_scanner.l" +#line 1568 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY); } -#line 5479 "Zend/zend_language_scanner.c" +#line 5686 "Zend/zend_language_scanner.c" yy486: YYDEBUG(486, *YYCURSOR); ++YYCURSOR; @@ -5484,11 +5691,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(487, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1280 "Zend/zend_language_scanner.l" +#line 1364 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BREAK); } -#line 5492 "Zend/zend_language_scanner.c" +#line 5699 "Zend/zend_language_scanner.c" yy488: YYDEBUG(488, *YYCURSOR); yych = *++YYCURSOR; @@ -5503,11 +5710,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(490, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1192 "Zend/zend_language_scanner.l" +#line 1276 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CATCH); } -#line 5511 "Zend/zend_language_scanner.c" +#line 5718 "Zend/zend_language_scanner.c" yy491: YYDEBUG(491, *YYCURSOR); ++YYCURSOR; @@ -5516,11 +5723,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(492, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1300 "Zend/zend_language_scanner.l" +#line 1384 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS); } -#line 5524 "Zend/zend_language_scanner.c" +#line 5731 "Zend/zend_language_scanner.c" yy493: YYDEBUG(493, *YYCURSOR); ++YYCURSOR; @@ -5529,11 +5736,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(494, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1364 "Zend/zend_language_scanner.l" +#line 1448 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLONE); } -#line 5537 "Zend/zend_language_scanner.c" +#line 5744 "Zend/zend_language_scanner.c" yy495: YYDEBUG(495, *YYCURSOR); ++YYCURSOR; @@ -5542,11 +5749,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(496, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1170 "Zend/zend_language_scanner.l" +#line 1254 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONST); } -#line 5550 "Zend/zend_language_scanner.c" +#line 5757 "Zend/zend_language_scanner.c" yy497: YYDEBUG(497, *YYCURSOR); yych = *++YYCURSOR; @@ -5579,11 +5786,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(502, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1440 "Zend/zend_language_scanner.l" +#line 1524 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EMPTY); } -#line 5587 "Zend/zend_language_scanner.c" +#line 5794 "Zend/zend_language_scanner.c" yy503: YYDEBUG(503, *YYCURSOR); yych = *++YYCURSOR; @@ -5604,11 +5811,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(506, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1212 "Zend/zend_language_scanner.l" +#line 1296 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDIF); } -#line 5612 "Zend/zend_language_scanner.c" +#line 5819 "Zend/zend_language_scanner.c" yy507: YYDEBUG(507, *YYCURSOR); yych = *++YYCURSOR; @@ -5650,11 +5857,11 @@ int start_line = CG(zend_lineno); yy511: YYDEBUG(511, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1456 "Zend/zend_language_scanner.l" +#line 1540 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINAL); } -#line 5658 "Zend/zend_language_scanner.c" +#line 5865 "Zend/zend_language_scanner.c" yy512: YYDEBUG(512, *YYCURSOR); yych = *++YYCURSOR; @@ -5711,11 +5918,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(521, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1436 "Zend/zend_language_scanner.l" +#line 1520 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ISSET); } -#line 5719 "Zend/zend_language_scanner.c" +#line 5926 "Zend/zend_language_scanner.c" yy522: YYDEBUG(522, *YYCURSOR); yych = *++YYCURSOR; @@ -5730,11 +5937,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(524, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1296 "Zend/zend_language_scanner.l" +#line 1380 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRINT); } -#line 5738 "Zend/zend_language_scanner.c" +#line 5945 "Zend/zend_language_scanner.c" yy525: YYDEBUG(525, *YYCURSOR); yych = *++YYCURSOR; @@ -5785,11 +5992,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(533, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1200 "Zend/zend_language_scanner.l" +#line 1284 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_THROW); } -#line 5793 "Zend/zend_language_scanner.c" +#line 6000 "Zend/zend_language_scanner.c" yy534: YYDEBUG(534, *YYCURSOR); ++YYCURSOR; @@ -5798,11 +6005,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(535, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1308 "Zend/zend_language_scanner.l" +#line 1392 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT); } -#line 5806 "Zend/zend_language_scanner.c" +#line 6013 "Zend/zend_language_scanner.c" yy536: YYDEBUG(536, *YYCURSOR); ++YYCURSOR; @@ -5811,11 +6018,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(537, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1472 "Zend/zend_language_scanner.l" +#line 1556 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET); } -#line 5819 "Zend/zend_language_scanner.c" +#line 6026 "Zend/zend_language_scanner.c" yy538: YYDEBUG(538, *YYCURSOR); ++YYCURSOR; @@ -5824,11 +6031,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(539, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1220 "Zend/zend_language_scanner.l" +#line 1304 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_WHILE); } -#line 5832 "Zend/zend_language_scanner.c" +#line 6039 "Zend/zend_language_scanner.c" yy540: YYDEBUG(540, *YYCURSOR); yyaccept = 6; @@ -5846,11 +6053,11 @@ int start_line = CG(zend_lineno); yy541: YYDEBUG(541, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1184 "Zend/zend_language_scanner.l" +#line 1268 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_YIELD); } -#line 5854 "Zend/zend_language_scanner.c" +#line 6061 "Zend/zend_language_scanner.c" yy542: YYDEBUG(542, *YYCURSOR); yych = *++YYCURSOR; @@ -5942,11 +6149,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(557, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1392 "Zend/zend_language_scanner.l" +#line 1476 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOL_CAST); } -#line 5950 "Zend/zend_language_scanner.c" +#line 6157 "Zend/zend_language_scanner.c" yy558: YYDEBUG(558, *YYCURSOR); yych = *++YYCURSOR; @@ -5976,11 +6183,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(563, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1376 "Zend/zend_language_scanner.l" +#line 1460 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_CAST); } -#line 5984 "Zend/zend_language_scanner.c" +#line 6191 "Zend/zend_language_scanner.c" yy564: YYDEBUG(564, *YYCURSOR); yych = *++YYCURSOR; @@ -6045,11 +6252,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(574, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1208 "Zend/zend_language_scanner.l" +#line 1292 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSEIF); } -#line 6053 "Zend/zend_language_scanner.c" +#line 6260 "Zend/zend_language_scanner.c" yy575: YYDEBUG(575, *YYCURSOR); yych = *++YYCURSOR; @@ -6079,11 +6286,11 @@ int start_line = CG(zend_lineno); yy577: YYDEBUG(577, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1236 "Zend/zend_language_scanner.l" +#line 1320 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOR); } -#line 6087 "Zend/zend_language_scanner.c" +#line 6294 "Zend/zend_language_scanner.c" yy578: YYDEBUG(578, *YYCURSOR); yych = *++YYCURSOR; @@ -6128,11 +6335,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(585, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1432 "Zend/zend_language_scanner.l" +#line 1516 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GLOBAL); } -#line 6136 "Zend/zend_language_scanner.c" +#line 6343 "Zend/zend_language_scanner.c" yy586: YYDEBUG(586, *YYCURSOR); yych = *++YYCURSOR; @@ -6189,11 +6396,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(595, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1468 "Zend/zend_language_scanner.l" +#line 1552 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PUBLIC); } -#line 6197 "Zend/zend_language_scanner.c" +#line 6404 "Zend/zend_language_scanner.c" yy596: YYDEBUG(596, *YYCURSOR); yych = *++YYCURSOR; @@ -6208,11 +6415,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(598, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1174 "Zend/zend_language_scanner.l" +#line 1258 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_RETURN); } -#line 6216 "Zend/zend_language_scanner.c" +#line 6423 "Zend/zend_language_scanner.c" yy599: YYDEBUG(599, *YYCURSOR); ++YYCURSOR; @@ -6221,11 +6428,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(600, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1448 "Zend/zend_language_scanner.l" +#line 1532 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STATIC); } -#line 6229 "Zend/zend_language_scanner.c" +#line 6436 "Zend/zend_language_scanner.c" yy601: YYDEBUG(601, *YYCURSOR); ++YYCURSOR; @@ -6234,11 +6441,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(602, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1264 "Zend/zend_language_scanner.l" +#line 1348 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SWITCH); } -#line 6242 "Zend/zend_language_scanner.c" +#line 6449 "Zend/zend_language_scanner.c" yy603: YYDEBUG(603, *YYCURSOR); ++YYCURSOR; @@ -6318,11 +6525,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(615, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1384 "Zend/zend_language_scanner.l" +#line 1468 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY_CAST); } -#line 6326 "Zend/zend_language_scanner.c" +#line 6533 "Zend/zend_language_scanner.c" yy616: YYDEBUG(616, *YYCURSOR); ++YYCURSOR; @@ -6368,11 +6575,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(623, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1396 "Zend/zend_language_scanner.l" +#line 1480 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET_CAST); } -#line 6376 "Zend/zend_language_scanner.c" +#line 6583 "Zend/zend_language_scanner.c" yy624: YYDEBUG(624, *YYCURSOR); yych = *++YYCURSOR; @@ -6399,11 +6606,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(628, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1248 "Zend/zend_language_scanner.l" +#line 1332 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DECLARE); } -#line 6407 "Zend/zend_language_scanner.c" +#line 6614 "Zend/zend_language_scanner.c" yy629: YYDEBUG(629, *YYCURSOR); ++YYCURSOR; @@ -6412,11 +6619,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(630, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1276 "Zend/zend_language_scanner.l" +#line 1360 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEFAULT); } -#line 6420 "Zend/zend_language_scanner.c" +#line 6627 "Zend/zend_language_scanner.c" yy631: YYDEBUG(631, *YYCURSOR); yych = *++YYCURSOR; @@ -6449,11 +6656,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(636, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1312 "Zend/zend_language_scanner.l" +#line 1396 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXTENDS); } -#line 6457 "Zend/zend_language_scanner.c" +#line 6664 "Zend/zend_language_scanner.c" yy637: YYDEBUG(637, *YYCURSOR); ++YYCURSOR; @@ -6462,11 +6669,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(638, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1196 "Zend/zend_language_scanner.l" +#line 1280 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINALLY); } -#line 6470 "Zend/zend_language_scanner.c" +#line 6677 "Zend/zend_language_scanner.c" yy639: YYDEBUG(639, *YYCURSOR); ++YYCURSOR; @@ -6475,11 +6682,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(640, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1240 "Zend/zend_language_scanner.l" +#line 1324 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOREACH); } -#line 6483 "Zend/zend_language_scanner.c" +#line 6690 "Zend/zend_language_scanner.c" yy641: YYDEBUG(641, *YYCURSOR); yych = *++YYCURSOR; @@ -6513,11 +6720,11 @@ int start_line = CG(zend_lineno); yy644: YYDEBUG(644, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1404 "Zend/zend_language_scanner.l" +#line 1488 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE); } -#line 6521 "Zend/zend_language_scanner.c" +#line 6728 "Zend/zend_language_scanner.c" yy645: YYDEBUG(645, *YYCURSOR); yych = *++YYCURSOR; @@ -6550,11 +6757,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(650, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1460 "Zend/zend_language_scanner.l" +#line 1544 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRIVATE); } -#line 6558 "Zend/zend_language_scanner.c" +#line 6765 "Zend/zend_language_scanner.c" yy651: YYDEBUG(651, *YYCURSOR); yych = *++YYCURSOR; @@ -6582,11 +6789,11 @@ int start_line = CG(zend_lineno); yy653: YYDEBUG(653, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1412 "Zend/zend_language_scanner.l" +#line 1496 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE); } -#line 6590 "Zend/zend_language_scanner.c" +#line 6797 "Zend/zend_language_scanner.c" yy654: YYDEBUG(654, *YYCURSOR); yych = *++YYCURSOR; @@ -6606,11 +6813,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(657, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1814 "Zend/zend_language_scanner.l" +#line 1898 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIR); } -#line 6614 "Zend/zend_language_scanner.c" +#line 6821 "Zend/zend_language_scanner.c" yy658: YYDEBUG(658, *YYCURSOR); yych = *++YYCURSOR; @@ -6655,21 +6862,21 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(666, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1380 "Zend/zend_language_scanner.l" +#line 1464 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STRING_CAST); } -#line 6663 "Zend/zend_language_scanner.c" +#line 6870 "Zend/zend_language_scanner.c" yy667: YYDEBUG(667, *YYCURSOR); ++YYCURSOR; YYDEBUG(668, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1388 "Zend/zend_language_scanner.l" +#line 1472 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_CAST); } -#line 6673 "Zend/zend_language_scanner.c" +#line 6880 "Zend/zend_language_scanner.c" yy669: YYDEBUG(669, *YYCURSOR); ++YYCURSOR; @@ -6678,11 +6885,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(670, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1452 "Zend/zend_language_scanner.l" +#line 1536 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ABSTRACT); } -#line 6686 "Zend/zend_language_scanner.c" +#line 6893 "Zend/zend_language_scanner.c" yy671: YYDEBUG(671, *YYCURSOR); ++YYCURSOR; @@ -6691,11 +6898,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(672, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1488 "Zend/zend_language_scanner.l" +#line 1572 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CALLABLE); } -#line 6699 "Zend/zend_language_scanner.c" +#line 6906 "Zend/zend_language_scanner.c" yy673: YYDEBUG(673, *YYCURSOR); ++YYCURSOR; @@ -6704,11 +6911,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(674, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1284 "Zend/zend_language_scanner.l" +#line 1368 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONTINUE); } -#line 6712 "Zend/zend_language_scanner.c" +#line 6919 "Zend/zend_language_scanner.c" yy675: YYDEBUG(675, *YYCURSOR); yych = *++YYCURSOR; @@ -6735,11 +6942,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(679, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1224 "Zend/zend_language_scanner.l" +#line 1308 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDWHILE); } -#line 6743 "Zend/zend_language_scanner.c" +#line 6950 "Zend/zend_language_scanner.c" yy680: YYDEBUG(680, *YYCURSOR); ++YYCURSOR; @@ -6748,11 +6955,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(681, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1166 "Zend/zend_language_scanner.l" +#line 1250 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNCTION); } -#line 6756 "Zend/zend_language_scanner.c" +#line 6963 "Zend/zend_language_scanner.c" yy682: YYDEBUG(682, *YYCURSOR); yych = *++YYCURSOR; @@ -6820,11 +7027,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(693, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1810 "Zend/zend_language_scanner.l" +#line 1894 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FILE); } -#line 6828 "Zend/zend_language_scanner.c" +#line 7035 "Zend/zend_language_scanner.c" yy694: YYDEBUG(694, *YYCURSOR); yych = *++YYCURSOR; @@ -6845,11 +7052,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(697, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1806 "Zend/zend_language_scanner.l" +#line 1890 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LINE); } -#line 6853 "Zend/zend_language_scanner.c" +#line 7060 "Zend/zend_language_scanner.c" yy698: YYDEBUG(698, *YYCURSOR); yych = *++YYCURSOR; @@ -6886,11 +7093,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(704, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1268 "Zend/zend_language_scanner.l" +#line 1352 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDSWITCH); } -#line 6894 "Zend/zend_language_scanner.c" +#line 7101 "Zend/zend_language_scanner.c" yy705: YYDEBUG(705, *YYCURSOR); yych = *++YYCURSOR; @@ -6917,11 +7124,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(709, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1428 "Zend/zend_language_scanner.l" +#line 1512 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTEADOF); } -#line 6925 "Zend/zend_language_scanner.c" +#line 7132 "Zend/zend_language_scanner.c" yy710: YYDEBUG(710, *YYCURSOR); ++YYCURSOR; @@ -6930,11 +7137,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(711, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1304 "Zend/zend_language_scanner.l" +#line 1388 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INTERFACE); } -#line 6938 "Zend/zend_language_scanner.c" +#line 7145 "Zend/zend_language_scanner.c" yy712: YYDEBUG(712, *YYCURSOR); ++YYCURSOR; @@ -6943,11 +7150,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(713, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1420 "Zend/zend_language_scanner.l" +#line 1504 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NAMESPACE); } -#line 6951 "Zend/zend_language_scanner.c" +#line 7158 "Zend/zend_language_scanner.c" yy714: YYDEBUG(714, *YYCURSOR); ++YYCURSOR; @@ -6956,11 +7163,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(715, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1464 "Zend/zend_language_scanner.l" +#line 1548 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PROTECTED); } -#line 6964 "Zend/zend_language_scanner.c" +#line 7171 "Zend/zend_language_scanner.c" yy716: YYDEBUG(716, *YYCURSOR); yych = *++YYCURSOR; @@ -6981,11 +7188,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(719, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1790 "Zend/zend_language_scanner.l" +#line 1874 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS_C); } -#line 6989 "Zend/zend_language_scanner.c" +#line 7196 "Zend/zend_language_scanner.c" yy720: YYDEBUG(720, *YYCURSOR); yych = *++YYCURSOR; @@ -7017,11 +7224,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(725, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1794 "Zend/zend_language_scanner.l" +#line 1878 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT_C); } -#line 7025 "Zend/zend_language_scanner.c" +#line 7232 "Zend/zend_language_scanner.c" yy726: YYDEBUG(726, *YYCURSOR); ++YYCURSOR; @@ -7030,11 +7237,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(727, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1252 "Zend/zend_language_scanner.l" +#line 1336 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDDECLARE); } -#line 7038 "Zend/zend_language_scanner.c" +#line 7245 "Zend/zend_language_scanner.c" yy728: YYDEBUG(728, *YYCURSOR); ++YYCURSOR; @@ -7043,11 +7250,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(729, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1244 "Zend/zend_language_scanner.l" +#line 1328 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOREACH); } -#line 7051 "Zend/zend_language_scanner.c" +#line 7258 "Zend/zend_language_scanner.c" yy730: YYDEBUG(730, *YYCURSOR); ++YYCURSOR; @@ -7056,11 +7263,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(731, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1316 "Zend/zend_language_scanner.l" +#line 1400 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IMPLEMENTS); } -#line 7064 "Zend/zend_language_scanner.c" +#line 7271 "Zend/zend_language_scanner.c" yy732: YYDEBUG(732, *YYCURSOR); yych = *++YYCURSOR; @@ -7075,11 +7282,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(734, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1256 "Zend/zend_language_scanner.l" +#line 1340 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTANCEOF); } -#line 7083 "Zend/zend_language_scanner.c" +#line 7290 "Zend/zend_language_scanner.c" yy735: YYDEBUG(735, *YYCURSOR); yych = *++YYCURSOR; @@ -7127,11 +7334,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(740, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1802 "Zend/zend_language_scanner.l" +#line 1886 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_METHOD_C); } -#line 7135 "Zend/zend_language_scanner.c" +#line 7342 "Zend/zend_language_scanner.c" yy741: YYDEBUG(741, *YYCURSOR); yych = *++YYCURSOR; @@ -7155,13 +7362,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(745, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1178 "Zend/zend_language_scanner.l" +#line 1262 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_YIELD_FROM); } -#line 7165 "Zend/zend_language_scanner.c" +#line 7372 "Zend/zend_language_scanner.c" yy746: YYDEBUG(746, *YYCURSOR); yych = *++YYCURSOR; @@ -7186,11 +7393,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(750, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1408 "Zend/zend_language_scanner.l" +#line 1492 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE_ONCE); } -#line 7194 "Zend/zend_language_scanner.c" +#line 7401 "Zend/zend_language_scanner.c" yy751: YYDEBUG(751, *YYCURSOR); ++YYCURSOR; @@ -7199,11 +7406,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(752, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1416 "Zend/zend_language_scanner.l" +#line 1500 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE_ONCE); } -#line 7207 "Zend/zend_language_scanner.c" +#line 7414 "Zend/zend_language_scanner.c" yy753: YYDEBUG(753, *YYCURSOR); ++YYCURSOR; @@ -7212,11 +7419,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(754, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1798 "Zend/zend_language_scanner.l" +#line 1882 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNC_C); } -#line 7220 "Zend/zend_language_scanner.c" +#line 7427 "Zend/zend_language_scanner.c" yy755: YYDEBUG(755, *YYCURSOR); yych = *++YYCURSOR; @@ -7242,11 +7449,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(759, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1818 "Zend/zend_language_scanner.l" +#line 1902 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_C); } -#line 7250 "Zend/zend_language_scanner.c" +#line 7457 "Zend/zend_language_scanner.c" yy760: YYDEBUG(760, *YYCURSOR); yych = *++YYCURSOR; @@ -7260,11 +7467,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(762, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1444 "Zend/zend_language_scanner.l" +#line 1528 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_HALT_COMPILER); } -#line 7268 "Zend/zend_language_scanner.c" +#line 7475 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_PROPERTY: @@ -7330,13 +7537,13 @@ int start_line = CG(zend_lineno); yy766: YYDEBUG(766, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1338 "Zend/zend_language_scanner.l" +#line 1422 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); goto restart; } -#line 7340 "Zend/zend_language_scanner.c" +#line 7547 "Zend/zend_language_scanner.c" yy767: YYDEBUG(767, *YYCURSOR); ++YYCURSOR; @@ -7348,11 +7555,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(769, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1325 "Zend/zend_language_scanner.l" +#line 1409 "Zend/zend_language_scanner.l" { goto return_whitespace; } -#line 7356 "Zend/zend_language_scanner.c" +#line 7563 "Zend/zend_language_scanner.c" yy770: YYDEBUG(770, *YYCURSOR); yych = *++YYCURSOR; @@ -7369,22 +7576,22 @@ int start_line = CG(zend_lineno); } YYDEBUG(773, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1333 "Zend/zend_language_scanner.l" +#line 1417 "Zend/zend_language_scanner.l" { yy_pop_state(); RETURN_TOKEN_WITH_STR(T_STRING, 0); } -#line 7378 "Zend/zend_language_scanner.c" +#line 7585 "Zend/zend_language_scanner.c" yy774: YYDEBUG(774, *YYCURSOR); ++YYCURSOR; YYDEBUG(775, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1329 "Zend/zend_language_scanner.l" +#line 1413 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 7388 "Zend/zend_language_scanner.c" +#line 7595 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_VARNAME: @@ -7441,14 +7648,14 @@ int start_line = CG(zend_lineno); yy779: YYDEBUG(779, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1642 "Zend/zend_language_scanner.l" +#line 1726 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); yy_push_state(ST_IN_SCRIPTING); goto restart; } -#line 7452 "Zend/zend_language_scanner.c" +#line 7659 "Zend/zend_language_scanner.c" yy780: YYDEBUG(780, *YYCURSOR); yych = *(YYMARKER = ++YYCURSOR); @@ -7495,14 +7702,14 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(785, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1634 "Zend/zend_language_scanner.l" +#line 1718 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_pop_state(); yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN_WITH_STR(T_STRING_VARNAME, 0); } -#line 7506 "Zend/zend_language_scanner.c" +#line 7713 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_NOWDOC: @@ -7513,11 +7720,10 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(789, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2429 "Zend/zend_language_scanner.l" +#line 2636 "Zend/zend_language_scanner.l" { - int newline = 0; - zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack)); + int newline = 0, indentation = 0, spacing = -1; if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -7533,28 +7739,51 @@ int start_line = CG(zend_lineno); } /* fall through */ case '\n': + indentation = spacing = 0; + + while (YYCURSOR < YYLIMIT && (*YYCURSOR == ' ' || *YYCURSOR == '\t')) { + if (*YYCURSOR == '\t') { + spacing |= HEREDOC_USING_TABS; + } else { + spacing |= HEREDOC_USING_SPACES; + } + ++YYCURSOR; + ++indentation; + } + + if (YYCURSOR == YYLIMIT) { + yyleng = YYCURSOR - SCNG(yy_text); + HANDLE_NEWLINES(yytext, yyleng); + ZVAL_NULL(zendlval); + RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); + } + /* Check for ending label on the next line */ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) { - YYCTYPE *end = YYCURSOR + heredoc_label->length; + if (IS_LABEL_START(YYCURSOR[heredoc_label->length])) { + continue; + } - if (*end == ';') { - end++; + if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) { + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); } - if (*end == '\n' || *end == '\r') { - /* newline before label will be subtracted from returned text, but - * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ - if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') { - newline = 2; /* Windows newline */ - } else { - newline = 1; - } + /* newline before label will be subtracted from returned text, but + * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ + if (YYCURSOR[-indentation - 2] == '\r' && YYCURSOR[-indentation - 1] == '\n') { + newline = 2; /* Windows newline */ + } else { + newline = 1; + } - CG(increment_lineno) = 1; /* For newline before label */ - BEGIN(ST_END_HEREDOC); + CG(increment_lineno) = 1; /* For newline before label */ - goto nowdoc_scan_done; - } + YYCURSOR -= indentation; + heredoc_label->indentation = indentation; + + BEGIN(ST_END_HEREDOC); + + goto nowdoc_scan_done; } /* fall through */ default: @@ -7564,12 +7793,17 @@ int start_line = CG(zend_lineno); nowdoc_scan_done: yyleng = YYCURSOR - SCNG(yy_text); + ZVAL_STRINGL(zendlval, yytext, yyleng); + + if (!EG(exception) && spacing != -1 && PARSER_MODE() + && !strip_multiline_string_indentation(zendlval, newline, indentation, spacing == HEREDOC_USING_SPACES)) { + RETURN_TOKEN(T_ERROR); + } - zend_copy_value(zendlval, yytext, yyleng - newline); HANDLE_NEWLINES(yytext, yyleng - newline); RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } -#line 7573 "Zend/zend_language_scanner.c" +#line 7807 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_VAR_OFFSET: { @@ -7657,7 +7891,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(793, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2486 "Zend/zend_language_scanner.l" +#line 2720 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -7666,13 +7900,13 @@ int start_line = CG(zend_lineno); zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE); goto restart; } -#line 7670 "Zend/zend_language_scanner.c" +#line 7904 "Zend/zend_language_scanner.c" yy794: YYDEBUG(794, *YYCURSOR); ++YYCURSOR; YYDEBUG(795, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1933 "Zend/zend_language_scanner.l" +#line 2017 "Zend/zend_language_scanner.l" { /* Invalid rule to return a more explicit parse error with proper line number */ yyless(0); @@ -7680,19 +7914,19 @@ int start_line = CG(zend_lineno); ZVAL_NULL(zendlval); RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } -#line 7684 "Zend/zend_language_scanner.c" +#line 7918 "Zend/zend_language_scanner.c" yy796: YYDEBUG(796, *YYCURSOR); ++YYCURSOR; yy797: YYDEBUG(797, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1928 "Zend/zend_language_scanner.l" +#line 2012 "Zend/zend_language_scanner.l" { /* Only '[' or '-' can be valid, but returning other tokens will allow a more explicit parse error */ RETURN_TOKEN(yytext[0]); } -#line 7696 "Zend/zend_language_scanner.c" +#line 7930 "Zend/zend_language_scanner.c" yy798: YYDEBUG(798, *YYCURSOR); yych = *++YYCURSOR; @@ -7727,7 +7961,7 @@ int start_line = CG(zend_lineno); yy800: YYDEBUG(800, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1756 "Zend/zend_language_scanner.l" +#line 1840 "Zend/zend_language_scanner.l" { /* Offset could be treated as a long */ if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) { char *end; @@ -7743,7 +7977,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN_WITH_VAL(T_NUM_STRING); } -#line 7747 "Zend/zend_language_scanner.c" +#line 7981 "Zend/zend_language_scanner.c" yy801: YYDEBUG(801, *YYCURSOR); ++YYCURSOR; @@ -7765,22 +7999,22 @@ int start_line = CG(zend_lineno); } YYDEBUG(805, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1941 "Zend/zend_language_scanner.l" +#line 2025 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_STRING, 0); } -#line 7773 "Zend/zend_language_scanner.c" +#line 8007 "Zend/zend_language_scanner.c" yy806: YYDEBUG(806, *YYCURSOR); ++YYCURSOR; YYDEBUG(807, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1923 "Zend/zend_language_scanner.l" +#line 2007 "Zend/zend_language_scanner.l" { yy_pop_state(); RETURN_TOKEN(']'); } -#line 7784 "Zend/zend_language_scanner.c" +#line 8018 "Zend/zend_language_scanner.c" yy808: YYDEBUG(808, *YYCURSOR); ++YYCURSOR; @@ -7805,11 +8039,11 @@ int start_line = CG(zend_lineno); yy810: YYDEBUG(810, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1919 "Zend/zend_language_scanner.l" +#line 2003 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7813 "Zend/zend_language_scanner.c" +#line 8047 "Zend/zend_language_scanner.c" yy811: YYDEBUG(811, *YYCURSOR); ++YYCURSOR; @@ -7821,7 +8055,7 @@ int start_line = CG(zend_lineno); yy813: YYDEBUG(813, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1772 "Zend/zend_language_scanner.l" +#line 1856 "Zend/zend_language_scanner.l" { /* Offset must be treated as a string */ if (yyleng == 1) { ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR((zend_uchar)*(yytext))); @@ -7830,7 +8064,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN_WITH_VAL(T_NUM_STRING); } -#line 7834 "Zend/zend_language_scanner.c" +#line 8068 "Zend/zend_language_scanner.c" yy814: YYDEBUG(814, *YYCURSOR); yych = *++YYCURSOR; @@ -7870,7 +8104,7 @@ int start_line = CG(zend_lineno); goto yy813; } } -#line 2495 "Zend/zend_language_scanner.l" +#line 2729 "Zend/zend_language_scanner.l" emit_token_with_str: diff --git a/Zend/zend_language_scanner.h b/Zend/zend_language_scanner.h index 2064d6d17ae07..29263b8e71988 100644 --- a/Zend/zend_language_scanner.h +++ b/Zend/zend_language_scanner.h @@ -61,6 +61,8 @@ typedef struct _zend_lex_state { typedef struct _zend_heredoc_label { char *label; int length; + int indentation; + zend_bool indentation_uses_spaces; } zend_heredoc_label; BEGIN_EXTERN_C() diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 5e256447f15c0..15afc4388733a 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -181,6 +181,7 @@ void startup_scanner(void) CG(extra_fn_flags) = 0; zend_stack_init(&SCNG(state_stack), sizeof(int)); zend_ptr_stack_init(&SCNG(heredoc_label_stack)); + SCNG(heredoc_scan_ahead) = 0; } static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) { @@ -194,6 +195,7 @@ void shutdown_scanner(void) zend_stack_destroy(&SCNG(state_stack)); zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1); zend_ptr_stack_destroy(&SCNG(heredoc_label_stack)); + SCNG(heredoc_scan_ahead) = 0; SCNG(on_event) = NULL; } @@ -1104,6 +1106,88 @@ skip_escape_conversion: return SUCCESS; } +#define HEREDOC_USING_SPACES 1 +#define HEREDOC_USING_TABS 2 + +static zend_bool strip_multiline_string_indentation(zval *zendlval, int newline, int indentation, zend_bool using_spaces) +{ + int len = Z_STRLEN_P(zendlval), new_len = len, i = 0, j = 0, skip, newline_count = 0; + char *copy = Z_STRVAL_P(zendlval); + zend_bool trailing_newline = 0; + + while (j < len) { + trailing_newline = 0; + + for (skip = 0; skip < indentation; ++skip, ++j, --new_len) { + if (copy[j] == '\r' || copy[j] == '\n') { + goto skip; + } + + if (copy[j] != ' ' && copy[j] != '\t') { + CG(zend_lineno) += newline_count; + zend_throw_exception_ex(zend_ce_parse_error, 0, "Invalid body indentation level (expecting an indentation level of at least %d)", indentation); + goto error; + } + + if ((!using_spaces && copy[j] == ' ') || (using_spaces && copy[j] == '\t')) { + CG(zend_lineno) += newline_count; + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); + goto error; + } + } + + while (j < len && copy[j] != '\r' && copy[j] != '\n') { + copy[i++] = copy[j++]; + } + + if (j == len) { + break; + } +skip: + if (copy[j] == '\r') { + copy[i++] = copy[j++]; + trailing_newline = 1; + } + + if (copy[j] == '\n') { + copy[i++] = copy[j++]; + trailing_newline = 1; + } + + if (trailing_newline) { + ++newline_count; + } + } + + if (YYSTATE != STATE(ST_END_HEREDOC) && trailing_newline && indentation) { + CG(zend_lineno) += newline_count; + zend_throw_exception_ex(zend_ce_parse_error, 0, "Invalid body indentation level (expecting an indentation level of at least %d)", indentation); + goto error; + } + + Z_STRVAL_P(zendlval)[new_len - newline] = '\0'; + Z_STRLEN_P(zendlval) = new_len - newline; + + return 1; + +error: + zval_dtor(zendlval); + ZVAL_UNDEF(zendlval); + + return 0; +} + +static void copy_heredoc_label_stack(void *void_heredoc_label) +{ + zend_heredoc_label *heredoc_label = void_heredoc_label; + zend_heredoc_label *new_heredoc_label = emalloc(sizeof(zend_heredoc_label)); + + *new_heredoc_label = *heredoc_label; + new_heredoc_label->label = estrndup(heredoc_label->label, heredoc_label->length); + + zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) new_heredoc_label); +} + #define PARSER_MODE() \ EXPECTED(elem != NULL) @@ -2164,8 +2248,10 @@ skip_escape_conversion: b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} { char *s; - int bprefix = (yytext[0] != '<') ? 1 : 0; + unsigned char *saved_cursor; + int bprefix = (yytext[0] != '<') ? 1 : 0, spacing = 0, indentation = 0; zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label)); + zend_bool is_heredoc = 1; CG(zend_lineno)++; heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0); @@ -2178,6 +2264,7 @@ skip_escape_conversion: if (*s == '\'') { s++; heredoc_label->length -= 2; + is_heredoc = 0; BEGIN(ST_NOWDOC); } else { @@ -2190,21 +2277,101 @@ skip_escape_conversion: } heredoc_label->label = estrndup(s, heredoc_label->length); + heredoc_label->indentation = 0; + saved_cursor = YYCURSOR; + + zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label); + + while (YYCURSOR < YYLIMIT && (*YYCURSOR == ' ' || *YYCURSOR == '\t')) { + if (*YYCURSOR == '\t') { + spacing |= HEREDOC_USING_TABS; + } else { + spacing |= HEREDOC_USING_SPACES; + } + ++YYCURSOR; + ++indentation; + } + + if (YYCURSOR == YYLIMIT) { + YYCURSOR = saved_cursor; + RETURN_TOKEN(T_START_HEREDOC); + } /* Check for ending label on the next line */ if (heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, heredoc_label->length)) { - YYCTYPE *end = YYCURSOR + heredoc_label->length; + if (!IS_LABEL_START(YYCURSOR[heredoc_label->length])) { + if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) { + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); + } - if (*end == ';') { - end++; - } + YYCURSOR = saved_cursor; + heredoc_label->indentation = indentation; - if (*end == '\n' || *end == '\r') { BEGIN(ST_END_HEREDOC); + RETURN_TOKEN(T_START_HEREDOC); } } - zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label); + YYCURSOR = saved_cursor; + + if (is_heredoc && !SCNG(heredoc_scan_ahead)) { + zend_lex_state current_state; + int heredoc_nesting_level = 1; + int first_token = 0; + + zend_save_lexical_state(¤t_state); + + SCNG(heredoc_scan_ahead) = 1; + SCNG(heredoc_indentation) = 0; + SCNG(heredoc_indentation_uses_spaces) = 0; + LANG_SCNG(on_event) = NULL; + + zend_ptr_stack_reverse_apply(¤t_state.heredoc_label_stack, copy_heredoc_label_stack); + + while (heredoc_nesting_level) { + zval zv; + int retval; + + ZVAL_UNDEF(&zv); + retval = lex_scan(&zv, NULL); + zval_dtor(&zv); + + if (EG(exception)) { + zend_clear_exception(); + break; + } + + if (!first_token) { + first_token = retval; + } + + switch (retval) { + case T_START_HEREDOC: + ++heredoc_nesting_level; + break; + case T_END_HEREDOC: + --heredoc_nesting_level; + break; + case END: + heredoc_nesting_level = 0; + } + } + + if ( + (first_token == T_VARIABLE + || first_token == T_DOLLAR_OPEN_CURLY_BRACES + || first_token == T_CURLY_OPEN + ) && SCNG(heredoc_indentation)) { + zend_throw_exception_ex(zend_ce_parse_error, 0, "Invalid body indentation level (expecting an indentation level of at least %d)", SCNG(heredoc_indentation)); + } + + heredoc_label->indentation = SCNG(heredoc_indentation); + heredoc_label->indentation_uses_spaces = SCNG(heredoc_indentation_uses_spaces); + + zend_restore_lexical_state(¤t_state); + SCNG(heredoc_scan_ahead) = 0; + CG(increment_lineno) = 0; + } RETURN_TOKEN(T_START_HEREDOC); } @@ -2219,8 +2386,8 @@ skip_escape_conversion: {ANY_CHAR} { zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack)); - YYCURSOR += heredoc_label->length - 1; - yyleng = heredoc_label->length; + yyleng = heredoc_label->indentation + heredoc_label->length; + YYCURSOR += yyleng - 1; heredoc_label_dtor(heredoc_label); efree(heredoc_label); @@ -2349,9 +2516,8 @@ double_quotes_scan_done: {ANY_CHAR} { - int newline = 0; - zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack)); + int newline = 0, indentation = 0, spacing = 0; if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -2367,28 +2533,55 @@ double_quotes_scan_done: } /* fall through */ case '\n': + indentation = spacing = 0; + + while (YYCURSOR < YYLIMIT && (*YYCURSOR == ' ' || *YYCURSOR == '\t')) { + if (*YYCURSOR == '\t') { + spacing |= HEREDOC_USING_TABS; + } else { + spacing |= HEREDOC_USING_SPACES; + } + ++YYCURSOR; + ++indentation; + } + + if (YYCURSOR == YYLIMIT) { + yyleng = YYCURSOR - SCNG(yy_text); + HANDLE_NEWLINES(yytext, yyleng); + ZVAL_NULL(zendlval); + RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); + } + /* Check for ending label on the next line */ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) { - YYCTYPE *end = YYCURSOR + heredoc_label->length; + if (IS_LABEL_START(YYCURSOR[heredoc_label->length])) { + continue; + } - if (*end == ';') { - end++; + if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) { + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); } - if (*end == '\n' || *end == '\r') { - /* newline before label will be subtracted from returned text, but - * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ - if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') { - newline = 2; /* Windows newline */ - } else { - newline = 1; - } + /* newline before label will be subtracted from returned text, but + * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ + if (YYCURSOR[-indentation - 2] == '\r' && YYCURSOR[-indentation - 1] == '\n') { + newline = 2; /* Windows newline */ + } else { + newline = 1; + } - CG(increment_lineno) = 1; /* For newline before label */ - BEGIN(ST_END_HEREDOC); + CG(increment_lineno) = 1; /* For newline before label */ - goto heredoc_scan_done; + if (SCNG(heredoc_scan_ahead)) { + SCNG(heredoc_indentation) = indentation; + SCNG(heredoc_indentation_uses_spaces) = (spacing == HEREDOC_USING_SPACES); + } else { + YYCURSOR -= indentation; } + + BEGIN(ST_END_HEREDOC); + + goto heredoc_scan_done; } continue; case '$': @@ -2415,21 +2608,34 @@ double_quotes_scan_done: } heredoc_scan_done: + yyleng = YYCURSOR - SCNG(yy_text); + ZVAL_STRINGL(zendlval, yytext, yyleng); - if (EXPECTED(zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0) == SUCCESS) - || !PARSER_MODE()) { - RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); + if (!SCNG(heredoc_scan_ahead) && !EG(exception) && PARSER_MODE()) { + zend_string *copy = Z_STR_P(zendlval); + + if (!strip_multiline_string_indentation(zendlval, newline, heredoc_label->indentation, heredoc_label->indentation_uses_spaces)) { + RETURN_TOKEN(T_ERROR); + } + + if (UNEXPECTED(zend_scan_escape_string(zendlval, ZSTR_VAL(copy), ZSTR_LEN(copy), 0) != SUCCESS)) { + zend_string_free(copy); + RETURN_TOKEN(T_ERROR); + } + + zend_string_free(copy); } else { - RETURN_TOKEN(T_ERROR); + HANDLE_NEWLINES(yytext, yyleng - newline); } + + RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } {ANY_CHAR} { - int newline = 0; - zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack)); + int newline = 0, indentation = 0, spacing = -1; if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -2445,28 +2651,51 @@ heredoc_scan_done: } /* fall through */ case '\n': + indentation = spacing = 0; + + while (YYCURSOR < YYLIMIT && (*YYCURSOR == ' ' || *YYCURSOR == '\t')) { + if (*YYCURSOR == '\t') { + spacing |= HEREDOC_USING_TABS; + } else { + spacing |= HEREDOC_USING_SPACES; + } + ++YYCURSOR; + ++indentation; + } + + if (YYCURSOR == YYLIMIT) { + yyleng = YYCURSOR - SCNG(yy_text); + HANDLE_NEWLINES(yytext, yyleng); + ZVAL_NULL(zendlval); + RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); + } + /* Check for ending label on the next line */ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) { - YYCTYPE *end = YYCURSOR + heredoc_label->length; + if (IS_LABEL_START(YYCURSOR[heredoc_label->length])) { + continue; + } - if (*end == ';') { - end++; + if (spacing == (HEREDOC_USING_SPACES | HEREDOC_USING_TABS)) { + zend_throw_exception(zend_ce_parse_error, "Invalid indentation - tabs and spaces cannot be mixed", 0); } - if (*end == '\n' || *end == '\r') { - /* newline before label will be subtracted from returned text, but - * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ - if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') { - newline = 2; /* Windows newline */ - } else { - newline = 1; - } + /* newline before label will be subtracted from returned text, but + * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */ + if (YYCURSOR[-indentation - 2] == '\r' && YYCURSOR[-indentation - 1] == '\n') { + newline = 2; /* Windows newline */ + } else { + newline = 1; + } - CG(increment_lineno) = 1; /* For newline before label */ - BEGIN(ST_END_HEREDOC); + CG(increment_lineno) = 1; /* For newline before label */ - goto nowdoc_scan_done; - } + YYCURSOR -= indentation; + heredoc_label->indentation = indentation; + + BEGIN(ST_END_HEREDOC); + + goto nowdoc_scan_done; } /* fall through */ default: @@ -2476,8 +2705,13 @@ heredoc_scan_done: nowdoc_scan_done: yyleng = YYCURSOR - SCNG(yy_text); + ZVAL_STRINGL(zendlval, yytext, yyleng); + + if (!EG(exception) && spacing != -1 && PARSER_MODE() + && !strip_multiline_string_indentation(zendlval, newline, indentation, spacing == HEREDOC_USING_SPACES)) { + RETURN_TOKEN(T_ERROR); + } - zend_copy_value(zendlval, yytext, yyleng - newline); HANDLE_NEWLINES(yytext, yyleng - newline); RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c index 97643dc47daf0..0c053c5ba4a46 100644 --- a/Zend/zend_ptr_stack.c +++ b/Zend/zend_ptr_stack.c @@ -90,6 +90,15 @@ ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *)) } } +ZEND_API void zend_ptr_stack_reverse_apply(zend_ptr_stack *stack, void (*func)(void *)) +{ + int i = 0; + + while (i < stack->top) { + func(stack->elements[i++]); + } +} + ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements) { diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h index 80aa8bb252989..01c1e0b87acde 100644 --- a/Zend/zend_ptr_stack.h +++ b/Zend/zend_ptr_stack.h @@ -39,6 +39,7 @@ ZEND_API void zend_ptr_stack_n_push(zend_ptr_stack *stack, int count, ...); ZEND_API void zend_ptr_stack_n_pop(zend_ptr_stack *stack, int count, ...); ZEND_API void zend_ptr_stack_destroy(zend_ptr_stack *stack); ZEND_API void zend_ptr_stack_apply(zend_ptr_stack *stack, void (*func)(void *)); +ZEND_API void zend_ptr_stack_reverse_apply(zend_ptr_stack *stack, void (*func)(void *)); ZEND_API void zend_ptr_stack_clean(zend_ptr_stack *stack, void (*func)(void *), zend_bool free_elements); ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack); END_EXTERN_C() diff --git a/ext/tokenizer/tests/token_get_all_heredoc_nowdoc.phpt b/ext/tokenizer/tests/token_get_all_heredoc_nowdoc.phpt new file mode 100644 index 0000000000000..5f21c384d79c2 --- /dev/null +++ b/ext/tokenizer/tests/token_get_all_heredoc_nowdoc.phpt @@ -0,0 +1,416 @@ +--TEST-- +Flexible heredoc and nowdoc testing with token_get_all +--SKIPIF-- + +--FILE-- +getMessage()} on line {$e->getLine()}\n"; + } +} + +$tests = []; + +$tests[1] = <<<'OUTER_END' + $test) { + echo "\nTest case $i\n\n"; + test($test, 0); +} + +echo "\nWith TOKEN_PARSE:\n"; +foreach ($tests as $i => $test) { + echo "\nTest case $i\n\n"; + test($test, TOKEN_PARSE); +} + +?> +--EXPECT-- +Without TOKEN_PARSE: + +Test case 1 + +Line 1: T_OPEN_TAG ('