forked from external/yambar
module/network: make module verification data driven
This is done by implementing a generic verify_dict() function, that takes an array of attribute metadata. The attribute metadata consists of the attribute name, whether it's required or optional, and a verify callback function.
This commit is contained in:
parent
e54e19e2c4
commit
3d22b30c87
1 changed files with 156 additions and 451 deletions
607
config-verify.c
607
config-verify.c
|
@ -10,6 +10,12 @@
|
||||||
|
|
||||||
typedef tll(const char *) keychain_t;
|
typedef tll(const char *) keychain_t;
|
||||||
|
|
||||||
|
struct attr_info {
|
||||||
|
const char *name;
|
||||||
|
bool required;
|
||||||
|
bool (*verify)(keychain_t *chain, const struct yml_node *node);
|
||||||
|
};
|
||||||
|
|
||||||
static keychain_t *
|
static keychain_t *
|
||||||
chain_push(keychain_t *chain, const char *key)
|
chain_push(keychain_t *chain, const char *key)
|
||||||
{
|
{
|
||||||
|
@ -135,6 +141,62 @@ verify_font(keychain_t *chain, const struct yml_node *node)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
verify_dict(keychain_t *chain, const struct yml_node *node,
|
||||||
|
const struct attr_info info[], size_t count)
|
||||||
|
{
|
||||||
|
if (!yml_is_dict(node)) {
|
||||||
|
LOG_ERR("%s: must be a dictionary", err_prefix(chain, node));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exists[count];
|
||||||
|
memset(exists, 0, sizeof(exists));
|
||||||
|
|
||||||
|
for (struct yml_dict_iter it = yml_dict_iter(node);
|
||||||
|
it.key != NULL;
|
||||||
|
yml_dict_next(&it))
|
||||||
|
{
|
||||||
|
const char *key = yml_value_as_string(it.key);
|
||||||
|
if (key == NULL) {
|
||||||
|
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct attr_info *attr = NULL;
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (strcmp(info[i].name, key) == 0) {
|
||||||
|
attr = &info[i];
|
||||||
|
exists[i] = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr == NULL) {
|
||||||
|
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attr->verify == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!attr->verify(chain_push(chain, key), it.value))
|
||||||
|
return false;
|
||||||
|
chain_pop(chain);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
if (!info[i].required || exists[i])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LOG_ERR("%s: missing required key: %s",
|
||||||
|
err_prefix(chain, node), info[i].name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
verify_border(keychain_t *chain, const struct yml_node *node)
|
verify_border(keychain_t *chain, const struct yml_node *node)
|
||||||
{
|
{
|
||||||
|
@ -176,440 +238,6 @@ verify_particle(keychain_t *chain, const struct yml_node *node)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_alsa(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "card") == 0 ||
|
|
||||||
strcmp(key, "mixer") == 0)
|
|
||||||
{
|
|
||||||
if (!verify_string(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_backlight(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "name") == 0) {
|
|
||||||
if (!verify_string(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_battery(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "name") == 0) {
|
|
||||||
if (!verify_string(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "poll_interval") == 0) {
|
|
||||||
if (!verify_int(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_clock(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "date-format") == 0 ||
|
|
||||||
strcmp(key, "time-format") == 0)
|
|
||||||
{
|
|
||||||
if (!verify_string(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_i3(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "spacing") == 0 ||
|
|
||||||
strcmp(key, "left_spacing") == 0 ||
|
|
||||||
strcmp(key, "right_spacing") == 0)
|
|
||||||
{
|
|
||||||
if (!verify_int(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_label(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_mpd(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "host") == 0) {
|
|
||||||
if (!verify_string(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "port") == 0) {
|
|
||||||
if (!verify_int(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_network(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "name") == 0) {
|
|
||||||
if (!verify_string(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_removables(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "spacing") == 0 ||
|
|
||||||
strcmp(key, "left_spacing") == 0 ||
|
|
||||||
strcmp(key, "right_spacing") == 0)
|
|
||||||
{
|
|
||||||
if (!verify_int(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_xkb(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
verify_module_xwindow(keychain_t *chain, const struct yml_node *node)
|
|
||||||
{
|
|
||||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
|
||||||
it.key != NULL;
|
|
||||||
yml_dict_next(&it))
|
|
||||||
{
|
|
||||||
const char *key = yml_value_as_string(it.key);
|
|
||||||
if (key == NULL) {
|
|
||||||
LOG_ERR("%s: key must be a string", err_prefix(chain, node));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(key, "content") == 0) {
|
|
||||||
if (!verify_particle(chain_push(chain, key), it.value))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (strcmp(key, "anchors") == 0) {
|
|
||||||
/* Skip */
|
|
||||||
chain_push(chain, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
LOG_ERR("%s: invalid key: %s", err_prefix(chain, node), key);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
chain_pop(chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
verify_module(keychain_t *chain, const struct yml_node *node)
|
verify_module(keychain_t *chain, const struct yml_node *node)
|
||||||
{
|
{
|
||||||
|
@ -629,30 +257,107 @@ verify_module(keychain_t *chain, const struct yml_node *node)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct attr_info alsa[] = {
|
||||||
|
{"card", true, &verify_string},
|
||||||
|
{"mixer", true, &verify_string},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info backlight[] = {
|
||||||
|
{"name", true, &verify_string},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info battery[] = {
|
||||||
|
{"name", true, &verify_string},
|
||||||
|
{"poll_interval", false, &verify_int},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info clock[] = {
|
||||||
|
{"date-format", false, &verify_string},
|
||||||
|
{"time-format", false, &verify_string},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info label[] = {
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info mpd[] = {
|
||||||
|
{"host", true, &verify_string},
|
||||||
|
{"port", false, &verify_int},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info i3[] = {
|
||||||
|
{"spacing", false, &verify_int},
|
||||||
|
{"left_spacing", false, &verify_int},
|
||||||
|
{"right_spacing", false, &verify_int},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info network[] = {
|
||||||
|
{"name", true, &verify_string},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info removables[] = {
|
||||||
|
{"spacing", false, &verify_int},
|
||||||
|
{"left_spacing", false, &verify_int},
|
||||||
|
{"right_spacing", false, &verify_int},
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info xkb[] = {
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attr_info xwindow[] = {
|
||||||
|
{"content", true, &verify_particle},
|
||||||
|
{"anchors", false, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
bool (*verify_fun)(keychain_t *chain, const struct yml_node *node);
|
const struct attr_info *attrs;
|
||||||
|
size_t count;
|
||||||
} modules[] = {
|
} modules[] = {
|
||||||
{"alsa", &verify_module_alsa},
|
{"alsa", alsa, sizeof(alsa) / sizeof(alsa[0])},
|
||||||
{"backlight", &verify_module_backlight},
|
{"backlight", backlight, sizeof(backlight) / sizeof(backlight[0])},
|
||||||
{"battery", &verify_module_battery},
|
{"battery", battery, sizeof(battery) / sizeof(battery[0])},
|
||||||
{"clock", &verify_module_clock},
|
{"clock", clock, sizeof(clock) / sizeof(clock[0])},
|
||||||
{"i3", &verify_module_i3},
|
{"i3", i3, sizeof(i3) / sizeof(i3[0])},
|
||||||
{"label", &verify_module_label},
|
{"label", label, sizeof(label) / sizeof(label[0])},
|
||||||
{"mpd", &verify_module_mpd},
|
{"mpd", mpd, sizeof(mpd) / sizeof(mpd[0])},
|
||||||
{"network", &verify_module_network},
|
{"network", network, sizeof(network) / sizeof(network[0])},
|
||||||
{"removables", &verify_module_removables},
|
{"removables", removables, sizeof(removables) / sizeof(removables[0])},
|
||||||
{"xkb", &verify_module_xkb},
|
{"xkb", xkb, sizeof(xkb) / sizeof(xkb[0])},
|
||||||
{"xwindow", &verify_module_xwindow},
|
{"xwindow", xwindow, sizeof(xwindow) / sizeof(xwindow[0])},
|
||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
|
for (size_t i = 0; i < sizeof(modules) / sizeof(modules[0]); i++) {
|
||||||
if (strcmp(mod_name, modules[i].name) == 0) {
|
if (strcmp(modules[i].name, mod_name) != 0)
|
||||||
if (!modules[i].verify_fun(chain_push(chain, mod_name), values))
|
continue;
|
||||||
return false;
|
|
||||||
chain_pop(chain);
|
if (!verify_dict(chain_push(chain, mod_name), values,
|
||||||
return true;
|
modules[i].attrs, modules[i].count))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chain_pop(chain);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_ERR("%s: invalid module name: %s", err_prefix(chain, node), mod_name);
|
LOG_ERR("%s: invalid module name: %s", err_prefix(chain, node), mod_name);
|
||||||
|
|
Loading…
Add table
Reference in a new issue