From 623d4af43a6253e843e045341b6d6689ee928228 Mon Sep 17 00:00:00 2001 From: Alex Denes Date: Tue, 1 Sep 2020 13:18:07 +0200 Subject: [PATCH] Add own strtok implementation that has defined behaviour and use that for tokenizers --- src/misc.c | 19 +++++++++++++++++++ src/misc.h | 1 + src/tokenizers.c | 10 +++++----- tests/CMakeLists.txt | 3 +++ 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/misc.c b/src/misc.c index 427571f..c35a91e 100644 --- a/src/misc.c +++ b/src/misc.c @@ -120,3 +120,22 @@ void skip_spaces(char** addr) for (; **addr == ' '; (*addr)++) ; } + +char* strtok_mr(char** addr, const char* tokens) +{ + if (addr == NULL || *addr == NULL || !**addr || tokens == NULL) + return NULL; + char* save = *addr; + const char* tok = NULL; + do { + if (!**addr) + return save; + for (tok = tokens; *tok; tok++) { + if (**addr == *tok) { + **addr = '\0'; + break; + } + } + } while (*(*addr)++); + return save; +} diff --git a/src/misc.h b/src/misc.h index c119f09..e1fb804 100644 --- a/src/misc.h +++ b/src/misc.h @@ -34,4 +34,5 @@ signed int Ircmd_stoi(char* str); int safe_strcpy(char** dest, const char* src, size_t lef); int safe_charcpy(char** dest, const char c, size_t lef); void skip_spaces(char** addr); +char* strtok_mr(char** addr, const char* tokens); #endif diff --git a/src/tokenizers.c b/src/tokenizers.c index 8115069..0c84bbb 100644 --- a/src/tokenizers.c +++ b/src/tokenizers.c @@ -26,7 +26,7 @@ signed int Tok_mesg(char* str, IRC_Message* out) #ifdef UIRC_IRCV3 if (*progr == '@') { char* tags; - if ((tags = strtok_r(progr, " ", &progr)) != NULL) { + if ((tags = strtok_mr(&progr, " ")) != NULL) { if ((ret = Tok_tags(tags, &out->tags)) < 0) return ret; } else @@ -36,7 +36,7 @@ signed int Tok_mesg(char* str, IRC_Message* out) #endif if (*progr == ':') { char* prefix; - if ((prefix = strtok_r(progr, " ", &progr)) != NULL) { + if ((prefix = strtok_mr(&progr, " ")) != NULL) { if ((ret = Tok_user(prefix, &out->name, false)) < 0) return ret; } else @@ -45,7 +45,7 @@ signed int Tok_mesg(char* str, IRC_Message* out) skip_spaces(&progr); - if ((command = strtok_r(NULL, " ", &progr)) != NULL) { + if ((command = strtok_mr(&progr, " ")) != NULL) { if (!(out->cmd = (isalpha(*command)) ? Ircmd_stoi(command) : atoi(command))) return ERR_UIRC_UNKNOWN_TOKEN; } else { @@ -60,7 +60,7 @@ signed int Tok_mesg(char* str, IRC_Message* out) out->args[i++] = (*progr == ':') ? progr + 1 : progr; out->trailing = true; } else { - if ((out->args[i] = strtok_r(NULL, " ", &progr)) == NULL) + if ((out->args[i] = strtok_mr(&progr, " ")) == NULL) return ERR_UIRC_INVALID_FORMAT; } skip_spaces(&progr); @@ -88,7 +88,7 @@ signed int Tok_tags(char* str, IRC_Tags* out) {.name = "reply", .assg = &out->reply}}; if (*cpos == '@') cpos++; - while ((ctag = strtok_r(NULL, "; ", &cpos)) != NULL) { + while ((ctag = strtok_mr(&cpos, "; ")) != NULL) { clientbound = false; if (*ctag == '+') { ctag++; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cecd777..a8028bf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -7,6 +7,7 @@ add_executable(msgassm msgassm.c) add_executable(numericmds numericmds.c) add_executable(notrail notrail.c) add_executable(spacedargs spacedargs.c) +add_executable(strtokmr strtokmr.c) target_link_libraries(tokenizer uirc) target_link_libraries(overflow uirc) @@ -15,6 +16,7 @@ target_link_libraries(msgassm uirc) target_link_libraries(numericmds uirc) target_link_libraries(notrail uirc) target_link_libraries(spacedargs uirc) +target_link_libraries(strtokmr uirc) add_test(NAME Tokenizer COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/tokenizer) add_test(NAME Overflow COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/overflow) @@ -23,6 +25,7 @@ add_test(NAME MessageAssembler COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/msgassm add_test(NAME NumericCmds COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/numericmds) add_test(NAME IncorrectTrailing COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/notrail) add_test(NAME SpacedArguments COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/spacedargs) +add_test(NAME StrTokMoveSave COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/strtokmr) if ( IRCV3 ) add_executable(tagtok tagtok.c)