Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:9804 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 91806 invoked by uid 1010); 10 May 2004 20:20:48 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 91566 invoked from network); 10 May 2004 20:20:45 -0000 Received: from unknown (HELO mrout3.yahoo.com) (216.145.54.173) by pb1.pair.com with SMTP; 10 May 2004 20:20:45 -0000 Received: from bourbon.corp.yahoo.com (bourbon.corp.yahoo.com [216.145.53.135]) by mrout3.yahoo.com (8.12.10/8.12.10/y.out) with ESMTP id i4AKKZud042610 for ; Mon, 10 May 2004 13:20:36 -0700 (PDT) Received: (from andrei@localhost) by bourbon.corp.yahoo.com (8.12.9/8.11.1) id i4AKKZoD011370 for internals@lists.php.net; Mon, 10 May 2004 13:20:35 -0700 (PDT) (envelope-from andrei@gravitonic.com) X-Authentication-Warning: bourbon.corp.yahoo.com: andrei set sender to andrei@gravitonic.com using -f Date: Mon, 10 May 2004 13:20:35 -0700 To: internals@lists.php.net Message-ID: <20040510202035.GA11348@gravitonic.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="ZPt4rx8FFjLCG7dd" Content-Disposition: inline User-Agent: Mutt/1.4.1i Subject: [patch] Variables in .ini files From: andrei@gravitonic.com (Andrei Zmievski) --ZPt4rx8FFjLCG7dd Content-Type: text/plain; charset=us-ascii Content-Disposition: inline This is a patch I'd like to propose for inclusion in PHP 5. It is very useful to be able to refer to other .ini variables when defining them. Things like concatenation and reusing the same dir in multiple places become possible. With the attached patch you can do things like: default_dir = "/home/www/apache" include_path = ".:" ${default_dir} "/htdocs" open_basedir = ${default_dir} "/share" Whitespace between variables and strings is optional. Strings don't have to be in quotes. If the variable is not found in the currently defined .ini hash, then the SAPI getenv() hook is used to see whether it exists there so you can refer to env variables this way. Patch is against latest Zend dir. - Andrei --ZPt4rx8FFjLCG7dd Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="zend-vars-in-ini.diff" ? zend-vars-in-ini.diff Index: zend_ini_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_ini_parser.y,v retrieving revision 1.29 diff -u -p -r1.29 zend_ini_parser.y --- zend_ini_parser.y 13 Jan 2004 17:00:10 -0000 1.29 +++ zend_ini_parser.y 10 May 2004 20:13:16 -0000 @@ -26,6 +26,7 @@ #include "zend_constants.h" #include "zend_ini_scanner.h" #include "zend_extensions.h" +#include "SAPI.h" #define YYSTYPE zval @@ -92,6 +93,24 @@ void zend_ini_do_op(char type, zval *res result->type = IS_STRING; } +void zend_ini_init_string(zval *result) +{ + result->value.str.val = malloc(1); + result->value.str.val[0] = 0; + result->value.str.len = 0; + result->type = IS_STRING; +} + +void zend_ini_add_string(zval *result, zval *op1, zval *op2) +{ + int length = op1->value.str.len + op2->value.str.len; + + result->value.str.val = (char *) realloc(op1->value.str.val, length+1); + memcpy(result->value.str.val+op1->value.str.len, op2->value.str.val, op2->value.str.len); + result->value.str.val[length] = 0; + result->value.str.len = length; + result->type = IS_STRING; +} void zend_ini_get_constant(zval *result, zval *name) { @@ -112,6 +131,24 @@ void zend_ini_get_constant(zval *result, } } +void zend_ini_get_var(zval *result, zval *name) +{ + zval curval; + char *envvar; + TSRMLS_FETCH(); + + if (zend_get_configuration_directive(name->value.str.val, name->value.str.len+1, &curval) == SUCCESS) { + result->value.str.val = zend_strndup(curval.value.str.val, curval.value.str.len); + result->value.str.len = curval.value.str.len; + } else if ((envvar = sapi_getenv(name->value.str.val, name->value.str.len TSRMLS_CC)) != NULL || + (envvar = getenv(name->value.str.val)) != NULL) { + result->value.str.val = strdup(envvar); + result->value.str.len = strlen(envvar); + } else { + zend_ini_init_string(result); + } +} + static void ini_error(char *str) { @@ -175,6 +212,7 @@ int zend_parse_ini_file(zend_file_handle %token SECTION %token CFG_TRUE %token CFG_FALSE +%token TC_DOLLAR_CURLY %left '|' '&' %right '~' '!' @@ -210,13 +248,25 @@ statement: string_or_value: expr { $$ = $1; } - | TC_ENCAPSULATED_STRING { $$ = $1; } | CFG_TRUE { $$ = $1; } | CFG_FALSE { $$ = $1; } - | '\n' { $$.value.str.val = strdup(""); $$.value.str.len=0; $$.type = IS_STRING; } - | /* empty */ { $$.value.str.val = strdup(""); $$.value.str.len=0; $$.type = IS_STRING; } + | var_string_list { $$ = $1; } + | '\n' { zend_ini_init_string(&$$); } + | /* empty */ { zend_ini_init_string(&$$); } ; + +var_string_list: + var_string_list cfg_var_ref { zend_ini_add_string(&$$, &$1, &$2); free($2.value.str.val); } + | var_string_list TC_ENCAPSULATED_STRING { zend_ini_add_string(&$$, &$1, &$2); } + | var_string_list constant_string { zend_ini_add_string(&$$, &$1, &$2); } + | /* empty */ { zend_ini_init_string(&$$); } + + +cfg_var_ref: + TC_DOLLAR_CURLY TC_STRING '}' { zend_ini_get_var(&$$, &$2); } + + expr: constant_string { $$ = $1; } | expr '|' expr { zend_ini_do_op('|', &$$, &$1, &$3); } Index: zend_ini_scanner.l =================================================================== RCS file: /repository/ZendEngine2/zend_ini_scanner.l,v retrieving revision 1.33 diff -u -p -r1.33 zend_ini_scanner.l --- zend_ini_scanner.l 8 Jan 2004 08:23:23 -0000 1.33 +++ zend_ini_scanner.l 10 May 2004 20:13:16 -0000 @@ -153,12 +153,20 @@ NEWLINE ("\r"|"\n"|"\r\n") return TC_ENCAPSULATED_STRING; } -[&|~()!] { +[&|~$(){}!] { return yytext[0]; } +"${" { + return TC_DOLLAR_CURLY; +} + +"}" { + ini_lval->value.lval = (long) yytext[0]; + return yytext[0]; +} -[^=\n\r\t;|&~()!"\[]+ { +[^=\n\r\t;|&$~(){}!"\[]+ { /* STRING */ register int i; @@ -190,8 +198,6 @@ NEWLINE ("\r"|"\n"|"\r\n") } } - - [=\n] { if (yytext[0] == '\n') { SCNG(lineno)++; --ZPt4rx8FFjLCG7dd--