star-phor-input

File format for describing photoreactor configurations
git clone https://www.edstar.cnrs.fr/git/star-phor-input.git
Log | Files | Refs | README | LICENSE

commit 29c8ad742e449de4c7d56f412790d30f2fc8b1c1
parent 23f8d73b56802f07152fa9cbe558d31bd09fd313
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date:   Tue, 28 Jan 2025 17:06:38 +0100

Implemented trim_string

Diffstat:
Msrc/sphin_config.c | 74+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Msrc/sphin_config.h | 36++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 11 deletions(-)

diff --git a/src/sphin_config.c b/src/sphin_config.c @@ -102,6 +102,7 @@ load_stream struct txtrdr* txtrdr = NULL; struct str line; char* keyword = NULL; + char* name = NULL; char* token = NULL; char* token_ptr = NULL; res_T res = RES_OK; @@ -134,23 +135,33 @@ load_stream goto error; } - /* volume : "Mon volume"\0 */ - /* volume \0 "Mon volume"\0 */ - /* volume\0\0 "Mon volume"\0 */ - + /* parse keyword */ token = strtok_r(str_get(&line), ":", &token_ptr); keyword = trim_keyword(token); if (NULL == keyword){ res = RES_BAD_ARG; + goto error; + } + + /* parse value (name) */ + token = strtok_r(NULL, "", &token_ptr); + name = trim_string(token); + if (NULL == name){ + res = RES_BAD_ARG; + goto error; } - else if (0 == strcmp(keyword, "volume")){ - // res = parse_volume(txtrdr, config) /* Not yet implemented */ + + if (0 == strcmp(keyword, "volume")){ + if (RES_OK != (res = txtrdr_read_line(txtrdr))) goto error; + // res = parse_volume(txtrdr, config, name) /* Not yet implemented */ } else if (0 == strcmp(keyword, "source")){ - // res = parse_source(txtrdr, config) /* Not yet implemented */ + if (RES_OK != (res = txtrdr_read_line(txtrdr))) goto error; + // res = parse_source(txtrdr, config, name) /* Not yet implemented */ } else if (0 == strcmp(keyword, "surface")){ - // res = parse_surface(txtrdr, config) /* Not yet implemented */ + if (RES_OK != (res = txtrdr_read_line(txtrdr))) goto error; + // res = parse_surface(txtrdr, config, name) /* Not yet implemented */ } else { res = RES_BAD_ARG; @@ -186,24 +197,65 @@ error: /******************************************************************************* * Local functions ******************************************************************************/ -char* +char* /* 'volume' */ trim_keyword - (char* str) + (char* str) /* ' volume ' */ { char* token_ptr = NULL; char* token = NULL; char* remaining_token = NULL; ASSERT(NULL != str); - token = strtok_r(str, " \t", &token_ptr); + /* If no token was found (empty string or invalid input) */ if (NULL == token) return NULL; + /* Check for any remaining tokens to ensure there's only one word in the + * string. */ remaining_token = strtok_r(NULL, " \t", &token_ptr); if (NULL != remaining_token) return NULL; return token; } +char* /* 'mon volume ' */ +trim_string + (char* str) /* ' erreur "mon volume " salut ' */ +{ + char* a = NULL; + char* b = NULL; + size_t len = 0; + + a = strchr(str, '"'); /* find the first occurrence of " */ + b = strrchr(str, '"'); /* find the last occurrence of " */ + + if (a == b) { + /* Either there is only one " or both are NULL (no ") */ + return NULL; + } + + if (a+1 == b) { + /* The string between quotes is empty */ + return NULL; + } + + len = strspn(str, " \t"); + if (str + len != a) { + /* There are characters before the first " other than spaces and tabs */ + return NULL; + } + + len = strspn(b+1, " \t"); /* Analyzes the part of str after b */ + if (b[1+len] != '\0') { + /* There are characters after the second " other than spaces and tabs */ + return NULL; + } + /* '"mon volume\0 \0' + * ^ ^ + * a b */ + *b = '\0'; + return a+1; +} + /******************************************************************************* * Exported functions ******************************************************************************/ diff --git a/src/sphin_config.h b/src/sphin_config.h @@ -27,8 +27,44 @@ #include <rsys/rsys.h> +/* Trim leading and trailing spaces and tabs from the input string and return + * the first word. If the input string is empty or if it contains multiple + * words, returns NULL to indicate an error or unexpected format. + */ extern LOCAL_SYM char* trim_keyword (char* str); +/* Trim spaces, tabs and double quotes (") of a string according to several + * rules: + * 1. The string starts and ends with quotes (although tabs and spaces are + * allowed outside the quotes) + * 2. There should be exactly two quotes in the string: the one that delimits + * its beginning and the one that delimits its end. Quotes in the middle of the + * string are expected to cause undefined behavior of the function. + * 3. No character other than spaces and tabs are allowed outside the quotes. + * However, any characters inside the quotes are allowed (including spaces and + * tabs). + * + * If one of these conditions are not respected, the function returns NULL, + * otherwise, * it returns a pointer to the beginning of the trimmed string + * (just after the first quote). + * Examples of allowed strings: + * -' "mon volume" ' -> 'mon volume' + * - '"\t mon volume \t "' -> '\t mon volume \t ' + * + * Examples of forbidden strings: + * - 'mon volume' // No quotes + * - '"mon volume' // Quote not closed + * - '"mon""volume"' // Multiple quotes (undefined behavior) + * - '"mon volume" salut' // Content after the last quote is not + * whitespace or tabs + * - '"mon volum"e' // Misplaced closing quote + * - '""' // Empty string + * + */ +extern LOCAL_SYM char* +trim_string + (char* str); + #endif /* SPHIN_CONFIG_H */