commit 29c8ad742e449de4c7d56f412790d30f2fc8b1c1
parent 23f8d73b56802f07152fa9cbe558d31bd09fd313
Author: Eduardo Fontana Lazzari <edufonlaz@gmail.com>
Date: Tue, 28 Jan 2025 17:06:38 +0100
Implemented trim_string
Diffstat:
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 */