conf: add an util to iterate on sequence

A YAML sequence of single key maps, such as `outputs`, stores its
entries at outputs.<n>.<name> so a direct lookup of outputs.<name>
never matches. Add SCConfNodeLookupInSequence() to walk such a
sequence and return the entries matching a given name.

Ticket: 8606
pull/16374/head
Eric Leblond 3 months ago
parent 215961d672
commit 1db9575bd2

@ -343,6 +343,11 @@ extern "C" {
node: *const SCConfNode, key: *const ::std::os::raw::c_char,
) -> *const ::std::os::raw::c_char;
}
extern "C" {
pub fn SCConfNodeLookupInSequence(
seq: *const SCConfNode, key: *const ::std::os::raw::c_char, prev: *const SCConfNode,
) -> *mut SCConfNode;
}
extern "C" {
pub fn SCConfNodeRemove(arg1: *mut SCConfNode);
}

@ -886,6 +886,48 @@ const char *SCConfNodeLookupChildValue(const SCConfNode *node, const char *name)
return NULL;
}
/**
* \brief Find a named entry inside a sequence node.
*
* A YAML sequence of single key maps -- the shape used by "outputs" --
* stores each entry as an unnamed node holding one child, so an entry is
* found at seq.<n>.<key> and not at seq.<key>. This walks the sequence and
* returns the child named \a key.
*
* A sequence may hold several entries with the same name (several eve-log
* outputs for instance), so \a prev allows iterating over all of them:
* pass NULL to get the first match, then the previous result to get the
* next one.
*
* \param seq The sequence node, may be NULL.
* \param key The name of the entry to look for.
* \param prev NULL to start, or the previously returned node to continue.
*
* \retval The matching SCConfNode or NULL when there is no (further) match.
*/
SCConfNode *SCConfNodeLookupInSequence(
const SCConfNode *seq, const char *key, const SCConfNode *prev)
{
if (seq == NULL || key == NULL)
return NULL;
bool seen = (prev == NULL);
SCConfNode *entry;
TAILQ_FOREACH (entry, &seq->head, next) {
SCConfNode *child = SCConfNodeLookupChild(entry, key);
if (child == NULL)
continue;
if (!seen) {
if (child == prev)
seen = true;
continue;
}
return child;
}
return NULL;
}
/**
* \brief Lookup for a key value under a specific node
*

@ -81,6 +81,8 @@ void SCConfCreateContextBackup(void);
void SCConfRestoreContextBackup(void);
SCConfNode *SCConfNodeLookupChild(const SCConfNode *node, const char *key);
const char *SCConfNodeLookupChildValue(const SCConfNode *node, const char *key);
SCConfNode *SCConfNodeLookupInSequence(
const SCConfNode *seq, const char *key, const SCConfNode *prev);
void SCConfNodeRemove(SCConfNode *);
void SCConfRegisterTests(void);
int SCConfNodeChildValueIsTrue(const SCConfNode *node, const char *key);

Loading…
Cancel
Save