lbarnaud Wed Nov 5 21:33:19 2008 UTC Added files: /php-src/ext/standard/tests/general_functions parse_ini_string_001.phpt parse_ini_string_002.phpt
Modified files: /ZendEngine2 zend_ini_scanner.l /php-src/ext/standard basic_functions.c basic_functions.h Log: Added parse_ini_string() function (grange at lemonde dot fr, Arnaud) [DOC] new function parse_ini_string() proto array parse_ini_string(string ini_string [, bool process_sections [, int scanner_mode]]) Same as parse_ini_file() except that it takes a string instead of a filename.
http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_ini_scanner.l?r1=1.57&r2=1.58&diff_format=u Index: ZendEngine2/zend_ini_scanner.l diff -u ZendEngine2/zend_ini_scanner.l:1.57 ZendEngine2/zend_ini_scanner.l:1.58 --- ZendEngine2/zend_ini_scanner.l:1.57 Thu Sep 11 00:49:18 2008 +++ ZendEngine2/zend_ini_scanner.l Wed Nov 5 21:33:19 2008 @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_scanner.l,v 1.57 2008/09/11 00:49:18 stas Exp $ */ +/* $Id: zend_ini_scanner.l,v 1.58 2008/11/05 21:33:19 lbarnaud Exp $ */ #include <errno.h> #include "zend.h" @@ -188,7 +188,7 @@ */ char *zend_ini_scanner_get_filename(TSRMLS_D) { - return ini_filename; + return ini_filename ? ini_filename : "Unknown"; } /* }}} */ http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.933&r2=1.934&diff_format=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.933 php-src/ext/standard/basic_functions.c:1.934 --- php-src/ext/standard/basic_functions.c:1.933 Sun Nov 2 21:10:11 2008 +++ php-src/ext/standard/basic_functions.c Wed Nov 5 21:33:19 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.933 2008/11/02 21:10:11 felipe Exp $ */ +/* $Id: basic_functions.c,v 1.934 2008/11/05 21:33:19 lbarnaud Exp $ */ #include "php.h" #include "php_streams.h" @@ -982,6 +982,13 @@ ZEND_ARG_INFO(0, scanner_mode) ZEND_END_ARG_INFO() +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_parse_ini_string, 0, 0, 1) + ZEND_ARG_INFO(0, ini_string) + ZEND_ARG_INFO(0, process_sections) + ZEND_ARG_INFO(0, scanner_mode) +ZEND_END_ARG_INFO() + #if ZEND_DEBUG static ZEND_BEGIN_ARG_INFO(arginfo_config_get_hash, 0) @@ -3474,6 +3481,7 @@ PHP_FE(connection_status, arginfo_connection_status) PHP_FE(ignore_user_abort, arginfo_ignore_user_abort) PHP_FE(parse_ini_file, arginfo_parse_ini_file) + PHP_FE(parse_ini_string, arginfo_parse_ini_string) #if ZEND_DEBUG PHP_FE(config_get_hash, arginfo_config_get_hash) #endif @@ -6495,6 +6503,43 @@ } /* }}} */ +/* {{{ proto array parse_ini_string(string ini_string [, bool process_sections [, int scanner_mode]]) U + Parse configuration string */ +PHP_FUNCTION(parse_ini_string) +{ + char *string = NULL, *str = NULL; + int str_len = 0; + zend_bool process_sections = 0; + long scanner_mode = ZEND_INI_SCANNER_NORMAL; + zend_ini_parser_cb_t ini_parser_cb; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &str, &str_len, &process_sections, &scanner_mode) == FAILURE) { + RETURN_FALSE; + } + + /* Set callback function */ + if (process_sections) { + BG(active_ini_file_section) = NULL; + ini_parser_cb = (zend_ini_parser_cb_t) php_ini_parser_cb_with_sections; + } else { + ini_parser_cb = (zend_ini_parser_cb_t) php_simple_ini_parser_cb; + } + + /* Setup string */ + string = (char *) emalloc(str_len + ZEND_MMAP_AHEAD); + memcpy(string, str, str_len); + memset(string + str_len, 0, ZEND_MMAP_AHEAD); + + array_init(return_value); + if (zend_parse_ini_string(string, 0, scanner_mode, ini_parser_cb, return_value TSRMLS_CC) == FAILURE) { + zend_hash_destroy(Z_ARRVAL_P(return_value)); + efree(Z_ARRVAL_P(return_value)); + RETVAL_FALSE; + } + efree(string); +} +/* }}} */ + #if ZEND_DEBUG /* This function returns an array of ALL valid ini options with values and * is not the same as ini_get_all() which returns only registered ini options. Only useful for devs to debug php.ini scanner/parser! */ http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.h?r1=1.165&r2=1.166&diff_format=u Index: php-src/ext/standard/basic_functions.h diff -u php-src/ext/standard/basic_functions.h:1.165 php-src/ext/standard/basic_functions.h:1.166 --- php-src/ext/standard/basic_functions.h:1.165 Wed Oct 15 18:41:18 2008 +++ php-src/ext/standard/basic_functions.h Wed Nov 5 21:33:19 2008 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.h,v 1.165 2008/10/15 18:41:18 kalle Exp $ */ +/* $Id: basic_functions.h,v 1.166 2008/11/05 21:33:19 lbarnaud Exp $ */ #ifndef BASIC_FUNCTIONS_H #define BASIC_FUNCTIONS_H @@ -126,6 +126,7 @@ /* From the INI parser */ PHP_FUNCTION(parse_ini_file); +PHP_FUNCTION(parse_ini_string); #if ZEND_DEBUG PHP_FUNCTION(config_get_hash); #endif http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/parse_ini_string_001.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/general_functions/parse_ini_string_001.phpt +++ php-src/ext/standard/tests/general_functions/parse_ini_string_001.phpt --TEST-- Test parse_ini_string() function --FILE-- <?php /* Prototype: array parse_ini_string(string $string [,bool $process_sections]); Description: parse_ini_string() loads in the ini file specified in filename, and returns the settings in it in an associative array. */ $parse_string = <<<EOD ; Comment starts with semi-colon(;) ; Section starts with [<section name>] ; start of ini file [Constans] one = 1 five = 5 animal = BIRD Language = PHP PHP_CONSTANT = 1.2345678 10 = Ten HELLO = HELLO [date] date = time = [paths] path = /usr/local/bin URL = http://www.php.net [Decimal] Decimal_value1 = 100 Decimal_value2 = -100 Decimal_value3 = -2147483647 Decimal_value4 = 2147483647 Decimal_value5 = -2147483648 Decimal_value6 = 2147483648 [Octal] Octal_value = 0100 [Hex] Hex_value1 = 0x101 Hex_Value2 = 0x102 Hex_Value2 = 0x103 [Non-alphanumerics_as_values] ;Non-alpha numeric chars without quotes Non_alpha1 = ; Non_alpha2 = + Non_alpha3 = * Non_alpha4 = % Non_alpha5 = <> Non_alpha6 = @ Non_alpha7 = # Non_alpha8 = ^ Non_alpha9 = - Non_alpha10 = : Non_alpha11 = ? Non_alpha12 = / Non_alpha13 = \ ;These chars have a special meaning when used in the value, ; hence parser throws an error ;Non_alpha14 = & ;Non_alpha15 = {} ;Non_alpha16 = | ;Non_alpha17 = ~ ;Non_alpha18 = ! ;Non_alpha19 = $ ;Non_alpha20 = () Non_alpha1_quotes = ";" Non_alpha2_quotes = "+" Non_alpha3_quotes = "*" Non_alpha4_quotes = "%" Non_alpha5_quotes = "<>" Non_alpha6_quotes = "@" Non_alpha7_quotes = "#" Non_alpha8_quotes = "^" Non_alpha9_quotes = "-" Non_alpha10_quotes = "=" Non_alpha11_quotes = ":" Non_alpha12_quotes = "?" Non_alpha13_quotes = "/" ;Non_alpha14_quotes = "\" Non_alpha15_quotes = "&" Non_alpha16_quotes = "{}" Non_alpha17_quotes = "|" Non_alpha18_quotes = "~" Non_alpha19_quotes = "!" ;Non_alpha20_quotes = "$" Non_alpha21_quotes = "()" [Non-alpha numerics in strings] ;expected error, as the non-alphanumeric chars not enclosed in double quotes("") Non_alpha_string1 = [EMAIL PROTECTED] ;Non_alpha_string2 = Hello!world ;Non_alpha_string3 = Hello#world ;Non_alpha_string4 = Hello%world ;Non_alpha_string5 = Hello&world ;Non_alpha_string6 = Hello*world ;Non_alpha_string7 = Hello+world ;Non_alpha_string8 = Hello-world ;Non_alpha_string9 = Hello'world ;Non_alpha_string10 = Hello:world ;Non_alpha_string11 = Hello;world ;Non_alpha_string12 = Hello<world ;Non_alpha_string13 = Hello>world ;Non_alpha_string14 = Hello>world ;Non_alpha_string15 = Hello?world ;Non_alpha_string16 = Hello\world ;Non_alpha_string17 = Hello^world ;Non_alpha_string18 = Hello_world ;Non_alpha_string19 = Hello|world ;Non_alpha_string20 = Hello~world ;Non_alpha_string21 = Hello`world ;Non_alpha_string22 = Hello(world) [Non-alpha numerics in strings -with quotes] Non_alpha_string1_quotes = "[EMAIL PROTECTED]" Non_alpha_string2_quotes = "Hello!world" Non_alpha_string3_quotes = "Hello#world" Non_alpha_string4_quotes = "Hello&world" Non_alpha_string5_quotes = "Hello*world" Non_alpha_string6_quotes = "Hello+world" Non_alpha_string7_quotes = "Hello-world" Non_alpha_string8_quotes = "Hello'world" Non_alpha_string9_quotes = "Hello:world" Non_alpha_string10_quotes = "Hello;world" Non_alpha_string11_quotes = "Hello<world" Non_alpha_string12_quotes = "Hello>world" Non_alpha_string13_quotes = "Hello>world" Non_alpha_string14_quotes = "Hello?world" Non_alpha_string15_quotes = "Hello\world" Non_alpha_string16_quotes = "Hello^world" Non_alpha_string17_quotes = "Hello_world" Non_alpha_string18_quotes = "Hello|world" Non_alpha_string19_quotes = "Hello~world" Non_alpha_string20_quotes = "Hello`world" Non_alpha_string21_quotes = "Hello(world)" [Newlines_in_Values] String1 = "Hello, world\nGood Morning" String2 = "\nHello, world Good Morning\n" String3 = 'Hello, world\tGood Morning' String4 = "\n" String5 = "\n\n" String6 = Hello, world\tGood Morning [ReservedKeys_as_Values] Key1 = YES Key2 = Yes Key3 = yEs Key4 = NO Key5 = No Key6 = nO Key7 = TRUE Key8 = True Key9 = tRUE Key10 = true Key11 = FALSE Key12 = False Key13 = false Key14 = fAlSE Key15 = NULL Key16 = Null Key17 = nuLL Key18 = null [ReservedKeys_as_Keys] ; Expected:error, reserved key words must not be used as keys for ini file ;YES = 1 ;Yes = 2 ;yEs = 1.2 ;YES = YES ;NO = "" ;No = "string" ;nO = "\0" ;TRUE = 1.1 ;True = 1 ;tRUE = 5 ;true = TRUE ;FALSE = FALSE ;False = "" ;false = "hello" ;fAlSE = "" ;NULL = "" ;Null = 0 ;nuLL = "\0" ;null = NULL ; end of ini file EOD; echo "*** Test parse_ini_string() function: with various keys and values given in string ***\n"; echo "-- ini string without process_sections optional arg --\n"; define('BIRD', 'Humming bird'); $ini_array = parse_ini_string($parse_string); print_r($ini_array); echo "\n-- ini string with process_sections as TRUE --\n"; $ini_array = parse_ini_string($parse_string, TRUE); print_r($ini_array); echo "*** Done **\n"; ?> --EXPECTF-- *** Test parse_ini_string() function: with various keys and values given in string *** -- ini string without process_sections optional arg -- Array ( [one] => 1 [five] => 5 [animal] => Humming bird [Language] => PHP [PHP_CONSTANT] => 1.2345678 [10] => Ten [HELLO] => HELLO [date] => [time] => [path] => /usr/local/bin [URL] => http://www.php.net [Decimal_value1] => 100 [Decimal_value2] => -100 [Decimal_value3] => -2147483647 [Decimal_value4] => 2147483647 [Decimal_value5] => -2147483648 [Decimal_value6] => 2147483648 [Octal_value] => 0100 [Hex_value1] => 0x101 [Hex_Value2] => 0x103 [Non_alpha1] => [Non_alpha2] => + [Non_alpha3] => * [Non_alpha4] => % [Non_alpha5] => <> [Non_alpha6] => @ [Non_alpha7] => # [Non_alpha8] => ^ [Non_alpha9] => - [Non_alpha10] => : [Non_alpha11] => ? [Non_alpha12] => / [Non_alpha13] => \ [Non_alpha1_quotes] => ; [Non_alpha2_quotes] => + [Non_alpha3_quotes] => * [Non_alpha4_quotes] => % [Non_alpha5_quotes] => <> [Non_alpha6_quotes] => @ [Non_alpha7_quotes] => # [Non_alpha8_quotes] => ^ [Non_alpha9_quotes] => - [Non_alpha10_quotes] => = [Non_alpha11_quotes] => : [Non_alpha12_quotes] => ? [Non_alpha13_quotes] => / [Non_alpha15_quotes] => & [Non_alpha16_quotes] => {} [Non_alpha17_quotes] => | [Non_alpha18_quotes] => ~ [Non_alpha19_quotes] => ! [Non_alpha21_quotes] => () [Non_alpha_string1] => [EMAIL PROTECTED] [Non_alpha_string1_quotes] => [EMAIL PROTECTED] [Non_alpha_string2_quotes] => Hello!world [Non_alpha_string3_quotes] => Hello#world [Non_alpha_string4_quotes] => Hello&world [Non_alpha_string5_quotes] => Hello*world [Non_alpha_string6_quotes] => Hello+world [Non_alpha_string7_quotes] => Hello-world [Non_alpha_string8_quotes] => Hello'world [Non_alpha_string9_quotes] => Hello:world [Non_alpha_string10_quotes] => Hello;world [Non_alpha_string11_quotes] => Hello<world [Non_alpha_string12_quotes] => Hello>world [Non_alpha_string13_quotes] => Hello>world [Non_alpha_string14_quotes] => Hello?world [Non_alpha_string15_quotes] => Hello\world [Non_alpha_string16_quotes] => Hello^world [Non_alpha_string17_quotes] => Hello_world [Non_alpha_string18_quotes] => Hello|world [Non_alpha_string19_quotes] => Hello~world [Non_alpha_string20_quotes] => Hello`world [Non_alpha_string21_quotes] => Hello(world) [String1] => Hello, world Good Morning [String2] => Hello, world Good Morning [String3] => Hello, world Good Morning [String4] => [String5] => [String6] => Hello, world Good Morning [Key1] => 1 [Key2] => 1 [Key3] => 1 [Key4] => [Key5] => [Key6] => [Key7] => 1 [Key8] => 1 [Key9] => 1 [Key10] => 1 [Key11] => [Key12] => [Key13] => [Key14] => [Key15] => [Key16] => [Key17] => [Key18] => ) -- ini string with process_sections as TRUE -- Array ( [Constans] => Array ( [one] => 1 [five] => 5 [animal] => Humming bird [Language] => PHP [PHP_CONSTANT] => 1.2345678 [10] => Ten [HELLO] => HELLO ) [date] => Array ( [date] => [time] => ) [paths] => Array ( [path] => /usr/local/bin [URL] => http://www.php.net ) [Decimal] => Array ( [Decimal_value1] => 100 [Decimal_value2] => -100 [Decimal_value3] => -2147483647 [Decimal_value4] => 2147483647 [Decimal_value5] => -2147483648 [Decimal_value6] => 2147483648 ) [Octal] => Array ( [Octal_value] => 0100 ) [Hex] => Array ( [Hex_value1] => 0x101 [Hex_Value2] => 0x103 ) [Non-alphanumerics_as_values] => Array ( [Non_alpha1] => [Non_alpha2] => + [Non_alpha3] => * [Non_alpha4] => % [Non_alpha5] => <> [Non_alpha6] => @ [Non_alpha7] => # [Non_alpha8] => ^ [Non_alpha9] => - [Non_alpha10] => : [Non_alpha11] => ? [Non_alpha12] => / [Non_alpha13] => \ [Non_alpha1_quotes] => ; [Non_alpha2_quotes] => + [Non_alpha3_quotes] => * [Non_alpha4_quotes] => % [Non_alpha5_quotes] => <> [Non_alpha6_quotes] => @ [Non_alpha7_quotes] => # [Non_alpha8_quotes] => ^ [Non_alpha9_quotes] => - [Non_alpha10_quotes] => = [Non_alpha11_quotes] => : [Non_alpha12_quotes] => ? [Non_alpha13_quotes] => / [Non_alpha15_quotes] => & [Non_alpha16_quotes] => {} [Non_alpha17_quotes] => | [Non_alpha18_quotes] => ~ [Non_alpha19_quotes] => ! [Non_alpha21_quotes] => () ) [Non-alpha numerics in strings] => Array ( [Non_alpha_string1] => [EMAIL PROTECTED] ) [Non-alpha numerics in strings -with quotes] => Array ( [Non_alpha_string1_quotes] => [EMAIL PROTECTED] [Non_alpha_string2_quotes] => Hello!world [Non_alpha_string3_quotes] => Hello#world [Non_alpha_string4_quotes] => Hello&world [Non_alpha_string5_quotes] => Hello*world [Non_alpha_string6_quotes] => Hello+world [Non_alpha_string7_quotes] => Hello-world [Non_alpha_string8_quotes] => Hello'world [Non_alpha_string9_quotes] => Hello:world [Non_alpha_string10_quotes] => Hello;world [Non_alpha_string11_quotes] => Hello<world [Non_alpha_string12_quotes] => Hello>world [Non_alpha_string13_quotes] => Hello>world [Non_alpha_string14_quotes] => Hello?world [Non_alpha_string15_quotes] => Hello\world [Non_alpha_string16_quotes] => Hello^world [Non_alpha_string17_quotes] => Hello_world [Non_alpha_string18_quotes] => Hello|world [Non_alpha_string19_quotes] => Hello~world [Non_alpha_string20_quotes] => Hello`world [Non_alpha_string21_quotes] => Hello(world) ) [Newlines_in_Values] => Array ( [String1] => Hello, world Good Morning [String2] => Hello, world Good Morning [String3] => Hello, world Good Morning [String4] => [String5] => [String6] => Hello, world Good Morning ) [ReservedKeys_as_Values] => Array ( [Key1] => 1 [Key2] => 1 [Key3] => 1 [Key4] => [Key5] => [Key6] => [Key7] => 1 [Key8] => 1 [Key9] => 1 [Key10] => 1 [Key11] => [Key12] => [Key13] => [Key14] => [Key15] => [Key16] => [Key17] => [Key18] => ) [ReservedKeys_as_Keys] => Array ( ) ) *** Done ** http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/general_functions/parse_ini_string_002.phpt?view=markup&rev=1.1 Index: php-src/ext/standard/tests/general_functions/parse_ini_string_002.phpt +++ php-src/ext/standard/tests/general_functions/parse_ini_string_002.phpt --TEST-- parse_ini_string() multiple calls --FILE-- <?php var_dump(parse_ini_string()); var_dump(parse_ini_string(1,1,1,1)); $ini = " test = "; var_dump(parse_ini_string($ini)); $ini = " test== "; var_dump(parse_ini_string($ini)); $ini = " test=test= "; var_dump(parse_ini_string($ini)); $ini = " test= \"new line\" "; var_dump(parse_ini_string($ini)); define("TEST_CONST", "test const value"); $ini = " test=TEST_CONST "; var_dump(parse_ini_string($ini)); $ini = " [section] test=hello "; var_dump(parse_ini_string($ini, true)); $ini = " [section] test=hello "; var_dump(parse_ini_string($ini, false)); $ini = " section.test=hello "; var_dump(parse_ini_string($ini, true)); $ini = " [section] section.test=hello "; var_dump(parse_ini_string($ini, true)); $ini = " [section] 1=2 "; var_dump(parse_ini_string($ini, true)); $ini = " 1=2 "; var_dump(parse_ini_string($ini, true)); $ini = " test=test2 test=test3 test=test4 "; var_dump(parse_ini_string($ini, true)); /* From bug #44574 */ $ini = "[section1]\nname = value"; var_dump(parse_ini_string($ini, true)); /* #44842, labels starting with underscore */ $ini = <<<'INI' foo=bar1 _foo=bar2 foo_=bar3 INI; var_dump(parse_ini_string($ini, true)); echo "Done\n"; ?> --EXPECTF-- Warning: parse_ini_string() expects at least 1 parameter, 0 given in %s bool(false) Warning: parse_ini_string() expects at most 3 parameters, 4 given in %s bool(false) array(1) { [%u|b%"test"]=> %unicode|string%(0) "" } Warning: syntax error, unexpected '=' in Unknown on line 2 in %s bool(false) Warning: syntax error, unexpected '=' in Unknown on line 2 in %s bool(false) array(1) { [%u|b%"test"]=> %unicode|string%(8) "new line" } array(1) { [%u|b%"test"]=> %unicode|string%(16) "test const value" } array(1) { [%u|b%"section"]=> array(1) { [%u|b%"test"]=> %unicode|string%(5) "hello" } } array(1) { [%u|b%"test"]=> %unicode|string%(5) "hello" } array(1) { [%u|b%"section.test"]=> %unicode|string%(5) "hello" } array(1) { [%u|b%"section"]=> array(1) { [%u|b%"section.test"]=> %unicode|string%(5) "hello" } } array(1) { [%u|b%"section"]=> array(1) { [1]=> %unicode|string%(1) "2" } } array(1) { [1]=> %unicode|string%(1) "2" } array(1) { [%u|b%"test"]=> %unicode|string%(5) "test4" } array(1) { [%u|b%"section1"]=> array(1) { [%u|b%"name"]=> %unicode|string%(5) "value" } } array(3) { [%u|b%"foo"]=> %unicode|string%(4) "bar1" [%u|b%"_foo"]=> %unicode|string%(4) "bar2" [%u|b%"foo_"]=> %unicode|string%(4) "bar3" } Done