mirror of
https://github.com/systemd/systemd.git
synced 2024-10-30 06:25:37 +03:00
sd-hwdb: order properties by origin
If we find duplicates in a property-lookup, make sure to order them by their origin. That is, matches defined "later" take precedence over earlier matches. The "later"-order is defined by file-name + line-number combination. That is, if a match is defined below another one in the same hwdb file, it takes precedence, same as if it is defined in a file ordered after another one. Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
This commit is contained in:
parent
698c5a176e
commit
3a04b789c6
@ -141,12 +141,13 @@ static const struct trie_node_f *node_lookup_f(sd_hwdb *hwdb, const struct trie_
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int hwdb_add_property(sd_hwdb *hwdb, const char *key, const char *value) {
|
||||
static int hwdb_add_property(sd_hwdb *hwdb, const struct trie_value_entry_f *entry) {
|
||||
const char *key;
|
||||
int r;
|
||||
|
||||
assert(hwdb);
|
||||
assert(key);
|
||||
assert(value);
|
||||
|
||||
key = trie_string(hwdb, entry->key_off);
|
||||
|
||||
/*
|
||||
* Silently ignore all properties which do not start with a
|
||||
@ -157,11 +158,25 @@ static int hwdb_add_property(sd_hwdb *hwdb, const char *key, const char *value)
|
||||
|
||||
key++;
|
||||
|
||||
if (le64toh(hwdb->head->value_entry_size) >= sizeof(struct trie_value_entry2_f)) {
|
||||
const struct trie_value_entry2_f *old, *entry2;
|
||||
|
||||
entry2 = (const struct trie_value_entry2_f *)entry;
|
||||
old = ordered_hashmap_get(hwdb->properties, key);
|
||||
if (old) {
|
||||
/* on duplicates, we order by filename and line-number */
|
||||
r = strcmp(trie_string(hwdb, entry2->filename_off), trie_string(hwdb, old->filename_off));
|
||||
if (r < 0 ||
|
||||
(r == 0 && entry2->line_number < old->line_number))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = ordered_hashmap_ensure_allocated(&hwdb->properties, &string_hash_ops);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_hashmap_replace(hwdb->properties, key, (char*)value);
|
||||
r = ordered_hashmap_replace(hwdb->properties, key, (void *)entry);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -193,8 +208,7 @@ static int trie_fnmatch_f(sd_hwdb *hwdb, const struct trie_node_f *node, size_t
|
||||
|
||||
if (le64toh(node->values_count) && fnmatch(linebuf_get(buf), search, 0) == 0)
|
||||
for (i = 0; i < le64toh(node->values_count); i++) {
|
||||
err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_value(hwdb, node, i)->key_off),
|
||||
trie_string(hwdb, trie_node_value(hwdb, node, i)->value_off));
|
||||
err = hwdb_add_property(hwdb, trie_node_value(hwdb, node, i));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@ -259,8 +273,7 @@ static int trie_search_f(sd_hwdb *hwdb, const char *search) {
|
||||
size_t n;
|
||||
|
||||
for (n = 0; n < le64toh(node->values_count); n++) {
|
||||
err = hwdb_add_property(hwdb, trie_string(hwdb, trie_node_value(hwdb, node, n)->key_off),
|
||||
trie_string(hwdb, trie_node_value(hwdb, node, n)->value_off));
|
||||
err = hwdb_add_property(hwdb, trie_node_value(hwdb, node, n));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
@ -415,7 +428,7 @@ static int properties_prepare(sd_hwdb *hwdb, const char *modalias) {
|
||||
}
|
||||
|
||||
_public_ int sd_hwdb_get(sd_hwdb *hwdb, const char *modalias, const char *key, const char **_value) {
|
||||
const char *value;
|
||||
const struct trie_value_entry_f *entry;
|
||||
int r;
|
||||
|
||||
assert_return(hwdb, -EINVAL);
|
||||
@ -427,11 +440,11 @@ _public_ int sd_hwdb_get(sd_hwdb *hwdb, const char *modalias, const char *key, c
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
value = ordered_hashmap_get(hwdb->properties, key);
|
||||
if (!value)
|
||||
entry = ordered_hashmap_get(hwdb->properties, key);
|
||||
if (!entry)
|
||||
return -ENOENT;
|
||||
|
||||
*_value = value;
|
||||
*_value = trie_string(hwdb, entry->value_off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -454,8 +467,8 @@ _public_ int sd_hwdb_seek(sd_hwdb *hwdb, const char *modalias) {
|
||||
}
|
||||
|
||||
_public_ int sd_hwdb_enumerate(sd_hwdb *hwdb, const char **key, const char **value) {
|
||||
const struct trie_value_entry_f *entry;
|
||||
const void *k;
|
||||
void *v;
|
||||
|
||||
assert_return(hwdb, -EINVAL);
|
||||
assert_return(key, -EINVAL);
|
||||
@ -464,12 +477,12 @@ _public_ int sd_hwdb_enumerate(sd_hwdb *hwdb, const char **key, const char **val
|
||||
if (hwdb->properties_modified)
|
||||
return -EAGAIN;
|
||||
|
||||
ordered_hashmap_iterate(hwdb->properties, &hwdb->properties_iterator, &v, &k);
|
||||
ordered_hashmap_iterate(hwdb->properties, &hwdb->properties_iterator, (void **)&entry, &k);
|
||||
if (!k)
|
||||
return 0;
|
||||
|
||||
*key = k;
|
||||
*value = v;
|
||||
*value = trie_string(hwdb, entry->value_off);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user