diff --git a/include/structs.h b/include/structs.h index 282f526..b916191 100644 --- a/include/structs.h +++ b/include/structs.h @@ -2,9 +2,8 @@ #ifndef _UIRC_STRUCTS_INCLUDED #define _UIRC_STRUCTS_INCLUDED typedef struct uirc_tag { - const char* value; + const char* value; /* if present, it isn't NULL and if it has no value, it is "" (aka '\0') */ bool clientbound; - bool present; } IRC_Tag; typedef struct name { const char* nick; diff --git a/src/uirc.c b/src/uirc.c index d8cf55e..0f8a187 100644 --- a/src/uirc.c +++ b/src/uirc.c @@ -179,7 +179,7 @@ signed int Assm_tags(char* buf, IRC_Tags* in) {.name = "react", .assg = &in->react}, {.name = "reply", .assg = &in->reply}}; for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) { - if ((*tagmps[i].assg).present) { + if ((*tagmps[i].assg).value != NULL) { if (pos == buf) { if (sprintf(pos++, "@") != 1) return ERR_UIRC_BUFFER_ERR; @@ -191,10 +191,7 @@ signed int Assm_tags(char* buf, IRC_Tags* in) if (sprintf(pos++, "+") != 1) return ERR_UIRC_BUFFER_ERR; } - if ((*tagmps[i].assg).value != NULL) - cnt = sprintf(pos, "%s=%s", tagmps[i].name, (*tagmps[i].assg).value); - else - cnt = sprintf(pos, "%s", tagmps[i].name); + cnt = (*(*tagmps[i].assg).value != '\0') ? sprintf(pos, "%s=%s", tagmps[i].name, (*tagmps[i].assg).value) : sprintf(pos, "%s", tagmps[i].name); if (cnt > 0) pos += cnt; else @@ -231,10 +228,12 @@ signed int Tok_tags(char* str, IRC_Tags* out) *(cval++) = '\0'; for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) { if (!strcmp(ctag, tagmps[i].name)) { - if (cval != NULL) - (*tagmps[i].assg).value = cval; + /* If the tag is present we point it to the value if given, or to the delimiter ('\0') + * This is done for a few reasons. First, we have a non-null address so we show that + * the tag is present and second, we have no value that way + */ + (*tagmps[i].assg).value = (cval != NULL) ? cval : ctag + strlen(ctag); (*tagmps[i].assg).clientbound = clientbound; - (*tagmps[i].assg).present = true; } } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 15c63d6..29cc95d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,16 @@ cmake_minimum_required(VERSION 3.16) -add_executable(parsing parsing.c) + +add_executable(tokenizer tokenizer.c) #add_executable(assembly assembly.c) -add_test(Parsing ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/parsing) -#add_test(Assembly ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/assembly) -target_link_libraries(parsing uirc) +add_executable(tagtok tagtok.c) +add_executable(tagassm tagassm.c) + +target_link_libraries(tokenizer uirc) +#target_link_libraries(assembly uirc) +target_link_libraries(tagtok uirc) +target_link_libraries(tagassm uirc) + +add_test(NAME Tokenizer COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/tokenizer) +#add_test(NAME Assembly COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/assembly) +add_test(NAME TagParser COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/tagtok) +add_test(NAME TagAssembler COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/tagassm) diff --git a/tests/parsing.c b/tests/parsing.c deleted file mode 100644 index b8b39e7..0000000 --- a/tests/parsing.c +++ /dev/null @@ -1,81 +0,0 @@ -#include "../include/uirc.h" -#include "stdio.h" -#include "stdlib.h" -#include "string.h" - -int main(void) -{ - IRC_Message results[] = { - {.name.nick = "user", .cmd = NOTICE, .trailing = "ok"}, - {.cmd = QUIT}, - {.name = {.nick = "nick", .user = "user", .host = "host"}, .cmd = PRIVMSG, .args[0] = "friend", .trailing = "hello there"}, - {.cmd = QUIT, .args = {"one", "two", "three", "four", "5", "6", "seven", "8", "nein", "10", "11", "12", "13", "14"}, .trailing = "i'm trailing"}}; - char mesg[][513] = { - ":user NOTICE :ok", - "QUIT", - ":nick!user@host PRIVMSG friend :hello there", - "QUIT one two three four 5 6 seven 8 nein 10 11 12 13 14 i'm trailing"}; - IRC_Message parseout; - int res = 0; - for (unsigned long i = 0; i < sizeof(results) / sizeof(IRC_Message); i++) { - memset((void*)&parseout, '\0', sizeof(parseout)); - printf("Testing [%lu] --> %s\n", i, mesg[i]); - printf("Tokenize: "); - if ((res = Tok_mesg(mesg[i], &parseout)) <= 0) { - printf("String could not be tokenized. %i\n", res); - return EXIT_FAILURE; - } - printf("OK\n"); - const char* const strings[][2] = { - {parseout.trailing, results[i].trailing}, // 0 - {parseout.name.nick, results[i].name.nick}, // 1 - {parseout.name.host, results[i].name.host}, // 2 - {parseout.name.user, results[i].name.user}, // 3 - {parseout.tags.account.value, results[i].tags.account.value}, // 4 - {parseout.tags.batch.value, results[i].tags.batch.value}, // 5 - {parseout.tags.label.value, results[i].tags.label.value}, // 6 - {parseout.tags.msgid.value, results[i].tags.msgid.value}, // 7 - {parseout.tags.multiline_concat.value, results[i].tags.multiline_concat.value}, // 8 - {parseout.tags.time.value, results[i].tags.time.value}, // 9 - {parseout.tags.typing.value, results[i].tags.typing.value}, // 10 - {parseout.tags.react.value, results[i].tags.react.value}, // 11 - {parseout.tags.reply.value, results[i].tags.reply.value} // 12 - }; - printf("Validation:\n"); - printf("\tArguments:\n"); - for (int k = 0; i < 14 && results[i].args[k] != NULL; k++) { - printf("\t\t[%i]: ", k); - if (parseout.args[k] == NULL) { - printf("Argument %i is NULL\n", k); - return EXIT_FAILURE; - } - if (strcmp(parseout.args[k], results[i].args[k])) { - printf("Argument %i does not match expected value. Expected %s, got %s instead\n", k, results[i].args[k], parseout.args[k]); - return EXIT_FAILURE; - } - printf("OK %s\n", parseout.args[k]); - } - printf("\tStrings:\n"); - for (unsigned long j = 0; j < sizeof(strings) / sizeof(char* [2]); j++) { - if (strings[j][1] != NULL && *strings[j][1] != '\0') { - printf("\t\t[%lu]: ", j); - if (strings[j][0] == NULL || *strings[j][0] == '\0') { - printf("Matching argument is a NULL pointer or zero-lenght --> %s\n", strings[j][0]); - return EXIT_FAILURE; - } - if (strcmp(strings[j][0], strings[j][1])) { - printf("Arguments didn't match at iteration %lu: expected %s but got %s", i, strings[j][1], strings[j][0]); - return EXIT_FAILURE; - } - printf("OK %s\n", strings[j][0]); - } - } - printf("\tCommand: "); - if (parseout.cmd == 0 || parseout.cmd != results[i].cmd) { - printf("Command is not parsed or non-matching. Got %s (%i) and expected %s\n", uirc_ircmd[parseout.cmd], parseout.cmd, uirc_ircmd[results[i].cmd]); - return EXIT_FAILURE; - } - printf("OK\n"); - } - return EXIT_SUCCESS; -}