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:
parent
2023872dff
commit
be59185856
@ -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
4
ini.c
@ -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 */
|
||||
|
61
tests/baseline_call_handler_on_new_section.txt
Normal file
61
tests/baseline_call_handler_on_new_section.txt
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
6
tests/duplicate_sections.ini
Normal file
6
tests/duplicate_sections.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[section1]
|
||||
single1 = abc
|
||||
single2 = xyz
|
||||
[section1]
|
||||
single1 = def
|
||||
single2 = qrs
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user