Hi again, Well I first though of copying and changing parse_ini_file. But the implementation of the function is located in the zend core, spread out of 3 files and does all kind of strange things with global variables. My C skills are ok but not great and I've got next to no experience in writing/editing PHP extensions. I've managed to write an extension by following the (great) tutorial, but understanding parts of the zend core is simply out of my reach at this moment.
I know newbie questions are always a pain in the butt, but I hope you see that I have read the manual and besides I have to start somewhere. Perhaps you can have a look at the code still. Off course, I can send you all the file of the extension if you like. Thank you, Arnold -----Original Message----- From: M.Sokolewicz [mailto:[EMAIL PROTECTED] Sent: woensdag 8 november 2006 19:40 To: Arnold Daniels Cc: internals@lists.php.net Subject: [PHP-DEV] Re: Newbie question: zend_hash_find 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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php