1
0
mirror of https://github.com/benhoyt/inih.git synced 2025-01-28 22:52:54 +08:00

Add option to call handler when a new section is encountered (#79)

Some programs have ini files with multiple sections that have the same name, which would make it very useful to know when a new section is encountered.

This patch adds this ability as an option that's enabled by setting INI_CALL_HANDLER_ON_NEW_SECTION to 1
This commit is contained in:
ksdhans 2019-04-08 20:44:21 +08:00 committed by Ben Hoyt
parent 2023872dff
commit be59185856
17 changed files with 145 additions and 3 deletions

View File

@ -22,6 +22,7 @@ You can control various aspects of inih using preprocessor defines:
* **Stop on first error:** By default, inih keeps parsing the rest of the file after an error. To stop parsing on the first error, add `-DINI_STOP_ON_FIRST_ERROR=1`.
* **Report line numbers:** By default, the `ini_handler` callback doesn't receive the line number as a parameter. If you need that, add `-DINI_HANDLER_LINENO=1`.
* **Detect section headers:** By default, inih is compatible with [ConfigParser's](http://docs.python.org/library/configparser.html), which does **not** provide a way to detect entering new sections. If you need to detect new sections (e.g., the ini file has multiple sections with the same name), then add `-DINI_CALL_HANDLER_ON_NEW_SECTION=1`. Your handler function will then be called each time a new section is encountered, with the section parameter set to the new section while name and value are set to NULL.
### Memory options ###

4
ini.c
View File

@ -166,6 +166,10 @@ int ini_parse_stream(ini_reader reader, void* stream, ini_handler handler,
*end = '\0';
strncpy0(section, start + 1, sizeof(section));
*prev_name = '\0';
#if INI_CALL_HANDLER_ON_NEW_SECTION
if (!HANDLER(user, section, NULL, NULL) && !error)
error = lineno;
#endif
}
else if (!error) {
/* No ']' found on section line */

View File

@ -0,0 +1,61 @@
no_file.ini: e=-1 user=0
... [section1]
... one=This is a test;
... two=1234;
... [ section 2 ]
... happy=4;
... sad=;
... [empty]
... [comment_test]
... test1=1;2;3;
... test2=2;3;4;this won't be a comment, needs whitespace before ';';
... test;3=345;
... test4=4#5#6;
... test7=;
... test8=; not a comment, needs whitespace before ';';
... [colon_tests]
... Content-Type=text/html;
... foo=bar;
... adams=42;
... funny1=with = equals;
... funny2=with : colons;
... funny3=two = equals;
... funny4=two : colons;
normal.ini: e=0 user=101
... [section1]
... name1=value1;
... name2=value2;
bad_section.ini: e=3 user=102
bad_comment.ini: e=1 user=102
... [section]
... a=b;
... user=parse_error;
... c=d;
user_error.ini: e=3 user=104
... [section1]
... single1=abc;
... multi=this is a;
... multi=multi-line value;
... single2=xyz;
... [section2]
... multi=a;
... multi=b;
... multi=c;
... [section3]
... single=ghi;
... multi=the quick;
... multi=brown fox;
... name=bob smith;
multi_line.ini: e=0 user=105
bad_multi.ini: e=1 user=105
... [bom_section]
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... [section1]
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -52,3 +52,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -51,3 +51,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value; line 2
... key“=value“; line 3
bom.ini: e=0 user=107
... [section1]
... single1=abc; line 2
... single2=xyz; line 3
... single1=def; line 5
... single2=qrs; line 6
duplicate_sections.ini: e=0 user=108

View File

@ -51,3 +51,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -55,3 +55,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -51,3 +51,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -55,3 +55,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -51,3 +51,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -55,3 +55,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -47,3 +47,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -49,3 +49,9 @@ bad_multi.ini: e=1 user=105
... bom_name=bom_value;
... key“=value“;
bom.ini: e=0 user=107
... [section1]
... single1=abc;
... single2=xyz;
... single1=def;
... single2=qrs;
duplicate_sections.ini: e=0 user=108

View File

@ -0,0 +1,6 @@
[section1]
single1 = abc
single2 = xyz
[section1]
single1 = def
single2 = qrs

View File

@ -9,3 +9,4 @@
@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -DINI_ALLOW_REALLOC=1 -DINI_INITIAL_ALLOC=5 -run unittest.c > baseline_heap_realloc.txt
@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_ALLOW_REALLOC=1 -DINI_INITIAL_ALLOC=5 -run unittest.c > baseline_heap_realloc_max_line.txt
@call tcc ..\ini.c -I..\ -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_INITIAL_ALLOC=20 -run unittest.c > baseline_heap_string.txt
@call tcc ..\ini.c -I..\ -DINI_CALL_HANDLER_ON_NEW_SECTION=1 -run unittest.c > baseline_call_handler_on_new_section.txt

View File

@ -27,16 +27,20 @@ int dumper(void* user, const char* section, const char* name,
#endif
{
User = *((int*)user);
if (strcmp(section, Prev_section)) {
if (!name || strcmp(section, Prev_section)) {
printf("... [%s]\n", section);
strncpy(Prev_section, section, sizeof(Prev_section));
Prev_section[sizeof(Prev_section) - 1] = '\0';
}
if (!name) {
return 1;
}
#if INI_HANDLER_LINENO
printf("... %s=%s; line %d\n", name, value, lineno);
printf("... %s=%s; line %d\n", name, value, lineno);
#else
printf("... %s=%s;\n", name, value);
printf("... %s=%s;\n", name, value);
#endif
return strcmp(name, "user")==0 && strcmp(value, "parse_error")==0 ? 0 : 1;
@ -62,5 +66,6 @@ int main(void)
parse("multi_line.ini");
parse("bad_multi.ini");
parse("bom.ini");
parse("duplicate_sections.ini");
return 0;
}

View File

@ -47,3 +47,7 @@ rm -f unittest_heap_realloc_max_line
gcc ../ini.c -DINI_USE_STACK=0 -DINI_MAX_LINE=20 -DINI_INITIAL_ALLOC=20 unittest_string.c -o unittest_heap_string
./unittest_heap_string > baseline_heap_string.txt
rm -f unittest_heap_string
gcc ../ini.c -DINI_CALL_HANDLER_ON_NEW_SECTION=1 unittest.c -o unittest_call_handler_on_new_section
./unittest_call_handler_on_new_section > baseline_call_handler_on_new_section.txt
rm -f unittest_call_handler_on_new_section