From 3ca5e4160229cf7d0b389ec8fdf2ec18f6e1aa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 30 Oct 2020 23:12:39 +0100 Subject: [PATCH] Implement config read function --- stm-firmware/config-parser/config-parser.c | 86 ++++++++++++++++++- .../include/config-parser/config-parser.h | 7 +- 2 files changed, 88 insertions(+), 5 deletions(-) diff --git a/stm-firmware/config-parser/config-parser.c b/stm-firmware/config-parser/config-parser.c index 3d15e19..6b58a2d 100644 --- a/stm-firmware/config-parser/config-parser.c +++ b/stm-firmware/config-parser/config-parser.c @@ -26,6 +26,7 @@ #include #include #include +#include #define CONFIG_PARSER_MAGIC 0x464a6e2bUL #define CONFIG_PARSER(p) ((struct config_parser *)(p)) @@ -36,7 +37,7 @@ } while (0) config_parser_handle_t config_parser_open_file(struct config_parser *config_parser, bool write, const char *file_name, - char *working_buffer) + char *working_buffer, size_t buff_size) { FRESULT res; @@ -46,6 +47,7 @@ config_parser_handle_t config_parser_open_file(struct config_parser *config_pars config_parser->magic = CONFIG_PARSER_MAGIC; config_parser->write = write; config_parser->buffer = working_buffer; + config_parser->buff_size = buff_size; res = f_open(&config_parser->file, file_name, (write ? FA_CREATE_ALWAYS | FA_WRITE : FA_READ)); if (res != FR_OK) @@ -54,10 +56,90 @@ config_parser_handle_t config_parser_open_file(struct config_parser *config_pars return (config_parser_handle_t)config_parser; } +static const char * const token_delim = " \t"; + +static int parse_value(struct config_parser_entry *entry, char *value_start_token) +{ + char *dot; + char *endptr; + + /* Check if token is a float number */ + dot = strstr(value_start_token, "."); + if (dot) { + /* Try parsing as float */ + entry->value.float_val = strtof(value_start_token, &endptr); + if (endptr == value_start_token) + return -1; + entry->type = CONFIG_PARSER_TYPE_FLOAT; + } + + if (value_start_token[0] != '-') { + /* Try parsing as ul */ + /* Try parsing as int */ + entry->value.uint_val = strtoul(value_start_token, &endptr, 0); + if (endptr == value_start_token) { + return -1; + } + entry->type = CONFIG_PARSER_TYPE_UINT; + } else { + /* Try parsing as int */ + entry->value.int_val = strtod(value_start_token, &endptr); + if (endptr == value_start_token) { + return -1; + } + entry->type = CONFIG_PARSER_TYPE_INT; + } + + return 0; +} + enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, struct config_parser_entry *entry) { - (void)entry; + struct config_parser *p; config_parser_check_handle(handle); + p = CONFIG_PARSER(handle); + char *token; + int token_round = 0; + + if (!entry) + return CONFIG_PARSER_PARAM_ERR; + + p->buffer[0] = '\0'; + if (f_gets(p->buffer, (int)p->buff_size, &p->file) == NULL) + return CONFIG_PARSER_IOERR; + + token = strtok(p->buffer, token_delim); + while (token != NULL) { + /* Check for comment */ + if (token[0] == '#') { + if (token_round == 0) + return CONFIG_PARSER_LINE_COMMENT; + else + break; + } + + switch (token_round) { + case 0: /* KEY */ + entry->name = token; + break; + case 1: /* = Symbol */ + if (strcmp(token, "=")) { + return CONFIG_PARSER_LINE_MALFORM; + } + break; + case 2: /* VALUE */ + if (!parse_value(entry, token)) + return CONFIG_PARSER_LINE_MALFORM; + break; + default: + return CONFIG_PARSER_LINE_MALFORM; + } + + + token_round++; + strtok(NULL, token_delim); + } + return CONFIG_PARSER_OK; } diff --git a/stm-firmware/config-parser/include/config-parser/config-parser.h b/stm-firmware/config-parser/include/config-parser/config-parser.h index cf11ba9..e228363 100644 --- a/stm-firmware/config-parser/include/config-parser/config-parser.h +++ b/stm-firmware/config-parser/include/config-parser/config-parser.h @@ -29,6 +29,7 @@ #define _CONFIG_PARSER_H_ #include +#include #include #include @@ -37,6 +38,7 @@ struct config_parser { bool write; FIL file; char *buffer; + size_t buff_size; }; typedef void * config_parser_handle_t; @@ -44,7 +46,6 @@ typedef void * config_parser_handle_t; enum config_parser_value_type { CONFIG_PARSER_TYPE_UINT = 0, CONFIG_PARSER_TYPE_INT, - CONFIG_PARSER_TYPE_STRING, CONFIG_PARSER_TYPE_FLOAT, }; @@ -53,6 +54,7 @@ enum config_parser_ret { CONFIG_PARSER_PARAM_ERR, CONFIG_PARSER_GENERIC_ERR, CONFIG_PARSER_IOERR, + CONFIG_PARSER_LINE_COMMENT, CONFIG_PARSER_LINE_TOO_LONG, CONFIG_PARSER_LINE_MALFORM, CONFIG_PARSER_END_REACHED, @@ -65,13 +67,12 @@ struct config_parser_entry { union { uint32_t uint_val; int32_t int_val; - const char *string_val; float float_val; } value; }; config_parser_handle_t config_parser_open_file(struct config_parser *config_parser, bool write, const char *file_name, - char *working_buffer); + char *working_buffer, size_t buff_size); /** * @brief Parse the current line in the config file.