hi,
Have you tried looking at how the parse_ini_file function works? that
should answer your questions on this.
- tul
Arnold Daniels wrote:
Hi,
I'm new at PHP internals and have read the 'Extension Writing' tutorial
(part 1-3) of devzone.zend.com. I'm writing a set of parsers, to parse
different kind of configuration formats. The first is an .ini parser.
The code almost works correctly. The only problem I have is that
sections get overwritten if appear multiple times in the .ini content.
[abc]
test = 1
[abc]
xyz = 2
Should result in: array('abc'=>array('test'=>1, 'xyz'=>2))
but instead returns: array('abc'=>array('xyz'=>2))
The logical conclusion is that my zend_hash_find call doesn't work
correctly and is always returning FAILURE. Though I've got no clue
what's wrong. Perhaps someone could have a quick look at the code.
Thanks a lot,
Arnold
--------------------
/**
* Parse .ini content into a zend array
*/
PHP_FUNCTION(qconf_ini_parse)
{
char *content;
int len;
char *c;
char *ln_start;
char key[ASCIILINESZ+1];
char val[ASCIILINESZ+1];
zval *cur_out;
zval **fnd_sec;
char t; // boolean: trim value yes/no
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &content,
&len) == FAILURE) {
RETURN_NULL();
}
array_init(return_value);
cur_out = return_value;
ln_start = content;
for (c=content; c <= content+len; c++) {
if (*c == '\n' || *c == '\0' || c == content+len) {
*c = '\0';
t = 0;
ln_start = strskp(ln_start); /* Skip leading spaces */
if (*ln_start!=';' && *ln_start!='#' && *ln_start!=0) { /*
Skip comment lines */
if (sscanf(ln_start, "[%[^]]", key)==1) {
/* Valid section name */
if (zend_hash_find(Z_ARRVAL_P(return_value), key,
strlen(key), (void**)&fnd_sec) == FAILURE) {
ALLOC_INIT_ZVAL(cur_out);
array_init(cur_out);
add_assoc_zval(return_value, key, cur_out);
} else {
cur_out = *fnd_sec;
}
} else if (sscanf (ln_start, "%[^=] = \"%[^\"]\"", key,
val) == 2
|| sscanf (ln_start, "%[^=] = '%[^\']'", key,
val) == 2
|| (t=1 && sscanf (ln_start, "%[^=] = %[^;#]",
key, val) == 2)) {
strcpy(key, strlwc(strcrop(key)));
/*
* sscanf cannot handle "" or '' as empty value,
* this is done here
*/
if (!strcmp(val, "\"\"") || !strcmp(val, "''")) {
val[0] = (char)0;
} else if (t) {
strcpy(val, strcrop(val));
}
add_assoc_string(cur_out, key, val, 1);
}
}
ln_start = c+1;
}
}
}
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php