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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_HEAD/lcov_data/Zend - zend_language_scanner.l
Test: PHP Code Coverage
Date: 2009-11-23 Instrumented lines: 1212
Code covered: 83.7 % Executed lines: 1014
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2009 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: zend_language_scanner.l 281094 2009-05-25 14:32:15Z felipe $ */
      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                 : #include "zend_alloc.h"
      37                 : #include <zend_language_parser.h>
      38                 : #include "zend_compile.h"
      39                 : #include "zend_language_scanner.h"
      40                 : #include "zend_highlight.h"
      41                 : #include "zend_constants.h"
      42                 : #include "zend_variables.h"
      43                 : #include "zend_operators.h"
      44                 : #include "zend_API.h"
      45                 : #include "zend_strtod.h"
      46                 : #include "zend_unicode.h"
      47                 : #include "tsrm_virtual_cwd.h"
      48                 : #include "tsrm_config_common.h"
      49                 : 
      50                 : #define YYCTYPE   unsigned char
      51                 : #define YYFILL(n) { if ((YYCURSOR + n) >= (YYLIMIT + ZEND_MMAP_AHEAD)) { return 0; } }
      52                 : #define YYCURSOR  SCNG(yy_cursor)
      53                 : #define YYLIMIT   SCNG(yy_limit)
      54                 : #define YYMARKER  SCNG(yy_marker)
      55                 : 
      56                 : #define YYGETCONDITION()  SCNG(yy_state)
      57                 : #define YYSETCONDITION(s) SCNG(yy_state) = s
      58                 : 
      59                 : #define STATE(name)  yyc##name
      60                 : 
      61                 : /* emulate flex constructs */
      62                 : #define BEGIN(state) YYSETCONDITION(STATE(state))
      63                 : #define YYSTATE      YYGETCONDITION()
      64                 : #define yytext       ((char*)SCNG(yy_text))
      65                 : #define yyleng       SCNG(yy_leng)
      66                 : #define yyless(x)    do { YYCURSOR = (unsigned char*)yytext + (x); \
      67                 :                           yyleng   = (unsigned int)(x); } while(0)
      68                 : #define yymore()     goto yymore_restart
      69                 : 
      70                 : /* perform sanity check. If this message is triggered you should
      71                 :    increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */
      72                 : /*!max:re2c */
      73                 : #if ZEND_MMAP_AHEAD < YYMAXFILL
      74                 : # error ZEND_MMAP_AHEAD should be greater than or equal to YYMAXFILL
      75                 : #endif
      76                 : 
      77                 : #ifdef HAVE_STDARG_H
      78                 : # include <stdarg.h>
      79                 : #endif
      80                 : 
      81                 : #ifdef HAVE_UNISTD_H
      82                 : # include <unistd.h>
      83                 : #endif
      84                 : 
      85                 : /* Globals Macros */
      86                 : #define SCNG    LANG_SCNG
      87                 : #ifdef ZTS
      88                 : ZEND_API ts_rsrc_id language_scanner_globals_id;
      89                 : #else
      90                 : ZEND_API zend_php_scanner_globals language_scanner_globals;
      91                 : #endif
      92                 : 
      93                 : /*
      94                 : #define YY_INPUT(buf, result, max_size) \
      95                 :         if ( ((result = zend_unicode_yyinput(yyin, buf, max_size TSRMLS_CC)) == 0)) \
      96                 :                 YY_FATAL_ERROR( "input in flex scanner failed" );
      97                 : */
      98                 : 
      99                 : #define HANDLE_NEWLINES(s, l)                                                                                                   \
     100                 : do {                                                                                                                                                    \
     101                 :         char *p = (s), *boundary = p+(l);                                                                                       \
     102                 :                                                                                                                                                                 \
     103                 :         while (p<boundary) {                                                                                                         \
     104                 :                 if (*p == '\n' || (*p == '\r' && (*(p+1) != '\n'))) {                                   \
     105                 :                         CG(zend_lineno)++;                                                                                                      \
     106                 :                 }                                                                                                                                               \
     107                 :                 p++;                                                                                                                                    \
     108                 :         }                                                                                                                                                       \
     109                 : } while (0)
     110                 : 
     111                 : #define HANDLE_NEWLINE(c) \
     112                 : { \
     113                 :         if (c == '\n' || c == '\r') { \
     114                 :                 CG(zend_lineno)++; \
     115                 :         } \
     116                 : }
     117                 : 
     118                 : /* To save initial string length after scanning to first variable, CG(doc_comment_len) can be reused */
     119                 : #define SET_DOUBLE_QUOTES_SCANNED_LENGTH(len) CG(doc_comment_len) = (len)
     120                 : #define GET_DOUBLE_QUOTES_SCANNED_LENGTH()    CG(doc_comment_len)
     121                 : 
     122                 : #define IS_LABEL_START(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || (c) == '_' || (c) >= 0x7F)
     123                 : 
     124                 : #define ZEND_IS_OCT(c)  ((c)>='0' && (c)<='7')
     125                 : #define ZEND_IS_HEX(c)  (((c)>='0' && (c)<='9') || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F'))
     126                 : 
     127                 : BEGIN_EXTERN_C()
     128                 : 
     129                 : static void _yy_push_state(int new_state TSRMLS_DC)
     130          121663 : {
     131          121663 :         zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
     132          121663 :         YYSETCONDITION(new_state);
     133          121663 : }
     134                 : 
     135                 : #define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm)
     136                 : 
     137                 : static void yy_pop_state(TSRMLS_D)
     138          121577 : {
     139                 :         int *stack_state;
     140          121577 :         zend_stack_top(&SCNG(state_stack), (void **) &stack_state);
     141          121577 :         YYSETCONDITION(*stack_state);
     142          121577 :         zend_stack_del_top(&SCNG(state_stack));
     143          121577 : }
     144                 : 
     145                 : static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
     146           25345 : {
     147           25345 :         YYCURSOR       = (YYCTYPE*)str;
     148           25345 :         SCNG(yy_start) = YYCURSOR;
     149           25345 :         YYLIMIT        = YYCURSOR + len;
     150           25345 :  }
     151                 : 
     152                 : void startup_scanner(TSRMLS_D)
     153           16993 : {
     154           16993 :         CG(heredoc) = NULL;
     155           16993 :         CG(heredoc_len) = 0;
     156           16993 :         CG(doc_comment) = NULL_ZSTR;
     157           16993 :         CG(doc_comment_len) = 0;
     158                 : 
     159           16993 :         SCNG(input_conv) = NULL;
     160           16993 :         SCNG(output_conv) = NULL;
     161           16993 :         SCNG(encoding_checked) = 0;
     162           16993 :         SCNG(rest_str) = NULL;
     163           16993 :         SCNG(rest_len) = 0;
     164                 : 
     165           16993 :         zend_stack_init(&SCNG(state_stack));
     166           16993 : }
     167                 : 
     168                 : 
     169                 : void shutdown_scanner(TSRMLS_D)
     170           17025 : {
     171           17025 :         if (CG(heredoc)) {
     172               2 :                 efree(CG(heredoc));
     173               2 :                 CG(heredoc_len)=0;
     174                 :         }
     175           17025 :         zend_stack_destroy(&SCNG(state_stack));
     176           17025 :         RESET_DOC_COMMENT();
     177                 : 
     178           17025 :         if (SCNG(input_conv)) {
     179               0 :                 ucnv_close(SCNG(input_conv));
     180               0 :                 SCNG(input_conv) = NULL;
     181                 :         }
     182           17025 :         if (SCNG(output_conv)) {
     183             177 :                 ucnv_close(SCNG(output_conv));
     184             177 :                 SCNG(output_conv) = NULL;
     185                 :         }
     186           17025 :         SCNG(encoding_checked) = 0;
     187           17025 :         if (SCNG(rest_str)) {
     188               0 :                 efree(SCNG(rest_str));
     189               0 :                 SCNG(rest_str) = NULL;
     190                 :         }
     191           17025 :         SCNG(rest_len) = 0;
     192           17025 : }
     193                 : 
     194                 : ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
     195           25369 : {
     196           25369 :         lex_state->yy_leng   = SCNG(yy_leng);
     197           25369 :         lex_state->yy_start  = SCNG(yy_start);
     198           25369 :         lex_state->yy_text   = SCNG(yy_text);
     199           25369 :         lex_state->yy_cursor = SCNG(yy_cursor);
     200           25369 :         lex_state->yy_marker = SCNG(yy_marker);
     201           25369 :         lex_state->yy_limit  = SCNG(yy_limit);
     202                 : 
     203           25369 :         lex_state->state_stack = SCNG(state_stack);
     204           25369 :         zend_stack_init(&SCNG(state_stack));
     205                 : 
     206           25369 :         lex_state->in = SCNG(yy_in);
     207           25369 :         lex_state->yy_state = YYSTATE;
     208           25369 :         lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
     209           25369 :         lex_state->lineno = CG(zend_lineno);
     210                 : 
     211           25369 :         lex_state->input_conv = SCNG(input_conv);
     212           25369 :         lex_state->output_conv = SCNG(output_conv);
     213           25369 :         lex_state->encoding_checked = SCNG(encoding_checked);
     214           25369 :         lex_state->rest_str = SCNG(rest_str);
     215           25369 :         lex_state->rest_len = SCNG(rest_len);
     216           25369 :         SCNG(input_conv) = NULL;
     217           25369 :         SCNG(output_conv) = NULL;
     218           25369 :         SCNG(encoding_checked) = 0;
     219           25369 :         SCNG(rest_str) = NULL;
     220           25369 :         SCNG(rest_len) = 0;
     221           25369 : }
     222                 : 
     223                 : ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
     224           25195 : {
     225           25195 :         SCNG(yy_leng)   = lex_state->yy_leng;
     226           25195 :         SCNG(yy_start)  = lex_state->yy_start;
     227           25195 :         SCNG(yy_text)   = lex_state->yy_text;
     228           25195 :         SCNG(yy_cursor) = lex_state->yy_cursor;
     229           25195 :         SCNG(yy_marker) = lex_state->yy_marker;
     230           25195 :         SCNG(yy_limit)  = lex_state->yy_limit;
     231                 : 
     232           25195 :         zend_stack_destroy(&SCNG(state_stack));
     233           25195 :         SCNG(state_stack) = lex_state->state_stack;
     234                 : 
     235           25195 :         SCNG(yy_in) = lex_state->in;
     236           25195 :         YYSETCONDITION(lex_state->yy_state);
     237           25195 :         CG(zend_lineno) = lex_state->lineno;
     238           25195 :         zend_restore_compiled_filename(lex_state->filename TSRMLS_CC);
     239           25195 :         zend_restore_compiled_script_encoding(lex_state->script_encoding TSRMLS_CC);
     240                 : 
     241           25195 :         if (SCNG(input_conv)) {
     242               0 :                 ucnv_close(SCNG(input_conv));
     243                 :         }
     244           25195 :         SCNG(input_conv) = lex_state->input_conv;
     245           25195 :         if (SCNG(output_conv)) {
     246           25165 :                 ucnv_close(SCNG(output_conv));
     247                 :         }
     248           25195 :         SCNG(output_conv) = lex_state->output_conv;
     249           25195 :         SCNG(encoding_checked) = lex_state->encoding_checked;
     250           25195 :         if (SCNG(rest_str)) {
     251               0 :                 efree(SCNG(rest_str));
     252                 :         }
     253           25195 :         SCNG(rest_str) = lex_state->rest_str;
     254           25195 :         SCNG(rest_len) = lex_state->rest_len;
     255           25195 : }
     256                 : 
     257                 : ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC)
     258           24193 : {
     259           24193 :         zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles);
     260                 :         /* zend_file_handle_dtor() operates on the copy, so we have to NULLify the original here */
     261           24193 :         file_handle->opened_path = NULL;
     262           24193 :         if (file_handle->free_filename) {
     263               0 :                 file_handle->filename = NULL;
     264                 :         }
     265           24193 : }
     266                 : 
     267                 : /* Convert one octal digit to a numeric value 0..7, or -1 on failure */
     268            2199 : static inline int8_t zend_get_octal_digit(UChar c) {
     269            2199 :     if (c >= 0x0030 && c <= 0x0037) {
     270            1064 :         return (int8_t)(c - 0x0030);
     271                 :     }
     272            1135 :     return -1;
     273                 : }
     274                 : 
     275                 : /*
     276                 :  * Convert one hex digit to a numeric value 0..F, or -1 on failure.
     277                 :  * Borrowed from ICU.
     278                 :  */
     279            2259 : static inline int8_t zend_get_hex_digit(UChar c) {
     280            2259 :     if (c >= 0x0030 && c <= 0x0039) {
     281            1475 :         return (int8_t)(c - 0x0030);
     282                 :     }
     283             784 :     if (c >= 0x0041 && c <= 0x0046) {
     284              78 :         return (int8_t)(c - (0x0041 - 10));
     285                 :     }
     286             706 :     if (c >= 0x0061 && c <= 0x0066) {
     287             660 :         return (int8_t)(c - (0x0061 - 10));
     288                 :     }
     289              46 :     return -1;
     290                 : }
     291                 : 
     292                 : static inline zend_bool zend_udigits_to_codepoint(UChar *s, UChar *end, UChar32 *c, int8_t digits)
     293               0 : {
     294               0 :         int8_t n = 0;
     295               0 :         int8_t digit = 0;
     296               0 :         UChar32 codepoint = 0;
     297                 : 
     298               0 :         while (s < end && n < digits) {
     299               0 :                 digit = zend_get_hex_digit(*s);
     300               0 :                 if (digit < 0) {
     301               0 :                         break;
     302                 :                 }
     303               0 :                 codepoint = (codepoint << 4) | digit;
     304               0 :                 ++s;
     305               0 :                 ++n;
     306                 :         }
     307                 : 
     308               0 :         if (n < digits) {
     309               0 :                 return 0;
     310                 :         }
     311                 : 
     312               0 :         *c = codepoint;
     313               0 :         return 1;
     314                 : }
     315                 : 
     316                 : static inline int zend_uchar_from_uname(UChar *name, int name_len, UChar32 *c TSRMLS_DC)
     317               0 : {
     318               0 :         UChar32 codepoint = 0;
     319               0 :         UErrorCode status = U_ZERO_ERROR;
     320                 :         char *buf;
     321                 : 
     322               0 :         buf = zend_unicode_to_ascii(name, name_len TSRMLS_CC);
     323               0 :         if (!buf) return 0;
     324               0 :         codepoint = u_charFromName(U_UNICODE_CHAR_NAME, buf, &status);
     325               0 :         efree(buf);
     326               0 :         if (U_SUCCESS(status)) {
     327               0 :                 *c = codepoint;
     328               0 :                 return 1;
     329                 :         } else {
     330               0 :                 return 0;
     331                 :         }
     332                 : }
     333                 : 
     334                 : static inline int zend_parse_charname_sequence(UChar **s, UChar *end, UChar32 *c TSRMLS_DC)
     335               0 : {
     336                 :         UChar *start;
     337                 : 
     338               0 :         if (**s == '{') {
     339               0 :                 start = ++(*s);
     340               0 :                 while ((*s)++ != end) {
     341               0 :                         if (**s == '}') {
     342               0 :                                 if (zend_uchar_from_uname(start, *s - start, c TSRMLS_CC)) {
     343               0 :                                         return 1;
     344                 :                                 } else {
     345                 :                                         /* safe, since *s points to '}' */
     346               0 :                                         **s = 0;
     347               0 :                                         zend_error(E_COMPILE_WARNING, "Invalid Unicode character name: '%r'", start);
     348               0 :                                         break;
     349                 :                                 }
     350                 :                         }
     351                 :                 }
     352                 :         }
     353                 : 
     354               0 :         return 0;
     355                 : }
     356                 : 
     357                 : ZEND_API int zend_copy_scanner_string(zval *zendlval, char *str, zend_uint str_len, zend_uchar type, UConverter *conv TSRMLS_DC)
     358         1294317 : {
     359         1294317 :         UErrorCode status = U_ZERO_ERROR;
     360         1294317 :         int consumed = 0;
     361                 : 
     362         1294317 :         if (type == IS_UNICODE) {
     363         1294313 :                 consumed = zend_convert_scanner_output(conv, &Z_USTRVAL_P(zendlval), &Z_USTRLEN_P(zendlval), str, str_len, &status TSRMLS_CC);
     364                 : 
     365         1294313 :                 if (U_FAILURE(status)) {
     366               0 :                         zend_error(E_COMPILE_WARNING,"Illegal or truncated character in input: offset %d, state=%d", consumed, YYSTATE);
     367               0 :                         efree(Z_USTRVAL_P(zendlval));
     368               0 :                         return 0;
     369                 :                 }
     370         1294313 :                 Z_TYPE_P(zendlval) = IS_UNICODE;
     371                 :         } else {
     372               4 :                 Z_STRVAL_P(zendlval) = (char *)estrndup(str, str_len);
     373               4 :                 Z_STRLEN_P(zendlval) = str_len;
     374               4 :                 Z_TYPE_P(zendlval) = IS_STRING;
     375                 :         }
     376                 : 
     377         1294317 :         return 1;
     378                 : }
     379                 : 
     380                 : static inline int zend_check_and_normalize_identifier(zval *zendlval)
     381          938008 : {
     382                 :         UChar *norm;
     383                 :         int norm_len;
     384                 : 
     385          938008 :         if (!zend_is_valid_identifier(Z_USTRVAL_P(zendlval), Z_USTRLEN_P(zendlval))) {
     386               0 :                 zend_error(E_COMPILE_WARNING, "Invalid identifier syntax: %r", Z_USTRVAL_P(zendlval));
     387               0 :                 efree(Z_USTRVAL_P(zendlval));
     388               0 :                 return 0;
     389                 :         }
     390          938008 :         if (zend_normalize_identifier(&norm, &norm_len, Z_USTRVAL_P(zendlval), Z_USTRLEN_P(zendlval), 0) == FAILURE) {
     391               0 :                 zend_error(E_COMPILE_WARNING, "Could not normalize identifier: %r", Z_USTRVAL_P(zendlval));
     392               0 :                 efree(Z_USTRVAL_P(zendlval));
     393               0 :                 return 0;
     394                 :         }
     395          938008 :         if (norm != Z_USTRVAL_P(zendlval)) {
     396               0 :                 efree(Z_USTRVAL_P(zendlval));
     397               0 :                 ZVAL_UNICODEL(zendlval, norm, norm_len, 0);
     398                 :         }
     399          938008 :         return 1;
     400                 : }
     401                 : 
     402                 : static void zend_scanner_output_callback(
     403                 :     const void *context,
     404                 :     UConverterToUnicodeArgs *toUArgs,
     405                 :     const char *codeUnits,
     406                 :     int32_t length,
     407                 :     UConverterCallbackReason reason,
     408                 :     UErrorCode *err
     409                 :     )
     410         1319472 : {
     411         1319472 :     if (*err == U_TRUNCATED_CHAR_FOUND ||
     412                 :         *err == U_ILLEGAL_CHAR_FOUND ||
     413                 :                 *err == U_INVALID_CHAR_FOUND) {
     414               0 :         *(const char **)context = toUArgs->source - length;
     415                 :     }
     416                 : 
     417                 :     return;
     418                 : }
     419                 : 
     420                 : static int is_encoding_flex_compatible(const char *enc TSRMLS_DC)
     421           25408 : {
     422           25408 :         int key_len = strlen(enc)+1;
     423                 :         unsigned char ret;
     424                 :         unsigned char *ret_ptr;
     425                 : 
     426           25408 :         if (zend_hash_find(&UG(flex_compatible), (char*)enc, key_len, (void**)&ret_ptr) == SUCCESS) {
     427            8374 :                 return *ret_ptr;
     428                 :         } else {
     429           17034 :                 UErrorCode status = U_ZERO_ERROR;
     430           17034 :                 UConverter *conv = ucnv_open(enc, &status);
     431                 : 
     432           17034 :                 if (U_FAILURE(status)) {
     433               3 :                         return 0;
     434                 :                 }
     435                 : 
     436           17031 :                 switch (ucnv_getType(conv)) {
     437                 :                         case UCNV_DBCS:
     438                 :                         case UCNV_UTF16_BigEndian:
     439                 :                         case UCNV_UTF16_LittleEndian:
     440                 :                         case UCNV_UTF32_BigEndian:
     441                 :                         case UCNV_UTF32_LittleEndian:
     442                 :                         case UCNV_EBCDIC_STATEFUL:
     443                 :                         case UCNV_ISO_2022:
     444                 :                         case UCNV_LMBCS_1:
     445                 :                         case UCNV_LMBCS_2:
     446                 :                         case UCNV_LMBCS_3:
     447                 :                         case UCNV_LMBCS_4:
     448                 :                         case UCNV_LMBCS_5:
     449                 :                         case UCNV_LMBCS_6:
     450                 :                         case UCNV_LMBCS_8:
     451                 :                         case UCNV_LMBCS_11:
     452                 :                         case UCNV_LMBCS_16:
     453                 :                         case UCNV_LMBCS_17:
     454                 :                         case UCNV_LMBCS_18:
     455                 :                         case UCNV_LMBCS_19:
     456                 :                         case UCNV_HZ:
     457                 :                         case UCNV_SCSU:
     458                 :                         case UCNV_UTF7:
     459                 :                         case UCNV_BOCU1:
     460                 :                         case UCNV_UTF16:
     461                 :                         case UCNV_UTF32:
     462                 :                         case UCNV_IMAP_MAILBOX:
     463               0 :                                 ret = 0;
     464               0 :                                 break;
     465                 :                         case UCNV_LATIN_1:
     466                 :                         case UCNV_UTF8:
     467                 :                         case UCNV_ISCII:
     468                 :                         case UCNV_US_ASCII:
     469                 :                         case UCNV_CESU8:
     470           17031 :                                 ret = 1;
     471           17031 :                                 break;
     472                 :                         default: {
     473                 :                                 static const UChar ascii[] = {
     474                 :                                         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
     475                 :                                         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
     476                 :                                         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
     477                 :                                         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
     478                 :                                         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
     479                 :                                         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
     480                 :                                         0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
     481                 :                                         0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E
     482                 :                                 };
     483                 :                                 static const char expected[] =
     484                 :                                         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
     485                 :                                         "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
     486                 :                                         "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F"
     487                 :                                         "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F"
     488                 :                                         "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F"
     489                 :                                         "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F"
     490                 :                                         "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F"
     491                 :                                         "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E";
     492                 :                                 char output[sizeof(expected)];
     493                 : 
     494               0 :                                 if (ucnv_fromUChars(conv,
     495                 :                                                     output, sizeof(output),
     496                 :                                                     ascii, sizeof(expected),
     497                 :                                                     &status) != sizeof(expected) ||
     498                 :                                     U_FAILURE(status)) {
     499               0 :                                         ret = 0;
     500                 :                                 } else {
     501               0 :                                         ret = (memcmp(expected, output, sizeof(expected)) == 0);
     502                 :                                 }
     503                 :                         }
     504                 :                 }
     505           17031 :                 ucnv_close(conv);
     506                 : 
     507           17031 :                 zend_hash_add(&UG(flex_compatible), (char*)enc, key_len, (void**)&ret, sizeof(ret), NULL);
     508                 : 
     509           17031 :                 return ret;
     510                 :         }
     511                 : }
     512                 : 
     513                 : ZEND_API int zend_prepare_scanner_converters(const char *onetime_encoding, int run_time TSRMLS_DC)
     514           25408 : {
     515           25408 :         const char *encoding = NULL;
     516                 : 
     517           25408 :         if (SCNG(input_conv)) {
     518                 :                 /* Script is already converted to UTF-8 */
     519               0 :                 return zend_set_converter_encoding(&SCNG(output_conv), "UTF-8");
     520                 :         } else {
     521           25408 :                 encoding = onetime_encoding;
     522                 :         }
     523                 : 
     524                 :         /* We need to convert the input stream only if script_encoding is not ASCII compatible */
     525           25408 :         if (!is_encoding_flex_compatible(encoding TSRMLS_CC)) {
     526               3 :                 if (zend_set_converter_encoding(&SCNG(input_conv), encoding) == FAILURE) {
     527               3 :                         return FAILURE;
     528                 :                 }
     529                 : #ifdef scottmac_0
     530                 :                 if (run_time) {
     531                 :                         /* Convert rest of the buffer to unicode.runtime_encoding. */
     532                 :                         YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
     533                 :                         int offset, length, size;
     534                 :                         const char *src, *old_src;
     535                 :                         char rt_buf[8192];
     536                 :                         char *target = rt_buf;
     537                 :                         UErrorCode status = U_ZERO_ERROR;
     538                 : 
     539                 :                         old_src = src = yy_c_buf_p;
     540                 :                         offset = yy_c_buf_p - b->yy_ch_buf;
     541                 :                         length = b->yy_n_chars - offset;
     542                 :                         size = b->yy_buf_size - offset;
     543                 : 
     544                 :                         ucnv_convertEx(UG(utf8_conv),
     545                 :                                        SCNG(input_conv),
     546                 :                                        &target, rt_buf+size-2,
     547                 :                                        &src, src+length,
     548                 :                                        NULL, NULL, NULL, NULL,
     549                 :                                        TRUE, TRUE,
     550                 :                                        &status);
     551                 : 
     552                 :                         if (src - old_src < length) {
     553                 :                                 /* Cannot fit into buffer. Schedule for next read. */
     554                 :                                 SCNG(rest_len) = length - (src - old_src);
     555                 :                                 SCNG(rest_str) = emalloc(SCNG(rest_len));
     556                 :                                 memcpy(SCNG(rest_str), src, SCNG(rest_len));
     557                 :                         }
     558                 :                         length = target - rt_buf;
     559                 :                         memcpy(yy_c_buf_p, rt_buf, length);
     560                 :                         SCNG(yy_n_chars) = b->yy_n_chars = length + offset;
     561                 :                         b->yy_ch_buf[b->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
     562                 :                         b->yy_ch_buf[b->yy_n_chars+1] = YY_END_OF_BUFFER_CHAR;
     563                 :                 }
     564                 : #endif
     565               0 :                 encoding = "UTF-8";
     566                 :         }
     567           25405 :         return zend_set_converter_encoding(&SCNG(output_conv), encoding);
     568                 : }
     569                 : 
     570                 : ZEND_API int zend_convert_scanner_output(UConverter *conv, UChar **target, int *target_len, const char *source, int source_len, UErrorCode *status TSRMLS_DC)
     571         1294313 : {
     572         1294313 :         const char *source_consumed = NULL;
     573                 : 
     574                 :         /* set our custom callback with context */
     575         1294313 :         ucnv_setToUCallBack(conv, zend_scanner_output_callback, &source_consumed, NULL, NULL, status);
     576                 : 
     577                 :         /* reset the error and perform conversion */
     578         1294313 :         *status = U_ZERO_ERROR;
     579         1294313 :         zend_string_to_unicode_ex(conv, target, target_len, source, source_len, status);
     580                 : 
     581                 :         /* figure out how many source bytes were consumed */
     582         1294313 :         if (U_SUCCESS(*status)) {
     583         1294313 :                 return source_len;
     584               0 :         } else if (source_consumed) {
     585               0 :                 return source_consumed - source;
     586                 :         } else {
     587               0 :                 return 0;
     588                 :         }
     589                 : }
     590                 : 
     591                 : int zend_unicode_yyinput(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC)
     592               0 : {
     593               0 :         size_t n = len;
     594               0 :         const char *src = buf;
     595                 : 
     596                 : #ifdef scottmac_0
     597                 :         /* Look of we have rest from previous call */
     598                 :         if (SCNG(rest_str)) {
     599                 :                 if (len >= SCNG(rest_len)) {
     600                 :                         memcpy(buf, SCNG(rest_str), SCNG(rest_len));
     601                 :                         efree(SCNG(rest_str));
     602                 :                         SCNG(rest_str) = NULL;
     603                 :                         n = SCNG(rest_len);
     604                 :                         SCNG(rest_len) = 0;
     605                 :                 } else {
     606                 :                         memcpy(buf, SCNG(rest_str), len);
     607                 :                         memcpy(SCNG(rest_str), SCNG(rest_str)+len, SCNG(rest_len)-len);
     608                 :                         n = len;
     609                 :                         SCNG(rest_len) -= len;
     610                 :                 }
     611                 :         } else {
     612                 :                 n = zend_stream_read(file_handle, buf, len TSRMLS_CC);
     613                 :         }
     614                 : #endif
     615                 :         /* Autodetect encoding */
     616               0 :         if (!SCNG(encoding_checked)) {
     617                 :                 int32_t    signatureLength;
     618               0 :                 UErrorCode status = U_ZERO_ERROR;
     619                 :                 const char *encoding;
     620                 : 
     621               0 :                 encoding = ucnv_detectUnicodeSignature(buf, n, &signatureLength, &status);
     622               0 :                 if (encoding && U_SUCCESS(status)) {
     623               0 :                         src += signatureLength;
     624               0 :                         n -= signatureLength;
     625               0 :                         if (is_encoding_flex_compatible(encoding TSRMLS_CC)) {
     626               0 :                                 if (SCNG(input_conv)) {
     627               0 :                                         ucnv_close(SCNG(input_conv));
     628               0 :                                         SCNG(input_conv) = NULL;
     629                 :                                 }
     630               0 :                                 zend_set_converter_encoding(&SCNG(output_conv), encoding);
     631               0 :                                 if (signatureLength > 0) {
     632               0 :                                         memcpy(buf, src, n);
     633                 :                                 }
     634                 :                         } else {
     635               0 :                                 zend_set_converter_encoding(&SCNG(input_conv), encoding);
     636               0 :                                 zend_set_converter_encoding(&SCNG(output_conv), "UTF-8");
     637                 :                         }
     638                 :                 }
     639               0 :                 status = U_ZERO_ERROR;
     640               0 :                 SCNG(encoding_checked) = 1;
     641                 :         }
     642                 : 
     643               0 :         if (SCNG(input_conv) && n >= 0) {
     644               0 :                 UErrorCode status = U_ZERO_ERROR;
     645                 :                 char rt_buf[8192];
     646               0 :                 char *target = rt_buf;
     647               0 :                 const char *old_src = src;
     648                 : 
     649               0 :                 ucnv_convertEx(UG(utf8_conv),
     650                 :                                SCNG(input_conv),
     651                 :                                &target, rt_buf+len,
     652                 :                                &src, src+n,
     653                 :                                NULL, NULL, NULL, NULL,
     654                 :                                TRUE, TRUE,
     655                 :                                &status);
     656               0 :                 if (src - old_src < n) {
     657                 :                         /* Cannot fit into buffer. Schedule for next read. */
     658               0 :                         SCNG(rest_len) = n - (src - old_src);
     659               0 :                         SCNG(rest_str) = emalloc(SCNG(rest_len));
     660               0 :                         memcpy(SCNG(rest_str), src, SCNG(rest_len));
     661                 :                 }
     662               0 :                 n = target - rt_buf;
     663               0 :                 memcpy(buf, rt_buf, n);
     664                 :         }
     665               0 :         return n;
     666                 : }
     667                 : 
     668                 : ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC)
     669           24376 : {
     670           24376 :         char *file_path=NULL, *buf;
     671           24376 :         UErrorCode status = U_ZERO_ERROR;
     672                 :         size_t size;
     673                 : 
     674           24376 :         if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) {
     675              30 :                 return FAILURE;
     676                 :         }
     677                 : 
     678           24346 :         zend_llist_add_element(&CG(open_files), file_handle);
     679                 : 
     680           24346 :         if (file_handle->handle.stream.handle >= (void*)file_handle && file_handle->handle.stream.handle <= (void*)(file_handle+1)) {
     681           17165 :                 zend_file_handle *fh = (zend_file_handle*)zend_llist_get_last(&CG(open_files));
     682           17165 :                 size_t diff = (char*)file_handle->handle.stream.handle - (char*)file_handle;
     683           17165 :                 fh->handle.stream.handle = (void*)(((char*)fh) + diff);
     684           17165 :                 file_handle->handle.stream.handle = fh->handle.stream.handle;
     685                 :         }
     686                 : 
     687                 :         /* Reset the scanner for scanning the new file */
     688           24346 :         SCNG(yy_in) = file_handle;
     689                 : 
     690           24346 :         zend_prepare_scanner_converters(ucnv_getName(ZEND_U_CONVERTER(UG(script_encoding_conv)), &status), 0 TSRMLS_CC);
     691                 : 
     692           24346 :         if (size != -1) {
     693                 :                 /* Re-encode for Unicode if needed */
     694           24346 :                 yy_scan_buffer(buf, size TSRMLS_CC);
     695                 :         } else {
     696               0 :                 zend_error_noreturn(E_COMPILE_ERROR, "zend_stream_mmap() failed");
     697                 :         }
     698                 : 
     699           24346 :         BEGIN(INITIAL);
     700                 : 
     701           24346 :         if (file_handle->opened_path) {
     702           24315 :                 file_path = file_handle->opened_path;
     703                 :         } else {
     704              31 :                 file_path = file_handle->filename;
     705                 :         }
     706                 : 
     707           24346 :         zend_set_compiled_filename(file_path TSRMLS_CC);
     708           24346 :         zend_set_compiled_script_encoding((char*)ucnv_getName(SCNG(output_conv), &status) TSRMLS_CC);
     709                 : 
     710           24346 :         if (CG(start_lineno)) {
     711           16602 :                 CG(zend_lineno) = CG(start_lineno);
     712           16602 :                 CG(start_lineno) = 0;
     713                 :         } else {
     714            7744 :                 CG(zend_lineno) = 1;
     715                 :         }
     716                 : 
     717           24346 :         CG(increment_lineno) = 0;
     718           24346 :         return SUCCESS;
     719                 : }
     720                 : END_EXTERN_C()
     721                 : 
     722                 : 
     723                 : ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
     724           24345 : {
     725                 :         zend_lex_state original_lex_state;
     726           24345 :         zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
     727           24345 :         zend_op_array *original_active_op_array = CG(active_op_array);
     728           24345 :         zend_op_array *retval=NULL;
     729                 :         int compiler_result;
     730           24345 :         zend_bool compilation_successful=0;
     731                 :         znode retval_znode;
     732           24345 :         zend_bool original_in_compilation = CG(in_compilation);
     733                 : 
     734           24345 :         retval_znode.op_type = IS_CONST;
     735           24345 :         Z_TYPE(retval_znode.u.constant) = IS_LONG;
     736           24345 :         Z_LVAL(retval_znode.u.constant) = 1;
     737           24345 :         Z_UNSET_ISREF(retval_znode.u.constant);
     738           24345 :         Z_SET_REFCOUNT(retval_znode.u.constant, 1);
     739                 : 
     740           24345 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     741                 : 
     742           24345 :         retval = op_array; /* success oriented */
     743                 : 
     744           24345 :         if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) {
     745              26 :                 if (type==ZEND_REQUIRE) {
     746               0 :                         zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC);
     747               0 :                         zend_bailout();
     748                 :                 } else {
     749              26 :                         zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC);
     750                 :                 }
     751              26 :                 compilation_successful=0;
     752                 :         } else {
     753           24319 :                 init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
     754           24319 :                 CG(in_compilation) = 1;
     755           24319 :                 CG(active_op_array) = op_array;
     756           24319 :                 compiler_result = zendparse(TSRMLS_C);
     757           24172 :                 zend_do_return(&retval_znode, 0 TSRMLS_CC);
     758           24172 :                 CG(in_compilation) = original_in_compilation;
     759           24172 :                 if (compiler_result==1) { /* parser error */
     760              23 :                         zend_bailout();
     761                 :                 }
     762           24149 :                 compilation_successful=1;
     763                 :         }
     764                 : 
     765           24175 :         if (retval) {
     766           24175 :                 CG(active_op_array) = original_active_op_array;
     767           24175 :                 if (compilation_successful) {
     768           24149 :                         pass_two(op_array TSRMLS_CC);
     769           24146 :                         zend_release_labels(TSRMLS_C);
     770                 :                 } else {
     771              26 :                         efree(op_array);
     772              26 :                         retval = NULL;
     773                 :                 }
     774                 :         }
     775           24172 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     776           24172 :         return retval;
     777                 : }
     778                 : 
     779                 : 
     780                 : zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC)
     781            2683 : {
     782                 :         zend_file_handle file_handle;
     783                 :         zval tmp;
     784                 :         zend_op_array *retval;
     785            2683 :         char *opened_path = NULL;
     786                 : 
     787            2683 :         if (Z_TYPE_P(filename) != IS_STRING) {
     788               0 :                 tmp = *filename;
     789               0 :                 zval_copy_ctor(&tmp);
     790               0 :                 convert_to_string(&tmp);
     791               0 :                 filename = &tmp;
     792                 :         }
     793            2683 :         file_handle.filename = Z_STRVAL_P(filename);
     794            2683 :         file_handle.free_filename = 0;
     795            2683 :         file_handle.type = ZEND_HANDLE_FILENAME;
     796            2683 :         file_handle.opened_path = NULL;
     797            2683 :         file_handle.handle.fp = NULL;
     798                 : 
     799            2683 :         retval = zend_compile_file(&file_handle, type TSRMLS_CC);
     800            2679 :         if (retval && file_handle.handle.stream.handle) {
     801            2653 :                 int dummy = 1;
     802                 : 
     803            2653 :                 if (!file_handle.opened_path) {
     804              17 :                         file_handle.opened_path = opened_path = estrndup(Z_STRVAL_P(filename), Z_STRLEN_P(filename));
     805                 :                 }
     806                 : 
     807            2653 :                 zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL);
     808                 : 
     809            2653 :                 if (opened_path) {
     810              17 :                         efree(opened_path);
     811                 :                 }
     812                 :         }
     813            2679 :         zend_destroy_file_handle(&file_handle TSRMLS_CC);
     814                 : 
     815            2679 :         if (filename==&tmp) {
     816               0 :                 zval_dtor(&tmp);
     817                 :         }
     818            2679 :         return retval;
     819                 : }
     820                 : 
     821                 : ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_DC)
     822             999 : {
     823                 :         const char *encoding;
     824             999 :         UErrorCode status = U_ZERO_ERROR;
     825                 : 
     826             999 :         if (Z_TYPE_P(str) == IS_UNICODE) {
     827             819 :                 convert_to_string_with_converter(str, UG(utf8_conv));
     828             819 :                 encoding = "UTF-8";
     829                 :         } else {
     830             180 :                 UErrorCode status = U_ZERO_ERROR;
     831             180 :                 encoding = ucnv_getName(ZEND_U_CONVERTER(UG(runtime_encoding_conv)), &status);
     832                 :         }
     833                 : 
     834             999 :         str->value.str.val = safe_erealloc(str->value.str.val, 1, str->value.str.len, ZEND_MMAP_AHEAD);
     835             999 :         memset(str->value.str.val + str->value.str.len, 0, ZEND_MMAP_AHEAD);
     836                 : 
     837             999 :         SCNG(yy_in)=NULL;
     838                 : 
     839             999 :         zend_prepare_scanner_converters(encoding, 0 TSRMLS_CC);
     840                 :         /* Re-encode for Unicode if needed */
     841             999 :         yy_scan_buffer(Z_STRVAL_P(str), Z_STRLEN_P(str) TSRMLS_CC);
     842                 : 
     843             999 :         zend_set_compiled_filename(filename TSRMLS_CC);
     844             999 :         zend_set_compiled_script_encoding((char*)ucnv_getName(SCNG(output_conv), &status) TSRMLS_CC);
     845             999 :         CG(zend_lineno) = 1;
     846             999 :         CG(increment_lineno) = 0;
     847             999 :         return SUCCESS;
     848                 : }
     849                 : 
     850                 : 
     851                 : ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D)
     852             270 : {
     853             270 :         return SCNG(yy_cursor) - SCNG(yy_start);
     854                 : }
     855                 : 
     856                 : 
     857                 : zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
     858             973 : {
     859                 :         zend_lex_state original_lex_state;
     860             973 :         zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
     861             973 :         zend_op_array *original_active_op_array = CG(active_op_array);
     862                 :         zend_op_array *retval;
     863                 :         zval tmp;
     864                 :         int compiler_result;
     865             973 :         zend_bool original_in_compilation = CG(in_compilation);
     866                 : 
     867             973 :         tmp = *source_string;
     868             973 :         zval_copy_ctor(&tmp);
     869             973 :         if (Z_TYPE(tmp) != IS_STRING && Z_TYPE(tmp) != IS_UNICODE) {
     870               0 :                 convert_to_unicode(&tmp);
     871                 :         }
     872             973 :         source_string = &tmp;
     873                 : 
     874             973 :         if (Z_UNILEN_P(source_string)==0) {
     875              53 :                 efree(op_array);
     876              53 :                 zval_dtor(&tmp);
     877              53 :                 return NULL;
     878                 :         }
     879                 : 
     880             920 :         CG(in_compilation) = 1;
     881                 : 
     882             920 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     883             920 :         if (zend_prepare_string_for_scanning(source_string, filename TSRMLS_CC)==FAILURE) {
     884               0 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     885               0 :                 efree(op_array);
     886               0 :                 retval = NULL;
     887                 :         } else {
     888             920 :                 zend_bool orig_interactive = CG(interactive);
     889                 : 
     890             920 :                 CG(interactive) = 0;
     891             920 :                 init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
     892             920 :                 CG(interactive) = orig_interactive;
     893             920 :                 CG(active_op_array) = op_array;
     894             920 :                 BEGIN(ST_IN_SCRIPTING);
     895             920 :                 compiler_result = zendparse(TSRMLS_C);
     896                 : 
     897             919 :                 if (compiler_result==1) {
     898               6 :                         CG(active_op_array) = original_active_op_array;
     899               6 :                         CG(unclean_shutdown)=1;
     900               6 :                         retval = NULL;
     901                 :                 } else {
     902             913 :                         zend_do_return(NULL, 0 TSRMLS_CC);
     903             913 :                         CG(active_op_array) = original_active_op_array;
     904             913 :                         pass_two(op_array TSRMLS_CC);
     905             913 :                         zend_release_labels(TSRMLS_C);
     906             913 :                         retval = op_array;
     907                 :                 }
     908             919 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     909                 :         }
     910             919 :         zval_dtor(&tmp);
     911             919 :         CG(in_compilation) = original_in_compilation;
     912             919 :         return retval;
     913                 : }
     914                 : 
     915                 : 
     916                 : BEGIN_EXTERN_C()
     917                 : int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC)
     918              20 : {
     919                 :         zend_lex_state original_lex_state;
     920                 :         zend_file_handle file_handle;
     921                 : 
     922              20 :         file_handle.type = ZEND_HANDLE_FILENAME;
     923              20 :         file_handle.filename = filename;
     924              20 :         file_handle.free_filename = 0;
     925              20 :         file_handle.opened_path = NULL;
     926              20 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     927              20 :         if (open_file_for_scanning(&file_handle TSRMLS_CC)==FAILURE) {
     928               2 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     929               2 :                 zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename TSRMLS_CC);
     930               2 :                 return FAILURE;
     931                 :         }
     932              18 :         zend_highlight(syntax_highlighter_ini TSRMLS_CC);
     933              18 :         zend_destroy_file_handle(&file_handle TSRMLS_CC);
     934              18 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     935              18 :         return SUCCESS;
     936                 : }
     937                 : 
     938                 : int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC)
     939              12 : {
     940                 :         zend_lex_state original_lex_state;
     941              12 :         zval tmp = *str;
     942                 : 
     943              12 :         str = &tmp;
     944              12 :         zval_copy_ctor(str);
     945              12 :         zend_save_lexical_state(&original_lex_state TSRMLS_CC);
     946              12 :         if (zend_prepare_string_for_scanning(str, str_name TSRMLS_CC)==FAILURE) {
     947               0 :                 zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     948               0 :                 return FAILURE;
     949                 :         }
     950              12 :         BEGIN(INITIAL);
     951              12 :         zend_highlight(syntax_highlighter_ini TSRMLS_CC);
     952              12 :         zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
     953              12 :         zval_dtor(str);
     954              12 :         return SUCCESS;
     955                 : }
     956                 : END_EXTERN_C()
     957                 : 
     958                 : #define zend_copy_value(zendlval, yytext, yyleng) \
     959                 :         Z_STRVAL_P(zendlval) = (char *)estrndup(yytext, yyleng); \
     960                 :         Z_STRLEN_P(zendlval) = yyleng;
     961                 : 
     962                 : static int zend_scan_unicode_escape_string(zval *zendlval, char *str, int len, UChar quote_type, int type TSRMLS_DC)
     963          168596 : {
     964                 :         register UChar *s, *t, c;
     965                 :         UChar *end;
     966          168596 :         UChar32 codepoint = 0;
     967                 :         int8_t digit;
     968          168596 :         int8_t min_digits = 0, max_digits = 0;
     969                 :         int8_t bits;
     970                 :         int8_t n;
     971                 : 
     972          168596 :         if (!zend_copy_scanner_string(zendlval, str, len, IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
     973               0 :                 return 0;
     974                 :         }
     975                 : 
     976                 :         /* convert escape sequences */
     977          168596 :         s = t = Z_USTRVAL_P(zendlval);
     978          168596 :         end = s+Z_USTRLEN_P(zendlval);
     979         3252709 :         while (s<end) {
     980         2915521 :                 if (*s==0x5C /*'\\'*/) {
     981           49221 :                         s++;
     982           49221 :                         c = *s;
     983           49221 :                         if (s >= end) {
     984               4 :                                 *t++ = 0x5C; /*'\\'*/
     985               4 :                                 break;
     986                 :                         }
     987                 : 
     988           49217 :                         min_digits = 0;
     989           49217 :                         codepoint = 0;
     990           49217 :                         bits = 4;
     991           49217 :                         n = 0;
     992                 : 
     993           49217 :                         switch(c) {
     994                 :                                 case 0x6E:               /*'n'*/
     995           40722 :                                         *t++ = (UChar) 0x0A; /*'\n'*/
     996           40722 :                                         Z_USTRLEN_P(zendlval)--;
     997           40722 :                                         break;
     998                 :                                 case 0x72:               /*'r'*/
     999            3395 :                                         *t++ = (UChar) 0x0D; /*'\r'*/
    1000            3395 :                                         Z_USTRLEN_P(zendlval)--;
    1001            3395 :                                         break;
    1002                 :                                 case 0x74:               /*'t'*/
    1003             569 :                                         *t++ = (UChar) 0x09; /*'\t'*/
    1004             569 :                                         Z_USTRLEN_P(zendlval)--;
    1005             569 :                                         break;
    1006                 :                                 case 0x66:                               /*'f'*/
    1007              68 :                                         *t++ = (UChar) 0x0C; /*'\f'*/
    1008              68 :                                         Z_USTRLEN_P(zendlval)--;
    1009              68 :                                         break;
    1010                 :                                 case 0x76:                               /*'v'*/
    1011             102 :                                         *t++ = (UChar) 0x0B; /*'\v'*/
    1012             102 :                                         Z_USTRLEN_P(zendlval)--;
    1013             102 :                                         break;
    1014                 :                                 case 0x22:               /*'"'*/
    1015                 :                                 case 0x60:               /*'`'*/
    1016             995 :                                         if (c != quote_type) {
    1017               3 :                                                 *t++ = 0x5C; /*'\\'*/
    1018               3 :                                                 *t++ = *s;
    1019               3 :                                                 break;
    1020                 :                                         }
    1021                 :                                 case 0x5C:               /*'\\'*/
    1022                 :                                 case 0x24:               /*'$'*/
    1023            1961 :                                         *t++ = *s;
    1024            1961 :                                         Z_USTRLEN_P(zendlval)--;
    1025            1961 :                                         break;
    1026                 :                                 case 0x43:                               /*'C'*/
    1027                 :                                         {
    1028               0 :                                                 UChar *p = s+1;
    1029               0 :                                                 if (p < end && zend_parse_charname_sequence(&p, end, &codepoint TSRMLS_CC)) {
    1030               0 :                                                         Z_USTRLEN_P(zendlval) -= p - s + 1;
    1031               0 :                                                         s = p;
    1032               0 :                                                         if (U_IS_BMP(codepoint)) {
    1033               0 :                                                                 *t++ = (UChar) codepoint;
    1034                 :                                                         } else {
    1035               0 :                                                                 *t++ = (UChar) U16_LEAD(codepoint);
    1036               0 :                                                                 *t++ = (UChar) U16_TRAIL(codepoint);
    1037               0 :                                                                 Z_USTRLEN_P(zendlval)++;
    1038                 :                                                         }
    1039                 :                                                 } else {
    1040               0 :                                                         zend_error(E_COMPILE_WARNING, "Invalid \\C{..} sequence");
    1041               0 :                                                         efree(Z_USTRVAL_P(zendlval));
    1042               0 :                                                         return 0;
    1043                 :                                                 }
    1044               0 :                                                 break;
    1045                 :                                         }
    1046                 :                                 case 0x75:               /*'u'*/
    1047              34 :                                         min_digits = 4;
    1048              34 :                                         max_digits = 4;
    1049              34 :                                         Z_USTRLEN_P(zendlval)--;
    1050              34 :                                         break;
    1051                 :                                 case 0x55:               /*'U'*/
    1052               9 :                                         min_digits = 6;
    1053               9 :                                         max_digits = 6;
    1054               9 :                                         Z_USTRLEN_P(zendlval)--;
    1055               9 :                                         break;
    1056                 :                                 case 0x78:               /*'x'*/
    1057                 :                                 case 0x58:               /*'X'*/
    1058            1045 :                                         if ((digit = zend_get_hex_digit(*(s+1))) >= 0) {
    1059            1024 :                                                 min_digits = 1;
    1060            1024 :                                                 max_digits = 2;
    1061            1024 :                                                 Z_USTRLEN_P(zendlval)--;
    1062            1024 :                                                 s++;
    1063            1024 :                                                 n = 1; /* already have one digit */
    1064            1024 :                                                 codepoint = digit;
    1065                 :                                         } else {
    1066              21 :                                                 *t++ = 0x5C; /*'\\'*/
    1067              21 :                                                 *t++ = *s;
    1068                 :                                         }
    1069            1045 :                                         break;
    1070                 :                                 default:
    1071            1309 :                                         digit = zend_get_octal_digit(*s);
    1072            1309 :                                         if (digit >= 0) {
    1073             695 :                                                 min_digits = 1;
    1074             695 :                                                 max_digits = 3;
    1075             695 :                                                 bits = 3;
    1076             695 :                                                 n = 1; /* already have one digit */
    1077             695 :                                                 codepoint = digit;
    1078                 :                                         } else {
    1079             614 :                                                 *t++ = 0x5C; /*'\\'*/
    1080             614 :                                                 *t++ = *s;
    1081                 :                                         }
    1082                 :                                         break;
    1083                 :                         }
    1084                 : 
    1085                 :                         /* need to parse a number for one of the escape sequences */
    1086           49217 :                         if (min_digits != 0) {
    1087            5082 :                                 while (s++ < end && n < max_digits) {
    1088            2104 :                                         digit = (bits == 4) ? zend_get_hex_digit(*s) : zend_get_octal_digit(*s);
    1089            2104 :                                         if (digit < 0) {
    1090             546 :                                                 break;
    1091                 :                                         }
    1092            1558 :                                         codepoint = (codepoint << bits) | digit;
    1093            1558 :                                         n++;
    1094                 :                                 }
    1095                 : 
    1096            1762 :                                 if (n < min_digits) {
    1097                 :                                         /* can only happen for \u and \U sequences */
    1098               0 :                                         zend_error(E_COMPILE_WARNING,"\\%c escape sequence requires exactly %d hexadecimal digits", (char) c, min_digits);
    1099               0 :                                         efree(Z_USTRVAL_P(zendlval));
    1100               0 :                                         return 0;
    1101                 :                                 }
    1102                 : 
    1103            1762 :                                 if (U_IS_BMP(codepoint)) {
    1104            1753 :                                         *t++ = (UChar) codepoint;
    1105            1753 :                                         Z_USTRLEN_P(zendlval) -= n;
    1106               9 :                                 } else if (codepoint <= 0x10FFFF) {
    1107               9 :                                         *t++ = (UChar) U16_LEAD(codepoint);
    1108               9 :                                         *t++ = (UChar) U16_TRAIL(codepoint);
    1109               9 :                                         Z_USTRLEN_P(zendlval) -= n-1;
    1110                 :                                 } else {
    1111               0 :                                         zend_error(E_COMPILE_WARNING,"\\U%06x is above the highest valid codepoint 0x10FFFF", codepoint);
    1112               0 :                                         efree(Z_USTRVAL_P(zendlval));
    1113               0 :                                         return 0;
    1114                 :                                 }
    1115                 : 
    1116                 :                                 /* s is already incremented and not past a newline */
    1117            1762 :                                 continue;
    1118                 :                         }
    1119                 :                 } else {
    1120         2866300 :                         *t++ = *s;
    1121                 :                 }
    1122                 : 
    1123         2913755 :                 if (*s == 0x0A /*'\n'*/ || (*s == 0x0D /*'\r'*/ && (*(s+1) != 0x0A /*'\n'*/))) {
    1124            9642 :                         CG(zend_lineno)++;
    1125                 :                 }
    1126         2913755 :                 s++;
    1127                 :         }
    1128          168596 :         *t = 0;
    1129                 : 
    1130          168596 :         return type;
    1131                 : }
    1132                 : 
    1133                 : static int zend_scan_unicode_single_string(zval *zendlval TSRMLS_DC)
    1134          185671 : {
    1135                 :         register UChar *s, *t;
    1136                 :         UChar *end;
    1137                 : 
    1138          185671 :         if (!zend_copy_scanner_string(zendlval, yytext+1, yyleng-2, IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    1139               0 :                 return 0;
    1140                 :         }
    1141                 : 
    1142                 :         /* convert escape sequences */
    1143          185671 :         s = t = Z_USTRVAL_P(zendlval);
    1144          185671 :         end = s+Z_USTRLEN_P(zendlval);
    1145         1997527 :         while (s<end) {
    1146         1626185 :                 if (*s==0x5C /*'\\'*/) {
    1147           10922 :                         s++;
    1148                 : 
    1149           10922 :                         switch(*s) {
    1150                 :                                 case 0x5C: /*'\\'*/
    1151                 :                                 case 0x27: /*'\''*/
    1152            1163 :                                         *t++ = *s;
    1153            1163 :                                         Z_USTRLEN_P(zendlval)--;
    1154            1163 :                                         break;
    1155                 :                                 default:
    1156            9759 :                                         *t++ = 0x5C; /*'\\'*/
    1157            9759 :                                         *t++ = *s;
    1158                 :                                         break;
    1159                 :                         }
    1160                 :                 } else {
    1161         1615263 :                         *t++ = *s;
    1162                 :                 }
    1163                 : 
    1164         1626185 :                 if (*s == 0x0A /*'\n'*/ || (*s == 0x0D /*'\r'*/ && (*(s+1) != 0x0A /*'\n'*/))) {
    1165            1064 :                         CG(zend_lineno)++;
    1166                 :                 }
    1167         1626185 :                 s++;
    1168                 :         }
    1169          185671 :         *t = 0;
    1170                 : 
    1171          185671 :         return T_CONSTANT_ENCAPSED_STRING;
    1172                 : }
    1173                 : 
    1174                 : static void zend_scan_binary_escape_string(zval *zendlval, char *str, int len, char quote_type TSRMLS_DC)
    1175            1197 : {
    1176                 :         register char *s, *t;
    1177                 :         char *end;
    1178                 : 
    1179            1197 :         ZVAL_STRINGL(zendlval, str, len, 1);
    1180                 : 
    1181                 :         /* convert escape sequences */
    1182            1197 :         s = t = Z_STRVAL_P(zendlval);
    1183            1197 :         end = s+Z_STRLEN_P(zendlval);
    1184           29606 :         while (s<end) {
    1185           27212 :                 if (*s=='\\') {
    1186             866 :                         s++;
    1187             866 :                         if (s >= end) {
    1188               0 :                                 *t++ = '\\';
    1189               0 :                                 break;
    1190                 :                         }
    1191                 : 
    1192             866 :                         switch(*s) {
    1193                 :                                 case 'n':
    1194             162 :                                         *t++ = '\n';
    1195             162 :                                         Z_STRLEN_P(zendlval)--;
    1196             162 :                                         break;
    1197                 :                                 case 'r':
    1198              45 :                                         *t++ = '\r';
    1199              45 :                                         Z_STRLEN_P(zendlval)--;
    1200              45 :                                         break;
    1201                 :                                 case 't':
    1202              34 :                                         *t++ = '\t';
    1203              34 :                                         Z_STRLEN_P(zendlval)--;
    1204              34 :                                         break;
    1205                 :                                 case 'f':
    1206               4 :                                         *t++ = '\f';
    1207               4 :                                         zendlval->value.str.len--;
    1208               4 :                                         break;
    1209                 :                                 case 'v':
    1210               4 :                                         *t++ = '\v';
    1211               4 :                                         zendlval->value.str.len--;
    1212               4 :                                         break;
    1213                 :                                 case '"':
    1214                 :                                 case '`':
    1215              10 :                                         if (*s != quote_type) {
    1216               0 :                                                 *t++ = '\\';
    1217               0 :                                                 *t++ = *s;
    1218               0 :                                                 break;
    1219                 :                                         }
    1220                 :                                 case '\\':
    1221                 :                                 case '$':
    1222              20 :                                         *t++ = *s;
    1223              20 :                                         Z_STRLEN_P(zendlval)--;
    1224              20 :                                         break;
    1225                 :                                 case 'x':
    1226                 :                                 case 'X':
    1227            1102 :                                         if (ZEND_IS_HEX(*(s+1))) {
    1228             551 :                                                 char hex_buf[3] = { 0, 0, 0 };
    1229                 : 
    1230             551 :                                                 Z_STRLEN_P(zendlval)--; /* for the 'x' */
    1231                 : 
    1232             551 :                                                 hex_buf[0] = *(++s);
    1233             551 :                                                 Z_STRLEN_P(zendlval)--;
    1234             551 :                                                 if (ZEND_IS_HEX(*(s+1))) {
    1235             544 :                                                         hex_buf[1] = *(++s);
    1236             544 :                                                         Z_STRLEN_P(zendlval)--;
    1237                 :                                                 }
    1238             551 :                                                 *t++ = (char) strtol(hex_buf, NULL, 16);
    1239                 :                                         } else {
    1240               0 :                                                 *t++ = '\\';
    1241               0 :                                                 *t++ = *s;
    1242                 :                                         }
    1243             551 :                                         break;
    1244                 :                                 default:
    1245                 :                                         /* check for an octal */
    1246              79 :                                         if (ZEND_IS_OCT(*s)) {
    1247              33 :                                                 char octal_buf[4] = { 0, 0, 0, 0 };
    1248                 : 
    1249              33 :                                                 octal_buf[0] = *s;
    1250              33 :                                                 Z_STRLEN_P(zendlval)--;
    1251              33 :                                                 if (ZEND_IS_OCT(*(s+1))) {
    1252               8 :                                                         octal_buf[1] = *(++s);
    1253               8 :                                                         Z_STRLEN_P(zendlval)--;
    1254               8 :                                                         if (ZEND_IS_OCT(*(s+1))) {
    1255               4 :                                                                 octal_buf[2] = *(++s);
    1256               4 :                                                                 Z_STRLEN_P(zendlval)--;
    1257                 :                                                         }
    1258                 :                                                 }
    1259              33 :                                                 *t++ = (char) strtol(octal_buf, NULL, 8);
    1260                 :                                         } else {
    1261              13 :                                                 *t++ = '\\';
    1262              13 :                                                 *t++ = *s;
    1263                 :                                         }
    1264                 :                                         break;
    1265                 :                         }
    1266                 :                 } else {
    1267           26346 :                         *t++ = *s;
    1268                 :                 }
    1269                 : 
    1270           27212 :                 if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
    1271             484 :                         CG(zend_lineno)++;
    1272                 :                 }
    1273           27212 :                 s++;
    1274                 :         }
    1275            1197 :         *t = 0;
    1276            1197 : }
    1277                 : 
    1278                 : static void zend_scan_binary_single_string(zval *zendlval, char *str, int len TSRMLS_DC)
    1279             936 : {
    1280                 :         register char *s, *t;
    1281                 :         char *end;
    1282                 : 
    1283             936 :         ZVAL_STRINGL(zendlval, str, len, 1);
    1284                 : 
    1285                 :         /* convert escape sequences */
    1286             936 :         s = t = Z_STRVAL_P(zendlval);
    1287             936 :         end = s+Z_STRLEN_P(zendlval);
    1288           18268 :         while (s<end) {
    1289           16396 :                 if (*s=='\\') {
    1290             385 :                         s++;
    1291                 : 
    1292             385 :                         switch(*s) {
    1293                 :                                 case '\\':
    1294                 :                                 case '\'':
    1295              76 :                                         *t++ = *s;
    1296              76 :                                         Z_STRLEN_P(zendlval)--;
    1297              76 :                                         break;
    1298                 :                                 default:
    1299             309 :                                         *t++ = '\\';
    1300             309 :                                         *t++ = *s;
    1301                 :                                         break;
    1302                 :                         }
    1303                 :                 } else {
    1304           16011 :                         *t++ = *s;
    1305                 :                 }
    1306                 : 
    1307           16396 :                 if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) {
    1308             138 :                         CG(zend_lineno)++;
    1309                 :                 }
    1310           16396 :                 s++;
    1311                 :         }
    1312             936 :         *t = 0;
    1313             936 : }
    1314                 : 
    1315                 : 
    1316                 : int lex_scan(zval *zendlval TSRMLS_DC)
    1317         5521534 : {
    1318         5521534 : restart:
    1319         5521534 :         SCNG(yy_text) = YYCURSOR;
    1320                 : 
    1321         5521540 : yymore_restart:
    1322                 : 
    1323                 : /*!re2c
    1324                 : re2c:yyfill:check = 0;
    1325                 : LNUM    [0-9]+
    1326                 : DNUM    ([0-9]*"."[0-9]+)|([0-9]+"."[0-9]*)
    1327                 : EXPONENT_DNUM   (({LNUM}|{DNUM})[eE][+-]?{LNUM})
    1328                 : HNUM    "0x"[0-9a-fA-F]+
    1329                 : LABEL   [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
    1330                 : WHITESPACE [ \n\r\t]+
    1331                 : TABS_AND_SPACES [ \t]*
    1332                 : TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@]
    1333                 : ANY_CHAR [^]
    1334                 : NEWLINE ("\r"|"\n"|"\r\n")
    1335                 : 
    1336                 : /* compute yyleng before each rule */
    1337                 : <!*> := yyleng = YYCURSOR - SCNG(yy_text);
    1338                 : 
    1339                 : 
    1340                 : <ST_IN_SCRIPTING>"exit" {
    1341            1310 :         return T_EXIT;
    1342                 : }
    1343                 : 
    1344                 : <ST_IN_SCRIPTING>"die" {
    1345           10366 :         return T_EXIT;
    1346                 : }
    1347                 : 
    1348                 : <ST_IN_SCRIPTING>"function" {
    1349           23529 :         return T_FUNCTION;
    1350                 : }
    1351                 : 
    1352                 : <ST_IN_SCRIPTING>"const" {
    1353             226 :         return T_CONST;
    1354                 : }
    1355                 : 
    1356                 : <ST_IN_SCRIPTING>"return" {
    1357           28027 :         return T_RETURN;
    1358                 : }
    1359                 : 
    1360                 : <ST_IN_SCRIPTING>"try" {
    1361            1748 :         return T_TRY;
    1362                 : }
    1363                 : 
    1364                 : <ST_IN_SCRIPTING>"catch" {
    1365            1755 :         return T_CATCH;
    1366                 : }
    1367                 : 
    1368                 : <ST_IN_SCRIPTING>"throw" {
    1369             230 :         return T_THROW;
    1370                 : }
    1371                 : 
    1372                 : <ST_IN_SCRIPTING>"if" {
    1373           54204 :         return T_IF;
    1374                 : }
    1375                 : 
    1376                 : <ST_IN_SCRIPTING>"elseif" {
    1377            1547 :         return T_ELSEIF;
    1378                 : }
    1379                 : 
    1380                 : <ST_IN_SCRIPTING>"endif" {
    1381               4 :         return T_ENDIF;
    1382                 : }
    1383                 : 
    1384                 : <ST_IN_SCRIPTING>"else" {
    1385           14625 :         return T_ELSE;
    1386                 : }
    1387                 : 
    1388                 : <ST_IN_SCRIPTING>"while" {
    1389            1001 :         return T_WHILE;
    1390                 : }
    1391                 : 
    1392                 : <ST_IN_SCRIPTING>"endwhile" {
    1393               1 :         return T_ENDWHILE;
    1394                 : }
    1395                 : 
    1396                 : <ST_IN_SCRIPTING>"do" {
    1397             267 :         return T_DO;
    1398                 : }
    1399                 : 
    1400                 : <ST_IN_SCRIPTING>"for" {
    1401            1840 :         return T_FOR;
    1402                 : }
    1403                 : 
    1404                 : <ST_IN_SCRIPTING>"endfor" {
    1405               3 :         return T_ENDFOR;
    1406                 : }
    1407                 : 
    1408                 : <ST_IN_SCRIPTING>"foreach" {
    1409            8915 :         return T_FOREACH;
    1410                 : }
    1411                 : 
    1412                 : <ST_IN_SCRIPTING>"endforeach" {
    1413               0 :         return T_ENDFOREACH;
    1414                 : }
    1415                 : 
    1416                 : <ST_IN_SCRIPTING>"declare" {
    1417              70 :         return T_DECLARE;
    1418                 : }
    1419                 : 
    1420                 : <ST_IN_SCRIPTING>"enddeclare" {
    1421               0 :         return T_ENDDECLARE;
    1422                 : }
    1423                 : 
    1424                 : <ST_IN_SCRIPTING>"instanceof" {
    1425              61 :         return T_INSTANCEOF;
    1426                 : }
    1427                 : 
    1428                 : <ST_IN_SCRIPTING>"as" {
    1429            8944 :         return T_AS;
    1430                 : }
    1431                 : 
    1432                 : <ST_IN_SCRIPTING>"switch" {
    1433             438 :         return T_SWITCH;
    1434                 : }
    1435                 : 
    1436                 : <ST_IN_SCRIPTING>"endswitch" {
    1437               1 :         return T_ENDSWITCH;
    1438                 : }
    1439                 : 
    1440                 : <ST_IN_SCRIPTING>"case" {
    1441            1469 :         return T_CASE;
    1442                 : }
    1443                 : 
    1444                 : <ST_IN_SCRIPTING>"default" {
    1445             264 :         return T_DEFAULT;
    1446                 : }
    1447                 : 
    1448                 : <ST_IN_SCRIPTING>"break" {
    1449            1632 :         return T_BREAK;
    1450                 : }
    1451                 : 
    1452                 : <ST_IN_SCRIPTING>"continue" {
    1453             206 :         return T_CONTINUE;
    1454                 : }
    1455                 : 
    1456                 : <ST_IN_SCRIPTING>"goto" {
    1457              24 :         return T_GOTO;
    1458                 : }
    1459                 : 
    1460                 : <ST_IN_SCRIPTING>"echo" {
    1461           25078 :         return T_ECHO;
    1462                 : }
    1463                 : 
    1464                 : <ST_IN_SCRIPTING>"print" {
    1465            2663 :         return T_PRINT;
    1466                 : }
    1467                 : 
    1468                 : <ST_IN_SCRIPTING>"class" {
    1469            5919 :         return T_CLASS;
    1470                 : }
    1471                 : 
    1472                 : <ST_IN_SCRIPTING>"interface" {
    1473             156 :         return T_INTERFACE;
    1474                 : }
    1475                 : 
    1476                 : <ST_IN_SCRIPTING>"extends" {
    1477            1996 :         return T_EXTENDS;
    1478                 : }
    1479                 : 
    1480                 : <ST_IN_SCRIPTING>"implements" {
    1481             242 :         return T_IMPLEMENTS;
    1482                 : }
    1483                 : 
    1484                 : <ST_IN_SCRIPTING>"->" {
    1485           31321 :         yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
    1486           31321 :         return T_OBJECT_OPERATOR;
    1487                 : }
    1488                 : 
    1489                 : <ST_IN_SCRIPTING,ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
    1490         1600081 :         Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    1491         1600081 :         Z_STRLEN_P(zendlval) = yyleng;
    1492         1600081 :         Z_TYPE_P(zendlval) = IS_STRING;
    1493         1600081 :         HANDLE_NEWLINES(yytext, yyleng);
    1494         1600081 :         return T_WHITESPACE;
    1495                 : }
    1496                 : 
    1497                 : <ST_LOOKING_FOR_PROPERTY>"->" {
    1498              59 :         return T_OBJECT_OPERATOR;
    1499                 : }
    1500                 : 
    1501                 : <ST_LOOKING_FOR_PROPERTY>{LABEL} {
    1502           31275 :         yy_pop_state(TSRMLS_C);
    1503           31275 :         if (!zend_copy_scanner_string(zendlval, yytext, yyleng, IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    1504               0 :                 return 0;
    1505                 :         }
    1506           31275 :         if (!zend_check_and_normalize_identifier(zendlval)) {
    1507               0 :                 return 0;
    1508                 :         }
    1509           31275 :         return T_STRING;
    1510                 : }
    1511                 : 
    1512                 : <ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} {
    1513             105 :         yyless(0);
    1514             105 :         yy_pop_state(TSRMLS_C);
    1515             105 :         goto restart;
    1516                 : }
    1517                 : 
    1518                 : <ST_IN_SCRIPTING>"::" {
    1519           14747 :         return T_PAAMAYIM_NEKUDOTAYIM;
    1520                 : }
    1521                 : 
    1522                 : <ST_IN_SCRIPTING>"\\" {
    1523             466 :         return T_NS_SEPARATOR;
    1524                 : }
    1525                 : 
    1526                 : <ST_IN_SCRIPTING>"new" {
    1527            9963 :         return T_NEW;
    1528                 : }
    1529                 : 
    1530                 : <ST_IN_SCRIPTING>"clone" {
    1531              76 :         return T_CLONE;
    1532                 : }
    1533                 : 
    1534                 : <ST_IN_SCRIPTING>"var" {
    1535             123 :         return T_VAR;
    1536                 : }
    1537                 : 
    1538                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("int"|"integer"){TABS_AND_SPACES}")" {
    1539            4449 :         return T_INT_CAST;
    1540                 : }
    1541                 : 
    1542                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("real"|"double"|"float"){TABS_AND_SPACES}")" {
    1543              19 :         return T_DOUBLE_CAST;
    1544                 : }
    1545                 : 
    1546                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"string"{TABS_AND_SPACES}")" {
    1547             380 :         return T_STRING_CAST;
    1548                 : }
    1549                 : 
    1550                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"unicode"{TABS_AND_SPACES}")" {
    1551              13 :         return T_UNICODE_CAST;
    1552                 : }
    1553                 : 
    1554                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"binary"{TABS_AND_SPACES}")" {
    1555            1326 :         return T_BINARY_CAST;
    1556                 : }
    1557                 : 
    1558                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"array"{TABS_AND_SPACES}")" {
    1559              10 :         return T_ARRAY_CAST;
    1560                 : }
    1561                 : 
    1562                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}"object"{TABS_AND_SPACES}")" {
    1563             144 :         return T_OBJECT_CAST;
    1564                 : }
    1565                 : 
    1566                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("bool"|"boolean"){TABS_AND_SPACES}")" {
    1567             241 :         return T_BOOL_CAST;
    1568                 : }
    1569                 : 
    1570                 : <ST_IN_SCRIPTING>"("{TABS_AND_SPACES}("unset"){TABS_AND_SPACES}")" {
    1571               1 :         return T_UNSET_CAST;
    1572                 : }
    1573                 : 
    1574                 : <ST_IN_SCRIPTING>"eval" {
    1575            1701 :         return T_EVAL;
    1576                 : }
    1577                 : 
    1578                 : <ST_IN_SCRIPTING>"include" {
    1579            1674 :         return T_INCLUDE;
    1580                 : }
    1581                 : 
    1582                 : <ST_IN_SCRIPTING>"include_once" {
    1583             401 :         return T_INCLUDE_ONCE;
    1584                 : }
    1585                 : 
    1586                 : <ST_IN_SCRIPTING>"require" {
    1587            1230 :         return T_REQUIRE;
    1588                 : }
    1589                 : 
    1590                 : <ST_IN_SCRIPTING>"require_once" {
    1591            5009 :         return T_REQUIRE_ONCE;
    1592                 : }
    1593                 : 
    1594                 : <ST_IN_SCRIPTING>"namespace" {
    1595             183 :         return T_NAMESPACE;
    1596                 : }
    1597                 : 
    1598                 : <ST_IN_SCRIPTING>"use" {
    1599              71 :         return T_USE;
    1600                 : }
    1601                 : 
    1602                 : <ST_IN_SCRIPTING>"global" {
    1603            3719 :         return T_GLOBAL;
    1604                 : }
    1605                 : 
    1606                 : <ST_IN_SCRIPTING>"isset" {
    1607            1869 :         return T_ISSET;
    1608                 : }
    1609                 : 
    1610                 : <ST_IN_SCRIPTING>"empty" {
    1611            5376 :         return T_EMPTY;
    1612                 : }
    1613                 : 
    1614                 : <ST_IN_SCRIPTING>"__halt_compiler" {
    1615             272 :         return T_HALT_COMPILER;
    1616                 : }
    1617                 : 
    1618                 : <ST_IN_SCRIPTING>"static" {
    1619            7283 :         return T_STATIC;
    1620                 : }
    1621                 : 
    1622                 : <ST_IN_SCRIPTING>"abstract" {
    1623             109 :         return T_ABSTRACT;
    1624                 : }
    1625                 : 
    1626                 : <ST_IN_SCRIPTING>"final" {
    1627              36 :         return T_FINAL;
    1628                 : }
    1629                 : 
    1630                 : <ST_IN_SCRIPTING>"private" {
    1631             636 :         return T_PRIVATE;
    1632                 : }
    1633                 : 
    1634                 : <ST_IN_SCRIPTING>"protected" {
    1635             536 :         return T_PROTECTED;
    1636                 : }
    1637                 : 
    1638                 : <ST_IN_SCRIPTING>"public" {
    1639            3301 :         return T_PUBLIC;
    1640                 : }
    1641                 : 
    1642                 : <ST_IN_SCRIPTING>"unset" {
    1643            1355 :         return T_UNSET;
    1644                 : }
    1645                 : 
    1646                 : <ST_IN_SCRIPTING>"=>" {
    1647           27478 :         return T_DOUBLE_ARROW;
    1648                 : }
    1649                 : 
    1650                 : <ST_IN_SCRIPTING>"list" {
    1651             111 :         return T_LIST;
    1652                 : }
    1653                 : 
    1654                 : <ST_IN_SCRIPTING>"array" {
    1655           20655 :         return T_ARRAY;
    1656                 : }
    1657                 : 
    1658                 : <ST_IN_SCRIPTING>"++" {
    1659            5560 :         return T_INC;
    1660                 : }
    1661                 : 
    1662                 : <ST_IN_SCRIPTING>"--" {
    1663              65 :         return T_DEC;
    1664                 : }
    1665                 : 
    1666                 : <ST_IN_SCRIPTING>"===" {
    1667            4773 :         return T_IS_IDENTICAL;
    1668                 : }
    1669                 : 
    1670                 : <ST_IN_SCRIPTING>"!==" {
    1671            6476 :         return T_IS_NOT_IDENTICAL;
    1672                 : }
    1673                 : 
    1674                 : <ST_IN_SCRIPTING>"==" {
    1675           11695 :         return T_IS_EQUAL;
    1676                 : }
    1677                 : 
    1678                 : <ST_IN_SCRIPTING>"!="|"<>" {
    1679            2412 :         return T_IS_NOT_EQUAL;
    1680                 : }
    1681                 : 
    1682                 : <ST_IN_SCRIPTING>"<=" {
    1683            1609 :         return T_IS_SMALLER_OR_EQUAL;
    1684                 : }
    1685                 : 
    1686                 : <ST_IN_SCRIPTING>">=" {
    1687             258 :         return T_IS_GREATER_OR_EQUAL;
    1688                 : }
    1689                 : 
    1690                 : <ST_IN_SCRIPTING>"+=" {
    1691             623 :         return T_PLUS_EQUAL;
    1692                 : }
    1693                 : 
    1694                 : <ST_IN_SCRIPTING>"-=" {
    1695             139 :         return T_MINUS_EQUAL;
    1696                 : }
    1697                 : 
    1698                 : <ST_IN_SCRIPTING>"*=" {
    1699              13 :         return T_MUL_EQUAL;
    1700                 : }
    1701                 : 
    1702                 : <ST_IN_SCRIPTING>"/=" {
    1703               4 :         return T_DIV_EQUAL;
    1704                 : }
    1705                 : 
    1706                 : <ST_IN_SCRIPTING>".=" {
    1707            1934 :         return T_CONCAT_EQUAL;
    1708                 : }
    1709                 : 
    1710                 : <ST_IN_SCRIPTING>"%=" {
    1711               1 :         return T_MOD_EQUAL;
    1712                 : }
    1713                 : 
    1714                 : <ST_IN_SCRIPTING>"<<=" {
    1715               4 :         return T_SL_EQUAL;
    1716                 : }
    1717                 : 
    1718                 : <ST_IN_SCRIPTING>">>=" {
    1719               5 :         return T_SR_EQUAL;
    1720                 : }
    1721                 : 
    1722                 : <ST_IN_SCRIPTING>"&=" {
    1723               3 :         return T_AND_EQUAL;
    1724                 : }
    1725                 : 
    1726                 : <ST_IN_SCRIPTING>"|=" {
    1727              96 :         return T_OR_EQUAL;
    1728                 : }
    1729                 : 
    1730                 : <ST_IN_SCRIPTING>"^=" {
    1731               2 :         return T_XOR_EQUAL;
    1732                 : }
    1733                 : 
    1734                 : <ST_IN_SCRIPTING>"||" {
    1735            1962 :         return T_BOOLEAN_OR;
    1736                 : }
    1737                 : 
    1738                 : <ST_IN_SCRIPTING>"&&" {
    1739            3663 :         return T_BOOLEAN_AND;
    1740                 : }
    1741                 : 
    1742                 : <ST_IN_SCRIPTING>"OR" {
    1743             639 :         return T_LOGICAL_OR;
    1744                 : }
    1745                 : 
    1746                 : <ST_IN_SCRIPTING>"AND" {
    1747               9 :         return T_LOGICAL_AND;
    1748                 : }
    1749                 : 
    1750                 : <ST_IN_SCRIPTING>"XOR" {
    1751               1 :         return T_LOGICAL_XOR;
    1752                 : }
    1753                 : 
    1754                 : <ST_IN_SCRIPTING>"<<" {
    1755             104 :         return T_SL;
    1756                 : }
    1757                 : 
    1758                 : <ST_IN_SCRIPTING>">>" {
    1759              34 :         return T_SR;
    1760                 : }
    1761                 : 
    1762                 : <ST_IN_SCRIPTING>{TOKENS} {
    1763         1802233 :         return yytext[0];
    1764                 : }
    1765                 : 
    1766                 : 
    1767                 : <ST_IN_SCRIPTING>"{" {
    1768           88992 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1769           88992 :         return '{';
    1770                 : }
    1771                 : 
    1772                 : 
    1773                 : <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"${" {
    1774              85 :         yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
    1775              85 :         return T_DOLLAR_OPEN_CURLY_BRACES;
    1776                 : }
    1777                 : 
    1778                 : 
    1779                 : <ST_IN_SCRIPTING>"}" {
    1780           89253 :         RESET_DOC_COMMENT();
    1781           89253 :         if (!zend_stack_is_empty(&SCNG(state_stack))) {
    1782           89252 :                 yy_pop_state(TSRMLS_C);
    1783                 :         }
    1784           89253 :         return '}';
    1785                 : }
    1786                 : 
    1787                 : 
    1788                 : <ST_LOOKING_FOR_VARNAME>{LABEL} {
    1789              85 :         if (!zend_copy_scanner_string(zendlval, yytext, yyleng, IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    1790               0 :                 return 0;
    1791                 :         }
    1792              85 :         if (!zend_check_and_normalize_identifier(zendlval)) {
    1793               0 :                 return 0;
    1794                 :         }
    1795              85 :         yy_pop_state(TSRMLS_C);
    1796              85 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1797              85 :         return T_STRING_VARNAME;
    1798                 : }
    1799                 : 
    1800                 : 
    1801                 : <ST_LOOKING_FOR_VARNAME>{ANY_CHAR} {
    1802               0 :         yyless(0);
    1803               0 :         yy_pop_state(TSRMLS_C);
    1804               0 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    1805               0 :         goto restart;
    1806                 : }
    1807                 : 
    1808                 : 
    1809                 : <ST_IN_SCRIPTING>{LNUM} {
    1810           79493 :         if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
    1811           78680 :                 Z_LVAL_P(zendlval) = strtol(yytext, NULL, 0);
    1812                 :         } else {
    1813             813 :                 errno = 0;
    1814             813 :                 Z_LVAL_P(zendlval) = strtol(yytext, NULL, 0);
    1815             813 :                 if (errno == ERANGE) { /* Overflow */
    1816             437 :                         if (yytext[0] == '0') { /* octal overflow */
    1817              82 :                                 Z_DVAL_P(zendlval) = zend_oct_strtod(yytext, NULL);
    1818                 :                         } else {
    1819             355 :                                 Z_DVAL_P(zendlval) = zend_strtod(yytext, NULL);
    1820                 :                         }
    1821             437 :                         Z_TYPE_P(zendlval) = IS_DOUBLE;
    1822             437 :                         return T_DNUMBER;
    1823                 :                 }
    1824                 :         }
    1825                 : 
    1826           79056 :         Z_TYPE_P(zendlval) = IS_LONG;
    1827           79056 :         return T_LNUMBER;
    1828                 : }
    1829                 : 
    1830                 : <ST_IN_SCRIPTING>{HNUM} {
    1831            1354 :         char *hex = yytext + 2; /* Skip "0x" */
    1832            1354 :         int len = yyleng - 2;
    1833                 : 
    1834                 :         /* Skip any leading 0s */
    1835            3412 :         while (*hex == '0') {
    1836             704 :                 hex++;
    1837             704 :                 len--;
    1838                 :         }
    1839                 : 
    1840            1354 :         if (len < SIZEOF_LONG * 2 || (len == SIZEOF_LONG * 2 && *hex <= '7')) {
    1841            1258 :                 Z_LVAL_P(zendlval) = strtol(hex, NULL, 16);
    1842            1258 :                 Z_TYPE_P(zendlval) = IS_LONG;
    1843            1258 :                 return T_LNUMBER;
    1844                 :         } else {
    1845              96 :                 Z_DVAL_P(zendlval) = zend_hex_strtod(hex, NULL);
    1846              96 :                 Z_TYPE_P(zendlval) = IS_DOUBLE;
    1847              96 :                 return T_DNUMBER;
    1848                 :         }
    1849                 : }
    1850                 : 
    1851                 : <ST_VAR_OFFSET>[0]|([1-9][0-9]*) { /* Offset could be treated as a long */
    1852             572 :         if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
    1853             286 :                 Z_LVAL_P(zendlval) = strtol(yytext, NULL, 10);
    1854             286 :                 Z_TYPE_P(zendlval) = IS_LONG;
    1855                 :         } else {
    1856               0 :                 if (!zend_copy_scanner_string(zendlval, yytext, yyleng, CG(literal_type), SCNG(output_conv) TSRMLS_CC)) {
    1857               0 :                         return 0;
    1858                 :                 }
    1859                 :         }
    1860             286 :         return T_NUM_STRING;
    1861                 : }
    1862                 : 
    1863                 : <ST_VAR_OFFSET>{LNUM}|{HNUM} { /* Offset must be treated as a string */
    1864               0 :         if (!zend_copy_scanner_string(zendlval, yytext, yyleng, CG(literal_type), SCNG(output_conv) TSRMLS_CC)) {
    1865               0 :                 return 0;
    1866                 :         }
    1867               0 :         return T_NUM_STRING;
    1868                 : }
    1869                 : 
    1870                 : <ST_IN_SCRIPTING>{DNUM}|{EXPONENT_DNUM} {
    1871            6817 :         Z_DVAL_P(zendlval) = zend_strtod(yytext, NULL);
    1872            6817 :         Z_TYPE_P(zendlval) = IS_DOUBLE;
    1873            6817 :         return T_DNUMBER;
    1874                 : }
    1875                 : 
    1876                 : <ST_IN_SCRIPTING>"__CLASS__" {
    1877              76 :         zstr class_name = NULL_ZSTR;
    1878                 : 
    1879              76 :         if (CG(active_class_entry)) {
    1880              75 :                 class_name = CG(active_class_entry)->name;
    1881                 :         }
    1882                 : 
    1883              76 :         if (!class_name.v) {
    1884               1 :                 ZVAL_EMPTY_UNICODE(zendlval);
    1885                 :         } else {
    1886              75 :                 ZVAL_UNICODE(zendlval, class_name.u, 1);
    1887                 :         }
    1888              76 :         return T_CLASS_C;
    1889                 : }
    1890                 : 
    1891                 : <ST_IN_SCRIPTING>"__FUNCTION__" {
    1892              98 :         zstr func_name = NULL_ZSTR;
    1893                 : 
    1894              98 :         if (CG(active_op_array)) {
    1895              97 :                 func_name = CG(active_op_array)->function_name;
    1896                 :         }
    1897                 : 
    1898              98 :         if (!func_name.v) {
    1899               2 :                 ZVAL_EMPTY_UNICODE(zendlval);
    1900                 :         } else {
    1901              96 :                 ZVAL_UNICODE(zendlval, func_name.u, 1);
    1902                 :         }
    1903              98 :         return T_FUNC_C;
    1904                 : }
    1905                 : 
    1906                 : <ST_IN_SCRIPTING>"__METHOD__" {
    1907             746 :         zstr class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL_ZSTR;
    1908             746 :         zstr func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL_ZSTR;
    1909             746 :         size_t len = 0;
    1910                 :         size_t len1;
    1911                 : 
    1912             746 :         if (class_name.u) {
    1913             724 :                 len += len1 = u_strlen(class_name.u);
    1914             724 :                 len += 2;
    1915                 :         }
    1916             746 :         if (func_name.u) {
    1917             744 :                 len += u_strlen(func_name.u);
    1918                 :         } else {
    1919               2 :                 func_name.u = EMPTY_STR;
    1920                 :         }
    1921             746 :         Z_USTRLEN_P(zendlval) = len;
    1922             746 :         Z_USTRVAL_P(zendlval) = eumalloc(len+1);
    1923             746 :         if (class_name.u) {
    1924             724 :                 u_strcpy(Z_USTRVAL_P(zendlval), class_name.u);
    1925             724 :                 Z_USTRVAL_P(zendlval)[len1] = 0x3a;   /* ':' */
    1926             724 :                 Z_USTRVAL_P(zendlval)[len1+1] = 0x3a; /* ':' */
    1927             724 :                 Z_USTRVAL_P(zendlval)[len1+2] = 0;
    1928                 :         } else {
    1929              22 :                 Z_USTRVAL_P(zendlval)[0] = 0;
    1930                 :         }
    1931             746 :         u_strcat(Z_USTRVAL_P(zendlval), func_name.u);
    1932             746 :         Z_TYPE_P(zendlval) = IS_UNICODE;
    1933                 : 
    1934             746 :         return T_METHOD_C;
    1935                 : }
    1936                 : 
    1937                 : <ST_IN_SCRIPTING>"__LINE__" {
    1938              16 :         Z_LVAL_P(zendlval) = CG(zend_lineno);
    1939              16 :         Z_TYPE_P(zendlval) = IS_LONG;
    1940              16 :         return T_LINE;
    1941                 : }
    1942                 : 
    1943                 : <ST_IN_SCRIPTING>"__FILE__" {
    1944            7428 :         char *filename = zend_get_compiled_filename(TSRMLS_C);
    1945                 : 
    1946            7428 :         if (!filename) {
    1947               0 :                 filename = "";
    1948                 :         }
    1949            7428 :         ZVAL_RT_STRING(zendlval, filename, 1);
    1950            7428 :         return T_FILE;
    1951                 : }
    1952                 : 
    1953                 : <ST_IN_SCRIPTING>"__DIR__" {
    1954              97 :         char *filename = zend_get_compiled_filename(TSRMLS_C);
    1955              97 :         const size_t filename_len = strlen(filename);
    1956                 :         char *dirname;
    1957                 : 
    1958              97 :         if (!filename) {
    1959               0 :                 filename = "";
    1960                 :         }
    1961                 : 
    1962              97 :         dirname = estrndup(filename, filename_len);
    1963              97 :         zend_dirname(dirname, filename_len);
    1964                 : 
    1965              97 :         if (strcmp(dirname, ".") == 0) {
    1966               0 :                 dirname = erealloc(dirname, MAXPATHLEN);
    1967                 : #if HAVE_GETCWD
    1968               0 :                 VCWD_GETCWD(dirname, MAXPATHLEN);
    1969                 : #elif HAVE_GETWD
    1970                 :                 VCWD_GETWD(dirname);
    1971                 : #endif
    1972                 :         }
    1973                 : 
    1974              97 :         zendlval->value.str.len = strlen(dirname);
    1975              97 :         zendlval->value.str.val = dirname;
    1976              97 :         zendlval->type = IS_STRING;
    1977              97 :         return T_DIR;
    1978                 : }
    1979                 : 
    1980                 : <ST_IN_SCRIPTING>"__NAMESPACE__" {
    1981              33 :         if (CG(current_namespace)) {
    1982              25 :                 *zendlval = *CG(current_namespace);
    1983              25 :                 zval_copy_ctor(zendlval);
    1984                 :         } else {
    1985               8 :                 ZVAL_EMPTY_UNICODE(zendlval);
    1986                 :         }
    1987              33 :         return T_NS_C;
    1988                 : }
    1989                 : 
    1990                 : <INITIAL>"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"'php'"){WHITESPACE}*">" {
    1991               5 :         YYCTYPE *bracket = zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
    1992                 : 
    1993               5 :         if (bracket != SCNG(yy_text)) {
    1994                 :                 /* Handle previously scanned HTML, as possible <script> tags found are assumed to not be PHP's */
    1995               1 :                 YYCURSOR = bracket;
    1996               1 :                 goto inline_html;
    1997                 :         }
    1998                 : 
    1999               4 :         HANDLE_NEWLINES(yytext, yyleng);
    2000               4 :         Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2001               4 :         Z_STRLEN_P(zendlval) = yyleng;
    2002               4 :         Z_TYPE_P(zendlval) = IS_STRING;
    2003               4 :         BEGIN(ST_IN_SCRIPTING);
    2004               4 :         return T_OPEN_TAG;
    2005                 : }
    2006                 : 
    2007                 : <INITIAL>"<%=" {
    2008               2 :         if (CG(asp_tags)) {
    2009               2 :                 Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2010               2 :                 Z_STRLEN_P(zendlval) = yyleng;
    2011               2 :                 Z_TYPE_P(zendlval) = IS_STRING;
    2012               2 :                 BEGIN(ST_IN_SCRIPTING);
    2013               2 :                 return T_OPEN_TAG_WITH_ECHO;
    2014                 :         } else {
    2015               0 :                 goto inline_char_handler;
    2016                 :         }
    2017                 : }
    2018                 : 
    2019                 : 
    2020                 : <INITIAL>"<?=" {
    2021               4 :         if (CG(short_tags)) {
    2022               3 :                 Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2023               3 :                 Z_STRLEN_P(zendlval) = yyleng;
    2024               3 :                 Z_TYPE_P(zendlval) = IS_STRING;
    2025               3 :                 BEGIN(ST_IN_SCRIPTING);
    2026               3 :                 return T_OPEN_TAG_WITH_ECHO;
    2027                 :         } else {
    2028               1 :                 goto inline_char_handler;
    2029                 :         }
    2030                 : }
    2031                 : 
    2032                 : 
    2033                 : <INITIAL>"<%" {
    2034               0 :         if (CG(asp_tags)) {
    2035               0 :                 Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2036               0 :                 Z_STRLEN_P(zendlval) = yyleng;
    2037               0 :                 Z_TYPE_P(zendlval) = IS_STRING;
    2038               0 :                 BEGIN(ST_IN_SCRIPTING);
    2039               0 :                 return T_OPEN_TAG;
    2040                 :         } else {
    2041               0 :                 goto inline_char_handler;
    2042                 :         }
    2043                 : }
    2044                 : 
    2045                 : 
    2046                 : <INITIAL>"<?php"([ \t]|{NEWLINE}) {
    2047           24719 :         Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2048           24719 :         Z_STRLEN_P(zendlval) = yyleng;
    2049           24719 :         Z_TYPE_P(zendlval) = IS_STRING;
    2050           24719 :         HANDLE_NEWLINE(yytext[yyleng-1]);
    2051           24719 :         BEGIN(ST_IN_SCRIPTING);
    2052           24719 :         return T_OPEN_TAG;
    2053                 : }
    2054                 : 
    2055                 : 
    2056                 : <INITIAL>"<?" {
    2057               6 :         if (CG(short_tags)) {
    2058               5 :                 Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2059               5 :                 Z_STRLEN_P(zendlval) = yyleng;
    2060               5 :                 Z_TYPE_P(zendlval) = IS_STRING;
    2061               5 :                 BEGIN(ST_IN_SCRIPTING);
    2062               5 :                 return T_OPEN_TAG;
    2063                 :         } else {
    2064               1 :                 goto inline_char_handler;
    2065                 :         }
    2066                 : }
    2067                 : 
    2068                 : <INITIAL>{ANY_CHAR} {
    2069           26639 :         if (YYCURSOR > YYLIMIT) {
    2070           23453 :                 return 0;
    2071                 :         }
    2072                 : 
    2073            3298 : inline_char_handler:
    2074                 : 
    2075                 :         while (1) {
    2076            3298 :                 YYCTYPE *ptr = memchr(YYCURSOR, '<', YYLIMIT - YYCURSOR);
    2077                 : 
    2078            3298 :                 YYCURSOR = ptr ? ptr + 1 : YYLIMIT;
    2079                 : 
    2080            3298 :                 if (YYCURSOR < YYLIMIT) {
    2081             331 :                         switch (*YYCURSOR) {
    2082                 :                                 case '?':
    2083             215 :                                         if (CG(short_tags) || !strncasecmp(YYCURSOR + 1, "php", 3)) { /* Assume [ \t\n\r] follows "php" */
    2084                 :                                                 break;
    2085                 :                                         }
    2086               2 :                                         continue;
    2087                 :                                 case '%':
    2088               4 :                                         if (CG(asp_tags)) {
    2089               2 :                                                 break;
    2090                 :                                         }
    2091               2 :                                         continue;
    2092                 :                                 case 's':
    2093                 :                                 case 'S':
    2094                 :                                         /* Probably NOT an opening PHP <script> tag, so don't end the HTML chunk yet
    2095                 :                                          * If it is, the PHP <script> tag rule checks for any HTML scanned before it */
    2096               6 :                                         YYCURSOR--;
    2097               6 :                                         yymore();
    2098                 :                                 default:
    2099             106 :                                         continue;
    2100                 :                         }
    2101                 : 
    2102             215 :                         YYCURSOR--;
    2103                 :                 }
    2104                 : 
    2105            3182 :                 break;
    2106             110 :         }
    2107                 : 
    2108            3183 : inline_html:
    2109            3183 :         yyleng = YYCURSOR - SCNG(yy_text);
    2110                 : 
    2111            3183 :         Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng);
    2112            3183 :         Z_STRLEN_P(zendlval) = yyleng;
    2113            3183 :         Z_TYPE_P(zendlval) = IS_STRING;
    2114            3183 :         HANDLE_NEWLINES(yytext, yyleng);
    2115            3183 :         return T_INLINE_HTML;
    2116                 : }
    2117                 : 
    2118                 : /* Make sure a label character follows "->", otherwise there is no property
    2119                 :  * and "->" will be taken literally
    2120                 :  */
    2121                 : <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"->"[a-zA-Z_\x7f-\xff] {
    2122              59 :         yyless(yyleng - 3);
    2123              59 :         yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
    2124                 : 
    2125              59 :         if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-1), IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    2126               0 :                 return 0;
    2127                 :         }
    2128              59 :         if (!zend_check_and_normalize_identifier(zendlval)) {
    2129               0 :                 return 0;
    2130                 :         }
    2131              59 :         return T_VARIABLE;
    2132                 : }
    2133                 : 
    2134                 : /* A [ always designates a variable offset, regardless of what follows
    2135                 :  */
    2136                 : <ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"[" {
    2137             860 :         yyless(yyleng - 1);
    2138             860 :         yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
    2139                 : 
    2140             860 :         if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-1), IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    2141               0 :                 return 0;
    2142                 :         }
    2143             860 :         if (!zend_check_and_normalize_identifier(zendlval)) {
    2144               0 :                 return 0;
    2145                 :         }
    2146             860 :         return T_VARIABLE;
    2147                 : }
    2148                 : 
    2149                 : <ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} {
    2150          553530 :         if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-1), IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    2151               0 :                 return 0;
    2152                 :         }
    2153          553530 :         if (!zend_check_and_normalize_identifier(zendlval)) {
    2154               0 :                 return 0;
    2155                 :         }
    2156          553530 :         return T_VARIABLE;
    2157                 : }
    2158                 : 
    2159                 : <ST_VAR_OFFSET>"]" {
    2160             858 :         yy_pop_state(TSRMLS_C);
    2161             858 :         return ']';
    2162                 : }
    2163                 : 
    2164                 : <ST_VAR_OFFSET>{TOKENS}|[{}"`] {
    2165                 :         /* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
    2166             860 :         return yytext[0];
    2167                 : }
    2168                 : 
    2169                 : <ST_VAR_OFFSET>[ \n\r\t\\'#] {
    2170                 :         /* Invalid rule to return a more explicit parse error with proper line number */
    2171               2 :         yyless(0);
    2172               2 :         yy_pop_state(TSRMLS_C);
    2173               2 :         return T_ENCAPSED_AND_WHITESPACE;
    2174                 : }
    2175                 : 
    2176                 : <ST_IN_SCRIPTING>{LABEL} {
    2177          352199 :         if (!zend_copy_scanner_string(zendlval, yytext, yyleng, IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    2178               0 :                 return 0;
    2179                 :         }
    2180          352199 :         if (!zend_check_and_normalize_identifier(zendlval)) {
    2181               0 :                 return 0;
    2182                 :         }
    2183          352199 :         return T_STRING;
    2184                 : }
    2185                 : 
    2186                 : <ST_VAR_OFFSET>{LABEL} {
    2187               0 :         if (!zend_copy_scanner_string(zendlval, yytext, yyleng, CG(literal_type), SCNG(output_conv) TSRMLS_CC)) {
    2188               0 :                 return 0;
    2189                 :         }
    2190               0 :         return T_STRING;
    2191                 : }
    2192                 : 
    2193                 : 
    2194                 : <ST_IN_SCRIPTING>"#"|"//" {
    2195         1274739 :         while (YYCURSOR < YYLIMIT) {
    2196         1235909 :                 switch (*YYCURSOR++) {
    2197                 :                         case '\r':
    2198             116 :                                 if (*YYCURSOR == '\n') {
    2199             116 :                                         YYCURSOR++;
    2200                 :                                 }
    2201                 :                                 /* fall through */
    2202                 :                         case '\n':
    2203           38818 :                                 CG(zend_lineno)++;
    2204           38818 :                                 break;
    2205                 :                         case '%':
    2206              27 :                                 if (!CG(asp_tags)) {
    2207              27 :                                         continue;
    2208                 :                                 }
    2209                 :                                 /* fall through */
    2210                 :                         case '?':
    2211             511 :                                 if (*YYCURSOR == '>') {
    2212               2 :                                         YYCURSOR--;
    2213               2 :                                         break;
    2214                 :                                 }
    2215                 :                                 /* fall through */
    2216                 :                         default:
    2217         1197062 :                                 continue;
    2218                 :                 }
    2219                 : 
    2220           38820 :                 break;
    2221                 :         }
    2222                 : 
    2223           38825 :         yyleng = YYCURSOR - SCNG(yy_text);
    2224                 : 
    2225           38825 :         return T_COMMENT;
    2226                 : }
    2227                 : 
    2228                 : <ST_IN_SCRIPTING>"/*"|"/**"{WHITESPACE} {
    2229                 :         int doc_com;
    2230                 : 
    2231           21348 :         if (yyleng > 2) {
    2232            2005 :                 doc_com = 1;
    2233            2005 :                 RESET_DOC_COMMENT();
    2234                 :         } else {
    2235           19343 :                 doc_com = 0;
    2236                 :         }
    2237                 : 
    2238         3534936 :         while (YYCURSOR < YYLIMIT) {
    2239         3513587 :                 if (*YYCURSOR++ == '*' && *YYCURSOR == '/') {
    2240           21347 :                         break;
    2241                 :                 }
    2242                 :         }
    2243                 : 
    2244           21348 :         if (YYCURSOR < YYLIMIT) {
    2245           21347 :                 YYCURSOR++;
    2246                 :         } else {
    2247               1 :                 zend_error(E_COMPILE_WARNING, "Unterminated comment starting line %d", CG(zend_lineno));
    2248                 :         }
    2249                 : 
    2250           21348 :         yyleng = YYCURSOR - SCNG(yy_text);
    2251           21348 :         HANDLE_NEWLINES(yytext, yyleng);
    2252                 : 
    2253           21348 :         if (doc_com) {
    2254                 :                 zval tmp;
    2255                 : 
    2256            2005 :                 if (!zend_copy_scanner_string(&tmp, yytext, yyleng, IS_UNICODE, SCNG(output_conv) TSRMLS_CC)) {
    2257               0 :                         return 0;
    2258                 :                 }
    2259            2005 :                 CG(doc_comment) = tmp.value.uni.val;
    2260            2005 :                 CG(doc_comment_len) = tmp.value.uni.len;
    2261            2005 :                 return T_DOC_COMMENT;
    2262                 :         }
    2263                 : 
    2264           19343 :         return T_COMMENT;
    2265                 : }
    2266                 : 
    2267                 : <ST_IN_SCRIPTING>("?>"|"</script"{WHITESPACE}*">"){NEWLINE}? {
    2268           23759 :         Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2269           23759 :         Z_STRLEN_P(zendlval) = yyleng;
    2270           23759 :         Z_TYPE_P(zendlval) = IS_STRING;
    2271           23759 :         BEGIN(INITIAL);
    2272           23759 :         return T_CLOSE_TAG;  /* implicit ';' at php-end tag */
    2273                 : }
    2274                 : 
    2275                 : 
    2276                 : <ST_IN_SCRIPTING>"%>"{NEWLINE}? {
    2277               2 :         if (CG(asp_tags)) {
    2278               2 :                 BEGIN(INITIAL);
    2279               2 :                 Z_STRLEN_P(zendlval) = yyleng;
    2280               2 :                 Z_TYPE_P(zendlval) = IS_STRING;
    2281               2 :                 Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
    2282               2 :                 return T_CLOSE_TAG;  /* implicit ';' at php-end tag */
    2283                 :         } else {
    2284               0 :                 yyless(1);
    2285               0 :                 return yytext[0];
    2286                 :         }
    2287                 : }
    2288                 : 
    2289                 : 
    2290                 : <ST_IN_SCRIPTING>b?['] {
    2291          186608 :         int bprefix = (yytext[0] != '\'') ? 1 : 0;
    2292                 : 
    2293                 :         while (1) {
    2294         1830315 :                 if (YYCURSOR < YYLIMIT) {
    2295         1830314 :                         if (*YYCURSOR == '\'') {
    2296          186607 :                                 YYCURSOR++;
    2297          186607 :                                 yyleng = YYCURSOR - SCNG(yy_text);
    2298                 : 
    2299                 :                                 break;
    2300         1643707 :                         } else if (*YYCURSOR++ == '\\' && YYCURSOR < YYLIMIT) {
    2301           11307 :                                 YYCURSOR++;
    2302                 :                         }
    2303                 :                 } else {
    2304               1 :                         yyleng = YYLIMIT - SCNG(yy_text);
    2305                 : 
    2306                 :                         /* Unclosed single quotes; treat similar to double quotes, but without a separate token
    2307                 :                          * for ' (unrecognized by parser), instead of old flex fallback to "Unexpected character..."
    2308                 :                          * rule, which continued in ST_IN_SCRIPTING state after the quote */
    2309               1 :                         return T_ENCAPSED_AND_WHITESPACE;
    2310                 :                 }
    2311         1643707 :         }
    2312                 : 
    2313          186607 :         if (bprefix) {
    2314             936 :                 zend_scan_binary_single_string(zendlval, yytext+2, yyleng-3 TSRMLS_CC);
    2315             936 :                 return T_CONSTANT_ENCAPSED_STRING;
    2316                 :         } else {
    2317          185671 :                 return zend_scan_unicode_single_string(zendlval TSRMLS_CC);
    2318                 :         }
    2319                 : }
    2320                 : 
    2321                 : 
    2322                 : <ST_IN_SCRIPTING>b?["] {
    2323          159943 :         int bprefix = (yytext[0] != '"') ? 1 : 0;
    2324                 : 
    2325         2891175 :         while (YYCURSOR < YYLIMIT) {
    2326         2731231 :                 switch (*YYCURSOR++) {
    2327                 :                         case '"':
    2328          149439 :                                 yyleng = YYCURSOR - SCNG(yy_text);
    2329                 : 
    2330          149439 :                                 if (bprefix) {
    2331            1065 :                                         zend_scan_binary_escape_string(zendlval, yytext+2, yyleng-3, '"' TSRMLS_CC);
    2332            1065 :                                         return T_CONSTANT_ENCAPSED_STRING;
    2333                 :                                 } else {
    2334          148374 :                                         return zend_scan_unicode_escape_string(zendlval, yytext+1, yyleng-2, 0x22 /*'"'*/, T_CONSTANT_ENCAPSED_STRING TSRMLS_CC);
    2335                 :                                 }
    2336                 :                         case '$':
    2337           10673 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2338                 :                                         break;
    2339                 :                                 }
    2340             361 :                                 continue;
    2341                 :                         case '{':
    2342             302 :                                 if (*YYCURSOR == '$') {
    2343             191 :                                         break;
    2344                 :                                 }
    2345             111 :                                 continue;
    2346                 :                         case '\\':
    2347           43701 :                                 if (YYCURSOR < YYLIMIT) {
    2348           43701 :                                         YYCURSOR++;
    2349                 :                                 }
    2350                 :                                 /* fall through */
    2351                 :                         default:
    2352         2570817 :                                 continue;
    2353                 :                 }
    2354                 : 
    2355           10503 :                 YYCURSOR--;
    2356           10503 :                 break;
    2357                 :         }
    2358                 : 
    2359                 :         /* Remember how much was scanned to save rescanning */
    2360           10504 :         SET_DOUBLE_QUOTES_SCANNED_LENGTH(YYCURSOR - SCNG(yy_text) - yyleng);
    2361                 : 
    2362           10504 :         YYCURSOR = SCNG(yy_text) + yyleng;
    2363                 : 
    2364           10504 :         BEGIN(ST_DOUBLE_QUOTES);
    2365           10504 :         return bprefix ? T_BINARY_DOUBLE : '"';
    2366                 : }
    2367                 : 
    2368                 : 
    2369                 : <ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
    2370                 :         char *s;
    2371            1382 :         int bprefix = (yytext[0] != '<') ? 1 : 0;
    2372                 : 
    2373                 :         /* save old heredoc label */
    2374            1382 :         Z_STRVAL_P(zendlval) = CG(heredoc);
    2375            1382 :         Z_STRLEN_P(zendlval) = CG(heredoc_len);
    2376                 : 
    2377            1382 :         CG(zend_lineno)++;
    2378            1382 :         CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
    2379            1382 :         s = yytext+bprefix+3;
    2380            2791 :         while ((*s == ' ') || (*s == '\t')) {
    2381              27 :                 s++;
    2382              27 :                 CG(heredoc_len)--;
    2383                 :         }
    2384                 : 
    2385            1382 :         if (*s == '\'') {
    2386              42 :                 s++;
    2387              42 :                 CG(heredoc_len) -= 2;
    2388                 : 
    2389              42 :                 BEGIN(ST_NOWDOC);
    2390                 :         } else {
    2391            1340 :                 if (*s == '"') {
    2392               9 :                         s++;
    2393               9 :                         CG(heredoc_len) -= 2;
    2394                 :                 }
    2395                 : 
    2396            1340 :                 BEGIN(ST_HEREDOC);
    2397                 :         }
    2398                 : 
    2399            1382 :         CG(heredoc) = estrndup(s, CG(heredoc_len));
    2400                 : 
    2401                 :         /* Check for ending label on the next line */
    2402            1382 :         if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
    2403              64 :                 YYCTYPE *end = YYCURSOR + CG(heredoc_len);
    2404                 : 
    2405              64 :                 if (*end == ';') {
    2406              59 :                         end++;
    2407                 :                 }
    2408                 : 
    2409              64 :                 if (*end == '\n' || *end == '\r') {
    2410              60 :                         BEGIN(ST_END_HEREDOC);
    2411                 :                 }
    2412                 :         }
    2413                 : 
    2414            1382 :         return bprefix ? T_BINARY_HEREDOC : T_START_HEREDOC;
    2415                 : }
    2416                 : 
    2417                 : 
    2418                 : <ST_IN_SCRIPTING>[`] {
    2419             105 :         BEGIN(ST_BACKQUOTE);
    2420             105 :         return '`';
    2421                 : }
    2422                 : 
    2423                 : 
    2424                 : <ST_END_HEREDOC>{ANY_CHAR} {
    2425            1380 :         YYCURSOR += CG(heredoc_len) - 1;
    2426            1380 :         yyleng = CG(heredoc_len);
    2427                 : 
    2428            1380 :         Z_STRVAL_P(zendlval) = CG(heredoc);
    2429            1380 :         Z_STRLEN_P(zendlval) = CG(heredoc_len);
    2430            1380 :         CG(heredoc) = NULL;
    2431            1380 :         CG(heredoc_len) = 0;
    2432            1380 :         BEGIN(ST_IN_SCRIPTING);
    2433            1380 :         return T_END_HEREDOC;
    2434                 : }
    2435                 : 
    2436                 : 
    2437                 : <ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"{$" {
    2438             261 :         Z_LVAL_P(zendlval) = (long) '{';
    2439             261 :         yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
    2440             261 :         yyless(1);
    2441             261 :         return T_CURLY_OPEN;
    2442                 : }
    2443                 : 
    2444                 : 
    2445                 : <ST_DOUBLE_QUOTES>["] {
    2446           10501 :         BEGIN(ST_IN_SCRIPTING);
    2447           10501 :         return '"';
    2448                 : }
    2449                 : 
    2450                 : <ST_BACKQUOTE>[`] {
    2451             105 :         BEGIN(ST_IN_SCRIPTING);
    2452             105 :         return '`';
    2453                 : }
    2454                 : 
    2455                 : 
    2456                 : <ST_DOUBLE_QUOTES>{ANY_CHAR} {
    2457           18430 :         if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
    2458            6996 :                 YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
    2459            6996 :                 SET_DOUBLE_QUOTES_SCANNED_LENGTH(0);
    2460                 : 
    2461            6996 :                 goto double_quotes_scan_done;
    2462                 :         }
    2463                 : 
    2464           11434 :         if (YYCURSOR > YYLIMIT) {
    2465               1 :                 return 0;
    2466                 :         }
    2467           11433 :         if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
    2468            1349 :                 YYCURSOR++;
    2469                 :         }
    2470                 : 
    2471           72517 :         while (YYCURSOR < YYLIMIT) {
    2472           61084 :                 switch (*YYCURSOR++) {
    2473                 :                         case '"':
    2474            6638 :                                 break;
    2475                 :                         case '$':
    2476            4753 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2477                 :                                         break;
    2478                 :                                 }
    2479               1 :                                 continue;
    2480                 :                         case '{':
    2481              57 :                                 if (*YYCURSOR == '$') {
    2482              43 :                                         break;
    2483                 :                                 }
    2484              14 :                                 continue;
    2485                 :                         case '\\':
    2486            4406 :                                 if (YYCURSOR < YYLIMIT) {
    2487            4406 :                                         YYCURSOR++;
    2488                 :                                 }
    2489                 :                                 /* fall through */
    2490                 :                         default:
    2491           49636 :                                 continue;
    2492                 :                 }
    2493                 : 
    2494           11433 :                 YYCURSOR--;
    2495           11433 :                 break;
    2496                 :         }
    2497                 : 
    2498           18429 : double_quotes_scan_done:
    2499           18429 :         yyleng = YYCURSOR - SCNG(yy_text);
    2500                 : 
    2501           18429 :         if (CG(literal_type) == IS_UNICODE) {
    2502           18398 :                 return zend_scan_unicode_escape_string(zendlval, yytext, yyleng, 0x22 /*'"'*/, T_ENCAPSED_AND_WHITESPACE TSRMLS_CC);
    2503                 :         } else {
    2504              31 :                 zend_scan_binary_escape_string(zendlval, yytext, yyleng, '"' TSRMLS_CC);
    2505              31 :                 return T_ENCAPSED_AND_WHITESPACE;
    2506                 :         }
    2507                 : }
    2508                 : 
    2509                 : 
    2510                 : <ST_BACKQUOTE>{ANY_CHAR} {
    2511             180 :         if (YYCURSOR > YYLIMIT) {
    2512               0 :                 return 0;
    2513                 :         }
    2514             180 :         if (yytext[0] == '\\' && YYCURSOR < YYLIMIT) {
    2515               0 :                 YYCURSOR++;
    2516                 :         }
    2517                 : 
    2518            2526 :         while (YYCURSOR < YYLIMIT) {
    2519            2346 :                 switch (*YYCURSOR++) {
    2520                 :                         case '`':
    2521              92 :                                 break;
    2522                 :                         case '$':
    2523              88 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2524                 :                                         break;
    2525                 :                                 }
    2526               0 :                                 continue;
    2527                 :                         case '{':
    2528               4 :                                 if (*YYCURSOR == '$') {
    2529               0 :                                         break;
    2530                 :                                 }
    2531               4 :                                 continue;
    2532                 :                         case '\\':
    2533               6 :                                 if (YYCURSOR < YYLIMIT) {
    2534               6 :                                         YYCURSOR++;
    2535                 :                                 }
    2536                 :                                 /* fall through */
    2537                 :                         default:
    2538            2162 :                                 continue;
    2539                 :                 }
    2540                 : 
    2541             180 :                 YYCURSOR--;
    2542             180 :                 break;
    2543                 :         }
    2544                 : 
    2545             180 :         yyleng = YYCURSOR - SCNG(yy_text);
    2546                 : 
    2547             180 :         if (CG(literal_type) == IS_UNICODE) {
    2548             180 :                 return zend_scan_unicode_escape_string(zendlval, yytext, yyleng, 0x60 /*'`'*/, T_ENCAPSED_AND_WHITESPACE TSRMLS_CC);
    2549                 :         } else {
    2550               0 :                 zend_scan_binary_escape_string(zendlval, yytext, yyleng, '`' TSRMLS_CC);
    2551               0 :                 return T_ENCAPSED_AND_WHITESPACE;
    2552                 :         }
    2553                 : }
    2554                 : 
    2555                 : 
    2556                 : <ST_HEREDOC>{ANY_CHAR} {
    2557            1745 :         int newline = 0;
    2558                 : 
    2559            1745 :         if (YYCURSOR > YYLIMIT) {
    2560               0 :                 return 0;
    2561                 :         }
    2562                 : 
    2563            1745 :         YYCURSOR--;
    2564                 : 
    2565          317149 :         while (YYCURSOR < YYLIMIT) {
    2566          315404 :                 switch (*YYCURSOR++) {
    2567                 :                         case '\r':
    2568               0 :                                 if (*YYCURSOR == '\n') {
    2569               0 :                                         YYCURSOR++;
    2570                 :                                 }
    2571                 :                                 /* fall through */
    2572                 :                         case '\n':
    2573                 :                                 /* Check for ending label on the next line */
    2574            9380 :                                 if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
    2575            1287 :                                         YYCTYPE *end = YYCURSOR + CG(heredoc_len);
    2576                 : 
    2577            1287 :                                         if (*end == ';') {
    2578            1266 :                                                 end++;
    2579                 :                                         }
    2580                 : 
    2581            1287 :                                         if (*end == '\n' || *end == '\r') {
    2582                 :                                                 /* newline before label will be subtracted from returned text, but
    2583                 :                                                  * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */
    2584            1283 :                                                 if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') {
    2585               0 :                                                         newline = 2; /* Windows newline */
    2586                 :                                                 } else {
    2587            1283 :                                                         newline = 1;
    2588                 :                                                 }
    2589                 : 
    2590            1283 :                                                 CG(increment_lineno) = 1; /* For newline before label */
    2591            1283 :                                                 BEGIN(ST_END_HEREDOC);
    2592                 : 
    2593            1283 :                                                 goto heredoc_scan_done;
    2594                 :                                         }
    2595                 :                                 }
    2596            8097 :                                 continue;
    2597                 :                         case '$':
    2598             509 :                                 if (IS_LABEL_START(*YYCURSOR) || *YYCURSOR == '{') {
    2599                 :                                         break;
    2600                 :                                 }
    2601              70 :                                 continue;
    2602                 :                         case '{':
    2603              47 :                                 if (*YYCURSOR == '$') {
    2604              23 :                                         break;
    2605                 :                                 }
    2606              24 :                                 continue;
    2607                 :                         case '\\':
    2608             625 :                                 if (YYCURSOR < YYLIMIT && *YYCURSOR != '\n' && *YYCURSOR != '\r') {
    2609             617 :                                         YYCURSOR++;
    2610                 :                                 }
    2611                 :                                 /* fall through */
    2612                 :                         default:
    2613          305468 :                                 continue;
    2614                 :                 }
    2615                 : 
    2616             462 :                 YYCURSOR--;
    2617             462 :                 break;
    2618                 :         }
    2619                 : 
    2620            1745 : heredoc_scan_done:
    2621            1745 :         yyleng = YYCURSOR - SCNG(yy_text);
    2622                 : 
    2623            1745 :         if (CG(literal_type) == IS_UNICODE) {
    2624            1644 :                 return zend_scan_unicode_escape_string(zendlval, yytext, yyleng - newline, 0, T_ENCAPSED_AND_WHITESPACE TSRMLS_CC);
    2625                 :         } else {
    2626             101 :                 zend_scan_binary_escape_string(zendlval, yytext, yyleng - newline, 0 TSRMLS_CC);
    2627             101 :                 return T_ENCAPSED_AND_WHITESPACE;
    2628                 :         }
    2629                 : }
    2630                 : 
    2631                 : 
    2632                 : <ST_NOWDOC>{ANY_CHAR} {
    2633              37 :         int newline = 0;
    2634                 : 
    2635              37 :         if (YYCURSOR > YYLIMIT) {
    2636               0 :                 return 0;
    2637                 :         }
    2638                 : 
    2639              37 :         YYCURSOR--;
    2640                 : 
    2641            1404 :         while (YYCURSOR < YYLIMIT) {
    2642            1367 :                 switch (*YYCURSOR++) {
    2643                 :                         case '\r':
    2644               0 :                                 if (*YYCURSOR == '\n') {
    2645               0 :                                         YYCURSOR++;
    2646                 :                                 }
    2647                 :                                 /* fall through */
    2648                 :                         case '\n':
    2649                 :                                 /* Check for ending label on the next line */
    2650              91 :                                 if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
    2651              42 :                                         YYCTYPE *end = YYCURSOR + CG(heredoc_len);
    2652                 : 
    2653              42 :                                         if (*end == ';') {
    2654              34 :                                                 end++;
    2655                 :                                         }
    2656                 : 
    2657              42 :                                         if (*end == '\n' || *end == '\r') {
    2658                 :                                                 /* newline before label will be subtracted from returned text, but
    2659                 :                                                  * yyleng/yytext will include it, for zend_highlight/strip, tokenizer, etc. */
    2660              37 :                                                 if (YYCURSOR[-2] == '\r' && YYCURSOR[-1] == '\n') {
    2661               0 :                                                         newline = 2; /* Windows newline */
    2662                 :                                                 } else {
    2663              37 :                                                         newline = 1;
    2664                 :                                                 }
    2665                 : 
    2666              37 :                                                 CG(increment_lineno) = 1; /* For newline before label */
    2667              37 :                                                 BEGIN(ST_END_HEREDOC);
    2668                 : 
    2669              37 :                                                 goto nowdoc_scan_done;
    2670                 :                                         }
    2671                 :                                 }
    2672                 :                                 /* fall through */
    2673                 :                         default:
    2674                 :                                 continue;
    2675                 :                 }
    2676                 :         }
    2677                 : 
    2678              37 : nowdoc_scan_done:
    2679              37 :         yyleng = YYCURSOR - SCNG(yy_text);
    2680                 : 
    2681              37 :         if (!zend_copy_scanner_string(zendlval, yytext, yyleng - newline, CG(literal_type), SCNG(output_conv) TSRMLS_CC)) {
    2682               0 :                 return 0;
    2683                 :         }
    2684              37 :         HANDLE_NEWLINES(yytext, yyleng - newline);
    2685              37 :         return T_ENCAPSED_AND_WHITESPACE;
    2686                 : }
    2687                 : 
    2688                 : 
    2689                 : <ST_IN_SCRIPTING,ST_VAR_OFFSET>{ANY_CHAR} {
    2690            1445 :         if (YYCURSOR > YYLIMIT) {
    2691            1445 :                 return 0;
    2692                 :         }
    2693                 : 
    2694               0 :         zend_error(E_COMPILE_WARNING,"Unexpected character in input:  '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
    2695               0 :         goto restart;
    2696                 : }
    2697                 : 
    2698                 : */
    2699                 : }

Generated by: LTP GCOV extension version 1.5

Generated at Mon, 23 Nov 2009 17:39:45 +0000 (35 hours ago)

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