Thread safe version now uses a C++ scanner object. Works fully.
// This code is derived from software contributed to Berkeley by
// Kent Williams and Tom Epperly.
//
-// Redistribution and use in source and binary forms 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.
+// 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.
int yy_more_flag;
int yy_more_len;
+ int yy_more_offset;
+ int yy_prev_more_offset;
};
#endif
{ \
/* Undo effects of setting up yytext. */ \
*yy_cp = yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
/* Undo the effects of YY_DO_BEFORE_ACTION. */
*yy_cp = yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
{
#ifndef _LANGUAGE_SCANNER_H
#define _LANGUAGE_SCANNER_H
+#ifdef ZTS
+class ZendFlexLexer : public yyFlexLexer
+{
+public:
+ int lex_scan(zval *zendlval CLS_DC);
+};
+
+#endif /* ZTS */
+
+
+#ifndef ZTS
typedef struct {
YY_BUFFER_STATE buffer_state;
int state;
FILE *in;
char *filename;
} zend_lex_state;
+#else
+typedef struct {
+ ZendFlexLexer *ZFL;
+ istream *input_file;
+} zend_lex_state;
+#endif
#endif
+----------------------------------------------------------------------+
| This source file is subject to the Zend license, that is bundled |
| with this package in the file LICENSE. If you did not receive a |
- | copy of the Zend license, please mail us at zend@zend.com so we can |
+ | copy of the Zen license, please mail us at zend@zend.com so we can |
| send you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Andi Gutmans <andi@zend.com> |
#include <errno.h>
+#ifdef ZTS
+#include <fstream.h>
+#endif
+
#include "zend.h"
#include "zend_alloc.h"
#include "zend_compile.h"
#include <stdarg.h>
#endif
+#ifdef ZTS
+#define YY_DECL int ZendFlexLexer::lex_scan(zval *zendlval CLS_DC)
+#else
#define YY_DECL int lex_scan(zval *zendlval CLS_DC)
+#endif
#define ECHO { ZEND_WRITE( yytext, yyleng ); }
-#ifdef __cplusplus
+#ifdef ZTS
# define MY_INPUT yyinput
#else
# define MY_INPUT input
}
+BEGIN_EXTERN_C()
void startup_scanner(CLS_D)
{
CG(heredoc) = NULL;
CG(heredoc_len)=0;
}
}
-
-
-void reset_scanner(CLS_D)
-{
- YY_TLS_VARS
-
- BEGIN(INITIAL);
- CG(zend_lineno)=1;
-}
+END_EXTERN_C()
static inline void save_lexical_state(zend_lex_state *lex_state CLS_DC)
{
+#ifndef ZTS
memcpy(&lex_state->buffer_state,&YY_CURRENT_BUFFER,sizeof(YY_BUFFER_STATE));
lex_state->in = yyin;
lex_state->lineno = CG(zend_lineno);
lex_state->state = YYSTATE;
lex_state->filename = zend_get_compiled_filename();
+#else
+ lex_state->ZFL = CG(ZFL);
+#endif
}
-static inline void restore_lexical_state(zend_lex_state *lex_state CLS_DC)
+inline void restore_lexical_state(zend_lex_state *lex_state CLS_DC)
{
+#ifndef ZTS
YY_BUFFER_STATE original_buffer_state = YY_CURRENT_BUFFER;
if (lex_state->buffer_state) {
CG(zend_lineno) = lex_state->lineno;
BEGIN(lex_state->state);
zend_restore_compiled_filename(lex_state->filename);
+#else
+ delete(CG(ZFL));
+ CG(ZFL) = lex_state->ZFL;
+#endif
}
+BEGIN_EXTERN_C()
inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
{
+#ifndef ZTS
FILE *tmp;
YY_BUFFER_STATE buffer_state = YY_CURRENT_BUFFER;
zend_set_compiled_filename(file_handle->filename);
return SUCCESS;
-}
+#else
+ ifstream *input_file = new ifstream(file_handle->filename);
+ CG(ZFL) = new ZendFlexLexer;
+ CG(ZFL)->switch_streams(input_file, &cout);
+ return SUCCESS;
+#endif
+}
+END_EXTERN_C()
ZEND_API zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...)
}
if (open_file_for_scanning(file_handle CLS_CC)==FAILURE) {
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+
destroy_op_array(op_array);
efree(op_array);
retval = NULL;
retval = NULL;
break;
} else {
+#ifndef ZTS
fclose(yyin);
+#endif
restore_lexical_state(&original_lex_state CLS_CC);
CG(active_op_array) = original_active_op_array;
retval = op_array;
static inline int prepare_string_for_scanning(zval *str)
{
+#ifndef ZTS
/* enforce two trailing NULLs for flex... */
str->value.str.val = (char *) erealloc(str->value.str.val,str->value.str.len+2);
str->value.str.val[str->value.str.len+1]=0;
yyin=NULL;
yy_scan_buffer(str->value.str.val, str->value.str.len+2);
+#endif
return SUCCESS;
}
zend_op_array *compile_string(zval *source_string CLS_DC)
{
+#ifndef ZTS
zend_lex_state original_lex_state;
zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
zend_op_array *original_active_op_array = CG(active_op_array);
zval_dtor(&tmp);
return retval;
+#else
+ return NULL;
+#endif
}
+BEGIN_EXTERN_C()
int require_filename(char *filename CLS_DC)
{
zend_file_handle file_handle;
return FAILURE;
}
zendparse(CLS_C);
+#ifndef ZTS
fclose(yyin);
+#endif
restore_lexical_state(&original_lex_state CLS_CC);
return SUCCESS;
}
+
int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini)
{
zend_lex_state original_lex_state;
return FAILURE;
}
zend_highlight(syntax_highlighter_ini);
+#ifndef ZTS
fclose(yyin);
+#endif
restore_lexical_state(&original_lex_state CLS_CC);
return SUCCESS;
}
}
+#ifdef ZTS
+int lex_scan(zval *zendlval CLS_DC)
+{
+ return CG(ZFL)->lex_scan(zendlval CLS_CC);
+}
+
+
+int yyFlexLexer::yylex()
+{
+ fprintf(stderr, "Error: yyFlexLexer::yylex() called\n");
+ return -1;
+}
+
+#endif
+
+
+
+#ifdef ZTS
+const char *zend_get_zendtext(CLS_D)
+{
+ return CG(ZFL)->YYText();
+}
+
+
+int zend_get_zendleng(CLS_D)
+{
+ return CG(ZFL)->YYLeng();
+}
+#endif
+
+
+END_EXTERN_C()
+
+
/* redefine YY_INPUT to handle urls for win32*/
#if 0 /*WIN32|WINNT*/
#define YY_INPUT(buf,result,max_size) \
%option noyylineno
%option noyywrap
%%
-%{
-TLS_VARS;
-%}
<IN_SCRIPTING>"exit" {
return T_EXIT;
#define ZEND_VERSION "0.80A"
+
+#ifdef __cplusplus
+#define BEGIN_EXTERN_C() extern "C" {
+#define END_EXTERN_C() }
+#else
+#define BEGIN_EXTERN_C()
+#define END_EXTERN_C()
+#endif
+
+
#include <stdio.h>
/*
#define ZEND_PUTS(str) zend_write((str), strlen((str)))
#define ZEND_PUTC(c) zend_write(&(c), 1), (c)
+BEGIN_EXTERN_C()
extern ZEND_API int (*zend_printf)(const char *format, ...);
extern ZEND_API int (*zend_write)(const char *str, uint str_length);
extern ZEND_API void (*zend_error)(int type, const char *format, ...);
extern FILE *(*zend_fopen)(const char *filename);
-extern void (*zend_message_dispatcher)(long message, void *data);
extern void (*zend_block_interruptions)();
extern void (*zend_unblock_interruptions)();
+extern void (*zend_message_dispatcher)(long message, void *data);
+END_EXTERN_C()
void zenderror(char *error);
#define HANDLE_UNBLOCK_INTERRUPTIONS() if (zend_unblock_interruptions) { zend_unblock_interruptions(); }
-
-
/* Messages for applications of Zend */
#define ZMSG_ENABLE_TRACK_VARS 1L
#define ZMSG_FAILED_INCLUDE_FOPEN 2L
p->pLast = (mem_header *) NULL;
+
#if ZEND_DEBUG
ZEND_API void *_emalloc(size_t size, char *filename, uint lineno)
#else
HANDLE_UNBLOCK_INTERRUPTIONS();
}
-
/*
* Local variables:
* tab-width: 4
ZEND_API char *zend_strndup(const char *s, unsigned int length);
+BEGIN_EXTERN_C()
+
#if ZEND_DEBUG
ZEND_API void *_emalloc(size_t size,char *filename,uint lineno);
ZEND_API void _efree(void *ptr,char *filename,uint lineno);
#endif
+END_EXTERN_C()
+
#endif
/*
void init_compiler(CLS_D ELS_DC);
void shutdown_compiler(CLS_D);
+BEGIN_EXTERN_C()
extern ZEND_API zend_op_array *(*zend_compile_files)(int mark_as_ref CLS_DC, int file_count, ...);
int lex_scan(zval *zendlval CLS_DC);
-void reset_scanner(CLS_D);
void startup_scanner(CLS_D);
void shutdown_scanner(CLS_D);
ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename);
ZEND_API char *zend_get_compiled_filename();
+#ifdef ZTS
+const char *zend_get_zendtext(CLS_D);
+int zend_get_zendleng(CLS_D);
+#endif
+
+END_EXTERN_C()
/* parser-driven code generators */
void do_binary_op(int op, znode *result, znode *op1, znode *op2 CLS_DC);
/* helper functions in zend-scanner.l */
+BEGIN_EXTERN_C()
ZEND_API int require_file(zend_file_handle *file_handle CLS_DC);
ZEND_API int require_filename(char *filename CLS_DC);
ZEND_API zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...);
ZEND_API zend_op_array *compile_string(zval *source_string CLS_DC);
ZEND_API zend_op_array *compile_filename(zval *filename CLS_DC);
inline int open_file_for_scanning(zend_file_handle *file_handle CLS_DC);
+END_EXTERN_C()
#define INITIAL_OP_ARRAY_SIZE 64
+BEGIN_EXTERN_C()
ZEND_API void init_op_array(zend_op_array *op_array, int initial_ops_size);
ZEND_API void destroy_op_array(zend_op_array *op_array);
+END_EXTERN_C()
ZEND_API void destroy_zend_function(zend_function *function);
ZEND_API void destroy_zend_class(zend_class_entry *ce);
int get_next_op_number(zend_op_array *op_array);
int print_class(zend_class_entry *class_entry);
void print_op_array(zend_op_array *op_array, int optimizations);
+BEGIN_EXTERN_C()
int pass_two(zend_op_array *op_array);
void pass_include_eval(zend_op_array *op_array);
+END_EXTERN_C()
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array);
#include "zend_hash.h"
#include "zend_llist.h"
-
/* Define ZTS if you want a thread-safe Zend */
/*#undef ZTS*/
#ifdef ZTS
#include "../TSRM/TSRM.h"
+#ifdef __cplusplus
+class ZendFlexLexer;
+#endif
+
+BEGIN_EXTERN_C()
extern int compiler_globals_id;
extern int executor_globals_id;
extern int alloc_globals_id;
+END_EXTERN_C()
+
#endif
typedef struct _zend_compiler_globals zend_compiler_globals;
# define CLS_FETCH() zend_compiler_globals *compiler_globals = (zend_compiler_globals *) ts_resource(compiler_globals_id)
# define YYPARSE_PARAM compiler_globals
# define YYLEX_PARAM compiler_globals
+BEGIN_EXTERN_C()
int zendparse(void *compiler_globals);
+END_EXTERN_C()
#else
# define CLS_D
# define CLS_DC
/* For extensions support */
unsigned char extended_info; /* generate extension information for debugger/profiler */
unsigned char handle_op_arrays; /* run op_arrays through op_array handlers */
+
+#ifdef ZTS
+#ifdef __cplusplus
+ ZendFlexLexer *ZFL;
+#else
+ void *ZFL;
+#endif
+#endif
};
#include "zend_ptr_stack.h"
#include "zend_globals.h"
+#ifndef ZTS
extern char *zendtext;
extern int zendleng;
-
+#else
+#define zendtext ((char *) zend_get_zendtext(CLS_C))
+#define zendleng zend_get_zendleng(CLS_C)
+#endif
static void html_putc(char c)
{
-
void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini)
{
zval token;
char *highlight_keyword;
} zend_syntax_highlighter_ini;
-void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini);
+BEGIN_EXTERN_C()
+void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini);
int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini);
int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini);
+END_EXTERN_C()
extern zend_syntax_highlighter_ini syntax_highlighter_ini;
#include "zend_compile.h"
#include "zend_indent.h"
+#ifndef ZTS
extern char *zendtext;
extern int zendleng;
+#else
+#define zendtext ((char *) zend_get_zendtext(CLS_C))
+#define zendleng zend_get_zendleng(CLS_C)
+#endif
+
static void handle_whitespace(int *emit_whitespace)
{
ZEND_API int increment_function(zval *op1);
ZEND_API int decrement_function(zval *op2);
+BEGIN_EXTERN_C()
ZEND_API void convert_scalar_to_number(zval *op);
ZEND_API void convert_to_string(zval *op);
ZEND_API void convert_to_long(zval *op);
ZEND_API int add_char_to_string(zval *result, zval *op1, zval *op2);
ZEND_API int add_string_to_string(zval *result, zval *op1, zval *op2);
ZEND_API void convert_to_double(zval *op);
+END_EXTERN_C()
ZEND_API int zval_is_true(zval *op);
ZEND_API int compare_function(zval *result, zval *op1, zval *op2);
ZEND_API int zend_print_variable(zval *var);
+BEGIN_EXTERN_C()
ZEND_API int zval_copy_ctor(zval *zvalue);
ZEND_API void zval_dtor(zval *zvalue);
+END_EXTERN_C()
+
ZEND_API void zval_ptr_dtor(zval **zval_ptr);
void zval_add_ref(zval **p);