mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
MFB 5.3: Rewrite scanner to be based on re2c instead of flex
There are still changes in regards to parsing of Unicode encoded scripts to come.
This commit is contained in:
parent
f2ca4aaf6a
commit
e55a0de496
186
Zend/FlexLexer.h
186
Zend/FlexLexer.h
@ -1,186 +0,0 @@
|
||||
// $Header$
|
||||
|
||||
// FlexLexer.h -- define interfaces for lexical analyzer classes generated
|
||||
// by flex
|
||||
|
||||
// Copyright (c) 1993 The Regents of the University of California.
|
||||
// All rights reserved.
|
||||
//
|
||||
// This code is derived from software contributed to Berkeley by
|
||||
// Kent Williams and Tom Epperly.
|
||||
//
|
||||
// Redistribution and use in source and binary forms with or without
|
||||
// modification are permitted provided that: (1) source distributions retain
|
||||
// this entire copyright notice and comment, and (2) distributions including
|
||||
// binaries display the following acknowledgement: ``This product includes
|
||||
// software developed by the University of California, Berkeley and its
|
||||
// contributors'' in the documentation or other materials provided with the
|
||||
// distribution and in all advertising materials mentioning features or use
|
||||
// of this software. Neither the name of the University nor the names of
|
||||
// its contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
|
||||
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
// This file defines FlexLexer, an abstract class which specifies the
|
||||
// external interface provided to flex C++ lexer objects, and yyFlexLexer,
|
||||
// which defines a particular lexer class.
|
||||
//
|
||||
// If you want to create multiple lexer classes, you use the -P flag
|
||||
// to rename each yyFlexLexer to some other xxFlexLexer. You then
|
||||
// include <FlexLexer.h> in your other sources once per lexer class:
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer xxFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
//
|
||||
// #undef yyFlexLexer
|
||||
// #define yyFlexLexer zzFlexLexer
|
||||
// #include <FlexLexer.h>
|
||||
// ...
|
||||
|
||||
#ifndef FLEXLEXER_H
|
||||
// Never included before - need to define base class.
|
||||
#define FLEXLEXER_H
|
||||
#include <iostream.h>
|
||||
|
||||
extern "C++" {
|
||||
|
||||
struct yy_buffer_state;
|
||||
typedef int yy_state_type;
|
||||
|
||||
class FlexLexer {
|
||||
public:
|
||||
virtual ~FlexLexer() { }
|
||||
|
||||
const char* YYText() { return yytext; }
|
||||
int YYLeng() { return yyleng; }
|
||||
|
||||
virtual void
|
||||
yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0;
|
||||
virtual struct yy_buffer_state*
|
||||
yy_create_buffer( istream* s, int size ) = 0;
|
||||
virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0;
|
||||
virtual void yyrestart( istream* s ) = 0;
|
||||
|
||||
virtual int yylex() = 0;
|
||||
|
||||
// Call yylex with new input/output sources.
|
||||
int yylex( istream* new_in, ostream* new_out = 0 )
|
||||
{
|
||||
switch_streams( new_in, new_out );
|
||||
return yylex();
|
||||
}
|
||||
|
||||
// Switch to new input/output streams. A nil stream pointer
|
||||
// indicates "keep the current one".
|
||||
virtual void switch_streams( istream* new_in = 0,
|
||||
ostream* new_out = 0 ) = 0;
|
||||
|
||||
int lineno() const { return yylineno; }
|
||||
|
||||
int debug() const { return yy_flex_debug; }
|
||||
void set_debug( int flag ) { yy_flex_debug = flag; }
|
||||
|
||||
protected:
|
||||
char* yytext;
|
||||
int yyleng;
|
||||
int yylineno; // only maintained if you use %option yylineno
|
||||
int yy_flex_debug; // only has effect with -d or "%option debug"
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
|
||||
// Either this is the first time through (yyFlexLexerOnce not defined),
|
||||
// or this is a repeated include to define a different flavor of
|
||||
// yyFlexLexer, as discussed in the flex man page.
|
||||
#define yyFlexLexerOnce
|
||||
|
||||
class yyFlexLexer : public FlexLexer {
|
||||
public:
|
||||
// arg_yyin and arg_yyout default to the cin and cout, but we
|
||||
// only make that assignment when initializing in yylex().
|
||||
yyFlexLexer( istream* arg_yyin = 0, ostream* arg_yyout = 0 );
|
||||
|
||||
virtual ~yyFlexLexer();
|
||||
|
||||
void yy_switch_to_buffer( struct yy_buffer_state* new_buffer );
|
||||
struct yy_buffer_state* yy_create_buffer( istream* s, int size );
|
||||
void yy_delete_buffer( struct yy_buffer_state* b );
|
||||
void yyrestart( istream* s );
|
||||
|
||||
virtual int yylex();
|
||||
virtual void switch_streams( istream* new_in, ostream* new_out );
|
||||
|
||||
protected:
|
||||
virtual int LexerInput( char* buf, int max_size );
|
||||
virtual void LexerOutput( const char* buf, int size );
|
||||
virtual void LexerError( const char* msg );
|
||||
|
||||
void yyunput( int c, char* buf_ptr );
|
||||
int yyinput();
|
||||
|
||||
void yy_load_buffer_state();
|
||||
void yy_init_buffer( struct yy_buffer_state* b, istream* s );
|
||||
void yy_flush_buffer( struct yy_buffer_state* b );
|
||||
|
||||
int yy_start_stack_ptr;
|
||||
int yy_start_stack_depth;
|
||||
int* yy_start_stack;
|
||||
|
||||
void yy_push_state( int new_state );
|
||||
void yy_pop_state();
|
||||
int yy_top_state();
|
||||
|
||||
yy_state_type yy_get_previous_state();
|
||||
yy_state_type yy_try_NUL_trans( yy_state_type current_state );
|
||||
int yy_get_next_buffer();
|
||||
|
||||
istream* yyin; // input source for default LexerInput
|
||||
ostream* yyout; // output sink for default LexerOutput
|
||||
|
||||
struct yy_buffer_state* yy_current_buffer;
|
||||
|
||||
// yy_hold_char holds the character lost when yytext is formed.
|
||||
char yy_hold_char;
|
||||
|
||||
// Number of characters read into yy_ch_buf.
|
||||
int yy_n_chars;
|
||||
|
||||
// Points to current character in buffer.
|
||||
char* yy_c_buf_p;
|
||||
|
||||
int yy_init; // whether we need to initialize
|
||||
int yy_start; // start state number
|
||||
|
||||
// Flag which is used to allow yywrap()'s to do buffer switches
|
||||
// instead of setting up a fresh yyin. A bit of a hack ...
|
||||
int yy_did_buffer_switch_on_eof;
|
||||
|
||||
// The following are not always needed, but may be depending
|
||||
// on use of certain flex features (like REJECT or yymore()).
|
||||
|
||||
yy_state_type yy_last_accepting_state;
|
||||
char* yy_last_accepting_cpos;
|
||||
|
||||
yy_state_type* yy_state_buf;
|
||||
yy_state_type* yy_state_ptr;
|
||||
|
||||
char* yy_full_match;
|
||||
int* yy_full_state;
|
||||
int yy_full_lp;
|
||||
|
||||
int yy_lp;
|
||||
int yy_looking_for_trail_begin;
|
||||
|
||||
int yy_more_flag;
|
||||
int yy_more_len;
|
||||
int yy_more_offset;
|
||||
int yy_prev_more_offset;
|
||||
};
|
||||
|
||||
#endif
|
@ -31,7 +31,7 @@ zend_ini_scanner.lo: zend_ini_parser.h
|
||||
# Language parser/scanner rules
|
||||
|
||||
zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
|
||||
$(LEX) -Pzend -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_language_scanner.l
|
||||
$(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_language_scanner_defs.h -o$@ $(srcdir)/zend_language_scanner.l
|
||||
|
||||
zend_language_parser.h: zend_language_parser.c
|
||||
zend_language_parser.c: $(srcdir)/zend_language_parser.y
|
||||
@ -43,7 +43,7 @@ zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
|
||||
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o zend_ini_parser.c
|
||||
|
||||
zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
|
||||
$(LEX) -Pini_ -S$(srcdir)/flex.skl -o$@ -i $(srcdir)/zend_ini_scanner.l
|
||||
$(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_ini_scanner_defs.h -o$@ $(srcdir)/zend_ini_scanner.l
|
||||
|
||||
zend_ini_parser.h: zend_ini_parser.c
|
||||
|
||||
|
@ -31,7 +31,6 @@ AC_DEFUN([LIBZEND_BASIC_CHECKS],[
|
||||
AC_REQUIRE([AC_PROG_YACC])
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([AC_PROG_CC_C_O])
|
||||
AC_REQUIRE([AC_PROG_LEX])
|
||||
AC_REQUIRE([AC_HEADER_STDC])
|
||||
|
||||
LIBZEND_BISON_CHECK
|
||||
|
@ -7,7 +7,6 @@ AM_CONFIG_HEADER(zend_config.h)
|
||||
AM_SANITY_CHECK
|
||||
AM_MAINTAINER_MODE
|
||||
AC_PROG_CC
|
||||
AM_PROG_LEX
|
||||
AM_PROG_CC_STDC
|
||||
ZEND_VERSION=$VERSION
|
||||
AC_ZEND_C_BIGENDIAN
|
||||
|
1636
Zend/flex.skl
1636
Zend/flex.skl
File diff suppressed because it is too large
Load Diff
@ -21,6 +21,9 @@ class Loader {
|
||||
function stream_eof() {
|
||||
return $this->position >= strlen($this->data);
|
||||
}
|
||||
function stream_stat() {
|
||||
return array('size' => strlen($this->data));
|
||||
}
|
||||
}
|
||||
stream_wrapper_register('Loader', 'Loader');
|
||||
require 'Loader://qqq.php';
|
||||
|
@ -1,5 +1,12 @@
|
||||
--TEST--
|
||||
Bug #42767 (highlight_string() truncates trailing comments)
|
||||
--INI--
|
||||
highlight.string = #DD0000
|
||||
highlight.comment = #FF8000
|
||||
highlight.keyword = #007700
|
||||
highlight.bg = #FFFFFF
|
||||
highlight.default = #0000BB
|
||||
highlight.html = #000000
|
||||
--FILE--
|
||||
<?php
|
||||
highlight_string('<?php /*some comment..');
|
||||
|
32
Zend/zend.c
32
Zend/zend.c
@ -928,19 +928,15 @@ static void zend_new_thread_end_handler(THREAD_T thread_id TSRMLS_DC) /* {{{ */
|
||||
#include <floatingpoint.h>
|
||||
#endif
|
||||
|
||||
static void scanner_globals_ctor(zend_scanner_globals *scanner_globals_p TSRMLS_DC) /* {{{ */
|
||||
static void ini_scanner_globals_ctor(zend_ini_scanner_globals *scanner_globals_p TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
scanner_globals_p->c_buf_p = (char *) 0;
|
||||
scanner_globals_p->init = 1;
|
||||
scanner_globals_p->start = 0;
|
||||
scanner_globals_p->current_buffer = NULL;
|
||||
scanner_globals_p->yy_in = NULL;
|
||||
scanner_globals_p->yy_out = NULL;
|
||||
scanner_globals_p->_yy_more_flag = 0;
|
||||
scanner_globals_p->_yy_more_len = 0;
|
||||
scanner_globals_p->yy_start_stack_ptr = 0;
|
||||
scanner_globals_p->yy_start_stack_depth = 0;
|
||||
scanner_globals_p->yy_start_stack = 0;
|
||||
memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void php_scanner_globals_ctor(zend_php_scanner_globals *scanner_globals_p TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
memset(scanner_globals_p, 0, sizeof(*scanner_globals_p));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1022,8 +1018,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
|
||||
extern ZEND_API ts_rsrc_id language_scanner_globals_id;
|
||||
extern ZEND_API ts_rsrc_id unicode_globals_id;
|
||||
#else
|
||||
extern zend_scanner_globals ini_scanner_globals;
|
||||
extern zend_scanner_globals language_scanner_globals;
|
||||
extern zend_ini_scanner_globals ini_scanner_globals;
|
||||
extern zend_php_scanner_globals language_scanner_globals;
|
||||
extern zend_unicode_globals unicode_globals;
|
||||
#endif
|
||||
TSRMLS_FETCH();
|
||||
@ -1104,8 +1100,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
|
||||
ts_allocate_id(&unicode_globals_id, sizeof(zend_unicode_globals), (ts_allocate_ctor) unicode_globals_ctor, (ts_allocate_dtor) unicode_globals_dtor);
|
||||
ts_allocate_id(&compiler_globals_id, sizeof(zend_compiler_globals), (ts_allocate_ctor) compiler_globals_ctor, (ts_allocate_dtor) compiler_globals_dtor);
|
||||
ts_allocate_id(&executor_globals_id, sizeof(zend_executor_globals), (ts_allocate_ctor) executor_globals_ctor, (ts_allocate_dtor) executor_globals_dtor);
|
||||
ts_allocate_id(&language_scanner_globals_id, sizeof(zend_scanner_globals), (ts_allocate_ctor) scanner_globals_ctor, NULL);
|
||||
ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_scanner_globals), (ts_allocate_ctor) scanner_globals_ctor, NULL);
|
||||
ts_allocate_id(&language_scanner_globals_id, sizeof(zend_php_scanner_globals), (ts_allocate_ctor) php_scanner_globals_ctor, NULL);
|
||||
ts_allocate_id(&ini_scanner_globals_id, sizeof(zend_ini_scanner_globals), (ts_allocate_ctor) ini_scanner_globals_ctor, NULL);
|
||||
compiler_globals = ts_resource(compiler_globals_id);
|
||||
executor_globals = ts_resource(executor_globals_id);
|
||||
tsrm_ls = ts_resource_ex(0, NULL);
|
||||
@ -1123,8 +1119,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
|
||||
*executor_globals->zend_constants = *GLOBAL_CONSTANTS_TABLE;
|
||||
#else
|
||||
unicode_globals_ctor(&unicode_globals TSRMLS_CC);
|
||||
scanner_globals_ctor(&ini_scanner_globals TSRMLS_CC);
|
||||
scanner_globals_ctor(&language_scanner_globals TSRMLS_CC);
|
||||
ini_scanner_globals_ctor(&ini_scanner_globals TSRMLS_CC);
|
||||
php_scanner_globals_ctor(&language_scanner_globals TSRMLS_CC);
|
||||
zend_set_default_compile_time_values(TSRMLS_C);
|
||||
EG(user_error_handler) = NULL;
|
||||
EG(user_exception_handler) = NULL;
|
||||
|
@ -87,7 +87,7 @@ static void build_runtime_defined_function_key(zval *result, zend_uchar type, zs
|
||||
char *filename;
|
||||
uint filename_length;
|
||||
|
||||
char_pos_len = zend_sprintf(char_pos_buf, "%p", LANG_SCNG(_yy_last_accepting_cpos));
|
||||
char_pos_len = zend_sprintf(char_pos_buf, "%p", LANG_SCNG(yy_text));
|
||||
if (CG(active_op_array)->filename) {
|
||||
filename = CG(active_op_array)->filename;
|
||||
} else {
|
||||
@ -169,6 +169,14 @@ void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
zend_file_handle_dtor(fh TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void init_compiler(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
CG(auto_globals_cache) = emalloc(sizeof(zval**) * zend_hash_num_elements(CG(auto_globals)));
|
||||
@ -177,7 +185,7 @@ void init_compiler(TSRMLS_D) /* {{{ */
|
||||
zend_init_rsrc_list(TSRMLS_C);
|
||||
zend_hash_init(&CG(filenames_table), 5, NULL, (dtor_func_t) free_estring, 0);
|
||||
zend_hash_init(&CG(script_encodings_table), 5, NULL, (dtor_func_t) free_estring, 0);
|
||||
zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) zend_file_handle_dtor, 0);
|
||||
zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0);
|
||||
CG(unclean_shutdown) = 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -554,7 +554,6 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_size TSRMLS_DC);
|
||||
ZEND_API void destroy_op_array(zend_op_array *op_array TSRMLS_DC);
|
||||
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API void zend_file_handle_dtor(zend_file_handle *fh);
|
||||
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC);
|
||||
ZEND_API int zend_cleanup_function_data(zend_function *function TSRMLS_DC);
|
||||
ZEND_API int zend_cleanup_function_data_full(zend_function *function TSRMLS_DC);
|
||||
@ -694,14 +693,6 @@ int zendlex(znode *zendlval TSRMLS_DC);
|
||||
#define ZEND_CT (1<<0)
|
||||
#define ZEND_RT (1<<1)
|
||||
|
||||
|
||||
#define ZEND_HANDLE_FILENAME 0
|
||||
#define ZEND_HANDLE_FD 1
|
||||
#define ZEND_HANDLE_FP 2
|
||||
#define ZEND_HANDLE_STDIOSTREAM 3
|
||||
#define ZEND_HANDLE_FSTREAM 4
|
||||
#define ZEND_HANDLE_STREAM 5
|
||||
|
||||
#define ZEND_FETCH_STANDARD 0
|
||||
#define ZEND_FETCH_ADD_LOCK (1<<0)
|
||||
#define ZEND_FETCH_MAKE_REF (1<<1)
|
||||
|
@ -243,37 +243,45 @@ struct _zend_executor_globals {
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
};
|
||||
|
||||
struct _zend_scanner_globals {
|
||||
struct _zend_ini_scanner_globals {
|
||||
zend_file_handle *yy_in;
|
||||
zend_file_handle *yy_out;
|
||||
int yy_leng;
|
||||
char *yy_text;
|
||||
struct yy_buffer_state *current_buffer;
|
||||
char *c_buf_p;
|
||||
int init;
|
||||
int start;
|
||||
|
||||
unsigned int yy_leng;
|
||||
unsigned char *yy_start;
|
||||
unsigned char *yy_text;
|
||||
unsigned char *yy_cursor;
|
||||
unsigned char *yy_marker;
|
||||
unsigned char *yy_limit;
|
||||
int yy_state;
|
||||
zend_stack state_stack;
|
||||
char *filename;
|
||||
int lineno;
|
||||
char _yy_hold_char;
|
||||
int yy_n_chars;
|
||||
int _yy_did_buffer_switch_on_eof;
|
||||
int _yy_last_accepting_state; /* Must be of the same type as yy_state_type,
|
||||
* if for whatever reason it's no longer int!
|
||||
*/
|
||||
char *_yy_last_accepting_cpos;
|
||||
int _yy_more_flag;
|
||||
int _yy_more_len;
|
||||
int yy_start_stack_ptr;
|
||||
int yy_start_stack_depth;
|
||||
int *yy_start_stack;
|
||||
|
||||
/* Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW */
|
||||
int scanner_mode;
|
||||
};
|
||||
|
||||
struct _zend_php_scanner_globals {
|
||||
zend_file_handle *yy_in;
|
||||
zend_file_handle *yy_out;
|
||||
|
||||
unsigned int yy_leng;
|
||||
unsigned char *yy_start;
|
||||
unsigned char *yy_text;
|
||||
unsigned char *yy_cursor;
|
||||
unsigned char *yy_marker;
|
||||
unsigned char *yy_limit;
|
||||
int yy_state;
|
||||
zend_stack state_stack;
|
||||
|
||||
zend_llist used_state_stacks;
|
||||
|
||||
UConverter *input_conv; /* converter for flex input */
|
||||
UConverter *output_conv; /* converter for data from flex output */
|
||||
zend_bool encoding_checked;
|
||||
char* rest_str;
|
||||
int rest_len;
|
||||
|
||||
/* For ini scanner. Modes are: ZEND_INI_SCANNER_NORMAL, ZEND_INI_SCANNER_RAW */
|
||||
int scanner_mode;
|
||||
};
|
||||
|
||||
struct _zend_unicode_globals {
|
||||
|
@ -24,7 +24,8 @@
|
||||
|
||||
typedef struct _zend_compiler_globals zend_compiler_globals;
|
||||
typedef struct _zend_executor_globals zend_executor_globals;
|
||||
typedef struct _zend_scanner_globals zend_scanner_globals;
|
||||
typedef struct _zend_php_scanner_globals zend_php_scanner_globals;
|
||||
typedef struct _zend_ini_scanner_globals zend_ini_scanner_globals;
|
||||
typedef struct _zend_unicode_globals zend_unicode_globals;
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
@ -50,21 +51,21 @@ extern ZEND_API zend_executor_globals executor_globals;
|
||||
|
||||
/* Language Scanner */
|
||||
#ifdef ZTS
|
||||
# define LANG_SCNG(v) TSRMG(language_scanner_globals_id, zend_scanner_globals *, v)
|
||||
# define LANG_SCNG(v) TSRMG(language_scanner_globals_id, zend_php_scanner_globals *, v)
|
||||
extern ZEND_API ts_rsrc_id language_scanner_globals_id;
|
||||
#else
|
||||
# define LANG_SCNG(v) (language_scanner_globals.v)
|
||||
extern ZEND_API zend_scanner_globals language_scanner_globals;
|
||||
extern ZEND_API zend_php_scanner_globals language_scanner_globals;
|
||||
#endif
|
||||
|
||||
|
||||
/* INI Scanner */
|
||||
#ifdef ZTS
|
||||
# define INI_SCNG(v) TSRMG(ini_scanner_globals_id, zend_scanner_globals *, v)
|
||||
# define INI_SCNG(v) TSRMG(ini_scanner_globals_id, zend_ini_scanner_globals *, v)
|
||||
extern ZEND_API ts_rsrc_id ini_scanner_globals_id;
|
||||
#else
|
||||
# define INI_SCNG(v) (ini_scanner_globals.v)
|
||||
extern ZEND_API zend_scanner_globals ini_scanner_globals;
|
||||
extern ZEND_API zend_ini_scanner_globals ini_scanner_globals;
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -163,7 +163,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
}
|
||||
|
||||
/* handler for trailing comments, see bug #42767 */
|
||||
if (LANG_SCNG(yy_leng) && LANG_SCNG(_yy_more_len)) {
|
||||
if (LANG_SCNG(yy_leng) && LANG_SCNG(yy_text) < LANG_SCNG(yy_limit)) {
|
||||
if (last_color != syntax_highlighter_ini->highlight_comment) {
|
||||
if (last_color != syntax_highlighter_ini->highlight_html) {
|
||||
zend_printf("</span>");
|
||||
@ -172,7 +172,7 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
|
||||
zend_printf("<span style=\"color: %s\">", syntax_highlighter_ini->highlight_comment);
|
||||
}
|
||||
}
|
||||
zend_html_puts(LANG_SCNG(yy_text), LANG_SCNG(_yy_more_len) TSRMLS_CC);
|
||||
zend_html_puts(LANG_SCNG(yy_text), (LANG_SCNG(yy_limit) - LANG_SCNG(yy_text)) TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (last_color != syntax_highlighter_ini->highlight_html) {
|
||||
|
@ -204,7 +204,7 @@ ZEND_API int zend_parse_ini_file(zend_file_handle *fh, zend_bool unbuffered_erro
|
||||
|
||||
CG(ini_parser_unbuffered_errors) = unbuffered_errors;
|
||||
retval = ini_parse(TSRMLS_C);
|
||||
zend_ini_close_file(fh TSRMLS_CC);
|
||||
zend_file_handle_dtor(fh TSRMLS_CC);
|
||||
|
||||
shutdown_ini_scanner(TSRMLS_C);
|
||||
|
||||
|
@ -31,7 +31,6 @@ int zend_ini_scanner_get_lineno(TSRMLS_D);
|
||||
char *zend_ini_scanner_get_filename(TSRMLS_D);
|
||||
int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC);
|
||||
int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC);
|
||||
void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC);
|
||||
int ini_lex(zval *ini_lval TSRMLS_DC);
|
||||
void shutdown_ini_scanner(TSRMLS_D);
|
||||
END_EXTERN_C()
|
||||
|
@ -1,4 +1,3 @@
|
||||
%{
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
@ -15,18 +14,41 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Zeev Suraski <zeev@zend.com> |
|
||||
| Jani Taskinen <jani@php.net> |
|
||||
| Marcus Boerger <helly@php.net> |
|
||||
| Nuno Lopes <nlopess@php.net> |
|
||||
| Scott MacVicar <scottmac@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#define DEBUG_CFG_SCANNER 0
|
||||
|
||||
#if 0
|
||||
# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c)
|
||||
#else
|
||||
# define YYDEBUG(s, c)
|
||||
#endif
|
||||
|
||||
#include "zend_ini_scanner_defs.h"
|
||||
|
||||
#define YYCTYPE unsigned char
|
||||
#define YYFILL(n) { if (YYCURSOR >= YYLIMIT) return 0; }
|
||||
#define YYCURSOR SCNG(yy_cursor)
|
||||
#define YYLIMIT SCNG(yy_limit)
|
||||
#define YYMARKER SCNG(yy_marker)
|
||||
|
||||
#define YYGETCONDITION() SCNG(yy_state)
|
||||
#define YYSETCONDITION(s) SCNG(yy_state) = s
|
||||
|
||||
#define STATE(name) yyc##name
|
||||
|
||||
/* emulate flex constructs */
|
||||
#define BEGIN(state) YYSETCONDITION(STATE(state))
|
||||
#define YYSTATE YYGETCONDITION()
|
||||
#define yytext ((char*)SCNG(yy_text))
|
||||
#define yyleng SCNG(yy_leng)
|
||||
#define yytext SCNG(yy_text)
|
||||
#define yytext_ptr SCNG(yy_text)
|
||||
#define yyin SCNG(yy_in)
|
||||
#define yyout SCNG(yy_out)
|
||||
#define yyless(x) YYCURSOR = yytext + x
|
||||
/* #define yymore() goto yymore_restart */
|
||||
|
||||
/* How it works (for the core ini directives):
|
||||
* ===========================================
|
||||
@ -58,46 +80,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* These are not needed when yymore() is not used */
|
||||
/*
|
||||
#define yy_last_accepting_state SCNG(_yy_last_accepting_state)
|
||||
#define yy_last_accepting_cpos SCNG(_yy_last_accepting_cpos)
|
||||
#define yy_more_flag SCNG(_yy_more_flag)
|
||||
#define yy_more_len SCNG(_yy_more_len)
|
||||
*/
|
||||
|
||||
%}
|
||||
|
||||
%x ST_DOUBLE_QUOTES
|
||||
%x ST_OFFSET
|
||||
%x ST_RAW
|
||||
%x ST_SECTION_RAW
|
||||
%x ST_SECTION_VALUE
|
||||
%x ST_VALUE
|
||||
%x ST_VARNAME
|
||||
%option stack
|
||||
|
||||
%{
|
||||
|
||||
#include <errno.h>
|
||||
#include "zend.h"
|
||||
#include "zend_globals.h"
|
||||
#include <zend_ini_parser.h>
|
||||
#include "zend_ini_scanner.h"
|
||||
|
||||
#define YY_DECL int ini_lex(zval *ini_lval TSRMLS_DC)
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_stream_read(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
|
||||
/* Globals Macros */
|
||||
#define SCNG INI_SCNG
|
||||
#ifdef ZTS
|
||||
ZEND_API ts_rsrc_id ini_scanner_globals_id;
|
||||
#else
|
||||
ZEND_API zend_scanner_globals ini_scanner_globals;
|
||||
ZEND_API zend_ini_scanner_globals ini_scanner_globals;
|
||||
#endif
|
||||
|
||||
/* Eat trailing whitespace + extra char */
|
||||
@ -110,7 +104,6 @@ ZEND_API zend_scanner_globals ini_scanner_globals;
|
||||
yytext[yyleng - 1] == ' ') \
|
||||
) { \
|
||||
yyleng--; \
|
||||
yytext[yyleng]=0; \
|
||||
}
|
||||
|
||||
/* Eat trailing whitespace */
|
||||
@ -127,7 +120,30 @@ ZEND_API zend_scanner_globals ini_scanner_globals;
|
||||
return type; \
|
||||
}
|
||||
|
||||
static char *ini_filename;
|
||||
static void _yy_push_state(int new_state TSRMLS_DC)
|
||||
{
|
||||
zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
|
||||
YYSETCONDITION(new_state);
|
||||
}
|
||||
|
||||
#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm)
|
||||
|
||||
static void yy_pop_state(TSRMLS_D)
|
||||
{
|
||||
int *stack_state;
|
||||
zend_stack_top(&SCNG(state_stack), (void **) &stack_state);
|
||||
YYSETCONDITION(*stack_state);
|
||||
zend_stack_del_top(&SCNG(state_stack));
|
||||
}
|
||||
|
||||
static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
|
||||
{
|
||||
YYCURSOR = (YYCTYPE*)str;
|
||||
SCNG(yy_start) = YYCURSOR;
|
||||
YYLIMIT = YYCURSOR + len;
|
||||
}
|
||||
|
||||
#define ini_filename SCNG(filename)
|
||||
|
||||
/* {{{ init_ini_scanner()
|
||||
*/
|
||||
@ -135,9 +151,8 @@ static void init_ini_scanner(TSRMLS_D)
|
||||
{
|
||||
SCNG(lineno) = 1;
|
||||
SCNG(scanner_mode) = ZEND_INI_SCANNER_NORMAL;
|
||||
SCNG(yy_start_stack_ptr) = 0;
|
||||
SCNG(yy_start_stack_depth) = 0;
|
||||
SCNG(current_buffer) = NULL;
|
||||
zend_stack_init(&SCNG(state_stack));
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -145,11 +160,7 @@ static void init_ini_scanner(TSRMLS_D)
|
||||
*/
|
||||
void shutdown_ini_scanner(TSRMLS_D)
|
||||
{
|
||||
if (SCNG(yy_start_stack)) {
|
||||
yy_flex_free(SCNG(yy_start_stack));
|
||||
SCNG(yy_start_stack) = NULL;
|
||||
}
|
||||
yy_delete_buffer(SCNG(current_buffer) TSRMLS_CC);
|
||||
zend_stack_destroy(&SCNG(state_stack));
|
||||
if (ini_filename) {
|
||||
free(ini_filename);
|
||||
}
|
||||
@ -176,14 +187,17 @@ char *zend_ini_scanner_get_filename(TSRMLS_D)
|
||||
*/
|
||||
int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRMLS_DC)
|
||||
{
|
||||
if (FAILURE == zend_stream_fixup(fh TSRMLS_CC)) {
|
||||
char *buf;
|
||||
size_t size;
|
||||
|
||||
if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
init_ini_scanner(TSRMLS_C);
|
||||
SCNG(scanner_mode) = scanner_mode;
|
||||
yyin = fh;
|
||||
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE TSRMLS_CC) TSRMLS_CC);
|
||||
SCNG(yy_in) = fh;
|
||||
yy_scan_buffer(buf, size TSRMLS_CC);
|
||||
ini_filename = zend_strndup(fh->filename, strlen(fh->filename));
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -197,21 +211,13 @@ int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC)
|
||||
|
||||
init_ini_scanner(TSRMLS_C);
|
||||
SCNG(scanner_mode) = scanner_mode;
|
||||
yyin = NULL;
|
||||
yy_scan_buffer(str, len + 2 TSRMLS_CC);
|
||||
SCNG(yy_in) = NULL;
|
||||
yy_scan_buffer(str, len TSRMLS_CC);
|
||||
ini_filename = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_ini_close_file()
|
||||
*/
|
||||
void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC)
|
||||
{
|
||||
zend_stream_close(fh);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_ini_escape_string()
|
||||
*/
|
||||
static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_type TSRMLS_DC)
|
||||
@ -272,8 +278,23 @@ static void zend_ini_escape_string(zval *lval, char *str, int len, char quote_ty
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
%}
|
||||
int ini_lex(zval *ini_lval TSRMLS_DC)
|
||||
{
|
||||
restart:
|
||||
SCNG(yy_text) = YYCURSOR;
|
||||
|
||||
/* yymore_restart: */
|
||||
/* detect EOF */
|
||||
if (YYCURSOR >= YYLIMIT) {
|
||||
if (YYSTATE == STATE(ST_VALUE) || YYSTATE == STATE(ST_RAW)) {
|
||||
BEGIN(INITIAL);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!re2c
|
||||
re2c:yyfill:check = 0;
|
||||
LNUM [0-9]+
|
||||
DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
|
||||
NUMBER [-]?{LNUM}|{DNUM}
|
||||
@ -292,20 +313,12 @@ SINGLE_QUOTED_CHARS [^']
|
||||
RAW_VALUE_CHARS [^=\n\r;]
|
||||
|
||||
/* Allow using ${foobar} in sections, quoted strings and values */
|
||||
LITERAL_DOLLAR ("$"([^a-zA-Z0-9{]|("\\"{ANY_CHAR})))
|
||||
VALUE_CHARS ([^$= \t\n\r;&|~()!"']|{LITERAL_DOLLAR})
|
||||
LITERAL_DOLLAR ("$"([^a-zA-Z0-9{\000]|("\\"{ANY_CHAR})))
|
||||
VALUE_CHARS ([^$= \t\n\r;&|~()!"'\000]|{LITERAL_DOLLAR})
|
||||
SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
|
||||
/* " */
|
||||
|
||||
%option nounput
|
||||
%option noyywrap
|
||||
%option noyylineno
|
||||
%option noyy_top_state
|
||||
%option never-interactive
|
||||
|
||||
%%
|
||||
+<!*> := yyleng = YYCURSOR - SCNG(yy_text);
|
||||
|
||||
<INITIAL>"[" { /* Section start */
|
||||
/* Enter section data lookup state */
|
||||
@ -320,9 +333,8 @@ DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
<ST_VALUE,ST_SECTION_VALUE,ST_OFFSET>"'"{SINGLE_QUOTED_CHARS}+"'" { /* Raw string */
|
||||
/* Eat leading and trailing single quotes */
|
||||
if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') {
|
||||
yytext++;
|
||||
SCNG(yy_text)++;
|
||||
yyleng = yyleng - 2;
|
||||
yytext[yyleng] = 0;
|
||||
}
|
||||
RETURN_TOKEN(TC_RAW, yytext, yyleng);
|
||||
}
|
||||
@ -386,7 +398,7 @@ DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
<ST_RAW>{RAW_VALUE_CHARS}+ { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
|
||||
/* Eat leading and trailing double quotes */
|
||||
if (yytext[0] == '"' && yytext[yyleng - 1] == '"') {
|
||||
yytext++;
|
||||
SCNG(yy_text)++;
|
||||
yyleng = yyleng - 2;
|
||||
yytext[yyleng] = 0;
|
||||
}
|
||||
@ -420,7 +432,7 @@ DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
}
|
||||
|
||||
<ST_VALUE>[=] { /* Make = used in option value to trigger error */
|
||||
yyless(yyleng - 1);
|
||||
yyless(0);
|
||||
BEGIN(INITIAL);
|
||||
return END_OF_LINE;
|
||||
}
|
||||
@ -454,6 +466,7 @@ DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
|
||||
<INITIAL,ST_RAW>{TABS_AND_SPACES}+ {
|
||||
/* eat whitespace */
|
||||
goto restart;
|
||||
}
|
||||
|
||||
<INITIAL>{TABS_AND_SPACES}*{NEWLINE} {
|
||||
@ -467,52 +480,14 @@ DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
|
||||
return END_OF_LINE;
|
||||
}
|
||||
|
||||
<ST_VALUE,ST_RAW><<EOF>> { /* End of option value (if EOF is reached before EOL */
|
||||
<ST_VALUE,ST_RAW>[^] { /* End of option value (if EOF is reached before EOL) */
|
||||
BEGIN(INITIAL);
|
||||
return END_OF_LINE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
#if DEBUG_CFG_SCANNER
|
||||
while (YYSTATE != INITIAL) {
|
||||
switch (YYSTATE) {
|
||||
case INITIAL:
|
||||
break;
|
||||
|
||||
case ST_DOUBLE_QUOTES:
|
||||
fprintf(stderr, "ERROR: Unterminated ini option value double quotes\n");
|
||||
break;
|
||||
|
||||
case ST_OFFSET:
|
||||
fprintf(stderr, "ERROR: Unterminated ini option offset\n");
|
||||
break;
|
||||
|
||||
case ST_RAW:
|
||||
fprintf(stderr, "ERROR: Unterminated raw ini option value\n");
|
||||
break;
|
||||
|
||||
case ST_SECTION_RAW:
|
||||
fprintf(stderr, "ERROR: Unterminated raw ini section value\n");
|
||||
break;
|
||||
|
||||
case ST_SECTION_VALUE:
|
||||
fprintf(stderr, "ERROR: Unterminated ini section value\n");
|
||||
break;
|
||||
|
||||
case ST_VALUE:
|
||||
fprintf(stderr, "ERROR: Unterminated ini option value\n");
|
||||
break;
|
||||
|
||||
case ST_VARNAME:
|
||||
fprintf(stderr, "ERROR: Unterminated ini variable\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "BUG: Unknown state (%d)\n", YYSTATE);
|
||||
break;
|
||||
}
|
||||
yy_pop_state(TSRMLS_C);
|
||||
}
|
||||
#endif
|
||||
yyterminate();
|
||||
<*>[^] {
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
@ -23,8 +23,15 @@
|
||||
#define ZEND_SCANNER_H
|
||||
|
||||
typedef struct _zend_lex_state {
|
||||
YY_BUFFER_STATE buffer_state;
|
||||
int state;
|
||||
unsigned int yy_leng;
|
||||
unsigned char *yy_start;
|
||||
unsigned char *yy_text;
|
||||
unsigned char *yy_cursor;
|
||||
unsigned char *yy_marker;
|
||||
unsigned char *yy_limit;
|
||||
int yy_state;
|
||||
zend_stack state_stack;
|
||||
|
||||
zend_file_handle *in;
|
||||
uint lineno;
|
||||
char *filename;
|
||||
@ -38,7 +45,6 @@ typedef struct _zend_lex_state {
|
||||
} zend_lex_state;
|
||||
|
||||
|
||||
void zend_fatal_scanner_error(char *);
|
||||
BEGIN_EXTERN_C()
|
||||
int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
|
||||
ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC);
|
||||
|
@ -1,5 +1,3 @@
|
||||
%{
|
||||
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
@ -14,43 +12,24 @@
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Andi Gutmans <andi@zend.com> |
|
||||
| Authors: Marcus Boerger <helly@php.net> |
|
||||
| Nuno Lopes <nlopess@php.net> |
|
||||
| Scott MacVicar <scottmac@php.net> |
|
||||
| Flex version authors: |
|
||||
| Andi Gutmans <andi@zend.com> |
|
||||
| Zeev Suraski <zeev@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
/* $Id$ */
|
||||
|
||||
#define yyleng SCNG(yy_leng)
|
||||
#define yytext SCNG(yy_text)
|
||||
#define yytext_ptr SCNG(yy_text)
|
||||
#define yyin SCNG(yy_in)
|
||||
#define yyout SCNG(yy_out)
|
||||
#define yy_last_accepting_state SCNG(_yy_last_accepting_state)
|
||||
#define yy_last_accepting_cpos SCNG(_yy_last_accepting_cpos)
|
||||
#define yy_more_flag SCNG(_yy_more_flag)
|
||||
#define yy_more_len SCNG(_yy_more_len)
|
||||
#if 0
|
||||
# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c)
|
||||
#else
|
||||
# define YYDEBUG(s, c)
|
||||
#endif
|
||||
|
||||
%}
|
||||
|
||||
%x ST_IN_SCRIPTING
|
||||
%x ST_DOUBLE_QUOTES
|
||||
%x ST_BACKQUOTE
|
||||
%x ST_HEREDOC
|
||||
%x ST_START_HEREDOC
|
||||
%x ST_END_HEREDOC
|
||||
%x ST_NOWDOC
|
||||
%x ST_START_NOWDOC
|
||||
%x ST_END_NOWDOC
|
||||
%x ST_LOOKING_FOR_PROPERTY
|
||||
%x ST_LOOKING_FOR_VARNAME
|
||||
%x ST_VAR_OFFSET
|
||||
%x ST_COMMENT
|
||||
%x ST_DOC_COMMENT
|
||||
%x ST_ONE_LINE_COMMENT
|
||||
%option stack
|
||||
|
||||
%{
|
||||
#include "zend_language_scanner_defs.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include "zend.h"
|
||||
@ -68,6 +47,25 @@
|
||||
#include "tsrm_virtual_cwd.h"
|
||||
#include "tsrm_config_common.h"
|
||||
|
||||
#define YYCTYPE unsigned char
|
||||
#define YYFILL(n) { if (YYCURSOR >= YYLIMIT) return 0; }
|
||||
#define YYCURSOR SCNG(yy_cursor)
|
||||
#define YYLIMIT SCNG(yy_limit)
|
||||
#define YYMARKER SCNG(yy_marker)
|
||||
|
||||
#define YYGETCONDITION() SCNG(yy_state)
|
||||
#define YYSETCONDITION(s) SCNG(yy_state) = s
|
||||
|
||||
#define STATE(name) yyc##name
|
||||
|
||||
/* emulate flex constructs */
|
||||
#define BEGIN(state) YYSETCONDITION(STATE(state))
|
||||
#define YYSTATE YYGETCONDITION()
|
||||
#define yytext ((char*)SCNG(yy_text))
|
||||
#define yyleng SCNG(yy_leng)
|
||||
#define yyless(x) YYCURSOR = yytext + x
|
||||
#define yymore() goto yymore_restart
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
# include <stdarg.h>
|
||||
#endif
|
||||
@ -76,31 +74,19 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define YY_DECL int lex_scan(zval *zendlval TSRMLS_DC)
|
||||
|
||||
#define ECHO { ZEND_WRITE( yytext, yyleng ); }
|
||||
|
||||
#ifdef ZTS
|
||||
# define MY_INPUT yyinput
|
||||
#else
|
||||
# define MY_INPUT input
|
||||
#endif
|
||||
|
||||
|
||||
/* Globals Macros */
|
||||
#define SCNG LANG_SCNG
|
||||
#ifdef ZTS
|
||||
ZEND_API ts_rsrc_id language_scanner_globals_id;
|
||||
#else
|
||||
ZEND_API zend_scanner_globals language_scanner_globals;
|
||||
ZEND_API zend_php_scanner_globals language_scanner_globals;
|
||||
#endif
|
||||
|
||||
/*
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
if ( ((result = zend_unicode_yyinput(yyin, buf, max_size TSRMLS_CC)) == 0) \
|
||||
&& zend_stream_ferror( yyin TSRMLS_CC) ) \
|
||||
if ( ((result = zend_unicode_yyinput(yyin, buf, max_size TSRMLS_CC)) == 0)) \
|
||||
YY_FATAL_ERROR( "input in flex scanner failed" );
|
||||
|
||||
#define YY_FATAL_ERROR zend_fatal_scanner_error
|
||||
*/
|
||||
|
||||
#define HANDLE_NEWLINES(s, l) \
|
||||
do { \
|
||||
@ -121,32 +107,50 @@ do { \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define ZEND_IS_OCT(c) ((c)>='0' && (c)<='7')
|
||||
#define ZEND_IS_HEX(c) (((c)>='0' && (c)<='9') || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F'))
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
void zend_fatal_scanner_error(char *message)
|
||||
{
|
||||
zend_error(E_COMPILE_ERROR, "%s", message);
|
||||
static void _yy_push_state(int new_state TSRMLS_DC)
|
||||
{
|
||||
zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int));
|
||||
YYSETCONDITION(new_state);
|
||||
}
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm)
|
||||
|
||||
static void yy_pop_state(TSRMLS_D)
|
||||
{
|
||||
int *stack_state;
|
||||
zend_stack_top(&SCNG(state_stack), (void **) &stack_state);
|
||||
YYSETCONDITION(*stack_state);
|
||||
zend_stack_del_top(&SCNG(state_stack));
|
||||
}
|
||||
|
||||
static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
|
||||
{
|
||||
YYCURSOR = (YYCTYPE*)str;
|
||||
SCNG(yy_start) = YYCURSOR;
|
||||
YYLIMIT = YYCURSOR + len;
|
||||
}
|
||||
|
||||
void startup_scanner(TSRMLS_D)
|
||||
{
|
||||
CG(heredoc) = NULL;
|
||||
CG(heredoc_len) = 0;
|
||||
CG(doc_comment) = NULL_ZSTR;
|
||||
CG(doc_comment_len) = 0;
|
||||
SCNG(yy_start_stack_ptr) = 0;
|
||||
SCNG(yy_start_stack_depth) = 0;
|
||||
SCNG(current_buffer) = NULL;
|
||||
|
||||
SCNG(input_conv) = NULL;
|
||||
SCNG(output_conv) = NULL;
|
||||
SCNG(encoding_checked) = 0;
|
||||
SCNG(rest_str) = NULL;
|
||||
SCNG(rest_len) = 0;
|
||||
|
||||
zend_llist_init(&SCNG(used_state_stacks), sizeof(zend_stack), (llist_dtor_func_t) zend_stack_destroy, 0);
|
||||
zend_stack_init(&SCNG(state_stack));
|
||||
zend_llist_add_element(&SCNG(used_state_stacks), &SCNG(state_stack));
|
||||
}
|
||||
|
||||
|
||||
@ -156,10 +160,7 @@ void shutdown_scanner(TSRMLS_D)
|
||||
efree(CG(heredoc));
|
||||
CG(heredoc_len)=0;
|
||||
}
|
||||
if (SCNG(yy_start_stack)) {
|
||||
yy_flex_free(SCNG(yy_start_stack));
|
||||
SCNG(yy_start_stack) = NULL;
|
||||
}
|
||||
zend_llist_destroy(&SCNG(used_state_stacks));
|
||||
RESET_DOC_COMMENT();
|
||||
|
||||
if (SCNG(input_conv)) {
|
||||
@ -177,14 +178,27 @@ void shutdown_scanner(TSRMLS_D)
|
||||
}
|
||||
SCNG(rest_len) = 0;
|
||||
}
|
||||
END_EXTERN_C()
|
||||
|
||||
static int compare_stacks(zend_stack *stack1, zend_stack *stack2)
|
||||
{
|
||||
return (stack1 == stack2);
|
||||
}
|
||||
|
||||
ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
|
||||
{
|
||||
memcpy(&lex_state->buffer_state, &YY_CURRENT_BUFFER, sizeof(YY_BUFFER_STATE));
|
||||
lex_state->yy_leng = SCNG(yy_leng);
|
||||
lex_state->yy_start = SCNG(yy_start);
|
||||
lex_state->yy_text = SCNG(yy_text);
|
||||
lex_state->yy_cursor = SCNG(yy_cursor);
|
||||
lex_state->yy_marker = SCNG(yy_marker);
|
||||
lex_state->yy_limit = SCNG(yy_limit);
|
||||
|
||||
lex_state->state_stack = SCNG(state_stack);
|
||||
zend_stack_init(&SCNG(state_stack));
|
||||
zend_llist_add_element(&SCNG(used_state_stacks), &SCNG(state_stack));
|
||||
|
||||
lex_state->in = SCNG(yy_in);
|
||||
lex_state->state = YYSTATE;
|
||||
lex_state->yy_state = YYSTATE;
|
||||
lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
lex_state->lineno = CG(zend_lineno);
|
||||
|
||||
@ -202,17 +216,18 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
|
||||
|
||||
ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
|
||||
{
|
||||
YY_BUFFER_STATE original_buffer_state = YY_CURRENT_BUFFER;
|
||||
SCNG(yy_leng) = lex_state->yy_leng;
|
||||
SCNG(yy_start) = lex_state->yy_start;
|
||||
SCNG(yy_text) = lex_state->yy_text;
|
||||
SCNG(yy_cursor) = lex_state->yy_cursor;
|
||||
SCNG(yy_marker) = lex_state->yy_marker;
|
||||
SCNG(yy_limit) = lex_state->yy_limit;
|
||||
|
||||
if (lex_state->buffer_state) {
|
||||
yy_switch_to_buffer(lex_state->buffer_state TSRMLS_CC);
|
||||
} else {
|
||||
YY_CURRENT_BUFFER = NULL;
|
||||
}
|
||||
zend_llist_del_element(&SCNG(used_state_stacks), &SCNG(state_stack), (int (*)(void *, void *)) compare_stacks);
|
||||
SCNG(state_stack) = lex_state->state_stack;
|
||||
|
||||
yy_delete_buffer(original_buffer_state TSRMLS_CC);
|
||||
SCNG(yy_in) = lex_state->in;
|
||||
BEGIN(lex_state->state);
|
||||
YYSETCONDITION(lex_state->yy_state);
|
||||
CG(zend_lineno) = lex_state->lineno;
|
||||
zend_restore_compiled_filename(lex_state->filename TSRMLS_CC);
|
||||
zend_restore_compiled_script_encoding(lex_state->script_encoding TSRMLS_CC);
|
||||
@ -233,57 +248,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
|
||||
SCNG(rest_len) = lex_state->rest_len;
|
||||
}
|
||||
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
|
||||
|
||||
ZEND_API void zend_file_handle_dtor(zend_file_handle *fh)
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
switch (fh->type) {
|
||||
case ZEND_HANDLE_FP:
|
||||
fclose(fh->handle.fp);
|
||||
break;
|
||||
case ZEND_HANDLE_STREAM:
|
||||
if (fh->handle.stream.closer) {
|
||||
fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC);
|
||||
}
|
||||
break;
|
||||
case ZEND_HANDLE_FILENAME:
|
||||
/* We're only supposed to get here when destructing the used_files hash,
|
||||
* which doesn't really contain open files, but references to their names/paths
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (fh->opened_path) {
|
||||
efree(fh->opened_path);
|
||||
fh->opened_path = NULL;
|
||||
}
|
||||
if (fh->free_filename && fh->filename) {
|
||||
efree(fh->filename);
|
||||
fh->filename = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2)
|
||||
{
|
||||
if (fh1->type != fh2->type) {
|
||||
return 0;
|
||||
}
|
||||
switch (fh1->type) {
|
||||
case ZEND_HANDLE_FP:
|
||||
return fh1->handle.fp==fh2->handle.fp;
|
||||
break;
|
||||
case ZEND_HANDLE_STREAM:
|
||||
return fh1->handle.stream.handle == fh2->handle.stream.handle;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC)
|
||||
{
|
||||
zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles);
|
||||
@ -556,6 +520,7 @@ ZEND_API int zend_prepare_scanner_converters(const char *onetime_encoding, int r
|
||||
if (zend_set_converter_encoding(&SCNG(input_conv), encoding) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
#ifdef scottmac_0
|
||||
if (run_time) {
|
||||
/* Convert rest of the buffer to unicode.runtime_encoding. */
|
||||
YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
|
||||
@ -590,6 +555,7 @@ ZEND_API int zend_prepare_scanner_converters(const char *onetime_encoding, int r
|
||||
b->yy_ch_buf[b->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
|
||||
b->yy_ch_buf[b->yy_n_chars+1] = YY_END_OF_BUFFER_CHAR;
|
||||
}
|
||||
#endif
|
||||
encoding = "UTF-8";
|
||||
}
|
||||
return zend_set_converter_encoding(&SCNG(output_conv), encoding);
|
||||
@ -622,6 +588,7 @@ int zend_unicode_yyinput(zend_file_handle *file_handle, char *buf, size_t len TS
|
||||
int c = '*';
|
||||
const char *src = buf;
|
||||
|
||||
#ifdef scottmac_0
|
||||
/* Look of we have rest from previous call */
|
||||
if (SCNG(rest_str)) {
|
||||
if (len >= SCNG(rest_len)) {
|
||||
@ -636,19 +603,10 @@ int zend_unicode_yyinput(zend_file_handle *file_handle, char *buf, size_t len TS
|
||||
n = len;
|
||||
SCNG(rest_len) -= len;
|
||||
}
|
||||
} else {
|
||||
if (file_handle->handle.stream.interactive) {
|
||||
for (n = 0; n < sizeof(buf) && (c = zend_stream_getc(yyin TSRMLS_CC)) != EOF && c != '\n'; ++n) {
|
||||
buf[n] = (char)c;
|
||||
}
|
||||
if (c == '\n') {
|
||||
buf[n++] = (char) c;
|
||||
}
|
||||
} else {
|
||||
n = zend_stream_read(file_handle, buf, len TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Don't make any conversions if unicode=off */
|
||||
if (!UG(unicode)) {
|
||||
return n;
|
||||
@ -709,20 +667,34 @@ int zend_unicode_yyinput(zend_file_handle *file_handle, char *buf, size_t len TS
|
||||
|
||||
ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC)
|
||||
{
|
||||
char *file_path=NULL;
|
||||
char *file_path=NULL, *buf;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
size_t size;
|
||||
|
||||
if (FAILURE == zend_stream_fixup(file_handle TSRMLS_CC)) {
|
||||
if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zend_llist_add_element(&CG(open_files), file_handle);
|
||||
|
||||
if (file_handle->handle.stream.handle >= (void*)file_handle && file_handle->handle.stream.handle <= (void*)(file_handle+1)) {
|
||||
zend_file_handle *fh = (zend_file_handle*)zend_llist_get_last(&CG(open_files));
|
||||
size_t diff = (char*)file_handle->handle.stream.handle - (char*)file_handle;
|
||||
fh->handle.stream.handle = (void*)(((char*)fh) + diff);
|
||||
file_handle->handle.stream.handle = fh->handle.stream.handle;
|
||||
}
|
||||
|
||||
/* Reset the scanner for scanning the new file */
|
||||
SCNG(yy_in) = file_handle;
|
||||
|
||||
zend_prepare_scanner_converters(ucnv_getName(ZEND_U_CONVERTER(UG(script_encoding_conv)), &status), 0 TSRMLS_CC);
|
||||
yy_switch_to_buffer(yy_create_buffer(SCNG(yy_in), YY_BUF_SIZE TSRMLS_CC) TSRMLS_CC);
|
||||
|
||||
if (size != -1) {
|
||||
/* Re-encode for Unicode if needed */
|
||||
yy_scan_buffer(buf, size TSRMLS_CC);
|
||||
} else {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "zend_stream_mmap() failed");
|
||||
}
|
||||
|
||||
BEGIN(INITIAL);
|
||||
|
||||
@ -869,7 +841,8 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D
|
||||
SCNG(yy_in)=NULL;
|
||||
|
||||
zend_prepare_scanner_converters(encoding, 0 TSRMLS_CC);
|
||||
yy_scan_buffer(Z_STRVAL_P(str), Z_STRLEN_P(str)+2 TSRMLS_CC);
|
||||
/* Re-encode for Unicode if needed */
|
||||
yy_scan_buffer(Z_STRVAL_P(str), Z_STRLEN_P(str) TSRMLS_CC);
|
||||
|
||||
zend_set_compiled_filename(filename TSRMLS_CC);
|
||||
zend_set_compiled_script_encoding((char*)ucnv_getName(SCNG(output_conv), &status) TSRMLS_CC);
|
||||
@ -881,15 +854,7 @@ ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_D
|
||||
|
||||
ZEND_API int zend_get_scanned_file_offset(TSRMLS_D)
|
||||
{
|
||||
if (yyin) {
|
||||
int offset_in_buffer = (yy_c_buf_p - (YY_CURRENT_BUFFER)->yy_ch_buf);
|
||||
int read_bytes = SCNG(yy_n_chars);
|
||||
int offset_from_the_end = read_bytes - offset_in_buffer;
|
||||
|
||||
return zend_stream_ftell(yyin TSRMLS_CC) - offset_from_the_end;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return SCNG(yy_cursor) - SCNG(yy_start);
|
||||
}
|
||||
|
||||
|
||||
@ -1349,17 +1314,34 @@ static void zend_scan_binary_single_string(zval *zendlval, char *str, int len TS
|
||||
*t = 0;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
int lex_scan(zval *zendlval TSRMLS_DC)
|
||||
{
|
||||
restart:
|
||||
SCNG(yy_text) = YYCURSOR;
|
||||
|
||||
yymore_restart:
|
||||
|
||||
/* detect EOF */
|
||||
if (YYCURSOR >= YYLIMIT) {
|
||||
/* special case */
|
||||
if (YYSTATE == STATE(ST_COMMENT) || YYSTATE == STATE(ST_DOC_COMMENT)) {
|
||||
zend_error(E_COMPILE_WARNING,"Unterminated comment starting line %d", CG(comment_start_line));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!re2c
|
||||
re2c:yyfill:check = 0;
|
||||
LNUM [0-9]+
|
||||
DNUM ([0-9]*[\.][0-9]+)|([0-9]+[\.][0-9]*)
|
||||
DNUM ([0-9]*"."[0-9]+)|([0-9]+"."[0-9]*)
|
||||
EXPONENT_DNUM (({LNUM}|{DNUM})[eE][+-]?{LNUM})
|
||||
HNUM "0x"[0-9a-fA-F]+
|
||||
LABEL [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
|
||||
WHITESPACE [ \n\r\t]+
|
||||
TABS_AND_SPACES [ \t]*
|
||||
TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@]
|
||||
ANY_CHAR (.|[\n])
|
||||
ANY_CHAR [^]
|
||||
NEWLINE ("\r"|"\n"|"\r\n")
|
||||
|
||||
/*
|
||||
@ -1416,9 +1398,9 @@ HEREDOC_CHARS ("{"*([^$\n\r\\{]|("\\"[^\n\r]))|{HEREDOC_LITERAL_DOLLAR}|({
|
||||
|
||||
NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_\x7f-\xff;\n\r][^\n\r]*)|({LABEL}[;][^\n\r]+)))
|
||||
|
||||
%option noyylineno
|
||||
%option noyywrap
|
||||
%%
|
||||
/* compute yyleng before each rule */
|
||||
<!*> := yyleng = YYCURSOR - SCNG(yy_text);
|
||||
|
||||
|
||||
<ST_IN_SCRIPTING>"exit" {
|
||||
return T_EXIT;
|
||||
@ -1569,6 +1551,11 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_OBJECT_OPERATOR;
|
||||
}
|
||||
|
||||
<ST_LOOKING_FOR_PROPERTY>{WHITESPACE}+ {
|
||||
/* do nothing */
|
||||
goto restart;
|
||||
}
|
||||
|
||||
<ST_LOOKING_FOR_PROPERTY>"->" {
|
||||
return T_OBJECT_OPERATOR;
|
||||
}
|
||||
@ -1587,6 +1574,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
<ST_LOOKING_FOR_PROPERTY>{ANY_CHAR} {
|
||||
yyless(0);
|
||||
yy_pop_state(TSRMLS_C);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"::" {
|
||||
@ -1849,7 +1837,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
<ST_IN_SCRIPTING>"}" {
|
||||
RESET_DOC_COMMENT();
|
||||
/* This is a temporary fix which is dependant on flex and it's implementation */
|
||||
if (yy_start_stack_ptr) {
|
||||
if (!zend_stack_is_empty(&SCNG(state_stack))) {
|
||||
yy_pop_state(TSRMLS_C);
|
||||
}
|
||||
return '}';
|
||||
@ -1873,6 +1861,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
yyless(0);
|
||||
yy_pop_state(TSRMLS_C);
|
||||
yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
|
||||
@ -1918,7 +1907,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
}
|
||||
|
||||
<ST_VAR_OFFSET>0|([1-9][0-9]*) { /* Offset could be treated as a long */
|
||||
<ST_VAR_OFFSET>[0]|([1-9][0-9]*) { /* Offset could be treated as a long */
|
||||
if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
|
||||
Z_LVAL_P(zendlval) = strtol(yytext, NULL, 10);
|
||||
Z_TYPE_P(zendlval) = IS_LONG;
|
||||
@ -1943,7 +1932,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_DNUMBER;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"__CLASS__" {
|
||||
<ST_IN_SCRIPTING>'__CLASS__' {
|
||||
zstr class_name = NULL_ZSTR;
|
||||
|
||||
if (CG(active_class_entry)) {
|
||||
@ -1958,7 +1947,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_CLASS_C;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"__FUNCTION__" {
|
||||
<ST_IN_SCRIPTING>'__FUNCTION__' {
|
||||
zstr func_name = NULL_ZSTR;
|
||||
|
||||
if (CG(active_op_array)) {
|
||||
@ -1973,7 +1962,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_FUNC_C;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"__METHOD__" {
|
||||
<ST_IN_SCRIPTING>'__METHOD__' {
|
||||
zstr class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL_ZSTR;
|
||||
zstr func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL_ZSTR;
|
||||
size_t len = 0;
|
||||
@ -2022,13 +2011,13 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_METHOD_C;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"__LINE__" {
|
||||
<ST_IN_SCRIPTING>'__LINE__' {
|
||||
Z_LVAL_P(zendlval) = CG(zend_lineno);
|
||||
Z_TYPE_P(zendlval) = IS_LONG;
|
||||
return T_LINE;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"__FILE__" {
|
||||
<ST_IN_SCRIPTING>'__FILE__' {
|
||||
char *filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
|
||||
if (!filename) {
|
||||
@ -2038,7 +2027,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_FILE;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"__DIR__" {
|
||||
<ST_IN_SCRIPTING>'__DIR__' {
|
||||
char *filename = zend_get_compiled_filename(TSRMLS_C);
|
||||
const size_t filename_len = strlen(filename);
|
||||
char *dirname;
|
||||
@ -2065,7 +2054,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_DIR;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING>"__NAMESPACE__" {
|
||||
<ST_IN_SCRIPTING>'__NAMESPACE__' {
|
||||
if (CG(current_namespace)) {
|
||||
*zendlval = *CG(current_namespace);
|
||||
zval_copy_ctor(zendlval);
|
||||
@ -2075,22 +2064,22 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_NS_C;
|
||||
}
|
||||
|
||||
<INITIAL>(([^<]|"<"[^?%s<]){1,400})|"<s"|"<" {
|
||||
Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng);
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
<INITIAL>"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"'php'"){WHITESPACE}*">" {
|
||||
HANDLE_NEWLINES(yytext, yyleng);
|
||||
return T_INLINE_HTML;
|
||||
}
|
||||
|
||||
<INITIAL>"<?"|"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"\'php\'"){WHITESPACE}*">" {
|
||||
HANDLE_NEWLINES(yytext, yyleng);
|
||||
if (CG(short_tags) || yyleng>2) { /* yyleng>2 means it's not <? but <script> */
|
||||
Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_OPEN_TAG;
|
||||
}
|
||||
|
||||
<INITIAL>"<%=" {
|
||||
if (CG(asp_tags)) {
|
||||
Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_OPEN_TAG_WITH_ECHO;
|
||||
} else {
|
||||
Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng);
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
@ -2100,8 +2089,8 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
|
||||
|
||||
<INITIAL>"<%="|"<?=" {
|
||||
if ((yytext[1]=='%' && CG(asp_tags)) || (yytext[1]=='?' && CG(short_tags))) {
|
||||
<INITIAL>"<?=" {
|
||||
if (CG(short_tags)) {
|
||||
Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
@ -2141,25 +2130,71 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_OPEN_TAG;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} {
|
||||
if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-1), UG(unicode)?IS_UNICODE:IS_STRING, SCNG(output_conv) TSRMLS_CC)) {
|
||||
return 0;
|
||||
|
||||
<INITIAL>"<?" {
|
||||
HANDLE_NEWLINES(yytext, yyleng);
|
||||
if (CG(short_tags)) {
|
||||
Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_OPEN_TAG;
|
||||
} else {
|
||||
Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng);
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
return T_INLINE_HTML;
|
||||
}
|
||||
if (UG(unicode) && !zend_check_and_normalize_identifier(zendlval)) {
|
||||
return 0;
|
||||
}
|
||||
return T_VARIABLE;
|
||||
}
|
||||
|
||||
%{
|
||||
<INITIAL>"#".+ {NEWLINE} {
|
||||
if ((YYCTYPE*)yytext == SCNG(yy_start)) {
|
||||
/* ignore first line when it's started with a # */
|
||||
goto restart;
|
||||
} else {
|
||||
goto inline_char_handler;
|
||||
}
|
||||
}
|
||||
|
||||
<INITIAL>{ANY_CHAR} {
|
||||
|
||||
while (1) {
|
||||
YYCTYPE *ptr = memchr(YYCURSOR, '<', YYLIMIT - YYCURSOR);
|
||||
|
||||
if (ptr == NULL) {
|
||||
YYCURSOR = YYLIMIT;
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
break;
|
||||
|
||||
} else {
|
||||
YYCURSOR = ptr + 1;
|
||||
|
||||
/* if it can be an opening tag, stop */
|
||||
if (ptr < YYLIMIT && (*YYCURSOR == '?' || *YYCURSOR == '%')) {
|
||||
--YYCURSOR;
|
||||
yyleng = YYCURSOR - SCNG(yy_text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline_char_handler:
|
||||
|
||||
Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng);
|
||||
Z_STRLEN_P(zendlval) = yyleng;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
HANDLE_NEWLINES(yytext, yyleng);
|
||||
return T_INLINE_HTML;
|
||||
}
|
||||
|
||||
/* Make sure a label character follows "->", otherwise there is no property
|
||||
* and "->" will be taken literally
|
||||
*/ %}
|
||||
*/
|
||||
<ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"->"[a-zA-Z_\x7f-\xff] {
|
||||
yyless(yyleng - 3);
|
||||
yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
|
||||
|
||||
if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-1), UG(unicode)?IS_UNICODE:IS_STRING, SCNG(output_conv) TSRMLS_CC)) {
|
||||
if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-4), UG(unicode)?IS_UNICODE:IS_STRING, SCNG(output_conv) TSRMLS_CC)) {
|
||||
return 0;
|
||||
}
|
||||
if (UG(unicode) && !zend_check_and_normalize_identifier(zendlval)) {
|
||||
@ -2168,13 +2203,22 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
return T_VARIABLE;
|
||||
}
|
||||
|
||||
%{
|
||||
/* A [ always designates a variable offset, regardless of what follows
|
||||
*/ %}
|
||||
*/
|
||||
<ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE>"$"{LABEL}"[" {
|
||||
yyless(yyleng - 1);
|
||||
yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
|
||||
|
||||
if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-2), UG(unicode)?IS_UNICODE:IS_STRING, SCNG(output_conv) TSRMLS_CC)) {
|
||||
return 0;
|
||||
}
|
||||
if (UG(unicode) && !zend_check_and_normalize_identifier(zendlval)) {
|
||||
return 0;
|
||||
}
|
||||
return T_VARIABLE;
|
||||
}
|
||||
|
||||
<ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_HEREDOC,ST_BACKQUOTE,ST_VAR_OFFSET>"$"{LABEL} {
|
||||
if (!zend_copy_scanner_string(zendlval, (yytext+1), (yyleng-1), UG(unicode)?IS_UNICODE:IS_STRING, SCNG(output_conv) TSRMLS_CC)) {
|
||||
return 0;
|
||||
}
|
||||
@ -2270,7 +2314,8 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
Z_STRVAL_P(zendlval) = yytext; /* no copying - intentional */
|
||||
Z_STRLEN_P(zendlval) = yyleng-2;
|
||||
Z_TYPE_P(zendlval) = IS_STRING;
|
||||
yyless(yyleng-2);
|
||||
yyleng -= 2;
|
||||
yyless(yyleng);
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_COMMENT;
|
||||
} else {
|
||||
@ -2342,9 +2387,8 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
|
||||
|
||||
%{
|
||||
/* ("{"*|"$"*) handles { or $ at the end of a string (or the entire contents)
|
||||
*/ %}
|
||||
*/
|
||||
<ST_IN_SCRIPTING>(["]{DOUBLE_QUOTES_CHARS}*("{"*|"$"*)["]) {
|
||||
if (UG(unicode)) {
|
||||
return zend_scan_unicode_escape_string(zendlval, yytext+1, yyleng-2, 0x22 /*'"'*/, T_CONSTANT_ENCAPSED_STRING TSRMLS_CC);
|
||||
@ -2426,6 +2470,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
<ST_START_HEREDOC>{ANY_CHAR} {
|
||||
yyless(0);
|
||||
BEGIN(ST_HEREDOC);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
<ST_START_HEREDOC>{LABEL}";"?[\n\r] {
|
||||
@ -2445,18 +2490,17 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_END_HEREDOC;
|
||||
} else {
|
||||
yymore();
|
||||
BEGIN(ST_HEREDOC);
|
||||
yymore();
|
||||
}
|
||||
}
|
||||
|
||||
%{
|
||||
/* Match everything up to and including a possible ending label, so if the label
|
||||
* doesn't match, it's kept with the rest of the string
|
||||
*
|
||||
* {HEREDOC_NEWLINE}+ handles the case of more than one newline sequence that
|
||||
* couldn't be matched with HEREDOC_CHARS, because of the following label
|
||||
*/ %}
|
||||
*/
|
||||
<ST_HEREDOC>{HEREDOC_CHARS}*{HEREDOC_NEWLINE}+{LABEL}";"?[\n\r] {
|
||||
char *end = yytext + yyleng - 1;
|
||||
|
||||
@ -2477,7 +2521,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
|
||||
/* Subtract the remaining label length. yyleng must include newline
|
||||
* before label, for zend_highlight/strip, tokenizer, etc. */
|
||||
yyleng -= CG(heredoc_len) - 1;
|
||||
yyleng = yyleng - CG(heredoc_len) - 1;
|
||||
|
||||
CG(increment_lineno) = 1; /* For newline before label */
|
||||
BEGIN(ST_END_HEREDOC);
|
||||
@ -2499,7 +2543,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
<ST_END_HEREDOC>{ANY_CHAR} {
|
||||
Z_STRVAL_P(zendlval) = CG(heredoc);
|
||||
Z_STRLEN_P(zendlval) = CG(heredoc_len);
|
||||
yytext = Z_STRVAL_P(zendlval);
|
||||
SCNG(yy_text) = Z_STRVAL_P(zendlval);
|
||||
yyleng = Z_STRLEN_P(zendlval);
|
||||
CG(heredoc) = NULL;
|
||||
CG(heredoc_len) = 0;
|
||||
@ -2525,15 +2569,15 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
}
|
||||
|
||||
%{
|
||||
/* "{"{2,}|"$"{2,} handles { before "{$" or literal $ before a variable or "${"
|
||||
* (("{"+|"$"+)["]) handles { or $ at the end of a string
|
||||
*
|
||||
* Same for backquotes and heredocs, except the second case doesn't apply to
|
||||
* heredocs. yyless(yyleng - 1) is used to correct taking one character too many
|
||||
*/ %}
|
||||
*/
|
||||
<ST_DOUBLE_QUOTES>{DOUBLE_QUOTES_CHARS}*("{"{2,}|"$"{2,}|(("{"+|"$"+)["])) {
|
||||
yyless(yyleng - 1);
|
||||
if (yytext[yyleng-1] == '"') --yyleng;
|
||||
|
||||
if (CG(literal_type) == IS_UNICODE) {
|
||||
return zend_scan_unicode_escape_string(zendlval, yytext, yyleng, 0x22 /*'"'*/, T_ENCAPSED_AND_WHITESPACE TSRMLS_CC);
|
||||
@ -2565,14 +2609,13 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
|
||||
|
||||
%{
|
||||
/* ({HEREDOC_NEWLINE}+({LABEL}";"?)?)? handles the possible case of newline
|
||||
* sequences, possibly followed by a label, that couldn't be matched with
|
||||
* HEREDOC_CHARS because of a following variable or "{$"
|
||||
*
|
||||
* This doesn't affect real ending labels, as they are followed by a newline,
|
||||
* which will result in a longer match for the correct rule if present
|
||||
*/ %}
|
||||
*/
|
||||
<ST_HEREDOC>{HEREDOC_CHARS}*({HEREDOC_NEWLINE}+({LABEL}";"?)?)? {
|
||||
if (CG(literal_type) == IS_UNICODE) {
|
||||
return zend_scan_unicode_escape_string(zendlval, yytext, yyleng, 0, T_ENCAPSED_AND_WHITESPACE TSRMLS_CC);
|
||||
@ -2594,9 +2637,8 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
|
||||
|
||||
%{
|
||||
/* BEGIN nowdoc */
|
||||
%}
|
||||
|
||||
<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}[']{LABEL}[']{NEWLINE} {
|
||||
int bprefix = (yytext[0] != '<') ? 1 : 0;
|
||||
char *s;
|
||||
@ -2619,6 +2661,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
<ST_START_NOWDOC>{ANY_CHAR} {
|
||||
yyless(0);
|
||||
BEGIN(ST_NOWDOC);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
<ST_START_NOWDOC>{LABEL}";"?[\r\n] {
|
||||
@ -2639,9 +2682,9 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
return T_ENCAPSED_AND_WHITESPACE;
|
||||
} else {
|
||||
BEGIN(ST_NOWDOC);
|
||||
yyless(label_len);
|
||||
yymore();
|
||||
BEGIN(ST_NOWDOC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2665,7 +2708,7 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
|
||||
/* Subtract the remaining label length. yyleng must include newline
|
||||
* before label, for zend_highlight/strip, tokenizer, etc. */
|
||||
yyleng -= CG(heredoc_len) - 1;
|
||||
yyleng = yyleng - CG(heredoc_len) - 1;
|
||||
|
||||
CG(increment_lineno) = 1; /* For newline before label */
|
||||
BEGIN(ST_END_NOWDOC);
|
||||
@ -2686,16 +2729,15 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
<ST_END_NOWDOC>{ANY_CHAR} {
|
||||
Z_STRVAL_P(zendlval) = CG(heredoc);
|
||||
Z_STRLEN_P(zendlval) = CG(heredoc_len);
|
||||
yytext = CG(heredoc);
|
||||
SCNG(yy_text) = CG(heredoc);
|
||||
yyleng = CG(heredoc_len);
|
||||
CG(heredoc) = NULL;
|
||||
CG(heredoc_len) = 0;
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
return T_END_NOWDOC;
|
||||
}
|
||||
%{
|
||||
|
||||
/* END nowdoc */
|
||||
%}
|
||||
|
||||
<ST_DOUBLE_QUOTES>["] {
|
||||
BEGIN(ST_IN_SCRIPTING);
|
||||
@ -2709,13 +2751,10 @@ NOWDOC_CHARS ({NEWLINE}*(([^a-zA-Z_\x7f-\xff\n\r][^\n\r]*)|({LABEL}[^a-zA-Z0-9_
|
||||
}
|
||||
|
||||
|
||||
<ST_COMMENT,ST_DOC_COMMENT><<EOF>> {
|
||||
zend_error(E_COMPILE_WARNING,"Unterminated comment starting line %d", CG(comment_start_line));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
<ST_IN_SCRIPTING,ST_VAR_OFFSET>{ANY_CHAR} {
|
||||
zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
|
||||
goto restart;
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
@ -95,15 +95,16 @@ ZEND_API int zend_stack_is_empty(zend_stack *stack) /* {{{ */
|
||||
|
||||
ZEND_API int zend_stack_destroy(zend_stack *stack) /* {{{ */
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
|
||||
if (stack->elements) {
|
||||
for (i = 0; i < stack->top; i++) {
|
||||
efree(stack->elements[i]);
|
||||
}
|
||||
|
||||
if (stack->elements) {
|
||||
efree(stack->elements);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -13,6 +13,9 @@
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Wez Furlong <wez@thebrainroom.com> |
|
||||
| Scott MacVicar <scottmac@php.net> |
|
||||
| Nuno Lopes <nlopess@php.net> |
|
||||
| Marcus Boerger <helly@php.net> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
@ -22,6 +25,12 @@
|
||||
#include "zend.h"
|
||||
#include "zend_compile.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#if HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
ZEND_DLIMPORT int isatty(int fd);
|
||||
|
||||
static size_t zend_stream_stdio_reader(void *handle, char *buf, size_t len TSRMLS_DC) /* {{{ */
|
||||
@ -32,17 +41,67 @@ static size_t zend_stream_stdio_reader(void *handle, char *buf, size_t len TSRML
|
||||
|
||||
static void zend_stream_stdio_closer(void *handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if ((FILE*)handle != stdin)
|
||||
if (handle && (FILE*)handle != stdin) {
|
||||
fclose((FILE*)handle);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static long zend_stream_stdio_fteller(void *handle TSRMLS_DC) /* {{{ */
|
||||
static size_t zend_stream_stdio_fsizer(void *handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return ftell((FILE*) handle);
|
||||
struct stat buf;
|
||||
if (handle && fstat(fileno((FILE*)handle), &buf) == 0) {
|
||||
return buf.st_size;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_stream_unmap(zend_stream *stream TSRMLS_DC) { /* {{{ */
|
||||
#if HAVE_MMAP
|
||||
if (stream->mmap.map) {
|
||||
munmap(stream->mmap.map, stream->mmap.len);
|
||||
} else
|
||||
#endif
|
||||
if (stream->mmap.buf) {
|
||||
efree(stream->mmap.buf);
|
||||
}
|
||||
stream->mmap.len = 0;
|
||||
stream->mmap.pos = 0;
|
||||
stream->mmap.map = 0;
|
||||
stream->mmap.buf = 0;
|
||||
stream->handle = stream->mmap.old_handle;
|
||||
} /* }}} */
|
||||
|
||||
static void zend_stream_mmap_closer(zend_stream *stream TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_stream_unmap(stream TSRMLS_CC);
|
||||
if (stream->mmap.old_closer && stream->handle) {
|
||||
stream->mmap.old_closer(stream->handle TSRMLS_CC);
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
static inline int zend_stream_is_mmap(zend_file_handle *file_handle) { /* {{{ */
|
||||
return file_handle->type == ZEND_HANDLE_MAPPED;
|
||||
} /* }}} */
|
||||
|
||||
static size_t zend_stream_fsize(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (zend_stream_is_mmap(file_handle)) {
|
||||
return file_handle->handle.stream.mmap.len;
|
||||
}
|
||||
if (file_handle->type == ZEND_HANDLE_STREAM || file_handle->type == ZEND_HANDLE_MAPPED) {
|
||||
return file_handle->handle.stream.fsizer(file_handle->handle.stream.handle TSRMLS_CC);
|
||||
}
|
||||
if (file_handle->handle.fp && fstat(fileno(file_handle->handle.fp), &buf) == 0) {
|
||||
return buf.st_size;
|
||||
}
|
||||
|
||||
return -1;
|
||||
} /* }}} */
|
||||
|
||||
ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (zend_stream_open_function) {
|
||||
@ -53,56 +112,25 @@ ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSR
|
||||
handle->handle.fp = zend_fopen(filename, &handle->opened_path);
|
||||
handle->filename = (char *)filename;
|
||||
handle->free_filename = 0;
|
||||
memset(&handle->handle.stream.mmap, 0, sizeof(zend_mmap));
|
||||
|
||||
return (handle->handle.fp) ? SUCCESS : FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
switch (file_handle->type) {
|
||||
case ZEND_HANDLE_FILENAME:
|
||||
if (FAILURE == zend_stream_open(file_handle->filename, file_handle TSRMLS_CC)) {
|
||||
return FAILURE;
|
||||
char buf;
|
||||
if (file_handle->handle.stream.reader(file_handle->handle.stream.handle, &buf, sizeof(buf) TSRMLS_CC)) {
|
||||
return (int)buf;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZEND_HANDLE_FD:
|
||||
file_handle->handle.fp = fdopen(file_handle->handle.fd, "rb");
|
||||
file_handle->type = ZEND_HANDLE_FP;
|
||||
break;
|
||||
|
||||
case ZEND_HANDLE_FP:
|
||||
file_handle->handle.fp = file_handle->handle.fp;
|
||||
break;
|
||||
|
||||
case ZEND_HANDLE_STREAM:
|
||||
/* nothing to do */
|
||||
return SUCCESS;
|
||||
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
if (file_handle->type == ZEND_HANDLE_FP) {
|
||||
if (!file_handle->handle.fp) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* make compatible with stream */
|
||||
file_handle->handle.stream.handle = file_handle->handle.fp;
|
||||
file_handle->handle.stream.reader = zend_stream_stdio_reader;
|
||||
file_handle->handle.stream.closer = zend_stream_stdio_closer;
|
||||
file_handle->handle.stream.fteller = zend_stream_stdio_fteller;
|
||||
|
||||
file_handle->handle.stream.interactive = isatty(fileno((FILE *)file_handle->handle.stream.handle));
|
||||
}
|
||||
return SUCCESS;
|
||||
return EOF;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC) /* {{{ */
|
||||
static size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (file_handle->handle.stream.interactive) {
|
||||
if (!zend_stream_is_mmap(file_handle) && file_handle->handle.stream.isatty) {
|
||||
int c = '*';
|
||||
size_t n;
|
||||
|
||||
@ -112,13 +140,15 @@ ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_
|
||||
Ascii value 4 is actually EOT character which is not defined anywhere in the LibC
|
||||
or else we can use instead of hardcoded 4.
|
||||
*/
|
||||
for ( n = 0; n < len && (c = zend_stream_getc( file_handle TSRMLS_CC)) != EOF && c != 4 && c != '\n'; ++n )
|
||||
for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != 4 && c != '\n'; ++n) {
|
||||
#else
|
||||
for ( n = 0; n < len && (c = zend_stream_getc( file_handle TSRMLS_CC)) != EOF && c != '\n'; ++n )
|
||||
for (n = 0; n < len && (c = zend_stream_getc(file_handle TSRMLS_CC)) != EOF && c != '\n'; ++n) {
|
||||
#endif
|
||||
buf[n] = (char) c;
|
||||
if ( c == '\n' )
|
||||
buf[n++] = (char) c;
|
||||
buf[n] = (char)c;
|
||||
}
|
||||
if (c == '\n') {
|
||||
buf[n++] = (char)c;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
@ -126,26 +156,171 @@ ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
|
||||
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char buf;
|
||||
size_t size;
|
||||
zend_stream_type old_type;
|
||||
|
||||
if (file_handle->handle.stream.reader(file_handle->handle.stream.handle, &buf, sizeof(buf) TSRMLS_CC)) {
|
||||
return (int)buf;
|
||||
if (file_handle->type == ZEND_HANDLE_FILENAME) {
|
||||
if (zend_stream_open(file_handle->filename, file_handle TSRMLS_CC) == FAILURE) {
|
||||
return FAILURE;
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
switch (file_handle->type) {
|
||||
case ZEND_HANDLE_FD:
|
||||
file_handle->type = ZEND_HANDLE_FP;
|
||||
file_handle->handle.fp = fdopen(file_handle->handle.fd, "rb");
|
||||
/* no break; */
|
||||
case ZEND_HANDLE_FP:
|
||||
if (!file_handle->handle.fp) {
|
||||
return FAILURE;
|
||||
}
|
||||
memset(&file_handle->handle.stream.mmap, 0, sizeof(zend_mmap));
|
||||
file_handle->handle.stream.isatty = isatty(fileno((FILE *)file_handle->handle.stream.handle)) ? 1 : 0;
|
||||
file_handle->handle.stream.reader = (zend_stream_reader_t)zend_stream_stdio_reader;
|
||||
file_handle->handle.stream.closer = (zend_stream_closer_t)zend_stream_stdio_closer;
|
||||
file_handle->handle.stream.fsizer = (zend_stream_fsizer_t)zend_stream_stdio_fsizer;
|
||||
memset(&file_handle->handle.stream.mmap, 0, sizeof(file_handle->handle.stream.mmap));
|
||||
/* no break; */
|
||||
case ZEND_HANDLE_STREAM:
|
||||
/* nothing to do */
|
||||
break;
|
||||
|
||||
case ZEND_HANDLE_MAPPED:
|
||||
file_handle->handle.stream.mmap.pos = 0;
|
||||
*buf = file_handle->handle.stream.mmap.buf;
|
||||
*len = file_handle->handle.stream.mmap.len;
|
||||
return SUCCESS;
|
||||
|
||||
default:
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
size = zend_stream_fsize(file_handle TSRMLS_CC);
|
||||
if (size == (size_t)-1) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
old_type = file_handle->type;
|
||||
file_handle->type = ZEND_HANDLE_STREAM; /* we might still be _FP but we need fsize() work */
|
||||
|
||||
if (old_type == ZEND_HANDLE_FP && !file_handle->handle.stream.isatty && size) {
|
||||
#if HAVE_MMAP
|
||||
if (file_handle->handle.fp && size) {
|
||||
/* *buf[size] is zeroed automatically by the kernel */
|
||||
*buf = mmap(0, size + ZEND_MMAP_AHEAD, PROT_READ, MAP_PRIVATE, fileno(file_handle->handle.fp), 0);
|
||||
if (*buf != MAP_FAILED) {
|
||||
file_handle->handle.stream.mmap.len = size;
|
||||
file_handle->handle.stream.mmap.map = *buf;
|
||||
file_handle->handle.stream.mmap.buf = *buf;
|
||||
goto return_mapped;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
file_handle->handle.stream.mmap.map = 0;
|
||||
file_handle->handle.stream.mmap.buf = *buf = safe_emalloc(1, size, ZEND_MMAP_AHEAD);
|
||||
file_handle->handle.stream.mmap.len = zend_stream_read(file_handle, *buf, size TSRMLS_CC);
|
||||
} else {
|
||||
size_t read, remain = 4*1024;
|
||||
*buf = emalloc(remain);
|
||||
size = 0;
|
||||
|
||||
while ((read = zend_stream_read(file_handle, *buf + size, remain TSRMLS_CC)) > 0) {
|
||||
size += read;
|
||||
remain -= read;
|
||||
|
||||
if (remain == 0) {
|
||||
*buf = safe_erealloc(*buf, size, 2, 0);
|
||||
remain = size;
|
||||
}
|
||||
}
|
||||
file_handle->handle.stream.mmap.map = 0;
|
||||
file_handle->handle.stream.mmap.buf = *buf;
|
||||
file_handle->handle.stream.mmap.len = size;
|
||||
if (size && remain < ZEND_MMAP_AHEAD) {
|
||||
*buf = safe_erealloc(*buf, size, 1, ZEND_MMAP_AHEAD);
|
||||
}
|
||||
}
|
||||
|
||||
if (file_handle->handle.stream.mmap.len == 0) {
|
||||
*buf = erealloc(*buf, ZEND_MMAP_AHEAD);
|
||||
file_handle->handle.stream.mmap.buf = *buf;
|
||||
}
|
||||
|
||||
if (ZEND_MMAP_AHEAD) {
|
||||
memset(file_handle->handle.stream.mmap.buf + file_handle->handle.stream.mmap.len, 0, ZEND_MMAP_AHEAD);
|
||||
}
|
||||
|
||||
return_mapped:
|
||||
file_handle->type = ZEND_HANDLE_MAPPED;
|
||||
file_handle->handle.stream.mmap.pos = 0;
|
||||
file_handle->handle.stream.mmap.old_handle = file_handle->handle.stream.handle;
|
||||
file_handle->handle.stream.mmap.old_closer = file_handle->handle.stream.closer;
|
||||
file_handle->handle.stream.handle = &file_handle->handle.stream;
|
||||
file_handle->handle.stream.closer = (zend_stream_closer_t)zend_stream_mmap_closer;
|
||||
|
||||
*buf = file_handle->handle.stream.mmap.buf;
|
||||
*len = file_handle->handle.stream.mmap.len;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
ZEND_API void zend_file_handle_dtor(zend_file_handle *fh TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
switch (fh->type) {
|
||||
case ZEND_HANDLE_FD:
|
||||
/* nothing to do */
|
||||
break;
|
||||
case ZEND_HANDLE_FP:
|
||||
fclose(fh->handle.fp);
|
||||
break;
|
||||
case ZEND_HANDLE_STREAM:
|
||||
case ZEND_HANDLE_MAPPED:
|
||||
if (fh->handle.stream.closer && fh->handle.stream.handle) {
|
||||
fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC);
|
||||
}
|
||||
fh->handle.stream.handle = NULL;
|
||||
break;
|
||||
case ZEND_HANDLE_FILENAME:
|
||||
/* We're only supposed to get here when destructing the used_files hash,
|
||||
* which doesn't really contain open files, but references to their names/paths
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (fh->opened_path) {
|
||||
efree(fh->opened_path);
|
||||
fh->opened_path = NULL;
|
||||
}
|
||||
if (fh->free_filename && fh->filename) {
|
||||
efree(fh->filename);
|
||||
fh->filename = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2) /* {{{ */
|
||||
{
|
||||
if (fh1->type != fh2->type) {
|
||||
return 0;
|
||||
}
|
||||
switch (fh1->type) {
|
||||
case ZEND_HANDLE_FD:
|
||||
return fh1->handle.fd == fh2->handle.fd;
|
||||
case ZEND_HANDLE_FP:
|
||||
return fh1->handle.fp == fh2->handle.fp;
|
||||
case ZEND_HANDLE_STREAM:
|
||||
return fh1->handle.stream.handle == fh2->handle.stream.handle;
|
||||
case ZEND_HANDLE_MAPPED:
|
||||
return (fh1->handle.stream.handle == &fh1->handle.stream &&
|
||||
fh2->handle.stream.handle == &fh2->handle.stream &&
|
||||
fh1->handle.stream.mmap.old_handle == fh2->handle.stream.mmap.old_handle)
|
||||
|| fh1->handle.stream.handle == fh2->handle.stream.handle;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return file_handle->handle.stream.fteller(file_handle->handle.stream.handle TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -25,20 +25,40 @@
|
||||
* These functions are private to the engine.
|
||||
* */
|
||||
|
||||
typedef size_t (*zend_stream_reader_t)(void *handle, char *buf, size_t len TSRMLS_DC);
|
||||
typedef void (*zend_stream_closer_t)(void *handle TSRMLS_DC);
|
||||
typedef long (*zend_stream_fteller_t)(void *handle TSRMLS_DC);
|
||||
typedef size_t (*zend_stream_fsizer_t)(void* handle TSRMLS_DC);
|
||||
typedef size_t (*zend_stream_reader_t)(void* handle, char *buf, size_t len TSRMLS_DC);
|
||||
typedef void (*zend_stream_closer_t)(void* handle TSRMLS_DC);
|
||||
|
||||
#define ZEND_MMAP_AHEAD 32
|
||||
|
||||
typedef enum {
|
||||
ZEND_HANDLE_FILENAME,
|
||||
ZEND_HANDLE_FD,
|
||||
ZEND_HANDLE_FP,
|
||||
ZEND_HANDLE_STREAM,
|
||||
ZEND_HANDLE_MAPPED,
|
||||
} zend_stream_type;
|
||||
|
||||
typedef struct _zend_mmap {
|
||||
size_t len;
|
||||
size_t pos;
|
||||
void *map;
|
||||
char *buf;
|
||||
void *old_handle;
|
||||
zend_stream_closer_t old_closer;
|
||||
} zend_mmap;
|
||||
|
||||
typedef struct _zend_stream {
|
||||
void *handle;
|
||||
int isatty;
|
||||
zend_mmap mmap;
|
||||
zend_stream_reader_t reader;
|
||||
zend_stream_fsizer_t fsizer;
|
||||
zend_stream_closer_t closer;
|
||||
zend_stream_fteller_t fteller;
|
||||
int interactive;
|
||||
} zend_stream;
|
||||
|
||||
typedef struct _zend_file_handle {
|
||||
zend_uchar type;
|
||||
zend_stream_type type;
|
||||
char *filename;
|
||||
char *opened_path;
|
||||
union {
|
||||
@ -51,13 +71,9 @@ typedef struct _zend_file_handle {
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC);
|
||||
ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf, size_t len TSRMLS_DC);
|
||||
ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC);
|
||||
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle, char **buf, size_t *len TSRMLS_DC);
|
||||
ZEND_API void zend_file_handle_dtor(zend_file_handle *fh TSRMLS_DC);
|
||||
ZEND_API int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
|
||||
END_EXTERN_C()
|
||||
|
||||
#define zend_stream_close(handle) zend_file_handle_dtor((handle))
|
||||
|
||||
#endif
|
||||
|
@ -2730,7 +2730,7 @@ ZEND_API double zend_oct_strtod(const char *str, char **endptr) /* {{{ */
|
||||
s++;
|
||||
|
||||
while ((c = *s++)) {
|
||||
if (c > '7') {
|
||||
if (c < '0' || c > '7') {
|
||||
/* break and return the current value if the number is not well-formed
|
||||
* that's what Linux strtol() does
|
||||
*/
|
||||
|
@ -3176,7 +3176,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
|
||||
new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
|
||||
zend_destroy_file_handle(&file_handle TSRMLS_CC);
|
||||
} else {
|
||||
zend_file_handle_dtor(&file_handle);
|
||||
zend_file_handle_dtor(&file_handle TSRMLS_CC);
|
||||
failure_retval=1;
|
||||
}
|
||||
} else {
|
||||
|
@ -1730,7 +1730,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
|
||||
zend_destroy_file_handle(&file_handle TSRMLS_CC);
|
||||
} else {
|
||||
zend_file_handle_dtor(&file_handle);
|
||||
zend_file_handle_dtor(&file_handle TSRMLS_CC);
|
||||
failure_retval=1;
|
||||
}
|
||||
} else {
|
||||
@ -5037,7 +5037,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
|
||||
zend_destroy_file_handle(&file_handle TSRMLS_CC);
|
||||
} else {
|
||||
zend_file_handle_dtor(&file_handle);
|
||||
zend_file_handle_dtor(&file_handle TSRMLS_CC);
|
||||
failure_retval=1;
|
||||
}
|
||||
} else {
|
||||
@ -8378,7 +8378,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
|
||||
zend_destroy_file_handle(&file_handle TSRMLS_CC);
|
||||
} else {
|
||||
zend_file_handle_dtor(&file_handle);
|
||||
zend_file_handle_dtor(&file_handle TSRMLS_CC);
|
||||
failure_retval=1;
|
||||
}
|
||||
} else {
|
||||
@ -22634,7 +22634,7 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
new_op_array = zend_compile_file(&file_handle, (Z_LVAL(opline->op2.u.constant)==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
|
||||
zend_destroy_file_handle(&file_handle TSRMLS_CC);
|
||||
} else {
|
||||
zend_file_handle_dtor(&file_handle);
|
||||
zend_file_handle_dtor(&file_handle TSRMLS_CC);
|
||||
failure_retval=1;
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user