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
? 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;
 }
 
-<INITIAL>[&|~()!] {
+<INITIAL>[&|~$(){}!] {
        return yytext[0];
 }
 
+<INITIAL>"${" {
+       return TC_DOLLAR_CURLY;
+}
+
+<INITIAL>"}" {
+       ini_lval->value.lval = (long) yytext[0];
+       return yytext[0];
+}
 
-<INITIAL>[^=\n\r\t;|&~()!"\[]+ {
+<INITIAL>[^=\n\r\t;|&$~(){}!"\[]+ {
        /* STRING */
        register int i;
 
@@ -190,8 +198,6 @@ NEWLINE ("\r"|"\n"|"\r\n")
        }
 }
 
-
-
 <INITIAL>[=\n] {
        if (yytext[0] == '\n') {
                SCNG(lineno)++;

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to