MEDIUM: initcall: allow to register mutiple post_section_parser per section

Before this patch, REGISTER_CONFIG_SECTION() allowed to register one and only
one callback (<post>) called after the parsing of a section.

It was limitating because you couldn't register a post callback from anywhere
else in the code.

This patch introduces the new REGISTER_CONFIG_SECTION_POST() macros which allows
to register a new post callback for a section keyword from anywhere.

This patch introduces the feature by allowing `struct cfg_section` entries that
does not have a `section_parser`, and then iterating on all cfg_section with a
post_section_parser for a keyword.
This commit is contained in:
William Lallemand 2025-02-10 15:07:05 +01:00
parent 5c2039b5b8
commit 4de86bbbfc
3 changed files with 57 additions and 19 deletions

View File

@ -314,6 +314,16 @@ alphanumerically ordered:
call to cfg_register_section() with the three arguments at stage
STG_REGISTER.
You can only register a section once, but you can register post callbacks
multiple time for this section with REGISTER_CONFIG_SECTION_POST().
- REGISTER_CONFIG_SECTION_POST(name, post)
Registers a function which will be called after a section is parsed. This is
the same as the <post> argument in REGISTER_CONFIG_SECTION(), the difference
is that it allows to register multiple <post> callbacks and to register them
elsewhere in the code.
- REGISTER_PER_THREAD_ALLOC(fct)
Registers a call to register_per_thread_alloc(fct) at stage STG_REGISTER.

View File

@ -151,6 +151,10 @@ ssize_t load_cfg_in_mem(char* filename, char** cfg_content);
#define REGISTER_CONFIG_SECTION(name, parse, post) \
INITCALL3(STG_REGISTER, cfg_register_section, (name), (parse), (post))
/* simplified way to define a post section parser */
#define REGISTER_CONFIG_POST_SECTION(name, post) \
INITCALL3(STG_REGISTER, cfg_register_section, (name), NULL, (post))
#define REGISTER_CONFIG_POSTPARSER(name, parser) \
INITCALL2(STG_REGISTER, cfg_register_postparser, (name), (parser))

View File

@ -2052,7 +2052,10 @@ int parse_cfg(const struct cfgfile *cfg)
/* if a word is in sections list, is_sect = 1 */
list_for_each_entry(sect, &sections, list) {
if (strcmp(args[0], sect->section_name) == 0) {
/* look for a section_name, but also a section_parser, because there might be
* only a post_section_parser */
if (strcmp(args[0], sect->section_name) == 0 &&
sect->section_parser) {
is_sect = 1;
break;
}
@ -2562,7 +2565,7 @@ int parse_cfg(const struct cfgfile *cfg)
/* detect section start */
list_for_each_entry(ics, &sections, list) {
if (strcmp(args[0], ics->section_name) == 0) {
if (strcmp(args[0], ics->section_name) == 0 && ics->section_parser) {
cursection = ics->section_name;
pcs = cs;
cs = ics;
@ -2573,20 +2576,29 @@ int parse_cfg(const struct cfgfile *cfg)
}
}
if (pcs && pcs->post_section_parser) {
if (pcs) {
struct cfg_section *psect;
int status;
/* don't call post_section_parser in MODE_DISCOVERY */
if (global.mode & MODE_DISCOVERY)
goto section_parser;
status = pcs->post_section_parser();
err_code |= status;
if (status & ERR_FATAL)
fatal++;
/* look for every post_section_parser for the previous section name */
list_for_each_entry(psect, &sections, list) {
if (strcmp(pcs->section_name, psect->section_name) == 0 &&
psect->post_section_parser) {
if (err_code & ERR_ABORT)
goto err;
/* don't call post_section_parser in MODE_DISCOVERY */
if (global.mode & MODE_DISCOVERY)
goto section_parser;
status = psect->post_section_parser();
err_code |= status;
if (status & ERR_FATAL)
fatal++;
if (err_code & ERR_ABORT)
goto err;
}
}
}
pcs = NULL;
@ -2625,10 +2637,19 @@ int parse_cfg(const struct cfgfile *cfg)
ha_free(&global.cfg_curr_section);
/* call post_section_parser of the last section when there is no more lines */
if (cs && cs->post_section_parser) {
if (cs) {
struct cfg_section *psect;
/* don't call post_section_parser in MODE_DISCOVERY */
if (!(global.mode & MODE_DISCOVERY))
err_code |= cs->post_section_parser();
if (!(global.mode & MODE_DISCOVERY)) {
list_for_each_entry(psect, &sections, list) {
if (strcmp(cs->section_name, psect->section_name) == 0 &&
psect->post_section_parser) {
err_code |= cs->post_section_parser();
}
}
}
}
if (nested_cond_lvl) {
@ -4722,10 +4743,13 @@ int cfg_register_section(char *section_name,
{
struct cfg_section *cs;
list_for_each_entry(cs, &sections, list) {
if (strcmp(cs->section_name, section_name) == 0) {
ha_alert("register section '%s': already registered.\n", section_name);
return 0;
if (section_parser) {
/* only checks if we register a section parser, not a post section callback */
list_for_each_entry(cs, &sections, list) {
if (strcmp(cs->section_name, section_name) == 0 && cs->section_parser) {
ha_alert("register section '%s': already registered.\n", section_name);
return 0;
}
}
}