Fixed settings lookup if the section/key contains dots, second try
This commit is contained in:
+106
-22
@@ -88,11 +88,60 @@ struct kv_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find a section by a given key
|
* Print a format key, but consume already processed arguments
|
||||||
*/
|
*/
|
||||||
static section_t *find_section(section_t *section, char *key, va_list args)
|
static bool print_key(char *buf, int len, char *start, char *key, va_list args)
|
||||||
{
|
{
|
||||||
char name[512], *pos;
|
va_list copy;
|
||||||
|
bool res;
|
||||||
|
char *pos;
|
||||||
|
|
||||||
|
va_copy(copy, args);
|
||||||
|
while (start < key)
|
||||||
|
{
|
||||||
|
pos = strchr(start, '%');
|
||||||
|
if (!pos)
|
||||||
|
{
|
||||||
|
start += strlen(start) + 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pos++;
|
||||||
|
switch (*pos)
|
||||||
|
{
|
||||||
|
case 'd':
|
||||||
|
va_arg(copy, int);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
va_arg(copy, char*);
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
va_arg(copy, enum_name_t*);
|
||||||
|
va_arg(copy, int);
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DBG1(DBG_CFG, "settings with %%%c not supported!", *pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
start = pos;
|
||||||
|
if (*start)
|
||||||
|
{
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = vsnprintf(buf, len, key, copy) < len;
|
||||||
|
va_end(copy);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find a section by a given key, using buffered key, reusable buffer
|
||||||
|
*/
|
||||||
|
static section_t *find_section_buffered(section_t *section,
|
||||||
|
char *start, char *key, va_list args, char *buf, int len)
|
||||||
|
{
|
||||||
|
char *pos;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
section_t *current, *found = NULL;
|
section_t *current, *found = NULL;
|
||||||
|
|
||||||
@@ -100,21 +149,20 @@ static section_t *find_section(section_t *section, char *key, va_list args)
|
|||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name))
|
pos = strchr(key, '.');
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = strchr(name, '.');
|
|
||||||
if (pos)
|
if (pos)
|
||||||
{
|
{
|
||||||
*pos = '\0';
|
*pos = '\0';
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
if (!print_key(buf, len, start, key, args))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
enumerator = section->sections->create_enumerator(section->sections);
|
enumerator = section->sections->create_enumerator(section->sections);
|
||||||
while (enumerator->enumerate(enumerator, ¤t))
|
while (enumerator->enumerate(enumerator, ¤t))
|
||||||
{
|
{
|
||||||
if (streq(current->name, name))
|
if (streq(current->name, buf))
|
||||||
{
|
{
|
||||||
found = current;
|
found = current;
|
||||||
break;
|
break;
|
||||||
@@ -123,14 +171,32 @@ static section_t *find_section(section_t *section, char *key, va_list args)
|
|||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
if (found && pos)
|
if (found && pos)
|
||||||
{
|
{
|
||||||
return find_section(found, pos, args);
|
return find_section_buffered(found, start, pos, args, buf, len);
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *find_value(section_t *section, char *key, va_list args)
|
/**
|
||||||
|
* find a section by a given key
|
||||||
|
*/
|
||||||
|
static section_t *find_section(section_t *section, char *key, va_list args)
|
||||||
{
|
{
|
||||||
char name[512], *pos, *value = NULL;
|
char buf[128], keybuf[512];
|
||||||
|
|
||||||
|
if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return find_section_buffered(section, keybuf, keybuf, args, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the string value for a key, using buffered key, reusable buffer
|
||||||
|
*/
|
||||||
|
static char *find_value_buffered(section_t *section,
|
||||||
|
char *start, char *key, va_list args, char *buf, int len)
|
||||||
|
{
|
||||||
|
char *pos, *value = NULL;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
kv_t *kv;
|
kv_t *kv;
|
||||||
section_t *current, *found = NULL;
|
section_t *current, *found = NULL;
|
||||||
@@ -140,20 +206,20 @@ static char *find_value(section_t *section, char *key, va_list args)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vsnprintf(name, sizeof(name), key, args) >= sizeof(name))
|
pos = strchr(key, '.');
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = strchr(name, '.');
|
|
||||||
if (pos)
|
if (pos)
|
||||||
{
|
{
|
||||||
*pos = '\0';
|
*pos = '\0';
|
||||||
pos++;
|
pos++;
|
||||||
|
|
||||||
|
if (!print_key(buf, len, start, key, args))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
enumerator = section->sections->create_enumerator(section->sections);
|
enumerator = section->sections->create_enumerator(section->sections);
|
||||||
while (enumerator->enumerate(enumerator, ¤t))
|
while (enumerator->enumerate(enumerator, ¤t))
|
||||||
{
|
{
|
||||||
if (streq(current->name, name))
|
if (streq(current->name, buf))
|
||||||
{
|
{
|
||||||
found = current;
|
found = current;
|
||||||
break;
|
break;
|
||||||
@@ -162,15 +228,19 @@ static char *find_value(section_t *section, char *key, va_list args)
|
|||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
return find_value(found, pos, args);
|
return find_value_buffered(found, start, pos, args, buf, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!print_key(buf, len, start, key, args))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
enumerator = section->kv->create_enumerator(section->kv);
|
enumerator = section->kv->create_enumerator(section->kv);
|
||||||
while (enumerator->enumerate(enumerator, &kv))
|
while (enumerator->enumerate(enumerator, &kv))
|
||||||
{
|
{
|
||||||
if (streq(kv->key, name))
|
if (streq(kv->key, buf))
|
||||||
{
|
{
|
||||||
value = kv->value;
|
value = kv->value;
|
||||||
break;
|
break;
|
||||||
@@ -181,6 +251,20 @@ static char *find_value(section_t *section, char *key, va_list args)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the string value for a key
|
||||||
|
*/
|
||||||
|
static char *find_value(section_t *section, char *key, va_list args)
|
||||||
|
{
|
||||||
|
char buf[128], keybuf[512];
|
||||||
|
|
||||||
|
if (snprintf(keybuf, sizeof(keybuf), "%s", key) >= sizeof(keybuf))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return find_value_buffered(section, keybuf, keybuf, args, buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of settings_t.get.
|
* Implementation of settings_t.get.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -49,8 +49,11 @@ typedef struct settings_t settings_t;
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
*
|
*
|
||||||
* The values are accesses using the get() functions using dotted keys, e.g.
|
* The values are accessed using the get() functions using dotted keys, e.g.
|
||||||
* section-one.subsection.othervalue
|
* section-one.subsection.othervalue
|
||||||
|
*
|
||||||
|
* Currently only a limited set of printf format specifiers are supported
|
||||||
|
* (namely %s, %d and %N, see implementation for details).
|
||||||
*/
|
*/
|
||||||
struct settings_t {
|
struct settings_t {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user