From 057a57448debbb942babf0a307294a9022863760 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 17 Jul 2014 08:12:09 +0200 Subject: Add function to parse a string in dfu format The dfu command parses a string which contains a list of devices and flags. This format is useful for other users aswell, so add common helper functions to parse it and let the dfu command use this format. Signed-off-by: Sascha Hauer --- common/Kconfig | 3 ++ common/Makefile | 1 + common/file-list.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 common/file-list.c (limited to 'common') diff --git a/common/Kconfig b/common/Kconfig index e7c22e5bae..4960b71802 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -64,6 +64,9 @@ config MENUTREE select GLOB select GLOB_SORT +config FILE_LIST + bool + menu "General Settings" config LOCALVERSION diff --git a/common/Makefile b/common/Makefile index 204241c919..b662045191 100644 --- a/common/Makefile +++ b/common/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_SHELL_HUSH) += hush.o obj-$(CONFIG_SHELL_SIMPLE) += parser.o obj-$(CONFIG_UIMAGE) += image.o uimage.o obj-$(CONFIG_MENUTREE) += menutree.o +obj-$(CONFIG_FILE_LIST) += file-list.o quiet_cmd_pwd_h = PWDH $@ ifdef CONFIG_PASSWORD diff --git a/common/file-list.c b/common/file-list.c new file mode 100644 index 0000000000..90c0f429c5 --- /dev/null +++ b/common/file-list.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include + +#define PARSE_DEVICE 0 +#define PARSE_NAME 1 +#define PARSE_FLAGS 2 + +static int file_list_parse_one(struct file_list *files, const char *partstr, const char **endstr) +{ + int i = 0, state = PARSE_DEVICE; + char filename[PATH_MAX]; + char name[PATH_MAX]; + struct file_list_entry *entry = xzalloc(sizeof(*entry)); + + memset(filename, 0, sizeof(filename)); + memset(name, 0, sizeof(name)); + + while (*partstr && *partstr != ',') { + switch (state) { + case PARSE_DEVICE: + if (*partstr == '(') { + state = PARSE_NAME; + i = 0; + } else { + filename[i++] = *partstr; + } + break; + case PARSE_NAME: + if (*partstr == ')') { + state = PARSE_FLAGS; + i = 0; + } else { + name[i++] = *partstr; + } + break; + case PARSE_FLAGS: + switch (*partstr) { + case 's': + entry->flags |= FILE_LIST_FLAG_SAFE; + break; + case 'r': + entry->flags |= FILE_LIST_FLAG_READBACK; + break; + case 'c': + entry->flags |= FILE_LIST_FLAG_CREATE; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + partstr++; + } + + if (state != PARSE_FLAGS) + return -EINVAL; + + entry->name = xstrdup(name); + entry->filename = xstrdup(filename); + if (*partstr == ',') + partstr++; + *endstr = partstr; + + list_add_tail(&entry->list, &files->list); + + return 0; +} + +struct file_list *file_list_parse(const char *str) +{ + struct file_list *files; + int ret; + const char *endptr; + + files = xzalloc(sizeof(*files)); + + INIT_LIST_HEAD(&files->list); + + while (*str) { + if (file_list_parse_one(files, str, &endptr)) { + printf("parse error\n"); + ret = -EINVAL; + goto out; + } + str = endptr; + + files->num_entries++; + } + + return files; +out: + free(files); + + return ERR_PTR(ret); +} + +void file_list_free(struct file_list *files) +{ + struct file_list_entry *entry, *tmp; + + list_for_each_entry_safe(entry, tmp, &files->list, list) { + free(entry->name); + free(entry->filename); + free(entry); + } + + free(files); +} -- cgit v1.2.3