PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - lcov_data/Zend - zend_language_scanner.l (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 853 980 87.0 %
Date: 2014-10-14 Functions: 26 28 92.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Marcus Boerger <helly@php.net>                              |
      16             :    |          Nuno Lopes <nlopess@php.net>                                |
      17             :    |          Scott MacVicar <scottmac@php.net>                           |
      18             :    | Flex version authors:                                                |
      19             :    |          Andi Gutmans <andi@zend.com>                                |
      20             :    |          Zeev Suraski <zeev@zend.com>                                |
      21             :    +----------------------------------------------------------------------+
      22             : */
      23             : 
      24             : /* $Id$ */
      25             : 
      26             : #if 0
      27             : # define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c)
      28             : #else
      29             : # define YYDEBUG(s, c)
      30             : #endif
      31             : 
      32             : #include "zend_language_scanner_defs.h"
      33             : 
      34             : #include <errno.h>
      35             : #include "zend.h"
      36             : #ifdef PHP_WIN32
      37             : # include <Winuser.h>
      38             : #endif
      39             : #include "zend_alloc.h"
      40             : #include <zend_language_parser.h>
      41             : #include "zend_compile.h"
      42             : #include "zend_language_scanner.h"
      43             : #include "zend_highlight.h"
      44             : #include "zend_constants.h"
      45             : #include "zend_variables.h"
      46             : #include "zend_operators.h"
      47             : #include "zend_API.h"
      48             : #include "zend_strtod.h"
      49             : #include "zend_exceptions.h"
      50             : #include "zend_virtual_cwd.h"
      51             : #include "tsrm_config_common.h"
      52             : 
      53             : #define YYCTYPE   unsigned char
      54             : #define YYFILL(n) { if ((YYCURSOR + n) >= (YYLIMIT + ZEND_MMAP_AHEAD)) { return 0; } }
      55             : #define YYCURSOR  SCNG(yy_cursor)
      56             : #define YYLIMIT   SCNG(yy_limit)
      57             : #define YYMARKER  SCNG(yy_marker)
      58             : 
      59             : #define YYGETCONDITION()  SCNG(yy_state)
      60             : #define YYSETCONDITION(s) SCNG(yy_state) = s
      61             : 
      62             : #define STATE(name)  yyc##name
      63             : 
      64             : /* emulate flex constructs */
      65             : #define BEGIN(state) YYSETCONDITION(STATE(state))
      66             : #define YYSTATE      YYGETCONDITION()
      67             : #define yytext       ((char*)SCNG(yy_text))
      68             : #define yyleng       SCNG(yy_leng)
      69             : #define yyless(x)    do { YYCURSOR = (unsigned char*)yytext + x; \
      70             :                           yyleng   = (unsigned int)x; } while(0)
      71             : #define yymore()     goto yymore_restart
      72             : 
      73             : /* perform sanity check. If this message is triggered you should
      74             :    increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */
      75             : /*!max:re2c */
      76             : #if ZEND_MMAP_AHEAD < YYMAXFILL
      77             : # error ZEND_MMAP_AHEAD should be greater than or equal to YYMAXFILL
      78             : #endif
      79             : 
      80             : #ifdef HAVE_STDARG_H
      81             : # include <stdarg.h>
      82             : #endif
      83             : 
      84             : #ifdef HAVE_UNISTD_H
      85             : # include <unistd.h>
      86             : #endif
      87             : 
      88             : /* Globals Macros */
      89             : #define SCNG    LANG_SCNG
      90             : #ifdef ZTS
      91             : ZEND_API ts_rsrc_id language_scanner_globals_id;
      92             : #else
      93             : ZEND_API zend_php_scanner_globals language_scanner_globals;
      94             : #endif
      95             : 
      96             : #define HANDLE_NEWLINES(s, l)                                                                                                   \
      97             : do {                                                                                                                                                    \
      98             :         char *p = (s), *boundary = p+(l);                                                                                       \
      99             :                                                                                                                                                                 \
     100             :         while (p<boundary) {                                                                                                         \
     101             :                 if (*p == '\n' || (*p == '\r' && (*(p+1) != '\n'))) {                                   \
     102             :                         CG(zend_lineno)++;                                                                                                      \
     103             :                 }                                                                                                                                               \
     104             :                 p++;                                                                                                                                    \
     105             :         }                                                                                                                                                       \
     106             : } while (0)
     107             : 
     108             : #define HANDLE_NEWLINE(c) \
     109             : { \
     110             :         if (c == '\n' || c == '\r') { \
     111             :                 CG(zend_lineno)++; \
     112             :         } \
     113             : }
     114             : 
     115             : /* To save initial string length after scanning to first variable */
     116             : #define SET_DOUBLE_QUOTES_SCANNED_LENGTH(len) SCNG(scanned_string_len) = (len)
     117             : #define GET_DOUBLE_QUOTES_SCANNED_LENGTH()    SCNG(scanned_string_len)
     118             : 
     119             : #define IS_LABEL_START(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || (c) == '_' || (c) >= 0x7F)
     120             : 
     121             : #define ZEND_IS_OCT(c)  ((c)>='0' && (c)<='7')
     122             : #define ZEND_IS_HEX(c)  (((c)>='0' && (c)<='9') || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F'))
     123             : 
     124             : BEGIN_EXTERN_C()
     125             : 
     126          35 : static size_t encoding_filter_script_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     127             : {
     128          35 :         const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
     129             :         ZEND_ASSERT(internal_encoding);
     130          35 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length, internal_encoding, LANG_SCNG(script_encoding) TSRMLS_CC);
     131             : }
     132             : 
     133           4 : static size_t encoding_filter_script_to_intermediate(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     134             : {
     135           4 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length, zend_multibyte_encoding_utf8, LANG_SCNG(script_encoding) TSRMLS_CC);
     136             : }
     137             : 
     138          27 : static size_t encoding_filter_intermediate_to_script(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     139             : {
     140          27 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length,
     141             : LANG_SCNG(script_encoding), zend_multibyte_encoding_utf8 TSRMLS_CC);
     142             : }
     143             : 
     144           0 : static size_t encoding_filter_intermediate_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC)
     145             : {
     146           0 :         const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
     147             :         ZEND_ASSERT(internal_encoding);
     148           0 :         return zend_multibyte_encoding_converter(to, to_length, from, from_length,
     149             : internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC);
     150             : }
     151             : 
     152             : 
     153      163141 : static void _yy_push_state(int new_state TSRMLS_DC)
     154             : {
     155      163141 :         zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION());
     156      163141 :         YYSETCONDITION(new_state);
     157      163141 : }
     158             : 
     159             : #define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm)
     160             : 
     161      163118 : static void yy_pop_state(TSRMLS_D)
     162             : {
     163      163118 :         int *stack_state = zend_stack_top(&SCNG(state_stack));
     164      163118 :         YYSETCONDITION(*stack_state);
     165      163118 :         zend_stack_del_top(&SCNG(state_stack));
     166      163118 : }
     167             : 
     168       29600 : static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
     169             : {
     170       29600 :         YYCURSOR       = (YYCTYPE*)str;
     171       29600 :         YYLIMIT        = YYCURSOR + len;
     172       29600 :         if (!SCNG(yy_start)) {
     173        1183 :                 SCNG(yy_start) = YYCURSOR;
     174             :         }
     175       29600 : }
     176             : 
     177       20358 : void startup_scanner(TSRMLS_D)
     178             : {
     179       20358 :         CG(parse_error) = 0;
     180       20358 :         CG(doc_comment) = NULL;
     181       20358 :         zend_stack_init(&SCNG(state_stack), sizeof(int));
     182       20358 :         zend_ptr_stack_init(&SCNG(heredoc_label_stack));
     183       20358 : }
     184             : 
     185        1546 : static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) {
     186        1546 :     efree(heredoc_label->label);
     187        1546 : }
     188             : 
     189       20394 : void shutdown_scanner(TSRMLS_D)
     190             : {
     191       20394 :         CG(parse_error) = 0;
     192       20394 :         RESET_DOC_COMMENT();
     193       20394 :         zend_stack_destroy(&SCNG(state_stack));
     194       20394 :         zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
     195       20394 :         zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
     196       20394 : }
     197             : 
     198       29626 : ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
     199             : {
     200       29626 :         lex_state->yy_leng   = SCNG(yy_leng);
     201       29626 :         lex_state->yy_start  = SCNG(yy_start);
     202       29626 :         lex_state->yy_text   = SCNG(yy_text);
     203       29626 :         lex_state->yy_cursor = SCNG(yy_cursor);
     204       29626 :         lex_state->yy_marker = SCNG(yy_marker);
     205       29626 :         lex_state->yy_limit  = SCNG(yy_limit);
     206             : 
     207       29626 :         lex_state->state_stack = SCNG(state_stack);
     208       29626 :         zend_stack_init(&SCNG(state_stack), sizeof(int));
     209             : 
     210       29626 :         lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
     211       29626 :         zend_ptr_stack_init(&SCNG(heredoc_label_stack));
     212             : 
     213       29626 :         lex_state->in = SCNG(yy_in);
     214       29626 :         lex_state->yy_state = YYSTATE;
     215       29626 :         lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
     216       29626 :         lex_state->lineno = CG(zend_lineno);
     217             : 
     218       29626 :         lex_state->script_org = SCNG(script_org);
     219       29626 :         lex_state->script_org_size = SCNG(script_org_size);
     220       29626 :         lex_state->script_filtered = SCNG(script_filtered);
     221       29626 :         lex_state->script_filtered_size = SCNG(script_filtered_size);
     222       29626 :         lex_state->input_filter = SCNG(input_filter);
     223       29626 :         lex_state->output_filter = SCNG(output_filter);
     224       29626 :         lex_state->script_encoding = SCNG(script_encoding);
     225       29626 : }
     226             : 
     227       29400 : ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
     228             : {
     229       29400 :         SCNG(yy_leng)   = lex_state->yy_leng;
     230       29400 :         SCNG(yy_start)  = lex_state->yy_start;
     231       29400 :         SCNG(yy_text)   = lex_state->yy_text;
     232       29400 :         SCNG(yy_cursor) = lex_state->yy_cursor;
     233       29400 :         SCNG(yy_marker) = lex_state->yy_marker;
     234       29400 :         SCNG(yy_limit)  = lex_state->yy_limit;
     235             : 
     236       29400 :         zend_stack_destroy(&SCNG(state_stack));
     237       29400 :         SCNG(state_stack) = lex_state->state_stack;
     238             : 
     239       29400 :         zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
     240       29400 :         zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
     241       29400 :         SCNG(heredoc_label_stack) = lex_state->heredoc_label_stack;
     242             : 
     243       29400 :         SCNG(yy_in) = lex_state->in;
     244       29400 :         YYSETCONDITION(lex_state->yy_state);
     245       29400 :         CG(zend_lineno) = lex_state->lineno;
     246       29400 :         zend_restore_compiled_filename(lex_state->filename TSRMLS_CC);
     247             : 
     248       29400 :         if (SCNG(script_filtered)) {
     249          17 :                 efree(SCNG(script_filtered));
     250          17 :                 SCNG(script_filtered) = NULL;
     251             :         }
     252       29400 :         SCNG(script_org) = lex_state->script_org;
     253       29400 :         SCNG(script_org_size) = lex_state->script_org_size;
     254       29400 :         SCNG(script_filtered) = lex_state->script_filtered;
     255       29400 :         SCNG(script_filtered_size) = lex_state->script_filtered_size;
     256       29400 :         SCNG(input_filter) = lex_state->input_filter;
     257       29400 :         SCNG(output_filter) = lex_state->output_filter;
     258       29400 :         SCNG(script_encoding) = lex_state->script_encoding;
     259             : 
     260       29424 :         RESET_DOC_COMMENT();
     261       29400 : }
     262             : 
     263       28217 : ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC)
     264             : {
     265       28217 :         zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles);
     266             :         /* zend_file_handle_dtor() operates on the copy, so we have to NULLify the original here */
     267       28217 :         file_handle->opened_path = NULL;
     268       28217 :         if (file_handle->free_filename) {
     269           0 :                 file_handle->filename = NULL;
     270             :         }
     271       28217 : }
     272             : 
     273             : #define BOM_UTF32_BE    "\x00\x00\xfe\xff"
     274             : #define BOM_UTF32_LE    "\xff\xfe\x00\x00"
     275             : #define BOM_UTF16_BE    "\xfe\xff"
     276             : #define BOM_UTF16_LE    "\xff\xfe"
     277             : #define BOM_UTF8                "\xef\xbb\xbf"
     278             : 
     279           0 : static const zend_encoding *zend_multibyte_detect_utf_encoding(const unsigned char *script, size_t script_size TSRMLS_DC)
     280             : {
     281             :         const unsigned char *p;
     282           0 :         int wchar_size = 2;
     283           0 :         int le = 0;
     284             : 
     285             :         /* utf-16 or utf-32? */
     286           0 :         p = script;
     287           0 :         while ((p-script) < script_size) {
     288           0 :                 p = memchr(p, 0, script_size-(p-script)-2);
     289           0 :                 if (!p) {
     290           0 :                         break;
     291             :                 }
     292           0 :                 if (*(p+1) == '\0' && *(p+2) == '\0') {
     293           0 :                         wchar_size = 4;
     294           0 :                         break;
     295             :                 }
     296             : 
     297             :                 /* searching for UTF-32 specific byte orders, so this will do */
     298           0 :                 p += 4;
     299             :         }
     300             : 
     301             :         /* BE or LE? */
     302           0 :         p = script;
     303           0 :         while ((p-script) < script_size) {
     304           0 :                 if (*p == '\0' && *(p+wchar_size-1) != '\0') {
     305             :                         /* BE */
     306           0 :                         le = 0;
     307           0 :                         break;
     308           0 :                 } else if (*p != '\0' && *(p+wchar_size-1) == '\0') {
     309             :                         /* LE* */
     310           0 :                         le = 1;
     311           0 :                         break;
     312             :                 }
     313           0 :                 p += wchar_size;
     314             :         }
     315             : 
     316           0 :         if (wchar_size == 2) {
     317           0 :                 return le ? zend_multibyte_encoding_utf16le : zend_multibyte_encoding_utf16be;
     318             :         } else {
     319           0 :                 return le ? zend_multibyte_encoding_utf32le : zend_multibyte_encoding_utf32be;
     320             :         }
     321             : 
     322             :         return NULL;
     323             : }
     324             : 
     325          30 : static const zend_encoding* zend_multibyte_detect_unicode(TSRMLS_D)
     326             : {
     327          30 :         const zend_encoding *script_encoding = NULL;
     328             :         int bom_size;
     329             :         unsigned char *pos1, *pos2;
     330             : 
     331          30 :         if (LANG_SCNG(script_org_size) < sizeof(BOM_UTF32_LE)-1) {
     332           0 :                 return NULL;
     333             :         }
     334             : 
     335             :         /* check out BOM */
     336          30 :         if (!memcmp(LANG_SCNG(script_org), BOM_UTF32_BE, sizeof(BOM_UTF32_BE)-1)) {
     337           0 :                 script_encoding = zend_multibyte_encoding_utf32be;
     338           0 :                 bom_size = sizeof(BOM_UTF32_BE)-1;
     339          30 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF32_LE, sizeof(BOM_UTF32_LE)-1)) {
     340           0 :                 script_encoding = zend_multibyte_encoding_utf32le;
     341           0 :                 bom_size = sizeof(BOM_UTF32_LE)-1;
     342          30 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF16_BE, sizeof(BOM_UTF16_BE)-1)) {
     343           0 :                 script_encoding = zend_multibyte_encoding_utf16be;
     344           0 :                 bom_size = sizeof(BOM_UTF16_BE)-1;
     345          30 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF16_LE, sizeof(BOM_UTF16_LE)-1)) {
     346           1 :                 script_encoding = zend_multibyte_encoding_utf16le;
     347           1 :                 bom_size = sizeof(BOM_UTF16_LE)-1;
     348          29 :         } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF8, sizeof(BOM_UTF8)-1)) {
     349           1 :                 script_encoding = zend_multibyte_encoding_utf8;
     350           1 :                 bom_size = sizeof(BOM_UTF8)-1;
     351             :         }
     352             : 
     353          30 :         if (script_encoding) {
     354             :                 /* remove BOM */
     355           2 :                 LANG_SCNG(script_org) += bom_size;
     356           2 :                 LANG_SCNG(script_org_size) -= bom_size;
     357             : 
     358           2 :                 return script_encoding;
     359             :         }
     360             : 
     361             :         /* script contains NULL bytes -> auto-detection */
     362          28 :         if ((pos1 = memchr(LANG_SCNG(script_org), 0, LANG_SCNG(script_org_size)))) {
     363             :                 /* check if the NULL byte is after the __HALT_COMPILER(); */
     364           0 :                 pos2 = LANG_SCNG(script_org);
     365             : 
     366           0 :                 while (pos1 - pos2 >= sizeof("__HALT_COMPILER();")-1) {
     367           0 :                         pos2 = memchr(pos2, '_', pos1 - pos2);
     368           0 :                         if (!pos2) break;
     369           0 :                         pos2++;
     370           0 :                         if (strncasecmp((char*)pos2, "_HALT_COMPILER", sizeof("_HALT_COMPILER")-1) == 0) {
     371           0 :                                 pos2 += sizeof("_HALT_COMPILER")-1;
     372           0 :                                 while (*pos2 == ' '  ||
     373           0 :                                            *pos2 == '\t' ||
     374           0 :                                            *pos2 == '\r' ||
     375           0 :                                            *pos2 == '\n') {
     376           0 :                                         pos2++;
     377             :                                 }
     378           0 :                                 if (*pos2 == '(') {
     379           0 :                                         pos2++;
     380           0 :                                         while (*pos2 == ' '  ||
     381           0 :                                                    *pos2 == '\t' ||
     382           0 :                                                    *pos2 == '\r' ||
     383           0 :                                                    *pos2 == '\n') {
     384           0 :                                                 pos2++;
     385             :                                         }
     386           0 :                                         if (*pos2 == ')') {
     387           0 :                                                 pos2++;
     388           0 :                                                 while (*pos2 == ' '  ||
     389           0 :                                                            *pos2 == '\t' ||
     390           0 :                                                            *pos2 == '\r' ||
     391           0 :                                                            *pos2 == '\n') {
     392           0 :                                                         pos2++;
     393             :                                                 }
     394           0 :                                                 if (*pos2 == ';') {
     395           0 :                                                         return NULL;
     396             :                                                 }
     397             :                                         }
     398             :                                 }
     399             :                         }
     400             :                 }
     401             :                 /* make best effort if BOM is missing */
     402           0 :                 return zend_multibyte_detect_utf_encoding(LANG_SCNG(script_org), LANG_SCNG(script_org_size) TSRMLS_CC);
     403             :         }
     404             : 
     405          28 :         return NULL;
     406             : }
     407             : 
     408          30 : static const zend_encoding* zend_multibyte_find_script_encoding(TSRMLS_D)
     409             : {
     410             :         const zend_encoding *script_encoding;
     411             : 
     412          30 :         if (CG(detect_unicode)) {
     413             :                 /* check out bom(byte order mark) and see if containing wchars */
     414          30 :                 script_encoding = zend_multibyte_detect_unicode(TSRMLS_C);
     415          30 :                 if (script_encoding != NULL) {
     416             :                         /* bom or wchar detection is prior to 'script_encoding' option */
     417           2 :                         return script_encoding;
     418             :                 }
     419             :         }
     420             : 
     421             :         /* if no script_encoding specified, just leave alone */
     422          28 :         if (!CG(script_encoding_list) || !CG(script_encoding_list_size)) {
     423          13 :                 return NULL;
     424             :         }
     425             : 
     426             :         /* if multiple encodings specified, detect automagically */
     427          15 :         if (CG(script_encoding_list_size) > 1) {
     428           0 :                 return zend_multibyte_encoding_detector(LANG_SCNG(script_org), LANG_SCNG(script_org_size), CG(script_encoding_list), CG(script_encoding_list_size) TSRMLS_CC);
     429             :         }
     430             : 
     431          15 :         return CG(script_encoding_list)[0];
     432             : }
     433             : 
     434          43 : ZEND_API int zend_multibyte_set_filter(const zend_encoding *onetime_encoding TSRMLS_DC)
     435             : {
     436          43 :         const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C);
     437          43 :         const zend_encoding *script_encoding = onetime_encoding ? onetime_encoding: zend_multibyte_find_script_encoding(TSRMLS_C);
     438             : 
     439          43 :         if (!script_encoding) {
     440          13 :                 return FAILURE;
     441             :         }
     442             : 
     443             :         /* judge input/output filter */
     444          30 :         LANG_SCNG(script_encoding) = script_encoding;
     445          30 :         LANG_SCNG(input_filter) = NULL;
     446          30 :         LANG_SCNG(output_filter) = NULL;
     447             : 
     448          30 :         if (!internal_encoding || LANG_SCNG(script_encoding) == internal_encoding) {
     449           7 :                 if (!zend_multibyte_check_lexer_compatibility(LANG_SCNG(script_encoding))) {
     450             :                         /* and if not, work around w/ script_encoding -> utf-8 -> script_encoding conversion */
     451           4 :                         LANG_SCNG(input_filter) = encoding_filter_script_to_intermediate;
     452           4 :                         LANG_SCNG(output_filter) = encoding_filter_intermediate_to_script;
     453             :                 } else {
     454           3 :                         LANG_SCNG(input_filter) = NULL;
     455           3 :                         LANG_SCNG(output_filter) = NULL;
     456             :                 }
     457           7 :                 return SUCCESS;
     458             :         }
     459             : 
     460          23 :         if (zend_multibyte_check_lexer_compatibility(internal_encoding)) {
     461          20 :                 LANG_SCNG(input_filter) = encoding_filter_script_to_internal;
     462          20 :                 LANG_SCNG(output_filter) = NULL;
     463           3 :         } else if (zend_multibyte_check_lexer_compatibility(LANG_SCNG(script_encoding))) {
     464           3 :                 LANG_SCNG(input_filter) = NULL;
     465           3 :                 LANG_SCNG(output_filter) = encoding_filter_script_to_internal;
     466             :         } else {
     467             :                 /* both script and internal encodings are incompatible w/ flex */
     468           0 :                 LANG_SCNG(input_filter) = encoding_filter_script_to_intermediate;
     469           0 :                 LANG_SCNG(output_filter) = encoding_filter_intermediate_to_internal;
     470             :         }
     471             : 
     472          23 :         return 0;
     473             : }
     474             : 
     475       28449 : ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC)
     476             : {
     477       28449 :         const char *file_path = NULL;
     478             :         char *buf;
     479       28449 :         size_t size, offset = 0;
     480             :         zend_string *compiled_filename;
     481             : 
     482             :         /* The shebang line was read, get the current position to obtain the buffer start */
     483       28449 :         if (CG(start_lineno) == 2 && file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) {
     484           4 :                 if ((offset = ftell(file_handle->handle.fp)) == -1) {
     485           0 :                         offset = 0;
     486             :                 }
     487             :         }
     488             : 
     489       28449 :         if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) {
     490          32 :                 return FAILURE;
     491             :         }
     492             : 
     493       28417 :         zend_llist_add_element(&CG(open_files), file_handle);
     494       28417 :         if (file_handle->handle.stream.handle >= (void*)file_handle && file_handle->handle.stream.handle <= (void*)(file_handle+1)) {
     495       20191 :                 zend_file_handle *fh = (zend_file_handle*)zend_llist_get_last(&CG(open_files));
     496       20191 :                 size_t diff = (char*)file_handle->handle.stream.handle - (char*)file_handle;
     497       20191 :                 fh->handle.stream.handle = (void*)(((char*)fh) + diff);
     498       20191 :                 file_handle->handle.stream.handle = fh->handle.stream.handle;
     499             :         }
     500             : 
     501             :         /* Reset the scanner for scanning the new file */
     502       28417 :         SCNG(yy_in) = file_handle;
     503       28417 :         SCNG(yy_start) = NULL;
     504             : 
     505       28417 :         if (size != -1) {
     506       28417 :                 if (CG(multibyte)) {
     507          30 :                         SCNG(script_org) = (unsigned char*)buf;
     508          30 :                         SCNG(script_org_size) = size;
     509          30 :                         SCNG(script_filtered) = NULL;
     510             : 
     511          30 :                         zend_multibyte_set_filter(NULL TSRMLS_CC);
     512             : 
     513          30 :                         if (SCNG(input_filter)) {
     514          14 :                                 if ((size_t)-1 == SCNG(input_filter)(&SCNG(script_filtered), &SCNG(script_filtered_size), SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) {
     515           0 :                                         zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected "
     516             :                                                         "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding)));
     517             :                                 }
     518          14 :                                 buf = (char*)SCNG(script_filtered);
     519          14 :                                 size = SCNG(script_filtered_size);
     520             :                         }
     521             :                 }
     522       28417 :                 SCNG(yy_start) = (unsigned char *)buf - offset;
     523       28417 :                 yy_scan_buffer(buf, size TSRMLS_CC);
     524             :         } else {
     525           0 :                 zend_error_noreturn(E_COMPILE_ERROR, "zend_stream_mmap() failed");
     526             :         }
     527             : 
     528       28417 :         BEGIN(INITIAL);
     529             : 
     530       28417 :         if (file_handle->opened_path) {
     531       28387 :                 file_path = file_handle->opened_path;
     532             :         } else {
     533          30 :                 file_path = file_handle->filename;
     534             :         }
     535             : 
     536       56834 :         compiled_filename = zend_string_init(file_path, strlen(file_path), 0);
     537       28417 :         zend_set_compiled_filename(compiled_filename TSRMLS_CC);
     538             :         zend_string_release(compiled_filename);
     539             : 
     540       28417 :         if (CG(start_lineno)) {
     541       19910 :                 CG(zend_lineno) = CG(start_lineno);
     542       19910 :                 CG(start_lineno) = 0;
     543             :         } else {
     544        8507 :                 CG(zend_lineno) = 1;
     545             :         }
     546             : 
     547       28417 :         RESET_DOC_COMMENT();
     548       28417 :         CG(increment_lineno) = 0;
     549       28417 :         return SUCCESS;
     550             : }
     551             : END_EXTERN_C()
     552             : 
     553             : 
     554       28416 : ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
     555             : {
     556             :         zend_lex_state original_lex_state;
     557       28416 :         zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
     558       28416 :         zend_op_array *original_active_op_array = CG(active_op_array);
     559             :         int compiler_result;
     560       28416 :         zend_bool compilation_successful=0;
     561             :         zval retval_zv;
     562       28416 :         zend_bool original_in_compilation = CG(in_compilation);
     563             : 
     564       28416 :         ZVAL_LONG(&retval_zv, 1);
     565             : 
     566       28416 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     567             : 
     568       28416 :         if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) {
     569          28 :                 if (type==ZEND_REQUIRE) {
     570           1 :                         zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC);
     571           0 :                         zend_bailout();
     572             :                 } else {
     573          27 :                         zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC);
     574             :                 }
     575          27 :                 compilation_successful=0;
     576             :         } else {
     577       28388 :                 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
     578       28388 :                 CG(in_compilation) = 1;
     579       28388 :                 CG(active_op_array) = op_array;
     580       28388 :                 zend_stack_push(&CG(context_stack), (void *) &CG(context));
     581       28388 :                 zend_init_compiler_context(TSRMLS_C);
     582       28388 :                 CG(ast_arena) = zend_arena_create(1024 * 32);
     583       28388 :                 compiler_result = zendparse(TSRMLS_C);
     584       28374 :                 if (compiler_result != 0) { /* parser error */
     585          28 :                         zend_bailout();
     586             :                 }
     587       28346 :                 zend_compile_top_stmt(CG(ast) TSRMLS_CC);
     588       28168 :                 zend_ast_destroy(CG(ast));
     589       28168 :                 zend_arena_destroy(CG(ast_arena));
     590       28168 :                 zend_do_end_compilation(TSRMLS_C);
     591       28168 :                 zend_emit_final_return(&retval_zv TSRMLS_CC);
     592       28168 :                 CG(in_compilation) = original_in_compilation;
     593       28168 :                 compilation_successful=1;
     594             :         }
     595             : 
     596       28195 :         CG(active_op_array) = original_active_op_array;
     597       28195 :         if (compilation_successful) {
     598       28168 :                 pass_two(op_array TSRMLS_CC);
     599       28165 :                 zend_release_labels(0 TSRMLS_CC);
     600             :         } else {
     601          27 :                 efree_size(op_array, sizeof(zend_op_array));
     602          27 :                 op_array = NULL;
     603             :         }
     604             : 
     605       28192 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     606       28192 :         return op_array;
     607             : }
     608             : 
     609             : 
     610        2712 : zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC)
     611             : {
     612             :         zend_file_handle file_handle;
     613             :         zval tmp;
     614             :         zend_op_array *retval;
     615        2712 :         char *opened_path = NULL;
     616             : 
     617        2712 :         if (Z_TYPE_P(filename) != IS_STRING) {
     618           0 :                 tmp = *filename;
     619             :                 zval_copy_ctor(&tmp);
     620           0 :                 convert_to_string(&tmp);
     621           0 :                 filename = &tmp;
     622             :         }
     623        2712 :         file_handle.filename = Z_STRVAL_P(filename);
     624        2712 :         file_handle.free_filename = 0;
     625        2712 :         file_handle.type = ZEND_HANDLE_FILENAME;
     626        2712 :         file_handle.opened_path = NULL;
     627        2712 :         file_handle.handle.fp = NULL;
     628             : 
     629        2712 :         retval = zend_compile_file(&file_handle, type TSRMLS_CC);
     630        2707 :         if (retval && file_handle.handle.stream.handle) {
     631        2678 :                 if (!file_handle.opened_path) {
     632          17 :                         file_handle.opened_path = opened_path = estrndup(Z_STRVAL_P(filename), Z_STRLEN_P(filename));
     633             :                 }
     634             : 
     635        2678 :                 zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path));
     636             : 
     637        2678 :                 if (opened_path) {
     638          17 :                         efree(opened_path);
     639             :                 }
     640             :         }
     641        2707 :         zend_destroy_file_handle(&file_handle TSRMLS_CC);
     642             : 
     643        2707 :         if (filename==&tmp) {
     644             :                 zval_dtor(&tmp);
     645             :         }
     646        2707 :         return retval;
     647             : }
     648             : 
     649        1183 : ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_DC)
     650             : {
     651             :         char *buf;
     652             :         size_t size, old_len;
     653             :         zend_string *new_compiled_filename;
     654             : 
     655             :         /* enforce ZEND_MMAP_AHEAD trailing NULLs for flex... */
     656        1183 :         old_len = Z_STRLEN_P(str);
     657        2366 :         Z_STR_P(str) = zend_string_realloc(Z_STR_P(str), old_len + ZEND_MMAP_AHEAD, 0);
     658        1183 :         Z_TYPE_INFO_P(str) = IS_STRING_EX;
     659        1183 :         memset(Z_STRVAL_P(str) + old_len, 0, ZEND_MMAP_AHEAD + 1);
     660             : 
     661        1183 :         SCNG(yy_in) = NULL;
     662        1183 :         SCNG(yy_start) = NULL;
     663             : 
     664        1183 :         buf = Z_STRVAL_P(str);
     665        1183 :         size = old_len;
     666             : 
     667        1183 :         if (CG(multibyte)) {
     668           0 :                 SCNG(script_org) = (unsigned char*)buf;
     669           0 :                 SCNG(script_org_size) = size;
     670           0 :                 SCNG(script_filtered) = NULL;
     671             : 
     672           0 :                 zend_multibyte_set_filter(zend_multibyte_get_internal_encoding(TSRMLS_C) TSRMLS_CC);
     673             : 
     674           0 :                 if (SCNG(input_filter)) {
     675           0 :                         if ((size_t)-1 == SCNG(input_filter)(&SCNG(script_filtered), &SCNG(script_filtered_size), SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) {
     676           0 :                                 zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected "
     677             :                                                 "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding)));
     678             :                         }
     679           0 :                         buf = (char*)SCNG(script_filtered);
     680           0 :                         size = SCNG(script_filtered_size);
     681             :                 }
     682             :         }
     683             : 
     684        1183 :         yy_scan_buffer(buf, size TSRMLS_CC);
     685             : 
     686        2366 :         new_compiled_filename = zend_string_init(filename, strlen(filename), 0);
     687        1183 :         zend_set_compiled_filename(new_compiled_filename TSRMLS_CC);
     688             :         zend_string_release(new_compiled_filename);
     689        1183 :         CG(zend_lineno) = 1;
     690        1183 :         CG(increment_lineno) = 0;
     691        1183 :         RESET_DOC_COMMENT();
     692        1183 :         return SUCCESS;
     693             : }
     694             : 
     695             : 
     696         275 : ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D)
     697             : {
     698         275 :         size_t offset = SCNG(yy_cursor) - SCNG(yy_start);
     699         275 :         if (SCNG(input_filter)) {
     700           1 :                 size_t original_offset = offset, length = 0;
     701             :                 do {
     702           7 :                         unsigned char *p = NULL;
     703           7 :                         if ((size_t)-1 == SCNG(input_filter)(&p, &length, SCNG(script_org), offset TSRMLS_CC)) {
     704           0 :                                 return (size_t)-1;
     705             :                         }
     706           7 :                         efree(p);
     707           7 :                         if (length > original_offset) {
     708           0 :                                 offset--;
     709           7 :                         } else if (length < original_offset) {
     710           6 :                                 offset++;
     711             :                         }
     712           7 :                 } while (original_offset != length);
     713             :         }
     714         275 :         return offset;
     715             : }
     716             : 
     717             : 
     718        1091 : zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
     719             : {
     720             :         zend_lex_state original_lex_state;
     721        1091 :         zend_op_array *op_array = NULL;
     722             :         zval tmp;
     723        1091 :         zend_bool original_in_compilation = CG(in_compilation);
     724             : 
     725        1091 :         if (Z_STRLEN_P(source_string)==0) {
     726           0 :                 return NULL;
     727             :         }
     728             : 
     729        1091 :         ZVAL_DUP(&tmp, source_string);
     730        1091 :         convert_to_string(&tmp);
     731        1091 :         source_string = &tmp;
     732             :         
     733        1091 :         CG(in_compilation) = 1;
     734        1091 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     735        1091 :         if (zend_prepare_string_for_scanning(source_string, filename TSRMLS_CC) == SUCCESS) {
     736        1091 :                 CG(ast) = NULL;
     737        1091 :                 CG(ast_arena) = zend_arena_create(1024 * 32);
     738        1091 :                 BEGIN(ST_IN_SCRIPTING);
     739             : 
     740        1091 :                 if (!zendparse(TSRMLS_C)) {
     741        1079 :                         zend_op_array *original_active_op_array = CG(active_op_array);
     742        1079 :                         op_array = emalloc(sizeof(zend_op_array));
     743        1079 :                         init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
     744        1079 :                         CG(active_op_array) = op_array;
     745             : 
     746        1079 :                         zend_stack_push(&CG(context_stack), (void *) &CG(context));
     747        1079 :                         zend_init_compiler_context(TSRMLS_C);
     748        1079 :                         zend_compile_top_stmt(CG(ast) TSRMLS_CC);
     749        1077 :                         zend_do_end_compilation(TSRMLS_C);
     750        1077 :                         zend_emit_final_return(NULL TSRMLS_CC);
     751        1077 :                         pass_two(op_array TSRMLS_CC);
     752        1077 :                         zend_release_labels(0 TSRMLS_CC);
     753             : 
     754        1077 :                         CG(active_op_array) = original_active_op_array;
     755             :                 }
     756             : 
     757        1089 :                 zend_ast_destroy(CG(ast));
     758        1089 :                 zend_arena_destroy(CG(ast_arena));
     759             :         }
     760             : 
     761        1089 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     762             :         zval_dtor(&tmp);
     763        1089 :         CG(in_compilation) = original_in_compilation;
     764        1089 :         return op_array;
     765             : }
     766             : 
     767             : 
     768             : BEGIN_EXTERN_C()
     769          20 : int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC)
     770             : {
     771             :         zend_lex_state original_lex_state;
     772             :         zend_file_handle file_handle;
     773             : 
     774          20 :         file_handle.type = ZEND_HANDLE_FILENAME;
     775          20 :         file_handle.filename = filename;
     776          20 :         file_handle.free_filename = 0;
     777          20 :         file_handle.opened_path = NULL;
     778          20 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     779          20 :         if (open_file_for_scanning(&file_handle TSRMLS_CC)==FAILURE) {
     780           2 :                 zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename TSRMLS_CC);
     781           2 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     782           2 :                 return FAILURE;
     783             :         }
     784          18 :         zend_highlight(syntax_highlighter_ini TSRMLS_CC);
     785          18 :         if (SCNG(script_filtered)) {
     786           0 :                 efree(SCNG(script_filtered));
     787           0 :                 SCNG(script_filtered) = NULL;
     788             :         }
     789          18 :         zend_destroy_file_handle(&file_handle TSRMLS_CC);
     790          18 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     791          18 :         return SUCCESS;
     792             : }
     793             : 
     794          14 : int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC)
     795             : {
     796             :         zend_lex_state original_lex_state;
     797          14 :         zval tmp = *str;
     798             : 
     799          14 :         str = &tmp;
     800             :         zval_copy_ctor(str);
     801          14 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     802          14 :         if (zend_prepare_string_for_scanning(str, str_name TSRMLS_CC)==FAILURE) {
     803           0 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     804           0 :                 return FAILURE;
     805             :         }
     806          14 :         BEGIN(INITIAL);
     807          14 :         zend_highlight(syntax_highlighter_ini TSRMLS_CC);
     808          14 :         if (SCNG(script_filtered)) {
     809           0 :                 efree(SCNG(script_filtered));
     810           0 :                 SCNG(script_filtered) = NULL;
     811             :         }
     812          14 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     813             :         zval_dtor(str);
     814          14 :         return SUCCESS;
     815             : }
     816             : 
     817          10 : ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter, const zend_encoding *old_encoding TSRMLS_DC)
     818             : {
     819             :         size_t length;
     820             :         unsigned char *new_yy_start;
     821             : 
     822             :         /* convert and set */
     823          10 :         if (!SCNG(input_filter)) {
     824           0 :                 if (SCNG(script_filtered)) {
     825           0 :                         efree(SCNG(script_filtered));
     826           0 :                         SCNG(script_filtered) = NULL;
     827             :                 }
     828           0 :                 SCNG(script_filtered_size) = 0;
     829           0 :                 length = SCNG(script_org_size);
     830           0 :                 new_yy_start = SCNG(script_org);
     831             :         } else {
     832          10 :                 if ((size_t)-1 == SCNG(input_filter)(&new_yy_start, &length, SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) {
     833           0 :                         zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected "
     834             :                                         "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding)));
     835             :                 }
     836          10 :                 if (SCNG(script_filtered)) {
     837           6 :                         efree(SCNG(script_filtered));
     838             :                 }
     839          10 :                 SCNG(script_filtered) = new_yy_start;
     840          10 :                 SCNG(script_filtered_size) = length;
     841             :         }
     842             : 
     843          10 :         SCNG(yy_cursor) = new_yy_start + (SCNG(yy_cursor) - SCNG(yy_start));
     844          10 :         SCNG(yy_marker) = new_yy_start + (SCNG(yy_marker) - SCNG(yy_start));
     845          10 :         SCNG(yy_text) = new_yy_start + (SCNG(yy_text) - SCNG(yy_start));
     846          10 :         SCNG(yy_limit) = new_yy_start + length;
     847             : 
     848          10 :         SCNG(yy_start) = new_yy_start;
     849          10 : }
     850             : 
     851             : 
     852             : // TODO: avoid reallocation ???
     853             : # define zend_copy_value(zendlval, yytext, yyleng) \
     854             :         if (SCNG(output_filter)) { \
     855             :                 size_t sz = 0; \
     856             :                 char *s = NULL; \
     857             :                 SCNG(output_filter)((unsigned char **)&s, &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \
     858             :                 ZVAL_STRINGL(zendlval, s, sz); \
     859             :                 efree(s); \
     860             :         } else { \
     861             :                 ZVAL_STRINGL(zendlval, yytext, yyleng); \
     862             :         }
     863             : 
     864      191289 : static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quote_type TSRMLS_DC)
     865             : {
     866             :         register char *s, *t;
     867             :         char *end;
     868             : 
     869      382578 :         ZVAL_STRINGL(zendlval, str, len);
     870             : 
     871             :         /* convert escape sequences */
     872      191289 :         s = t = Z_STRVAL_P(zendlval);
     873      191289 :         end = s+Z_STRLEN_P(zendlval);
     874     3737908 :         while (s<end) {
     875     3355334 :                 if (*s=='\\') {
     876       58217 :                         s++;
     877       58217 :                         if (s >= end) {
     878           4 :                                 *t++ = '\\';
     879           4 :                                 break;
     880             :                         }
     881             : 
     882       58213 :                         switch(*s) {
     883             :                                 case 'n':
     884       46675 :                                         *t++ = '\n';
     885       46675 :                                         Z_STRLEN_P(zendlval)--;
     886       46675 :                                         break;
     887             :                                 case 'r':
     888        3791 :                                         *t++ = '\r';
     889        3791 :                                         Z_STRLEN_P(zendlval)--;
     890        3791 :                                         break;
     891             :                                 case 't':
     892         822 :                                         *t++ = '\t';
     893         822 :                                         Z_STRLEN_P(zendlval)--;
     894         822 :                                         break;
     895             :                                 case 'f':
     896          72 :                                         *t++ = '\f';
     897          72 :                                         Z_STRLEN_P(zendlval)--;
     898          72 :                                         break;
     899             :                                 case 'v':
     900         106 :                                         *t++ = '\v';
     901         106 :                                         Z_STRLEN_P(zendlval)--;
     902         106 :                                         break;
     903             :                                 case 'e':
     904             : #ifdef PHP_WIN32
     905             :                                         *t++ = VK_ESCAPE;
     906             : #else
     907          15 :                                         *t++ = '\e';
     908             : #endif
     909          15 :                                         Z_STRLEN_P(zendlval)--;
     910          15 :                                         break;
     911             :                                 case '"':
     912             :                                 case '`':
     913        1130 :                                         if (*s != quote_type) {
     914          10 :                                                 *t++ = '\\';
     915          10 :                                                 *t++ = *s;
     916          10 :                                                 break;
     917             :                                         }
     918             :                                 case '\\':
     919             :                                 case '$':
     920        2198 :                                         *t++ = *s;
     921        2198 :                                         Z_STRLEN_P(zendlval)--;
     922        2198 :                                         break;
     923             :                                 case 'x':
     924             :                                 case 'X':
     925        5611 :                                         if (ZEND_IS_HEX(*(s+1))) {
     926        2795 :                                                 char hex_buf[3] = { 0, 0, 0 };
     927             : 
     928        2795 :                                                 Z_STRLEN_P(zendlval)--; /* for the 'x' */
     929             : 
     930        2795 :                                                 hex_buf[0] = *(++s);
     931        2795 :                                                 Z_STRLEN_P(zendlval)--;
     932        2795 :                                                 if (ZEND_IS_HEX(*(s+1))) {
     933        2767 :                                                         hex_buf[1] = *(++s);
     934        2767 :                                                         Z_STRLEN_P(zendlval)--;
     935             :                                                 }
     936        2795 :                                                 *t++ = (char) ZEND_STRTOL(hex_buf, NULL, 16);
     937             :                                         } else {
     938          21 :                                                 *t++ = '\\';
     939          21 :                                                 *t++ = *s;
     940             :                                         }
     941        2816 :                                         break;
     942             :                                 default:
     943             :                                         /* check for an octal */
     944        2736 :                                         if (ZEND_IS_OCT(*s)) {
     945        1028 :                                                 char octal_buf[4] = { 0, 0, 0, 0 };
     946             : 
     947        1028 :                                                 octal_buf[0] = *s;
     948        1028 :                                                 Z_STRLEN_P(zendlval)--;
     949        1028 :                                                 if (ZEND_IS_OCT(*(s+1))) {
     950         205 :                                                         octal_buf[1] = *(++s);
     951         205 :                                                         Z_STRLEN_P(zendlval)--;
     952         205 :                                                         if (ZEND_IS_OCT(*(s+1))) {
     953         181 :                                                                 octal_buf[2] = *(++s);
     954         181 :                                                                 Z_STRLEN_P(zendlval)--;
     955             :                                                         }
     956             :                                                 }
     957        1028 :                                                 *t++ = (char) ZEND_STRTOL(octal_buf, NULL, 8);
     958             :                                         } else {
     959         680 :                                                 *t++ = '\\';
     960         680 :                                                 *t++ = *s;
     961             :                                         }
     962             :                                         break;
     963             :                         }
     964             :                 } else {
     965     3297117 :                         *t++ = *s;
     966             :                 }
     967             : 
     968     3355330 :                 if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
     969        9614 :                         CG(zend_lineno)++;
     970             :                 }
     971     3355330 :                 s++;
     972             :         }
     973      191289 :         *t = 0;
     974      191289 :         if (SCNG(output_filter)) {
     975          11 :                 size_t sz = 0;
     976             :                 unsigned char *str;
     977             :                 // TODO: avoid realocation ???
     978          11 :                 s = Z_STRVAL_P(zendlval);
     979          11 :                 SCNG(output_filter)(&str, &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval) TSRMLS_CC);
     980          11 :                 zval_ptr_dtor(zendlval);
     981          22 :                 ZVAL_STRINGL(zendlval, (char *) str, sz);
     982          11 :                 efree(str);
     983             :         }
     984      191289 : }
     985             : 
     986             : 
     987     7059381 : int lex_scan(zval *zendlval TSRMLS_DC)
     988             : {
     989             : restart:
     990     7059381 :         SCNG(yy_text) = YYCURSOR;
     991             : 
     992             : /*!re2c
     993             : re2c:yyfill:check = 0;
     994             : LNUM    [0-9]+
     995             : DNUM    ([0-9]*"."[0-9]+)|([0-9]+"."[0-9]*)
     996             : EXPONENT_DNUM   (({LNUM}|{DNUM})[eE][+-]?{LNUM})
     997             : HNUM    "0x"[0-9a-fA-F]+
     998             : BNUM    "0b"[01]+
     999             : LABEL   [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
    1000             : WHITESPACE [ \n\r\t]+
    1001             : TABS_AND_SPACES [ \t]*
    1002             : TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@]
    1003             : ANY_CHAR [^]
    1004             : NEWLINE ("\r"|"\n"|"\r\n")
    1005             : 
    1006             : /* compute yyleng before each rule */
    1007             : <!*> := yyleng = YYCURSOR - SCNG(yy_text);
    1008             : 
    1009             : <ST_IN_SCRIPTING>"exit" {
    1010        1581 :         return T_EXIT;
    1011             : }
    1012             : 
    1013             : <ST_IN_SCRIPTING>"die" {
    1014       12769 :         return T_EXIT;
    1015             : }
    1016             : 
    1017             : <ST_IN_SCRIPTING>"function" {
    1018       35266 :         return T_FUNCTION;
    1019             : }
    1020             : 
    1021             : <ST_IN_SCRIPTING>"const" {
    1022         417 :         return T_CONST;
    1023             : }
    1024             : 
    1025             : <ST_IN_SCRIPTING>"return" {
    1026       43580 :         return T_RETURN;
    1027             : }
    1028             : 
    1029             : <ST_IN_SCRIPTING>"yield" {
    1030         121 :         return T_YIELD;
    1031             : }
    1032             : 
    1033             : <ST_IN_SCRIPTING>"try" {
    1034        1990 :         return T_TRY;
    1035             : }
    1036             : 
    1037             : <ST_IN_SCRIPTING>"catch" {
    1038        1956 :         return T_CATCH;
    1039             : }
    1040             : 
    1041             : <ST_IN_SCRIPTING>"finally" {
    1042          70 :         return T_FINALLY;
    1043             : }
    1044             : 
    1045             : <ST_IN_SCRIPTING>"throw" {
    1046         324 :         return T_THROW;
    1047             : }
    1048             : 
    1049             : <ST_IN_SCRIPTING>"if" {
    1050       68268 :         return T_IF;
    1051             : }
    1052             : 
    1053             : <ST_IN_SCRIPTING>"elseif" {
    1054        1708 :         return T_ELSEIF;
    1055             : }
    1056             : 
    1057             : <ST_IN_SCRIPTING>"endif" {
    1058           5 :         return T_ENDIF;
    1059             : }
    1060             : 
    1061             : <ST_IN_SCRIPTING>"else" {
    1062       16950 :         return T_ELSE;
    1063             : }
    1064             : 
    1065             : <ST_IN_SCRIPTING>"while" {
    1066        2161 :         return T_WHILE;
    1067             : }
    1068             : 
    1069             : <ST_IN_SCRIPTING>"endwhile" {
    1070           1 :         return T_ENDWHILE;
    1071             : }
    1072             : 
    1073             : <ST_IN_SCRIPTING>"do" {
    1074         290 :         return T_DO;
    1075             : }
    1076             : 
    1077             : <ST_IN_SCRIPTING>"for" {
    1078        1871 :         return T_FOR;
    1079             : }
    1080             : 
    1081             : <ST_IN_SCRIPTING>"endfor" {
    1082           3 :         return T_ENDFOR;
    1083             : }
    1084             : 
    1085             : <ST_IN_SCRIPTING>"foreach" {
    1086        9734 :         return T_FOREACH;
    1087             : }
    1088             : 
    1089             : <ST_IN_SCRIPTING>"endforeach" {
    1090           0 :         return T_ENDFOREACH;
    1091             : }
    1092             : 
    1093             : <ST_IN_SCRIPTING>"declare" {
    1094          26 :         return T_DECLARE;
    1095             : }
    1096             : 
    1097             : <ST_IN_SCRIPTING>"enddeclare" {
    1098           0 :         return T_ENDDECLARE;
    1099             : }
    1100             : 
    1101             : <ST_IN_SCRIPTING>"instanceof" {
    1102          66 :         return T_INSTANCEOF;
    1103             : }
    1104             : 
    1105             : <ST_IN_SCRIPTING>"as" {
    1106        9841 :         return T_AS;
    1107             : }
    1108             : 
    1109             : <ST_IN_SCRIPTING>"switch" {
    1110         451 :         return T_SWITCH;
    1111             : }
    1112             : 
    1113             : <ST_IN_SCRIPTING>"endswitch" {
    1114           1 :         return T_ENDSWITCH;
    1115             : }
    1116             : 
    1117             : <ST_IN_SCRIPTING>"case" {
    1118        1589 :         return T_CASE;
    1119             : }
    1120             : 
    1121             : <ST_IN_SCRIPTING>"default" {
    1122         269 :         return T_DEFAULT;
    1123             : }
    1124             : 
    1125             : <ST_IN_SCRIPTING>"break" {
    1126        1824 :         return T_BREAK;
    1127             : }
    1128             : 
    1129             : <ST_IN_SCRIPTING>"continue" {
    1130         270 :         return T_CONTINUE;
    1131             : }
    1132             : 
    1133             : <ST_IN_SCRIPTING>"goto" {
    1134          37 :         return T_GOTO;
    1135             : }
    1136             : 
    1137             : <ST_IN_SCRIPTING>"echo" {
    1138       29082 :         return T_ECHO;
    1139             : }
    1140             : 
    1141             : <ST_IN_SCRIPTING>"print" {
    1142        3389 :         return T_PRINT;
    1143             : }
    1144             : 
    1145             : <ST_IN_SCRIPTING>"class" {
    1146        6934 :         return T_CLASS;
    1147             : }
    1148             : 
    1149             : <ST_IN_SCRIPTING>"interface" {
    1150         188 :         return T_INTERFACE;
    1151             : }
    1152             : 
    1153             : <ST_IN_SCRIPTING>"trait" {
    1154         209 :         return T_TRAIT;
    1155             : }
    1156             : 
    1157             : <ST_IN_SCRIPTING>"extends" {
    1158        2361 :         return T_EXTENDS;
    1159             : }
    1160             : 
    1161             : <ST_IN_SCRIPTING>"implements" {
    1162         295 :         return T_IMPLEMENTS;
    1163             : }
    1164             : 
    1165             : <ST_IN_SCRIPTING>"->" {
    1166       44657 :         yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
    1167       44657 :         return T_OBJECT_OPERATOR;
    1168             : }
    1169             : 
    1170             : <ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
    1171     2092820 :         HANDLE_NEWLINES(yytext, yyleng);
    1172     2092820 :         return T_WHITESPACE;
    1173             : }
    1174             : 
    1175             : <ST_LOOKING_FOR_PROPERTY>"->" {
    1176          82 :         return T_OBJECT_OPERATOR;
    1177             : }
    1178             : 
    1179             : <ST_LOOKING_FOR_PROPERTY>{LABEL} {
    1180       44586 :         yy_pop_state(TSRMLS_C);
    1181       89172 :         zend_copy_value(zendlval, yytext, yyleng);
    1182       44586 :         return T_STRING;
    1183             : }
    1184             : 
    1185             : <ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} {
    1186         152 :         yyless(0);
    1187         152 :         yy_pop_state(TSRMLS_C);
    1188         152 :         goto restart;
    1189             : }
    1190             : 
    1191             : <ST_IN_SCRIPTING>"::" {
    1192       19952 :         return T_PAAMAYIM_NEKUDOTAYIM;
    1193             : }
    1194             : 
    1195             : <ST_IN_SCRIPTING>"\\" {
    1196         607 :         return T_NS_SEPARATOR;
    1197             : }
    1198             : 
    1199             : <ST_IN_SCRIPTING>"..." {
    1200         102 :         return T_ELLIPSIS;
    1201             : }
    1202             : 
    1203             : <ST_IN_SCRIPTING>"??" {
    1204          16 :         return T_COALESCE;
    1205             : }
    1206             : 
    1207             : <ST_IN_SCRIPTING>"new" {
    1208       14182 :         return T_NEW;
    1209             : }
    1210             : 
    1211             : <ST_IN_SCRIPTING>"clone" {
    1212         113 :         return T_CLONE;
    1213             : }
    1214             : 
    1215             : <ST_IN_SCRIPTING>"var" {
    1216         115 :         return T_VAR;
    1217             : }
    1218             : 
    1219             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" {
    1220        4935 :         return T_INT_CAST;
    1221             : }
    1222             : 
    1223             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("real"|"double"|"float"){TABS_AND_SPACES}")" {
    1224          50 :         return T_DOUBLE_CAST;
    1225             : }
    1226             : 
    1227             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("string"|"binary"){TABS_AND_SPACES}")" {
    1228        1308 :         return T_STRING_CAST;
    1229             : }
    1230             : 
    1231             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"array"{TABS_AND_SPACES}")" {
    1232          16 :         return T_ARRAY_CAST;
    1233             : }
    1234             : 
    1235             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"object"{TABS_AND_SPACES}")" {
    1236         161 :         return T_OBJECT_CAST;
    1237             : }
    1238             : 
    1239             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("bool"|"boolean"){TABS_AND_SPACES}")" {
    1240          70 :         return T_BOOL_CAST;
    1241             : }
    1242             : 
    1243             : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("unset"){TABS_AND_SPACES}")" {
    1244           1 :         return T_UNSET_CAST;
    1245             : }
    1246             : 
    1247             : <ST_IN_SCRIPTING>"eval" {
    1248        1895 :         return T_EVAL;
    1249             : }
    1250             : 
    1251             : <ST_IN_SCRIPTING>"include" {
    1252        1862 :         return T_INCLUDE;
    1253             : }
    1254             : 
    1255             : <ST_IN_SCRIPTING>"include_once" {
    1256         495 :         return T_INCLUDE_ONCE;
    1257             : }
    1258             : 
    1259             : <ST_IN_SCRIPTING>"require" {
    1260         814 :         return T_REQUIRE;
    1261             : }
    1262             : 
    1263             : <ST_IN_SCRIPTING>"require_once" {
    1264        5648 :         return T_REQUIRE_ONCE;
    1265             : }
    1266             : 
    1267             : <ST_IN_SCRIPTING>"namespace" {
    1268         259 :         return T_NAMESPACE;
    1269             : }
    1270             : 
    1271             : <ST_IN_SCRIPTING>"use" {
    1272         417 :         return T_USE;
    1273             : }
    1274             : 
    1275             : <ST_IN_SCRIPTING>"insteadof" {
    1276          17 :         return T_INSTEADOF;
    1277             : }
    1278             : 
    1279             : <ST_IN_SCRIPTING>"global" {
    1280        4002 :         return T_GLOBAL;
    1281             : }
    1282             : 
    1283             : <ST_IN_SCRIPTING>"isset" {
    1284        5477 :         return T_ISSET;
    1285             : }
    1286             : 
    1287             : <ST_IN_SCRIPTING>"empty" {
    1288        7733 :         return T_EMPTY;
    1289             : }
    1290             : 
    1291             : <ST_IN_SCRIPTING>"__halt_compiler" {
    1292         282 :         return T_HALT_COMPILER;
    1293             : }
    1294             : 
    1295             : <ST_IN_SCRIPTING>"static" {
    1296        8841 :         return T_STATIC;
    1297             : }
    1298             : 
    1299             : <ST_IN_SCRIPTING>"abstract" {
    1300         169 :         return T_ABSTRACT;
    1301             : }
    1302             : 
    1303             : <ST_IN_SCRIPTING>"final" {
    1304          44 :         return T_FINAL;
    1305             : }
    1306             : 
    1307             : <ST_IN_SCRIPTING>"private" {
    1308        1100 :         return T_PRIVATE;
    1309             : }
    1310             : 
    1311             : <ST_IN_SCRIPTING>"protected" {
    1312         574 :         return T_PROTECTED;
    1313             : }
    1314             : 
    1315             : <ST_IN_SCRIPTING>"public" {
    1316        4528 :         return T_PUBLIC;
    1317             : }
    1318             : 
    1319             : <ST_IN_SCRIPTING>"unset" {
    1320        1467 :         return T_UNSET;
    1321             : }
    1322             : 
    1323             : <ST_IN_SCRIPTING>"=>" {
    1324       31598 :         return T_DOUBLE_ARROW;
    1325             : }
    1326             : 
    1327             : <ST_IN_SCRIPTING>"list" {
    1328         175 :         return T_LIST;
    1329             : }
    1330             : 
    1331             : <ST_IN_SCRIPTING>"array" {
    1332       25049 :         return T_ARRAY;
    1333             : }
    1334             : 
    1335             : <ST_IN_SCRIPTING>"callable" {
    1336           8 :  return T_CALLABLE;
    1337             : }
    1338             : 
    1339             : <ST_IN_SCRIPTING>"++" {
    1340        5877 :         return T_INC;
    1341             : }
    1342             : 
    1343             : <ST_IN_SCRIPTING>"--" {
    1344         113 :         return T_DEC;
    1345             : }
    1346             : 
    1347             : <ST_IN_SCRIPTING>"===" {
    1348        5405 :         return T_IS_IDENTICAL;
    1349             : }
    1350             : 
    1351             : <ST_IN_SCRIPTING>"!==" {
    1352        6675 :         return T_IS_NOT_IDENTICAL;
    1353             : }
    1354             : 
    1355             : <ST_IN_SCRIPTING>"==" {
    1356       15919 :         return T_IS_EQUAL;
    1357             : }
    1358             : 
    1359             : <ST_IN_SCRIPTING>"!="|"<>" {
    1360        2683 :         return T_IS_NOT_EQUAL;
    1361             : }
    1362             : 
    1363             : <ST_IN_SCRIPTING>"<=" {
    1364        1561 :         return T_IS_SMALLER_OR_EQUAL;
    1365             : }
    1366             : 
    1367             : <ST_IN_SCRIPTING>">=" {
    1368         317 :         return T_IS_GREATER_OR_EQUAL;
    1369             : }
    1370             : 
    1371             : <ST_IN_SCRIPTING>"+=" {
    1372         680 :         return T_PLUS_EQUAL;
    1373             : }
    1374             : 
    1375             : <ST_IN_SCRIPTING>"-=" {
    1376         140 :         return T_MINUS_EQUAL;
    1377             : }
    1378             : 
    1379             : <ST_IN_SCRIPTING>"*=" {
    1380          17 :         return T_MUL_EQUAL;
    1381             : }
    1382             : 
    1383             : <ST_IN_SCRIPTING>"*\*" {
    1384          11 :         return T_POW;
    1385             : }
    1386             : 
    1387             : <ST_IN_SCRIPTING>"*\*=" {
    1388           3 :         return T_POW_EQUAL;
    1389             : }
    1390             : 
    1391             : <ST_IN_SCRIPTING>"/=" {
    1392           6 :         return T_DIV_EQUAL;
    1393             : }
    1394             : 
    1395             : <ST_IN_SCRIPTING>".=" {
    1396        2804 :         return T_CONCAT_EQUAL;
    1397             : }
    1398             : 
    1399             : <ST_IN_SCRIPTING>"%=" {
    1400           1 :         return T_MOD_EQUAL;
    1401             : }
    1402             : 
    1403             : <ST_IN_SCRIPTING>"<<=" {
    1404           5 :         return T_SL_EQUAL;
    1405             : }
    1406             : 
    1407             : <ST_IN_SCRIPTING>">>=" {
    1408           5 :         return T_SR_EQUAL;
    1409             : }
    1410             : 
    1411             : <ST_IN_SCRIPTING>"&=" {
    1412           3 :         return T_AND_EQUAL;
    1413             : }
    1414             : 
    1415             : <ST_IN_SCRIPTING>"|=" {
    1416          95 :         return T_OR_EQUAL;
    1417             : }
    1418             : 
    1419             : <ST_IN_SCRIPTING>"^=" {
    1420           2 :         return T_XOR_EQUAL;
    1421             : }
    1422             : 
    1423             : <ST_IN_SCRIPTING>"||" {
    1424        4264 :         return T_BOOLEAN_OR;
    1425             : }
    1426             : 
    1427             : <ST_IN_SCRIPTING>"&&" {
    1428        6543 :         return T_BOOLEAN_AND;
    1429             : }
    1430             : 
    1431             : <ST_IN_SCRIPTING>"OR" {
    1432         858 :         return T_LOGICAL_OR;
    1433             : }
    1434             : 
    1435             : <ST_IN_SCRIPTING>"AND" {
    1436          15 :         return T_LOGICAL_AND;
    1437             : }
    1438             : 
    1439             : <ST_IN_SCRIPTING>"XOR" {
    1440           3 :         return T_LOGICAL_XOR;
    1441             : }
    1442             : 
    1443             : <ST_IN_SCRIPTING>"<<" {
    1444         138 :         return T_SL;
    1445             : }
    1446             : 
    1447             : <ST_IN_SCRIPTING>">>" {
    1448          70 :         return T_SR;
    1449             : }
    1450             : 
    1451             : <ST_IN_SCRIPTING>{TOKENS} {
    1452     2324468 :         return yytext[0];
    1453             : }
    1454             : 
    1455             : 
    1456             : <ST_IN_SCRIPTING>"{" {
    1457      115957 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1458      115957 :         return '{';
    1459             : }
    1460             : 
    1461             : 
    1462             : <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"${" {
    1463         211 :         yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
    1464         211 :         return T_DOLLAR_OPEN_CURLY_BRACES;
    1465             : }
    1466             : 
    1467             : 
    1468             : <ST_IN_SCRIPTING>"}" {
    1469      117358 :         RESET_DOC_COMMENT();
    1470      117351 :         if (!zend_stack_is_empty(&SCNG(state_stack))) {
    1471      117350 :                 yy_pop_state(TSRMLS_C);
    1472             :         }
    1473      117351 :         return '}';
    1474             : }
    1475             : 
    1476             : 
    1477             : <ST_LOOKING_FOR_VARNAME>{LABEL}[[}] {
    1478         210 :         yyless(yyleng - 1);
    1479         420 :         zend_copy_value(zendlval, yytext, yyleng);
    1480         210 :         yy_pop_state(TSRMLS_C);
    1481         210 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1482         210 :         return T_STRING_VARNAME;
    1483             : }
    1484             : 
    1485             : 
    1486             : <ST_LOOKING_FOR_VARNAME>{ANY_CHAR} {
    1487           1 :         yyless(0);
    1488           1 :         yy_pop_state(TSRMLS_C);
    1489           1 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1490           1 :         goto restart;
    1491             : }
    1492             : 
    1493             : <ST_IN_SCRIPTING>{BNUM} {
    1494          73 :         char *bin = yytext + 2; /* Skip "0b" */
    1495          73 :         int len = yyleng - 2;
    1496             : 
    1497             :         /* Skip any leading 0s */
    1498         148 :         while (*bin == '0') {
    1499           2 :                 ++bin;
    1500           2 :                 --len;
    1501             :         }
    1502             : 
    1503          73 :         if (len < SIZEOF_ZEND_LONG * 8) {
    1504          68 :                 if (len == 0) {
    1505           1 :                         ZVAL_LONG(zendlval, 0);
    1506             :                 } else {
    1507          67 :                         ZVAL_LONG(zendlval, ZEND_STRTOL(bin, NULL, 2));
    1508             :                 }
    1509          68 :                 return T_LNUMBER;
    1510             :         } else {
    1511           5 :                 ZVAL_DOUBLE(zendlval, zend_bin_strtod(bin, NULL));
    1512           5 :                 return T_DNUMBER;
    1513             :         }
    1514             : }
    1515             : 
    1516             : <ST_IN_SCRIPTING>{LNUM} {
    1517      157684 :         if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
    1518      157505 :                 ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, NULL, 0));
    1519             :         } else {
    1520         179 :                 errno = 0;
    1521         179 :                 ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, NULL, 0));
    1522         179 :                 if (errno == ERANGE) { /* Overflow */
    1523          45 :                         if (yytext[0] == '0') { /* octal overflow */
    1524           1 :                                 ZVAL_DOUBLE(zendlval, zend_oct_strtod(yytext, NULL));
    1525             :                         } else {
    1526          44 :                                 ZVAL_DOUBLE(zendlval, zend_strtod(yytext, NULL));
    1527             :                         }
    1528          45 :                         return T_DNUMBER;
    1529             :                 }
    1530             :         }
    1531      157639 :         return T_LNUMBER;
    1532             : }
    1533             : 
    1534             : <ST_IN_SCRIPTING>{HNUM} {
    1535        3223 :         char *hex = yytext + 2; /* Skip "0x" */
    1536        3223 :         int len = yyleng - 2;
    1537             : 
    1538             :         /* Skip any leading 0s */
    1539        8030 :         while (*hex == '0') {
    1540        1584 :                 hex++;
    1541        1584 :                 len--;
    1542             :         }
    1543             : 
    1544        3223 :         if (len < SIZEOF_ZEND_LONG * 2 || (len == SIZEOF_ZEND_LONG * 2 && *hex <= '7')) {
    1545        3215 :                 if (len == 0) {
    1546          59 :                         ZVAL_LONG(zendlval, 0);
    1547             :                 } else {
    1548        3156 :                         ZVAL_LONG(zendlval, ZEND_STRTOL(hex, NULL, 16));
    1549             :                 }
    1550        3215 :                 return T_LNUMBER;
    1551             :         } else {
    1552           8 :                 ZVAL_DOUBLE(zendlval, zend_hex_strtod(hex, NULL));
    1553           8 :                 return T_DNUMBER;
    1554             :         }
    1555             : }
    1556             : 
    1557             : <ST_VAR_OFFSET>[0]|([1-9][0-9]*) { /* Offset could be treated as a long */
    1558         450 :         if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
    1559         225 :                 ZVAL_LONG(zendlval, ZEND_STRTOL(yytext, NULL, 10));
    1560             :         } else {
    1561           0 :                 ZVAL_STRINGL(zendlval, yytext, yyleng);
    1562             :         }
    1563         225 :         return T_NUM_STRING;
    1564             : }
    1565             : 
    1566             : <ST_VAR_OFFSET>{LNUM}|{HNUM}|{BNUM} { /* Offset must be treated as a string */
    1567           0 :         ZVAL_STRINGL(zendlval, yytext, yyleng);
    1568           0 :         return T_NUM_STRING;
    1569             : }
    1570             : 
    1571             : <ST_IN_SCRIPTING>{DNUM}|{EXPONENT_DNUM} {
    1572        6794 :         ZVAL_DOUBLE(zendlval, zend_strtod(yytext, NULL));
    1573        6794 :         return T_DNUMBER;
    1574             : }
    1575             : 
    1576             : <ST_IN_SCRIPTING>"__CLASS__" {
    1577          84 :         return T_CLASS_C;
    1578             : }
    1579             : 
    1580             : <ST_IN_SCRIPTING>"__TRAIT__" {
    1581           6 :         return T_TRAIT_C;
    1582             : }
    1583             : 
    1584             : <ST_IN_SCRIPTING>"__FUNCTION__" {
    1585         106 :         return T_FUNC_C;
    1586             : }
    1587             : 
    1588             : <ST_IN_SCRIPTING>"__METHOD__" {
    1589         753 :         return T_METHOD_C;
    1590             : }
    1591             : 
    1592             : <ST_IN_SCRIPTING>"__LINE__" {
    1593          13 :         return T_LINE;
    1594             : }
    1595             : 
    1596             : <ST_IN_SCRIPTING>"__FILE__" {
    1597        7184 :         return T_FILE;
    1598             : }
    1599             : 
    1600             : <ST_IN_SCRIPTING>"__DIR__" {
    1601         440 :         return T_DIR;
    1602             : }
    1603             : 
    1604             : <ST_IN_SCRIPTING>"__NAMESPACE__" {
    1605          36 :         return T_NS_C;
    1606             : }
    1607             : 
    1608             : 
    1609             : <INITIAL>"<?=" {
    1610           4 :         BEGIN(ST_IN_SCRIPTING);
    1611           4 :         return T_OPEN_TAG_WITH_ECHO;
    1612             : }
    1613             : 
    1614             : 
    1615             : <INITIAL>"<?php"([ \t]|{NEWLINE}) {
    1616       28939 :         HANDLE_NEWLINE(yytext[yyleng-1]);
    1617       28939 :         BEGIN(ST_IN_SCRIPTING);
    1618       28939 :         return T_OPEN_TAG;
    1619             : }
    1620             : 
    1621             : 
    1622             : <INITIAL>"<?" {
    1623           4 :         if (CG(short_tags)) {
    1624           3 :                 BEGIN(ST_IN_SCRIPTING);
    1625           3 :                 return T_OPEN_TAG;
    1626             :         } else {
    1627           1 :                 goto inline_char_handler;
    1628             :         }
    1629             : }
    1630             : 
    1631             : <INITIAL>{ANY_CHAR} {
    1632       29906 :         if (YYCURSOR > YYLIMIT) {
    1633       26371 :                 return 0;
    1634             :         }
    1635             : 
    1636             : inline_char_handler:
    1637             : 
    1638             :         while (1) {
    1639        3650 :                 YYCTYPE *ptr = memchr(YYCURSOR, '<', YYLIMIT - YYCURSOR);
    1640             : 
    1641        3650 :                 YYCURSOR = ptr ? ptr + 1 : YYLIMIT;
    1642             : 
    1643        3650 :                 if (YYCURSOR >= YYLIMIT) {
    1644        3322 :                         break;
    1645             :                 }
    1646             : 
    1647         328 :                 if (*YYCURSOR == '?') {
    1648         215 :                         if (CG(short_tags) || !strncasecmp((char*)YYCURSOR + 1, "php", 3) || (*(YYCURSOR + 1) == '=')) { /* Assume [ \t\n\r] follows "php" */
    1649             : 
    1650         214 :                                 YYCURSOR--;
    1651         214 :                                 break;
    1652             :                         }
    1653             :                 }
    1654         114 :         }
    1655             : 
    1656        3536 :         yyleng = YYCURSOR - SCNG(yy_text);
    1657             : 
    1658        3536 :         if (SCNG(output_filter)) {
    1659             :                 int readsize;
    1660           1 :                 char *s = NULL;
    1661           1 :                 size_t sz = 0;
    1662             :                 // TODO: avoid reallocation ???
    1663           1 :                 readsize = SCNG(output_filter)((unsigned char **)&s, &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC);
    1664           2 :                 ZVAL_STRINGL(zendlval, s, sz);
    1665           1 :                 efree(s);
    1666           1 :                 if (readsize < yyleng) {
    1667           0 :                         yyless(readsize);
    1668             :                 }
    1669             :         } else {
    1670        7070 :           ZVAL_STRINGL(zendlval, yytext, yyleng);
    1671             :         }
    1672        3536 :         HANDLE_NEWLINES(yytext, yyleng);
    1673        3536 :         return T_INLINE_HTML;
    1674             : }
    1675             : 
    1676             : 
    1677             : /* Make sure a label character follows "->", otherwise there is no property
    1678             :  * and "->" will be taken literally
    1679             :  */
    1680             : <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"->"[a-zA-Z_\x7f-\xff] {
    1681          82 :         yyless(yyleng - 3);
    1682          82 :         yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
    1683         164 :         zend_copy_value(zendlval, (yytext+1), (yyleng-1));
    1684          82 :         return T_VARIABLE;
    1685             : }
    1686             : 
    1687             : /* A [ always designates a variable offset, regardless of what follows
    1688             :  */
    1689             : <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"[" {
    1690         819 :         yyless(yyleng - 1);
    1691         819 :         yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
    1692        1638 :         zend_copy_value(zendlval, (yytext+1), (yyleng-1));
    1693         819 :         return T_VARIABLE;
    1694             : }
    1695             : 
    1696             : <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} {
    1697     1401622 :         zend_copy_value(zendlval, (yytext+1), (yyleng-1));
    1698      700811 :         return T_VARIABLE;
    1699             : }
    1700             : 
    1701             : <ST_VAR_OFFSET>"]" {
    1702         817 :         yy_pop_state(TSRMLS_C);
    1703         817 :         return ']';
    1704             : }
    1705             : 
    1706             : <ST_VAR_OFFSET>{TOKENS}|[{}"`] {
    1707             :         /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
    1708         819 :         return yytext[0];
    1709             : }
    1710             : 
    1711             : <ST_VAR_OFFSET>[ \n\r\t\\'#] {
    1712             :         /* Invalid rule to return a more explicit parse error with proper line number */
    1713           2 :         yyless(0);
    1714           2 :         yy_pop_state(TSRMLS_C);
    1715           2 :         ZVAL_NULL(zendlval);
    1716           2 :         return T_ENCAPSED_AND_WHITESPACE;
    1717             : }
    1718             : 
    1719             : <ST_IN_SCRIPTING,ST_VAR_OFFSET>{LABEL} {
    1720      863316 :         zend_copy_value(zendlval, yytext, yyleng);
    1721      431658 :         return T_STRING;
    1722             : }
    1723             : 
    1724             : 
    1725             : <ST_IN_SCRIPTING>"#"|"//" {
    1726     1376955 :         while (YYCURSOR < YYLIMIT) {
    1727     1334443 :                 switch (*YYCURSOR++) {
    1728             :                         case '\r':
    1729         124 :                                 if (*YYCURSOR == '\n') {
    1730         124 :                                         YYCURSOR++;
    1731             :                                 }
    1732             :                                 /* fall through */
    1733             :                         case '\n':
    1734       42500 :                                 CG(zend_lineno)++;
    1735       42500 :                                 break;
    1736             :                         case '?':
    1737         561 :                                 if (*YYCURSOR == '>') {
    1738           2 :                                         YYCURSOR--;
    1739           2 :                                         break;
    1740             :                                 }
    1741             :                                 /* fall through */
    1742             :                         default:
    1743     1291941 :                                 continue;
    1744             :                 }
    1745             : 
    1746       42502 :                 break;
    1747             :         }
    1748             : 
    1749       42507 :         yyleng = YYCURSOR - SCNG(yy_text);
    1750             : 
    1751       42507 :         return T_COMMENT;
    1752             : }
    1753             : 
    1754             : <ST_IN_SCRIPTING>"/*"|"/**"{WHITESPACE} {
    1755             :         int doc_com;
    1756             : 
    1757       24543 :         if (yyleng > 2) {
    1758        2200 :                 doc_com = 1;
    1759        2249 :                 RESET_DOC_COMMENT();
    1760             :         } else {
    1761       22343 :                 doc_com = 0;
    1762             :         }
    1763             : 
    1764     3690203 :         while (YYCURSOR < YYLIMIT) {
    1765     3665659 :                 if (*YYCURSOR++ == '*' && *YYCURSOR == '/') {
    1766       24542 :                         break;
    1767             :                 }
    1768             :         }
    1769             : 
    1770       24543 :         if (YYCURSOR < YYLIMIT) {
    1771       24542 :                 YYCURSOR++;
    1772             :         } else {
    1773           1 :                 zend_error(E_COMPILE_WARNING, "Unterminated comment starting line %d", CG(zend_lineno));
    1774             :         }
    1775             : 
    1776       24543 :         yyleng = YYCURSOR - SCNG(yy_text);
    1777       24543 :         HANDLE_NEWLINES(yytext, yyleng);
    1778             : 
    1779       24543 :         if (doc_com) {
    1780        4400 :                 CG(doc_comment) = zend_string_init(yytext, yyleng, 0);
    1781        2200 :                 return T_DOC_COMMENT;
    1782             :         }
    1783             : 
    1784       22343 :         return T_COMMENT;
    1785             : }
    1786             : 
    1787             : <ST_IN_SCRIPTING>"?>"{NEWLINE}? {
    1788       26808 :         BEGIN(INITIAL);
    1789       26808 :         return T_CLOSE_TAG;  /* implicit ';' at php-end tag */
    1790             : }
    1791             : 
    1792             : 
    1793             : <ST_IN_SCRIPTING>b?['] {
    1794             :         register char *s, *t;
    1795             :         char *end;
    1796      176992 :         int bprefix = (yytext[0] != '\'') ? 1 : 0;
    1797             : 
    1798             :         while (1) {
    1799     2062686 :                 if (YYCURSOR < YYLIMIT) {
    1800     2062686 :                         if (*YYCURSOR == '\'') {
    1801      176992 :                                 YYCURSOR++;
    1802      176992 :                                 yyleng = YYCURSOR - SCNG(yy_text);
    1803             : 
    1804      176992 :                                 break;
    1805     1885694 :                         } else if (*YYCURSOR++ == '\\' && YYCURSOR < YYLIMIT) {
    1806       13053 :                                 YYCURSOR++;
    1807             :                         }
    1808             :                 } else {
    1809           0 :                         yyleng = YYLIMIT - SCNG(yy_text);
    1810             : 
    1811             :                         /* Unclosed single quotes; treat similar to double quotes, but without a separate token
    1812             :                          * for ' (unrecognized by parser), instead of old flex fallback to "Unexpected character..."
    1813             :                          * rule, which continued in ST_IN_SCRIPTING state after the quote */
    1814           0 :                         ZVAL_NULL(zendlval);
    1815           0 :                         return T_ENCAPSED_AND_WHITESPACE;
    1816             :                 }
    1817     1885694 :         }
    1818             : 
    1819      353984 :         ZVAL_STRINGL(zendlval, yytext+bprefix+1, yyleng-bprefix-2);
    1820             : 
    1821             :         /* convert escape sequences */
    1822      176992 :         s = t = Z_STRVAL_P(zendlval);
    1823      176992 :         end = s+Z_STRLEN_P(zendlval);
    1824     2239678 :         while (s<end) {
    1825     1885694 :                 if (*s=='\\') {
    1826       13053 :                         s++;
    1827             : 
    1828       13053 :                         switch(*s) {
    1829             :                                 case '\\':
    1830             :                                 case '\'':
    1831        1879 :                                         *t++ = *s;
    1832        1879 :                                         Z_STRLEN_P(zendlval)--;
    1833        1879 :                                         break;
    1834             :                                 default:
    1835       11174 :                                         *t++ = '\\';
    1836       11174 :                                         *t++ = *s;
    1837             :                                         break;
    1838             :                         }
    1839             :                 } else {
    1840     1872641 :                         *t++ = *s;
    1841             :                 }
    1842             : 
    1843     1885694 :                 if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
    1844        1265 :                         CG(zend_lineno)++;
    1845             :                 }
    1846     1885694 :                 s++;
    1847             :         }
    1848      176992 :         *t = 0;
    1849             : 
    1850      176992 :         if (SCNG(output_filter)) {
    1851           0 :                 size_t sz = 0;
    1852           0 :                 char *str = NULL;
    1853           0 :                 s = Z_STRVAL_P(zendlval);
    1854             :                 // TODO: avoid reallocation ???
    1855           0 :                 SCNG(output_filter)((unsigned char **)&str, &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval) TSRMLS_CC);
    1856           0 :                 ZVAL_STRINGL(zendlval, str, sz);
    1857           0 :                 efree(s);
    1858             :         }
    1859      176992 :         return T_CONSTANT_ENCAPSED_STRING;
    1860             : }
    1861             : 
    1862             : 
    1863             : <ST_IN_SCRIPTING>b?["] {
    1864      179694 :         int bprefix = (yytext[0] != '"') ? 1 : 0;
    1865             : 
    1866     3321461 :         while (YYCURSOR < YYLIMIT) {
    1867     3141765 :                 switch (*YYCURSOR++) {
    1868             :                         case '"':
    1869      167553 :                                 yyleng = YYCURSOR - SCNG(yy_text);
    1870      167553 :                                 zend_scan_escape_string(zendlval, yytext+bprefix+1, yyleng-bprefix-2, '"' TSRMLS_CC);
    1871      167553 :                                 return T_CONSTANT_ENCAPSED_STRING;
    1872             :                         case '$':
    1873       11784 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    1874             :                                         break;
    1875             :                                 }
    1876         389 :                                 continue;
    1877             :                         case '{':
    1878         922 :                                 if (*YYCURSOR == '$') {
    1879         744 :                                         break;
    1880             :                                 }
    1881         178 :                                 continue;
    1882             :                         case '\\':
    1883       51207 :                                 if (YYCURSOR < YYLIMIT) {
    1884       51207 :                                         YYCURSOR++;
    1885             :                                 }
    1886             :                                 /* fall through */
    1887             :                         default:
    1888     2961506 :                                 continue;
    1889             :                 }
    1890             : 
    1891       12139 :                 YYCURSOR--;
    1892       12139 :                 break;
    1893             :         }
    1894             : 
    1895             :         /* Remember how much was scanned to save rescanning */
    1896       12141 :         SET_DOUBLE_QUOTES_SCANNED_LENGTH(YYCURSOR - SCNG(yy_text) - yyleng);
    1897             : 
    1898       12141 :         YYCURSOR = SCNG(yy_text) + yyleng;
    1899             : 
    1900       12141 :         BEGIN(ST_DOUBLE_QUOTES);
    1901       12141 :         return '"';
    1902             : }
    1903             : 
    1904             : 
    1905             : <ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
    1906             :         char *s;
    1907        1546 :         int bprefix = (yytext[0] != '<') ? 1 : 0;
    1908        1546 :         zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label));
    1909             : 
    1910        1546 :         CG(zend_lineno)++;
    1911        1546 :         heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
    1912        1546 :         s = yytext+bprefix+3;
    1913        3127 :         while ((*s == ' ') || (*s == '\t')) {
    1914          35 :                 s++;
    1915          35 :                 heredoc_label->length--;
    1916             :         }
    1917             : 
    1918        1546 :         if (*s == '\'') {
    1919         103 :                 s++;
    1920         103 :                 heredoc_label->length -= 2;
    1921             : 
    1922         103 :                 BEGIN(ST_NOWDOC);
    1923             :         } else {
    1924        1443 :                 if (*s == '"') {
    1925           7 :                         s++;
    1926           7 :                         heredoc_label->length -= 2;
    1927             :                 }
    1928             : 
    1929        1443 :                 BEGIN(ST_HEREDOC);
    1930             :         }
    1931             : 
    1932        1546 :         heredoc_label->label = estrndup(s, heredoc_label->length);
    1933             : 
    1934             :         /* Check for ending label on the next line */
    1935        1546 :         if (heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, heredoc_label->length)) {
    1936          65 :                 YYCTYPE *end = YYCURSOR + heredoc_label->length;
    1937             : 
    1938          65 :                 if (*end == ';') {
    1939          59 :                         end++;
    1940             :                 }
    1941             : 
    1942          65 :                 if (*end == '\n' || *end == '\r') {
    1943          61 :                         BEGIN(ST_END_HEREDOC);
    1944             :                 }
    1945             :         }
    1946             : 
    1947             :         zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label);
    1948             : 
    1949        1546 :         return T_START_HEREDOC;
    1950             : }
    1951             : 
    1952             : 
    1953             : <ST_IN_SCRIPTING>[`] {
    1954         113 :         BEGIN(ST_BACKQUOTE);
    1955         113 :         return '`';
    1956             : }
    1957             : 
    1958             : 
    1959             : <ST_END_HEREDOC>{ANY_CHAR} {
    1960        1543 :         zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack));
    1961             : 
    1962        1543 :         YYCURSOR += heredoc_label->length - 1;
    1963        1543 :         yyleng = heredoc_label->length;
    1964             : 
    1965        1543 :         heredoc_label_dtor(heredoc_label);
    1966        1543 :         efree(heredoc_label);
    1967             : 
    1968        1543 :         BEGIN(ST_IN_SCRIPTING);
    1969        1543 :         return T_END_HEREDOC;
    1970             : }
    1971             : 
    1972             : 
    1973             : <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"{$" {
    1974        1204 :         Z_LVAL_P(zendlval) = (zend_long) '{';
    1975        1204 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1976        1204 :         yyless(1);
    1977        1204 :         return T_CURLY_OPEN;
    1978             : }
    1979             : 
    1980             : 
    1981             : <ST_DOUBLE_QUOTES>["] {
    1982       12138 :         BEGIN(ST_IN_SCRIPTING);
    1983       12138 :         return '"';
    1984             : }
    1985             : 
    1986             : <ST_BACKQUOTE>[`] {
    1987         113 :         BEGIN(ST_IN_SCRIPTING);
    1988         113 :         return '`';
    1989             : }
    1990             : 
    1991             : 
    1992             : <ST_DOUBLE_QUOTES>{ANY_CHAR} {
    1993       21673 :         if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
    1994        8404 :                 YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
    1995        8404 :                 SET_DOUBLE_QUOTES_SCANNED_LENGTH(0);
    1996             : 
    1997        8404 :                 goto double_quotes_scan_done;
    1998             :         }
    1999             : 
    2000       13269 :         if (YYCURSOR > YYLIMIT) {
    2001           2 :                 return 0;
    2002             :         }
    2003       13267 :         if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
    2004        1588 :                 YYCURSOR++;
    2005             :         }
    2006             : 
    2007       86973 :         while (YYCURSOR < YYLIMIT) {
    2008       73706 :                 switch (*YYCURSOR++) {
    2009             :                         case '"':
    2010        7787 :                                 break;
    2011             :                         case '$':
    2012        5096 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2013             :                                         break;
    2014             :                                 }
    2015           1 :                                 continue;
    2016             :                         case '{':
    2017         404 :                                 if (*YYCURSOR == '$') {
    2018         385 :                                         break;
    2019             :                                 }
    2020          19 :                                 continue;
    2021             :                         case '\\':
    2022        4775 :                                 if (YYCURSOR < YYLIMIT) {
    2023        4775 :                                         YYCURSOR++;
    2024             :                                 }
    2025             :                                 /* fall through */
    2026             :                         default:
    2027       60419 :                                 continue;
    2028             :                 }
    2029             : 
    2030       13267 :                 YYCURSOR--;
    2031       13267 :                 break;
    2032             :         }
    2033             : 
    2034             : double_quotes_scan_done:
    2035       21671 :         yyleng = YYCURSOR - SCNG(yy_text);
    2036             : 
    2037       21671 :         zend_scan_escape_string(zendlval, yytext, yyleng, '"' TSRMLS_CC);
    2038       21671 :         return T_ENCAPSED_AND_WHITESPACE;
    2039             : }
    2040             : 
    2041             : 
    2042             : <ST_BACKQUOTE>{ANY_CHAR} {
    2043         176 :         if (YYCURSOR > YYLIMIT) {
    2044           0 :                 return 0;
    2045             :         }
    2046         176 :         if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
    2047           0 :                 YYCURSOR++;
    2048             :         }
    2049             : 
    2050        2621 :         while (YYCURSOR < YYLIMIT) {
    2051        2445 :                 switch (*YYCURSOR++) {
    2052             :                         case '`':
    2053         100 :                                 break;
    2054             :                         case '$':
    2055          76 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2056             :                                         break;
    2057             :                                 }
    2058           0 :                                 continue;
    2059             :                         case '{':
    2060           4 :                                 if (*YYCURSOR == '$') {
    2061           0 :                                         break;
    2062             :                                 }
    2063           4 :                                 continue;
    2064             :                         case '\\':
    2065           6 :                                 if (YYCURSOR < YYLIMIT) {
    2066           6 :                                         YYCURSOR++;
    2067             :                                 }
    2068             :                                 /* fall through */
    2069             :                         default:
    2070        2265 :                                 continue;
    2071             :                 }
    2072             : 
    2073         176 :                 YYCURSOR--;
    2074         176 :                 break;
    2075             :         }
    2076             : 
    2077         176 :         yyleng = YYCURSOR - SCNG(yy_text);
    2078             : 
    2079         176 :         zend_scan_escape_string(zendlval, yytext, yyleng, '`' TSRMLS_CC);
    2080         176 :         return T_ENCAPSED_AND_WHITESPACE;
    2081             : }
    2082             : 
    2083             : 
    2084             : <ST_HEREDOC>{ANY_CHAR} {
    2085        1890 :         int newline = 0;
    2086             : 
    2087        1890 :         zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
    2088             : 
    2089        1890 :         if (YYCURSOR > YYLIMIT) {
    2090           1 :                 return 0;
    2091             :         }
    2092             : 
    2093        1889 :         YYCURSOR--;
    2094             : 
    2095      326840 :         while (YYCURSOR < YYLIMIT) {
    2096      324950 :                 switch (*YYCURSOR++) {
    2097             :                         case '\r':
    2098           0 :                                 if (*YYCURSOR == '\n') {
    2099           0 :                                         YYCURSOR++;
    2100             :                                 }
    2101             :                                 /* fall through */
    2102             :                         case '\n':
    2103             :                                 /* Check for ending label on the next line */
    2104        9846 :                                 if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
    2105        1388 :                                         YYCTYPE *end = YYCURSOR + heredoc_label->length;
    2106             : 
    2107        1388 :                                         if (*end == ';') {
    2108        1327 :                                                 end++;
    2109             :                                         }
    2110             : 
    2111        1388 :                                         if (*end == '\n' || *end == '\r') {
    2112             :                                                 /* newline before label will be subtracted from returned text, but
    2113             :                                                  * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */
    2114        1384 :                                                 if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') {
    2115           0 :                                                         newline = 2; /* Windows newline */
    2116             :                                                 } else {
    2117        1384 :                                                         newline = 1;
    2118             :                                                 }
    2119             : 
    2120        1384 :                                                 CG(increment_lineno) = 1; /* For newline before label */
    2121        1384 :                                                 BEGIN(ST_END_HEREDOC);
    2122             : 
    2123        1384 :                                                 goto heredoc_scan_done;
    2124             :                                         }
    2125             :                                 }
    2126        8462 :                                 continue;
    2127             :                         case '$':
    2128         525 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2129             :                                         break;
    2130             :                                 }
    2131          79 :                                 continue;
    2132             :                         case '{':
    2133         106 :                                 if (*YYCURSOR == '$') {
    2134          58 :                                         break;
    2135             :                                 }
    2136          48 :                                 continue;
    2137             :                         case '\\':
    2138         641 :                                 if (YYCURSOR < YYLIMIT && *YYCURSOR != '\n' && *YYCURSOR != '\r') {
    2139         633 :                                         YYCURSOR++;
    2140             :                                 }
    2141             :                                 /* fall through */
    2142             :                         default:
    2143      314473 :                                 continue;
    2144             :                 }
    2145             : 
    2146         504 :                 YYCURSOR--;
    2147         504 :                 break;
    2148             :         }
    2149             : 
    2150             : heredoc_scan_done:
    2151        1889 :         yyleng = YYCURSOR - SCNG(yy_text);
    2152             : 
    2153        1889 :         zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0 TSRMLS_CC);
    2154        1889 :         return T_ENCAPSED_AND_WHITESPACE;
    2155             : }
    2156             : 
    2157             : 
    2158             : <ST_NOWDOC>{ANY_CHAR} {
    2159          98 :         int newline = 0;
    2160             : 
    2161          98 :         zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
    2162             : 
    2163          98 :         if (YYCURSOR > YYLIMIT) {
    2164           0 :                 return 0;
    2165             :         }
    2166             : 
    2167          98 :         YYCURSOR--;
    2168             : 
    2169       32098 :         while (YYCURSOR < YYLIMIT) {
    2170       32000 :                 switch (*YYCURSOR++) {
    2171             :                         case '\r':
    2172           0 :                                 if (*YYCURSOR == '\n') {
    2173           0 :                                         YYCURSOR++;
    2174             :                                 }
    2175             :                                 /* fall through */
    2176             :                         case '\n':
    2177             :                                 /* Check for ending label on the next line */
    2178         932 :                                 if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
    2179         103 :                                         YYCTYPE *end = YYCURSOR + heredoc_label->length;
    2180             : 
    2181         103 :                                         if (*end == ';') {
    2182          83 :                                                 end++;
    2183             :                                         }
    2184             : 
    2185         103 :                                         if (*end == '\n' || *end == '\r') {
    2186             :                                                 /* newline before label will be subtracted from returned text, but
    2187             :                                                  * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */
    2188          98 :                                                 if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') {
    2189           0 :                                                         newline = 2; /* Windows newline */
    2190             :                                                 } else {
    2191          98 :                                                         newline = 1;
    2192             :                                                 }
    2193             : 
    2194          98 :                                                 CG(increment_lineno) = 1; /* For newline before label */
    2195          98 :                                                 BEGIN(ST_END_HEREDOC);
    2196             : 
    2197          98 :                                                 goto nowdoc_scan_done;
    2198             :                                         }
    2199             :                                 }
    2200             :                                 /* fall through */
    2201             :                         default:
    2202       31902 :                                 continue;
    2203             :                 }
    2204             :         }
    2205             : 
    2206             : nowdoc_scan_done:
    2207          98 :         yyleng = YYCURSOR - SCNG(yy_text);
    2208             : 
    2209         196 :         zend_copy_value(zendlval, yytext, yyleng - newline);
    2210          98 :         HANDLE_NEWLINES(yytext, yyleng - newline);
    2211          98 :         return T_ENCAPSED_AND_WHITESPACE;
    2212             : }
    2213             : 
    2214             : 
    2215             : <ST_IN_SCRIPTING,ST_VAR_OFFSET>{ANY_CHAR} {
    2216        3174 :         if (YYCURSOR > YYLIMIT) {
    2217        3174 :                 return 0;
    2218             :         }
    2219             : 
    2220           0 :         zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
    2221           0 :         goto restart;
    2222             : }
    2223             : 
    2224             : */
    2225             : }

Generated by: LCOV version 1.10

Generated at Tue, 14 Oct 2014 07:25:53 +0000 (7 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.