lib/param_list: Add new parameter list routines
authorGeoff Levand <geoff@infradead.org>
Thu, 2 Aug 2018 17:29:38 +0000 (17:29 +0000)
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>
Tue, 7 Aug 2018 01:30:36 +0000 (11:30 +1000)
Based on the powerpc param routines adds new generic routines
to manage a name + value parameter list.

Signed-off-by: Geoff Levand <geoff@infradead.org>
Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
lib/Makefile.am
lib/param_list/param_list.c [new file with mode: 0644]
lib/param_list/param_list.h [new file with mode: 0644]

index 59d37ab793dc9efd38760a95bb1b655a4df399d8..016a14dd09f2783d5ac1306a4976678acf98f7ef 100644 (file)
@@ -67,7 +67,9 @@ lib_libpbcore_la_SOURCES = \
        lib/flash/flash.h \
        lib/security/security.h \
        lib/efi/efivar.h \
-       lib/efi/efivar.c
+       lib/efi/efivar.c \
+       lib/param_list/param_list.c \
+       lib/param_list/param_list.h
 
 if ENABLE_MTD
 lib_libpbcore_la_SOURCES += \
diff --git a/lib/param_list/param_list.c b/lib/param_list/param_list.c
new file mode 100644 (file)
index 0000000..b3a45f8
--- /dev/null
@@ -0,0 +1,118 @@
+
+#define _GNU_SOURCE
+
+#include <assert.h>
+#include <string.h>
+
+#include <log/log.h>
+#include <talloc/talloc.h>
+#include <param_list/param_list.h>
+
+const char **common_known_params(void)
+{
+       static const char *common[] = {
+               "auto-boot?",
+               "petitboot,network",
+               "petitboot,timeout",
+               "petitboot,bootdevs",
+               "petitboot,language",
+               "petitboot,debug?",
+               "petitboot,write?",
+               "petitboot,snapshots?",
+               "petitboot,console",
+               "petitboot,http_proxy",
+               "petitboot,https_proxy",
+               NULL,
+       };
+
+       return common;
+}
+
+void param_list_init(struct param_list *pl, const char *known_params[])
+{
+       assert(known_params);
+       list_init(&pl->params);
+       pl->known_params = known_params;
+}
+
+bool param_list_is_known_n(const struct param_list *pl, const char *name,
+       unsigned int name_len)
+{
+       const char **known;
+
+       assert(pl->known_params);
+
+       param_list_for_each_known_param(pl, known) {
+               if (name_len == strlen(*known) && !strncmp(name, *known, name_len)) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+bool param_list_is_known(const struct param_list *pl, const char *name)
+{
+       const char **known;
+
+       assert(pl->known_params);
+
+       param_list_for_each_known_param(pl, known) {
+               if (!strcmp(name, *known)) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+struct param *param_list_get_param(struct param_list *pl, const char *name)
+{
+       struct param *param;
+
+       param_list_for_each(pl, param) {
+               if (!strcmp(param->name, name))
+                       return param;
+       }
+       return NULL;
+}
+
+void param_list_set(struct param_list *pl, const char *name, const char *value,
+       bool modified_on_create)
+{
+       struct param *param;
+
+       param_list_for_each(pl, param) {
+               if (strcmp(param->name, name))
+                       continue;
+
+               if (!strcmp(param->value, value))
+                       return;
+
+               /* Update existing list entry. */
+               talloc_free(param->value);
+               param->value = talloc_strdup(param, value);
+               param->modified = true;
+               pb_debug_fn("Updated: %s:%s\n", name, value);
+               return;
+       }
+
+       /* Add new entry to list. */
+       param = talloc(pl, struct param);
+       param->modified = modified_on_create;
+       param->name = talloc_strdup(pl, name);
+       param->value = talloc_strdup(pl, value);
+       list_add(&pl->params, &param->list);
+       pb_debug_fn("Created: %s:%s\n", name, value);
+}
+
+void param_list_set_non_empty(struct param_list *pl, const char *name, const char *value,
+       bool modified_on_create)
+{
+       if (!param_list_get_value(pl, name) && !strlen(value)) {
+               return;
+       }
+
+       param_list_set(pl, name, value, modified_on_create);
+}
+
diff --git a/lib/param_list/param_list.h b/lib/param_list/param_list.h
new file mode 100644 (file)
index 0000000..89ef400
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef PARAM_LIST_H
+#define PARAM_LIST_H
+
+#include <stddef.h>
+
+#include <list/list.h>
+
+struct param {
+       char *name;
+       char *value;
+       bool modified;
+       struct list_item list;
+};
+
+struct param_list {
+       struct list params;
+       const char **known_params;
+};
+
+#define param_list_for_each(_pl_ptr, _pos) \
+       list_for_each_entry(&(_pl_ptr)->params, _pos, list)
+
+#define param_list_for_each_known_param(_pl_ptr, _pos) \
+       for (_pos = (_pl_ptr)->known_params; *_pos; _pos++)
+
+const char **common_known_params(void);
+
+void param_list_init(struct param_list *pl, const char *known_params[]);
+bool param_list_is_known(const struct param_list *pl, const char *name);
+bool param_list_is_known_n(const struct param_list *pl, const char *name,
+       unsigned int name_len);
+struct param *param_list_get_param(struct param_list *pl, const char *name);
+static inline const char *param_list_get_value(const struct param_list *pl,
+       const char *name)
+{
+       const struct param *param =
+               param_list_get_param((struct param_list *)pl, name);
+       return param ? param->value : NULL;
+}
+void param_list_set(struct param_list *pl, const char *name, const char *value,
+       bool modified_on_create);
+
+/* param_list_set_non_empty - Won't create a new parameter that would be empty. */
+void param_list_set_non_empty(struct param_list *pl, const char *name,
+       const char *value, bool modified_on_create);
+
+#endif /* PARAM_LIST_H */
+