Skip to content

Commit

Permalink
add FR_CONF_OFFSET_REF()
Browse files Browse the repository at this point in the history
which allows you to reference another conf_parser_t, without
requiring an intermediary CONF_SECTION
  • Loading branch information
alandekok committed Dec 4, 2024
1 parent 2b8d4bc commit 9a66cc1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
48 changes: 46 additions & 2 deletions src/lib/server/cf_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,9 @@ static int cf_section_parse_init(CONF_SECTION *cs, void *base, conf_parser_t con
{
CONF_PAIR *cp;

/*
* This rule refers to a named subsection
*/
if ((rule->flags & CONF_FLAG_SUBSECTION)) {
char const *name2 = NULL;
CONF_SECTION *subcs;
Expand Down Expand Up @@ -785,6 +788,14 @@ static int cf_section_parse_init(CONF_SECTION *cs, void *base, conf_parser_t con
return 0;
}

/*
* This rule refers to another conf_parse_t which is included in-line in
* this section.
*/
if ((rule->flags & CONF_FLAG_REF) != 0) {
return 0;
}

/*
* Don't re-initialize data which was already parsed.
*/
Expand Down Expand Up @@ -971,7 +982,7 @@ static int cf_subsection_parse(TALLOC_CTX *ctx, void *out, void *base, CONF_SECT
return 0;
}

static int cf_section_parse_rule(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs, conf_parser_t *rule)
static int cf_section_parse_rule(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs, conf_parser_t const *rule)
{
int ret;
bool *is_set = NULL;
Expand Down Expand Up @@ -999,7 +1010,40 @@ static int cf_section_parse_rule(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs,
*/
if (rule->flags & CONF_FLAG_SUBSECTION) {
return cf_subsection_parse(ctx, data, base, cs, rule);
} /* else it's a CONF_PAIR */
}

/*
* Ignore this rule if it's a reference, as the
* rules it points to have been pushed by the
* above function.
*/
if ((rule->flags & CONF_FLAG_REF) != 0) {
conf_parser_t const *rule_p;
uint8_t *sub_base = base;

fr_assert(rule->subcs != NULL);

sub_base += rule->offset;

for (rule_p = rule->subcs; rule_p->name1; rule_p++) {
if (rule_p->flags & CONF_FLAG_DEPRECATED) continue; /* Skip deprecated */

ret = cf_section_parse_rule(ctx, sub_base, cs, rule_p);
if (ret < 0) return ret;
}

/*
* Ensure we have a proper terminator, type so we catch
* missing terminators reliably
*/
fr_cond_assert(rule_p->type == conf_term.type);

return 0;
}

/*
* Else it's a CONF_PAIR
*/

/*
* Pair either needs an output destination or
Expand Down
14 changes: 14 additions & 0 deletions src/lib/server/cf_parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,19 @@ _Generic(&(_ct), \
.offset = offsetof(_struct, _field), \
.subcs = _subcs

/** conf_parser_t which populates a sub-struct using a CONF_SECTION
*
* @param[in] _name of the CONF_SECTION to search for.
* @param[in] _struct containing the sub-struct to populate.
* @param[in] _field containing the sub-struct to populate.
* @param[in] _subcs conf_parser_t to include in-line in this section
*/
# define FR_CONF_OFFSET_REF(__struct, _field, _subcs) \
.name1 = CF_IDENT_NONE, \
.flags = CONF_FLAG_REF, \
.offset = offsetof(_struct, _field), \
.subcs = _subcs

/** conf_parser_t which parses a single CONF_PAIR producing a single global result
*
* @param[in] _name of the CONF_PAIR to search for.
Expand Down Expand Up @@ -427,6 +440,7 @@ typedef enum CC_HINT(flag_enum) {
CONF_FLAG_OK_MISSING = (1 << 22), //!< OK if it's missing
CONF_FLAG_HIDDEN = (1 << 23), //!< Used by scripts to omit items from the
///< generated documentation.
CONF_FLAG_REF = (1 << 24), //!< reference another conf_parser_t inline in this one
} conf_parser_flags_t;
DIAG_ON(attributes)

Expand Down

0 comments on commit 9a66cc1

Please sign in to comment.