]> granicus.if.org Git - php/commitdiff
Thought I committed it ages ago... Anyway, without further delays, the final
authorZeev Suraski <zeev@php.net>
Sat, 4 Jun 2005 16:16:19 +0000 (16:16 +0000)
committerZeev Suraski <zeev@php.net>
Sat, 4 Jun 2005 16:16:19 +0000 (16:16 +0000)
__halt_compiler() patch

Zend/tests/halt01.phpt [new file with mode: 0644]
Zend/tests/halt02.phpt [new file with mode: 0644]
Zend/tests/halt03.phpt [new file with mode: 0644]
Zend/zend_compile.h
Zend/zend_language_parser.y
Zend/zend_language_scanner.l
Zend/zend_stream.c
Zend/zend_stream.h

diff --git a/Zend/tests/halt01.phpt b/Zend/tests/halt01.phpt
new file mode 100644 (file)
index 0000000..3af80d0
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+__HALT_COMPILER() basic test
+--FILE--
+<?php
+
+print "yo!\n";
+
+__HALT_COMPILER();
+
+none of this should be displayed!
+--EXPECT--
+yo!
diff --git a/Zend/tests/halt02.phpt b/Zend/tests/halt02.phpt
new file mode 100644 (file)
index 0000000..caaa474
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+__HALT_COMPILER() basic test
+--FILE--
+<?php
+
+$fp = fopen(__FILE__, "r");
+fseek($fp, __COMPILER_HALT_OFFSET__+1);
+print fread($fp, 1000);
+
+__HALT_COMPILER();
+Overlay information...
+--EXPECT--
+Overlay information...
diff --git a/Zend/tests/halt03.phpt b/Zend/tests/halt03.phpt
new file mode 100644 (file)
index 0000000..6e0931b
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+__HALT_COMPILER() basic test
+--FILE--
+<?php
+
+if (true) {
+       __HALT_COMPILER();
+}
+--EXPECTF--
+Fatal error: __HALT_COMPILER() can only be used from the outermost scope in %shalt03.php on line %d
index ab0f470999192ba8be1ab8bf6de14d06df6a0309..b5ae12ebca499f090b8d7a382b43cadeeaa32a5d 100644 (file)
@@ -321,6 +321,7 @@ ZEND_API char *zend_set_compiled_filename(char *new_compiled_filename TSRMLS_DC)
 ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC);
 ZEND_API char *zend_get_compiled_filename(TSRMLS_D);
 ZEND_API int zend_get_compiled_lineno(TSRMLS_D);
+ZEND_API int zend_get_scanned_file_offset(TSRMLS_D);
 
 ZEND_API char* zend_get_compiled_variable_name(zend_op_array *op_array, zend_uint var, int* name_len);
 
index 7fffd7e9cf68e6022bf4154ed56856d1ff3e217b..b5cf6ae9fed5e341d11ead73daa57ccd9bbcaa96 100644 (file)
@@ -35,6 +35,8 @@
 #include "zend_list.h"
 #include "zend_globals.h"
 #include "zend_API.h"
+#include "zend_constants.h"
+
 
 #define YYERROR_VERBOSE
 #define YYSTYPE znode
 %token T_UNSET
 %token T_ISSET
 %token T_EMPTY
+%token T_HALT_COMPILER
 %token T_CLASS
 %token T_INTERFACE
 %token T_EXTENDS
@@ -159,6 +162,7 @@ top_statement:
                statement
        |       function_declaration_statement  { zend_do_early_binding(TSRMLS_C); }
        |       class_declaration_statement             { zend_do_early_binding(TSRMLS_C); }
+       |       T_HALT_COMPILER '(' ')' ';'   { REGISTER_MAIN_LONG_CONSTANT("__COMPILER_HALT_OFFSET__", zend_get_scanned_file_offset(TSRMLS_C), CONST_CS); YYACCEPT; }
 ;
 
 
@@ -172,6 +176,7 @@ inner_statement:
                statement
        |       function_declaration_statement
        |       class_declaration_statement
+       |       T_HALT_COMPILER '(' ')' ';'   { zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope"); }
 ;
 
 
index 448221408228726bc180d8eee8bfba2f386027bc..7cd266fd39e030f7c04e107cab97a799de005f29 100644 (file)
@@ -494,6 +494,20 @@ 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 = (YY_CURRENT_BUFFER)->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;
+       }
+}
+
+
 zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
 {
        zend_lex_state original_lex_state;
@@ -1015,6 +1029,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
        return T_EMPTY;
 }
 
+<ST_IN_SCRIPTING>"__halt_compiler" {
+       return T_HALT_COMPILER;
+}
+
 <ST_IN_SCRIPTING>"static" {
        return T_STATIC;
 }
index bf68081b46064c50ca25edfd0025449304a0c575..95050d3d26989d80bc19fec022329a4f4371441d 100644 (file)
@@ -35,6 +35,12 @@ static void zend_stream_stdio_closer(void *handle TSRMLS_DC)
                fclose((FILE*)handle);
 }
 
+static long zend_stream_stdio_fteller(void *handle TSRMLS_DC)
+{
+       return ftell((FILE*) handle);
+}
+
+
 ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSRMLS_DC)
 {
        if (zend_stream_open_function) {
@@ -83,6 +89,7 @@ ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC)
                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));
        }
@@ -120,4 +127,7 @@ ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC)
        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);
+}
index c3d0ee128179491e8b91b8a8fdccba59a9fb5d08..6633f5923dfa35d1aeafd2129be4ad8818c2c989 100644 (file)
 
 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 struct _zend_stream {
        void *handle;
        zend_stream_reader_t reader;
        zend_stream_closer_t closer;
+       zend_stream_fteller_t fteller;
        int interactive;
 } zend_stream;
 
@@ -52,6 +54,7 @@ ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle TSR
 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);
 END_EXTERN_C()