Index: zend_globals.h =================================================================== RCS file: /repository/ZendEngine2/zend_globals.h,v retrieving revision 1.141.2.3.2.7.2.14 diff -u -r1.141.2.3.2.7.2.14 zend_globals.h --- zend_globals.h 28 Mar 2008 14:34:59 -0000 1.141.2.3.2.7.2.14 +++ zend_globals.h 8 Apr 2008 13:46:28 -0000 @@ -84,7 +84,7 @@ char *compiled_filename; int zend_lineno; - int comment_start_line; + char *heredoc; int heredoc_len; Index: zend_language_scanner.l =================================================================== RCS file: /repository/ZendEngine2/zend_language_scanner.l,v retrieving revision 1.131.2.11.2.13.2.12 diff -u -r1.131.2.11.2.13.2.12 zend_language_scanner.l --- zend_language_scanner.l 5 Apr 2008 22:29:07 -0000 1.131.2.11.2.13.2.12 +++ zend_language_scanner.l 8 Apr 2008 14:40:01 -0000 @@ -598,7 +598,7 @@ if (YYCURSOR >= YYLIMIT) { /* special case */ if (YYSTATE == STATE(ST_COMMENT) || YYSTATE == STATE(ST_DOC_COMMENT)) { - zend_error(E_COMPILE_WARNING,"Unterminated comment starting line %d", CG(comment_start_line)); + zend_error(E_COMPILE_WARNING, "Unterminated comment starting line %d", CG(zend_lineno)); } return 0; @@ -824,13 +824,16 @@ return T_OBJECT_OPERATOR; } -"->" { - return T_OBJECT_OPERATOR; +{WHITESPACE}+ { + zendlval->value.str.val = yytext; /* no copying - intentional */ + zendlval->value.str.len = yyleng; + zendlval->type = IS_STRING; + HANDLE_NEWLINES(yytext, yyleng); + return T_WHITESPACE; } -{WHITESPACE}+ { - /* do nothing */ - goto restart; +"->" { + return T_OBJECT_OPERATOR; } {LABEL} { @@ -1101,7 +1104,6 @@ "}" { RESET_DOC_COMMENT(); - /* This is a temporary fix which is dependant on flex and it's implementation */ if (!zend_stack_is_empty(&SCNG(state_stack))) { yy_pop_state(TSRMLS_C); } @@ -1430,9 +1432,10 @@ * and "->" will be taken literally */ "$"{LABEL}"->"[a-zA-Z_\x7f-\xff] { - yyless(yyleng - 3); + yyleng -= 3; + yyless(yyleng); yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC); - zend_copy_value(zendlval, (yytext+1), (yyleng-4)); + zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } @@ -1440,9 +1443,10 @@ /* A [ always designates a variable offset, regardless of what follows */ "$"{LABEL}"[" { - yyless(yyleng - 1); + yyleng--; + yyless(yyleng); yy_push_state(ST_VAR_OFFSET TSRMLS_CC); - zend_copy_value(zendlval, (yytext+1), (yyleng-2)); + zend_copy_value(zendlval, (yytext+1), (yyleng-1)); zendlval->type = IS_STRING; return T_VARIABLE; } @@ -1466,6 +1470,7 @@ [ \n\r\t\\'#] { /* Invalid rule to return a more explicit parse error with proper line number */ yyless(0); + yyleng = 0; yy_pop_state(TSRMLS_C); ZVAL_EMPTY_STRING(zendlval); /* Empty since it won't be used */ return T_ENCAPSED_AND_WHITESPACE; @@ -1478,15 +1483,6 @@ } -{WHITESPACE} { - zendlval->value.str.val = yytext; /* no copying - intentional */ - zendlval->value.str.len = yyleng; - zendlval->type = IS_STRING; - HANDLE_NEWLINES(yytext, yyleng); - return T_WHITESPACE; -} - - "#"|"//" { BEGIN(ST_ONE_LINE_COMMENT); yymore(); @@ -1538,14 +1534,12 @@ } "/**"{WHITESPACE} { - CG(comment_start_line) = CG(zend_lineno); RESET_DOC_COMMENT(); BEGIN(ST_DOC_COMMENT); yymore(); } "/*" { - CG(comment_start_line) = CG(zend_lineno); BEGIN(ST_COMMENT); yymore(); } @@ -1591,6 +1585,7 @@ return T_CLOSE_TAG; /* implicit ';' at php-end tag */ } else { yyless(1); + yyleng = 1; return yytext[0]; } } @@ -1659,15 +1654,19 @@ b?"<<<"{TABS_AND_SPACES}({LABEL}|["]{LABEL}["]){NEWLINE} { char *s; int bprefix = (yytext[0] != '<') ? 1 : 0; - int quotes = (yytext[bprefix + 3] == '"') ? 2 : 0; CG(zend_lineno)++; - CG(heredoc_len) = yyleng-bprefix-3-quotes-1-(yytext[yyleng-2]=='\r'?1:0); - s = yytext+bprefix+3+(quotes ? 1 : 0); + CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0); + s = yytext+bprefix+3; while ((*s == ' ') || (*s == '\t')) { s++; CG(heredoc_len)--; } + + if (*s == '"') { + s++; + CG(heredoc_len) -= 2; + } CG(heredoc) = estrndup(s, CG(heredoc_len)); BEGIN(ST_START_HEREDOC); return T_START_HEREDOC; @@ -1694,6 +1693,7 @@ } yyless(label_len); + yyleng = label_len; if (label_len==CG(heredoc_len) && !memcmp(yytext, CG(heredoc), label_len)) { zendlval->value.str.val = CG(heredoc); @@ -1725,16 +1725,22 @@ if (yyleng > CG(heredoc_len) && !memcmp(end - CG(heredoc_len), CG(heredoc), CG(heredoc_len))) { int len = yyleng - CG(heredoc_len) - 2; /* 2 for newline before and after label */ - if (len > 0 && yytext[len - 1] == '\r' && yytext[len] == '\n') { - len--; + /* May have matched fooLABEL; make sure there's a newline before it */ + if (yytext[len] != '\n') { + if (yytext[len] != '\r') { + yyless(yyleng - 1); + yymore(); + } + } else if (len > 0 && yytext[len - 1] == '\r') { + len--; /* Windows newline */ } /* Go back before last label char, to match in ST_END_HEREDOC state */ yyless(yyleng - 2); - /* Subtract the remaining label length. yyleng must include newline + /* Subtract the label/newline length. yyleng must include newline * before label, for zend_highlight/strip, tokenizer, etc. */ - yyleng = yyleng - CG(heredoc_len) - 1; + yyleng -= CG(heredoc_len) + 1; CG(increment_lineno) = 1; /* For newline before label */ BEGIN(ST_END_HEREDOC); @@ -1749,10 +1755,8 @@ } {ANY_CHAR} { - zendlval->value.str.val = CG(heredoc); - zendlval->value.str.len = CG(heredoc_len); - SCNG(yy_text) = zendlval->value.str.val; - yyleng = zendlval->value.str.len; + SCNG(yy_text) = Z_STRVAL_P(zendlval) = CG(heredoc); + SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len); CG(heredoc) = NULL; CG(heredoc_len) = 0; BEGIN(ST_IN_SCRIPTING); @@ -1760,10 +1764,10 @@ } -"{$" { +/* Will only match when $ follows: "{$" */ +"{" { zendlval->value.lval = (long) '{'; yy_push_state(ST_IN_SCRIPTING TSRMLS_CC); - yyless(1); return T_CURLY_OPEN; } @@ -1777,11 +1781,11 @@ * (("{"+|"$"+)["]) handles { or $ at the end of a string * * Same for backquotes and heredocs, except the second case doesn't apply to - * heredocs. yyless(yyleng - 1) is used to correct taking one character too many + * heredocs. yyleng--/yyless() is used to correct taking one character too many */ {DOUBLE_QUOTES_CHARS}*("{"{2,}|"$"{2,}|(("{"+|"$"+)["])) { - yyless(yyleng - 1); - if (yytext[yyleng-1] == '"') --yyleng; + yyleng--; + yyless(yyleng); zend_scan_escape_string(zendlval, yytext, yyleng, '"' TSRMLS_CC); return T_ENCAPSED_AND_WHITESPACE; } @@ -1793,7 +1797,8 @@ } {BACKQUOTE_CHARS}*("{"{2,}|"$"{2,}|(("{"+|"$"+)[`])) { - yyless(yyleng - 1); + yyleng--; + yyless(yyleng); zend_scan_escape_string(zendlval, yytext, yyleng, '`' TSRMLS_CC); return T_ENCAPSED_AND_WHITESPACE; } @@ -1812,7 +1817,8 @@ } {HEREDOC_CHARS}*({HEREDOC_NEWLINE}+({LABEL}";"?)?)?("{"{2,}|"$"{2,}) { - yyless(yyleng - 1); + yyleng--; + yyless(yyleng); zend_scan_escape_string(zendlval, yytext, yyleng, 0 TSRMLS_CC); return T_ENCAPSED_AND_WHITESPACE; } @@ -1874,16 +1880,22 @@ if (yyleng > CG(heredoc_len) && !memcmp(end - CG(heredoc_len), CG(heredoc), CG(heredoc_len))) { int len = yyleng - CG(heredoc_len) - 2; /* 2 for newline before and after label */ - if (len > 0 && yytext[len - 1] == '\r' && yytext[len] == '\n') { - len--; + /* May have matched fooLABEL; make sure there's a newline before it */ + if (yytext[len] != '\n') { + if (yytext[len] != '\r') { + yyless(yyleng - 1); + yymore(); + } + } else if (len > 0 && yytext[len - 1] == '\r') { + len--; /* Windows newline */ } - /* Go back before last label char, to match in ST_END_HEREDOC state */ + /* Go back before last label char, to match in ST_END_NOWDOC state */ yyless(yyleng - 2); - /* Subtract the remaining label length. yyleng must include newline + /* Subtract the label/newline length. yyleng must include newline * before label, for zend_highlight/strip, tokenizer, etc. */ - yyleng = yyleng - CG(heredoc_len) - 1; + yyleng -= CG(heredoc_len) + 1; CG(increment_lineno) = 1; /* For newline before label */ BEGIN(ST_END_NOWDOC); @@ -1894,17 +1906,15 @@ return T_ENCAPSED_AND_WHITESPACE; } else { /* Go back to end of label, so the next match works correctly in case of - * a variable or another label at the beginning of the next line */ + * another label at the beginning of the next line */ yyless(yyleng - 1); yymore(); } } {ANY_CHAR} { - Z_STRVAL_P(zendlval) = CG(heredoc); - Z_STRLEN_P(zendlval) = CG(heredoc_len); - SCNG(yy_text) = CG(heredoc); - yyleng = CG(heredoc_len); + SCNG(yy_text) = Z_STRVAL_P(zendlval) = CG(heredoc); + SCNG(yy_leng) = Z_STRLEN_P(zendlval) = CG(heredoc_len); CG(heredoc) = NULL; CG(heredoc_len) = 0; BEGIN(ST_IN_SCRIPTING);