]> granicus.if.org Git - php/commitdiff
- Add use support (behaves like require, but will not use the same file twice)
authorAndi Gutmans <andi@php.net>
Tue, 30 Nov 1999 20:15:04 +0000 (20:15 +0000)
committerAndi Gutmans <andi@php.net>
Tue, 30 Nov 1999 20:15:04 +0000 (20:15 +0000)
- Add import support (behaves like include, but requires parentheses;  will not
  use the same file twice; Currently, it is not yet properly implemented, and
  only behaves like include)

Zend/zend-parser.y
Zend/zend-scanner.l
Zend/zend.c
Zend/zend.h
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_globals.h

index e2461a39626ea1c4ebf1630f7b74bd7dad512db0..b8eb3239da69f634d0641277de51a99394f6331c 100644 (file)
@@ -43,7 +43,7 @@
 %pure_parser
 %expect 4
 
-%left T_INCLUDE T_EVAL
+%left T_INCLUDE T_EVAL T_IMPORT
 %left ','
 %left T_LOGICAL_OR
 %left T_LOGICAL_XOR
 %token T_CONST
 %token T_RETURN
 %token T_REQUIRE
+%token T_USE
 %token T_GLOBAL
 %token T_STATIC
 %token T_VAR
@@ -179,13 +180,20 @@ statement:
        |       T_ECHO echo_expr_list ';'
        |       T_INLINE_HTML                   { do_echo(&$1 CLS_CC); }
        |       expr ';'                        { do_free(&$1 CLS_CC); }
-       |       T_REQUIRE expr ';'                      { if ($2.op_type==IS_CONST && $2.u.constant.type==IS_STRING) { require_filename($2.u.constant.value.str.val CLS_CC); zval_dtor(&$2.u.constant); } else { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); } }
+       |       T_REQUIRE expr ';'                      { if ($2.op_type==IS_CONST && $2.u.constant.type==IS_STRING) { require_filename($2.u.constant.value.str.val, 0 CLS_CC); zval_dtor(&$2.u.constant); } else { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); } }
+       |       T_USE use_filename ';'          { require_filename($2.u.constant.value.str.val, 1 CLS_CC); zval_dtor(&$2.u.constant); }
        |       T_UNSET '(' r_cvar ')' ';' { do_unset(&$3 CLS_CC); }
        |       T_FOREACH '(' expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
        |       ';'             /* empty statement */
 ;
 
 
+use_filename:
+               T_CONSTANT_ENCAPSED_STRING                      { $$ = $1; }
+       |       '(' T_CONSTANT_ENCAPSED_STRING ')'      { $$ = $2; }
+;
+
+
 declaration_statement:
                T_FUNCTION { $1.u.opline_num = CG(zend_lineno); } T_STRING { do_begin_function_declaration(&$1, &$3, 0 CLS_CC); }
                        '(' parameter_list ')' '{' inner_statement_list '}' { do_end_function_declaration(&$1 CLS_CC); }
@@ -656,8 +664,9 @@ encaps_var_offset:
 internal_functions_in_yacc:
                T_ISSET '(' cvar ')'    { do_isset_or_isempty(ZEND_ISSET, &$$, &$3 CLS_CC); }
        |       T_EMPTY '(' cvar ')'    { do_isset_or_isempty(ZEND_ISEMPTY, &$$, &$3 CLS_CC); }
-       |       T_INCLUDE expr          { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); }
+       |       T_INCLUDE expr                  { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); }
        |       T_EVAL '(' expr ')'     { do_include_or_eval(ZEND_EVAL, &$$, &$3 CLS_CC); }
+       |       T_IMPORT '(' expr ')'   { do_include_or_eval(ZEND_IMPORT, &$$, &$3 CLS_CC); }
 ;
 
 
index 9e68ec439c05a06ec33455d17fa4ab42d74ed1c6..0e5ad67eccfa85ad398438169645e57877c02617 100644 (file)
@@ -235,12 +235,14 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
 #ifndef ZTS
        switch (file_handle->type) {
                case ZEND_HANDLE_FILENAME:
-                       file_handle->handle.fp = zend_fopen(file_handle->filename);
+                       file_handle->handle.fp = zend_fopen(file_handle->filename, &file_handle->opened_path);
                        break;
                case ZEND_HANDLE_FD:
+                       file_handle->opened_path = NULL;
                        file_handle->handle.fp = fdopen(file_handle->handle.fd, "r");
                        break;
                case ZEND_HANDLE_FP:
+                       file_handle->opened_path = NULL;
                        file_handle->handle.fp = file_handle->handle.fp;
                        break;
        }
@@ -258,12 +260,13 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
 #else
        switch (file_handle->type) {
                case ZEND_HANDLE_FD:
+                       file_handle->opened_path = NULL;
                        file_handle->handle.is = new ifstream(file_handle->handle.fd);
                        file_handle->type = ZEND_HANDLE_FSTREAM;
                        break;
                case ZEND_HANDLE_FILENAME:
                        {
-                               file_handle->handle.fp = zend_fopen(file_handle->filename);
+                               file_handle->handle.fp = zend_fopen(file_handle->filename, &file_handle->opened_path);
                                if (!file_handle->handle.fp) {
                                        return FAILURE;
                                }
@@ -272,6 +275,7 @@ ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC)
                                break;
                        }
                case ZEND_HANDLE_FP:
+                       file_handle->opened_path = NULL;
                        if (file_handle->handle.fp==stdin) {
                                file_handle->handle.is = (ifstream *) &cin;
                        } else {
@@ -366,7 +370,7 @@ ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count,
 }
 
 
-zend_op_array *compile_filename(zval *filename CLS_DC)
+zend_op_array *compile_filename(zval *filename, zend_bool unique CLS_DC)
 {
        zend_file_handle file_handle;
        zval tmp;
@@ -381,6 +385,9 @@ zend_op_array *compile_filename(zval *filename CLS_DC)
        file_handle.filename = filename->value.str.val;
        file_handle.type = ZEND_HANDLE_FILENAME;
        retval = zend_compile_files(1 CLS_CC, 1, &file_handle);
+       if (file_handle.opened_path) {
+               free(file_handle.opened_path);
+       }
        if (filename==&tmp) {
                zval_dtor(&tmp);
        }
@@ -459,13 +466,13 @@ zend_op_array *compile_string(zval *source_string CLS_DC)
 
 
 BEGIN_EXTERN_C()
-int require_filename(char *filename CLS_DC)
+int require_filename(char *filename, zend_bool unique CLS_DC)
 {
        zend_file_handle file_handle;
 
        file_handle.type = ZEND_HANDLE_FILENAME;
        file_handle.filename = filename;
-       if (require_file(&file_handle CLS_CC)==FAILURE) {
+       if (require_file(&file_handle, unique CLS_CC)==FAILURE) {
                zend_bailout();
                return FAILURE; /* will never get here */
        }
@@ -473,7 +480,7 @@ int require_filename(char *filename CLS_DC)
 }
 
 
-int require_file(zend_file_handle *file_handle CLS_DC)
+int require_file(zend_file_handle *file_handle, zend_bool unique CLS_DC)
 {
        zend_lex_state original_lex_state;
        int compiler_result;
@@ -483,6 +490,18 @@ int require_file(zend_file_handle *file_handle CLS_DC)
                zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
                return FAILURE;
        }
+       if (file_handle->opened_path) {
+               if (unique) {
+                       zend_bool exists=1;
+
+                       if (zend_hash_add(&CG(used_files), file_handle->opened_path, strlen(file_handle->opened_path)+1, &exists, sizeof(zend_bool), NULL)==FAILURE) {
+                               zend_close_file_handle(file_handle CLS_CC);
+                               restore_lexical_state(&original_lex_state CLS_CC);
+                               return SUCCESS;
+                       }
+               }
+               free(file_handle->opened_path);
+       }
        compiler_result = zendparse(CLS_C);
        zend_close_file_handle(file_handle CLS_CC);
        restore_lexical_state(&original_lex_state CLS_CC);
@@ -506,6 +525,9 @@ int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlight
                zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename);
                return FAILURE;
        }
+       if (file_handle.opened_path) {
+               free(file_handle.opened_path);
+       }
        zend_highlight(syntax_highlighter_ini);
        zend_close_file_handle(&file_handle CLS_CC);
        restore_lexical_state(&original_lex_state CLS_CC);
@@ -808,10 +830,18 @@ ESCAPED_AND_WHITESPACE [\n\t\r #'.:;,()|^&+-/*=%!~<>?@]+
        return T_INCLUDE;
 }
 
+<ST_IN_SCRIPTING>"import" {
+       return T_IMPORT;
+}
+
 <ST_IN_SCRIPTING>"require" {
        return T_REQUIRE;
 }
 
+<ST_IN_SCRIPTING>"use" {
+       return T_USE;
+}
+
 <ST_IN_SCRIPTING>"global" {
        return T_GLOBAL;
 }
index 7a8947091675b393510f5be4136e0b5dc92805f0..dc1b024d198811ee79c97e5c492717c864be47cf 100644 (file)
@@ -44,7 +44,7 @@ ZEND_API int (*zend_printf)(const char *format, ...);
 ZEND_API int (*zend_write)(const char *str, uint str_length);
 ZEND_API void (*zend_error)(int type, const char *format, ...);
 ZEND_API void (*zend_message_dispatcher)(long message, void *data);
-ZEND_API FILE *(*zend_fopen)(const char *filename);
+ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
 ZEND_API void (*zend_block_interruptions)();
 ZEND_API void (*zend_unblock_interruptions)();
 ZEND_API int (*zend_get_ini_entry)(char *name, uint name_length, zval *contents);
@@ -208,8 +208,11 @@ ZEND_API void zend_print_zval_r(zval *expr, int indent)
 }
 
 
-static FILE *zend_fopen_wrapper(const char *filename)
+static FILE *zend_fopen_wrapper(const char *filename, char **opened_path)
 {
+       if (opened_path) {
+               *opened_path = strdup(filename);
+       }
        return fopen(filename, "r");
 }
 
index 313f151be13e9617811a49d6c3c105fd3cc9f1b0..494c03913af5b3058df4e988f9018b56285b6677 100644 (file)
@@ -178,7 +178,7 @@ typedef struct _zend_utility_functions {
        void (*error_function)(int type, const char *format, ...);
        int (*printf_function)(const char *format, ...);
        int (*write_function)(const char *str, uint str_length);
-       FILE *(*fopen_function)(const char *filename);
+       FILE *(*fopen_function)(const char *filename, char **opened_path);
        void (*message_handler)(long message, void *data);
        void (*block_interruptions)();
        void (*unblock_interruptions)();
@@ -237,7 +237,7 @@ 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 ZEND_API FILE *(*zend_fopen)(const char *filename);
+extern ZEND_API FILE *(*zend_fopen)(const char *filename, char **opened_path);
 extern ZEND_API void (*zend_block_interruptions)();
 extern ZEND_API void (*zend_unblock_interruptions)();
 extern ZEND_API void (*zend_message_dispatcher)(long message, void *data);
index 9a6dbbe4ff06d6840dea9ef8888167bf181f77a2..d7d2aec69c22eaddcb19b4f6c61fbe453a475d2b 100644 (file)
@@ -95,6 +95,7 @@ void init_compiler(CLS_D ELS_DC)
        init_resource_list(ELS_C);
        CG(unclean_shutdown) = 0;
        zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) zend_open_file_dtor, 0);
+       zend_hash_init(&CG(used_files), 5, NULL, NULL, 0);
 }
 
 
@@ -109,6 +110,7 @@ void shutdown_compiler(CLS_D)
        zend_hash_apply(CG(function_table), (int (*)(void *)) is_not_internal_function);
        zend_hash_apply(CG(class_table), (int (*)(void *)) is_not_internal_class);
        zend_llist_destroy(&CG(open_files));
+       zend_hash_destroy(&CG(used_files));
 }
 
 
index 1d96cf9559e37513aa8c3aaa290bcd7700f4264f..eb56ca251908de0956a8c0b2c1e4f785d1b8c060 100644 (file)
@@ -169,6 +169,7 @@ typedef struct _list_llist_element {
 typedef struct _zend_file_handle {
        int type;
        char *filename;
+       char *opened_path;
        union {
                int fd;
                FILE *fp;
@@ -344,12 +345,12 @@ void do_extended_fcall_end(CLS_D);
 
 /* 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 int require_file(zend_file_handle *file_handle, zend_bool unique CLS_DC);     
+ZEND_API int require_filename(char *filename, zend_bool unique CLS_DC);
 ZEND_API zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...);
 ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count, va_list files);
 ZEND_API zend_op_array *compile_string(zval *source_string CLS_DC);    
-ZEND_API zend_op_array *compile_filename(zval *filename CLS_DC);
+ZEND_API zend_op_array *compile_filename(zval *filename, zend_bool unique CLS_DC);
 ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC);
 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);
@@ -535,6 +536,7 @@ int zendlex(znode *zendlval CLS_DC);
 
 #define ZEND_EVAL                              (1<<0)
 #define ZEND_INCLUDE                   (1<<1)
+#define ZEND_IMPORT                            (1<<2)
 
 #define ZEND_ISSET                             (1<<0)
 #define ZEND_ISEMPTY                   (1<<1)
index edfcc396febe64438957e2bbcfe5fd2686f28a66..758050a39c637bcb158aae24bd3bf781a6da1483 100644 (file)
@@ -1878,11 +1878,14 @@ send_by_ref:
 
                                        switch (opline->op2.u.constant.value.lval) {
                                                case ZEND_INCLUDE:
-                                                       new_op_array = compile_filename(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R) CLS_CC);
+                                                       new_op_array = compile_filename(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R), 0 CLS_CC);
                                                        break;
                                                case ZEND_EVAL:
                                                        new_op_array = compile_string(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R) CLS_CC);
                                                        break;
+                                               case ZEND_IMPORT:
+                                                       new_op_array = compile_filename(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R), 1 CLS_CC);
+                                                       break;
                                        }
                                        FREE_OP(&opline->op1, EG(free_op1));
                                        if (new_op_array) {
index 43ce0868bd2f763489554d18d56c3f17a829b88d..5ad78d57cb4c83dd5ba055b858fe5adf7f84a836 100644 (file)
@@ -115,6 +115,8 @@ void init_executor(CLS_D ELS_DC)
        zend_llist_apply(&zend_extensions, (void (*)(void *)) zend_extension_activator);
        EG(opline_ptr) = NULL;
        EG(garbage_ptr) = 0;
+
+       zend_hash_init(&EG(imported_files), 5, NULL, NULL, 0);
 }
 
 
@@ -148,6 +150,8 @@ void shutdown_executor(ELS_D)
                zval_dtor(EG(garbage)[EG(garbage_ptr)]);
                efree(EG(garbage)[EG(garbage_ptr)]);
        }
+
+       zend_hash_destroy(&EG(imported_files));
 }
 
 
index d61542d5068c2315f019af9fbd52327a4cf13688..947fc0044dd3eb1375d1e317bf41a1864317c388 100644 (file)
@@ -84,6 +84,8 @@ struct _zend_compiler_globals {
        HashTable *function_table;      /* function symbol table */
        HashTable *class_table;         /* class table */
 
+       HashTable used_files;           /* files already included using 'use' */
+
        zend_llist filenames_list;
 
        zend_bool short_tags;
@@ -130,6 +132,8 @@ struct _zend_executor_globals {
        HashTable *active_symbol_table;
        HashTable symbol_table;         /* main symbol table */
 
+       HashTable imported_files;       /* files already included using 'import' */
+
        jmp_buf bailout;
 
        int error_reporting;