Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:31744 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 76632 invoked by uid 1010); 20 Aug 2007 19:55:01 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 76617 invoked from network); 20 Aug 2007 19:55:01 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 20 Aug 2007 19:55:01 -0000 Authentication-Results: pb1.pair.com smtp.mail=greg@chiaraquartet.net; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=greg@chiaraquartet.net; sender-id=unknown Received-SPF: error (pb1.pair.com: domain chiaraquartet.net from 38.99.98.18 cause and error) X-PHP-List-Original-Sender: greg@chiaraquartet.net X-Host-Fingerprint: 38.99.98.18 beast.bluga.net Linux 2.6 Received: from [38.99.98.18] ([38.99.98.18:45932] helo=mail.bluga.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id F8/70-06760-E81F9C64 for ; Mon, 20 Aug 2007 15:54:55 -0400 Received: from mail.bluga.net (localhost.localdomain [127.0.0.1]) by mail.bluga.net (Postfix) with ESMTP id 77876C0F0C9; Mon, 20 Aug 2007 12:54:51 -0700 (MST) Received: from [192.168.0.106] (CPE-76-84-1-170.neb.res.rr.com [76.84.1.170]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.bluga.net (Postfix) with ESMTP id 94FA1C0F0C8; Mon, 20 Aug 2007 12:54:50 -0700 (MST) Message-ID: <46C9F217.8040804@chiaraquartet.net> Date: Mon, 20 Aug 2007 14:57:11 -0500 User-Agent: Thunderbird 1.5.0.12 (X11/20070604) MIME-Version: 1.0 To: internals Mailing List , Dmitry Stogov , Stanislav Malyshev Content-Type: multipart/mixed; boundary="------------000601090803010300020702" X-Virus-Scanned: ClamAV using ClamSMTP Subject: [PATCH] allowing multiple namespaces per file plus namespaces with brackets From: greg@chiaraquartet.net (Gregory Beaver) --------------000601090803010300020702 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Hi all, This patch is also available at http://pear.php.net/~greg/namespace.patch.txt The patch adds the syntax "namespace { *stuff }" and allows multiple namespaces per file with no performance penalty or added complexity as only 4 lines of code need to be changed, and 9 lines of code added to implement this support! Basically, there is one use case of multiple namespaces per file that the patch is designed to support, which is the ability to cram many files into a single file. I have done this for purposes of distributing things (prior to phar), it is used by some with phing tasks for performance reasons, and can have other uses as well. The patch provides the ability to do this, for example: Note that the old format "namespace OneRingToRuleThemAll;" is still fully supported, and should be the recommended format, as build tools can easily take an entire file, change namespace .*; into namespace .*{ and append to the end of the file. The attached patch is against php6, but as you can see, a blind monkey could port it to PHP_5_3 when the time comes. All of the introduced changes are now tested, including the error message for nested namespace declarations, and the error message for multiple namespace declarations with ; (which was previously untested by .phpt tests) Thanks, Greg --------------000601090803010300020702 Content-Type: text/plain; name="namespace.patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="namespace.patch.txt" ? halt_compiler_php6.patch.txt ? namespace.patch.txt Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.762 diff -u -r1.762 zend_compile.c --- Zend/zend_compile.c 20 Aug 2007 09:48:41 -0000 1.762 +++ Zend/zend_compile.c 20 Aug 2007 19:46:52 -0000 @@ -4966,16 +4966,16 @@ } /* }}} */ -void zend_do_namespace(znode *name TSRMLS_DC) /* {{{ */ +void zend_do_namespace(znode *name, int brackets TSRMLS_DC) /* {{{ */ { unsigned int lcname_len; zstr lcname; - if (CG(active_op_array)->last > 0) { + if (!brackets && CG(active_op_array)->last > 0) { zend_error(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script"); } if (CG(current_namespace)) { - zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice"); + zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice (without brackets) or nested within brackets"); } lcname = zend_u_str_case_fold(Z_TYPE(name->u.constant), Z_UNIVAL(name->u.constant), Z_UNILEN(name->u.constant), 0, &lcname_len); if (((lcname_len == sizeof("self")-1) && @@ -4991,6 +4991,16 @@ } /* }}} */ +void zend_do_end_namespace(TSRMLS_D) /* {{{ */ +{ + if (CG(current_namespace)) { + zval_dtor(CG(current_namespace)); + efree(CG(current_namespace)); + CG(current_namespace) = NULL; + } +} +/* }}} */ + void zend_do_import(znode *ns_name, znode *new_name TSRMLS_DC) /* {{{ */ { unsigned int lcname_len; Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.363 diff -u -r1.363 zend_compile.h --- Zend/zend_compile.h 20 Aug 2007 09:48:41 -0000 1.363 +++ Zend/zend_compile.h 20 Aug 2007 19:46:53 -0000 @@ -520,7 +520,8 @@ void zend_do_abstract_method(znode *function_name, znode *modifiers, znode *body TSRMLS_DC); void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC); -void zend_do_namespace(znode *name TSRMLS_DC); +void zend_do_namespace(znode *name, int brackets TSRMLS_DC); +void zend_do_end_namespace(TSRMLS_D); void zend_do_import(znode *name, znode *new_name TSRMLS_DC); void zend_do_end_compilation(TSRMLS_D); Index: Zend/zend_language_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_language_parser.y,v retrieving revision 1.188 diff -u -r1.188 zend_language_parser.y --- Zend/zend_language_parser.y 20 Aug 2007 09:48:41 -0000 1.188 +++ Zend/zend_language_parser.y 20 Aug 2007 19:46:54 -0000 @@ -171,12 +171,12 @@ | function_declaration_statement { zend_do_early_binding(TSRMLS_C); } | class_declaration_statement { zend_do_early_binding(TSRMLS_C); } | T_HALT_COMPILER '(' ')' ';' { zend_do_halt_compiler_register(TSRMLS_C); YYACCEPT; } - | T_NAMESPACE namespace_name ';' { zend_do_namespace(&$2 TSRMLS_CC); } + | T_NAMESPACE namespace_name ';' { zend_do_namespace(&$2, 0 TSRMLS_CC); } + | T_NAMESPACE namespace_name '{' { zend_do_namespace(&$2, 1 TSRMLS_CC); } top_statement_list '}' { zend_do_end_namespace(TSRMLS_C); } | T_IMPORT namespace_name ';' { zend_do_import(&$2, NULL TSRMLS_CC); } | T_IMPORT namespace_name T_AS T_STRING ';' { zend_do_import(&$2, &$4 TSRMLS_CC); } ; - inner_statement_list: inner_statement_list { zend_do_extended_info(TSRMLS_C); } inner_statement { HANDLE_INTERACTIVE(); } | /* empty */ Index: Zend/tests/ns_039.phpt =================================================================== RCS file: Zend/tests/ns_039.phpt diff -N Zend/tests/ns_039.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_039.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,14 @@ +--TEST-- +039: double namespace declaration +--FILE-- +