Merge pull request #29123 from yuwata/conf-parser-cleanups-for-config-section

conf-parser: several cleanups and generalizations for ConfigSection
This commit is contained in:
Mike Yuan 2023-09-08 18:11:12 +08:00 committed by GitHub
commit b8f18c3089
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 12 deletions

View file

@ -415,6 +415,11 @@ static inline int set_dump_sorted(Set *h, void ***ret, size_t *ret_n) {
* the entries were inserted.
* It is safe to remove the current entry.
*/
#define _HASHMAP_BASE_FOREACH(e, h, i) \
for (Iterator i = ITERATOR_FIRST; _hashmap_iterate((h), &i, (void**)&(e), NULL); )
#define HASHMAP_BASE_FOREACH(e, h) \
_HASHMAP_BASE_FOREACH(e, h, UNIQ_T(i, UNIQ))
#define _HASHMAP_FOREACH(e, h, i) \
for (Iterator i = ITERATOR_FIRST; hashmap_iterate((h), &i, (void**)&(e), NULL); )
#define HASHMAP_FOREACH(e, h) \
@ -425,6 +430,11 @@ static inline int set_dump_sorted(Set *h, void ***ret, size_t *ret_n) {
#define ORDERED_HASHMAP_FOREACH(e, h) \
_ORDERED_HASHMAP_FOREACH(e, h, UNIQ_T(i, UNIQ))
#define _HASHMAP_BASE_FOREACH_KEY(e, k, h, i) \
for (Iterator i = ITERATOR_FIRST; _hashmap_iterate((h), &i, (void**)&(e), (const void**) &(k)); )
#define HASHMAP_BASE_FOREACH_KEY(e, k, h) \
_HASHMAP_BASE_FOREACH_KEY(e, k, h, UNIQ_T(i, UNIQ))
#define _HASHMAP_FOREACH_KEY(e, k, h, i) \
for (Iterator i = ITERATOR_FIRST; hashmap_iterate((h), &i, (void**)&(e), (const void**) &(k)); )
#define HASHMAP_FOREACH_KEY(e, k, h) \

View file

@ -1945,7 +1945,9 @@ int network_add_ipv4ll_route(Network *network) {
if (!network->ipv4ll_route)
return 0;
section_line = hashmap_find_free_section_line(network->routes_by_section);
r = hashmap_by_section_find_unused_line(network->routes_by_section, network->filename, &section_line);
if (r < 0)
return r;
/* IPv4LLRoute= is in [Network] section. */
r = route_new_static(network, network->filename, section_line, &n);
@ -1978,7 +1980,9 @@ int network_add_default_route_on_device(Network *network) {
if (!network->default_route_on_device)
return 0;
section_line = hashmap_find_free_section_line(network->routes_by_section);
r = hashmap_by_section_find_unused_line(network->routes_by_section, network->filename, &section_line);
if (r < 0)
return r;
/* DefaultRouteOnDevice= is in [Network] section. */
r = route_new_static(network, network->filename, section_line, &n);

View file

@ -748,9 +748,13 @@ static int config_section_compare_func(const ConfigSection *x, const ConfigSecti
DEFINE_HASH_OPS(config_section_hash_ops, ConfigSection, config_section_hash_func, config_section_compare_func);
int config_section_new(const char *filename, unsigned line, ConfigSection **s) {
int config_section_new(const char *filename, unsigned line, ConfigSection **ret) {
ConfigSection *cs;
assert(filename);
assert(line > 0);
assert(ret);
cs = malloc0(offsetof(ConfigSection, filename) + strlen(filename) + 1);
if (!cs)
return -ENOMEM;
@ -758,21 +762,31 @@ int config_section_new(const char *filename, unsigned line, ConfigSection **s) {
strcpy(cs->filename, filename);
cs->line = line;
*s = TAKE_PTR(cs);
*ret = TAKE_PTR(cs);
return 0;
}
unsigned hashmap_find_free_section_line(Hashmap *hashmap) {
int _hashmap_by_section_find_unused_line(
HashmapBase *entries_by_section,
const char *filename,
unsigned *ret) {
ConfigSection *cs;
unsigned n = 0;
void *entry;
HASHMAP_FOREACH_KEY(entry, cs, hashmap)
if (n < cs->line)
n = cs->line;
HASHMAP_BASE_FOREACH_KEY(entry, cs, entries_by_section) {
if (filename && !streq(cs->filename, filename))
continue;
n = MAX(n, cs->line);
}
return n + 1;
/* overflow? */
if (n >= UINT_MAX)
return -EFBIG;
*ret = n + 1;
return 0;
}
#define DEFINE_PARSER(type, vartype, conv_func) \

View file

@ -136,9 +136,24 @@ static inline ConfigSection* config_section_free(ConfigSection *cs) {
}
DEFINE_TRIVIAL_CLEANUP_FUNC(ConfigSection*, config_section_free);
int config_section_new(const char *filename, unsigned line, ConfigSection **s);
int config_section_new(const char *filename, unsigned line, ConfigSection **ret);
extern const struct hash_ops config_section_hash_ops;
unsigned hashmap_find_free_section_line(Hashmap *hashmap);
int _hashmap_by_section_find_unused_line(
HashmapBase *entries_by_section,
const char *filename,
unsigned *ret);
static inline int hashmap_by_section_find_unused_line(
Hashmap *entries_by_section,
const char *filename,
unsigned *ret) {
return _hashmap_by_section_find_unused_line(HASHMAP_BASE(entries_by_section), filename, ret);
}
static inline int ordered_hashmap_by_section_find_unused_line(
OrderedHashmap *entries_by_section,
const char *filename,
unsigned *ret) {
return _hashmap_by_section_find_unused_line(HASHMAP_BASE(entries_by_section), filename, ret);
}
static inline bool section_is_invalid(ConfigSection *section) {
/* If this returns false, then it does _not_ mean the section is valid. */