diff --git a/CMakeLists.txt b/CMakeLists.txt index 713e916..8f7a7b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,7 +93,7 @@ if (BUILD_TESTS) add_test(NAME "EarlyTrail" COMMAND "earlytrail") add_test(NAME "OptCRLF" COMMAND "optcrlf") add_test(NAME "Allocators" COMMAND "allocs") - #add_test(NAME "ManualAssemblers" COMMAND "manassm") + add_test(NAME "ManualAssemblers" COMMAND "manassm") endif() add_library(uirc ${UIRC_SOURCE}) diff --git a/include/memory.h b/include/memory.h index 613bec4..df470b7 100644 --- a/include/memory.h +++ b/include/memory.h @@ -25,9 +25,8 @@ #ifndef UIRC_GUARD_PUBLIC_MEMORY #define UIRC_GUARD_PUBLIC_MEMORY -void* uirc_struct_copy(const void* src, IRC_Struct_Type type); -void uirc_struct_free(void* obj, IRC_Struct_Type type); -ptrdiff_t uirc_list_free(llist_t* list, IRC_Struct_Type type); +void* uirc_struct_copy(const void* src, IRC_Struct_Type type); +void uirc_struct_free(void* obj, IRC_Struct_Type type); #ifdef UIRC_FEATURE_IRCV3 IRC_Tag* uirc_struct_assm_tag(bool clientbound, const char* key, const char* value); @@ -38,5 +37,8 @@ IRC_Message* uirc_struct_assm_message(const char* cmd, bool trailing, unsigned i IRC_Buffer* uirc_struct_assm_buffer(IRC_Buffer_Type type, IRC_Modes modes, bool subscribed, const char* name, const char* key, const char* topic); IRC_Network* uirc_struct_assm_network(const char* addr, const char* svc, const char* pass); +void* uirc_list_append(llist_t* anchor, void* content); +ptrdiff_t uirc_list_free(llist_t* list, IRC_Struct_Type type); + #endif /* UIRC_GUARD_PUBLIC_MEMORY */ diff --git a/src/memory/list.c b/src/memory/list.c index 43fb12d..b252d9f 100644 --- a/src/memory/list.c +++ b/src/memory/list.c @@ -19,9 +19,20 @@ #include "memory.h" #include "types.h" // IRC_* -#include // assert() -#include // ptrdiff_t -#include // free() +#include // assert() +#include // llist_t +#include // ptrdiff_t + +void* +uirc_list_append(llist_t* anchor, void* content) +{ + assert(content != NULL); + llist_t* new = llist_elem_alloc(0); + if (new == NULL) return NULL; + new->content = content; + if (anchor != NULL) llist_elem_conn(anchor, new); + return new; +} ptrdiff_t uirc_list_free(llist_t* list, IRC_Struct_Type type) @@ -32,13 +43,8 @@ uirc_list_free(llist_t* list, IRC_Struct_Type type) llist_t* const save = list; list = list->next; uirc_struct_free(save->content, type); - remove_linked_list_elem(save); + llist_elem_rm(save); } return cnt; } -// TODO -// - List assemblers with va_arg() -// - IRC_Tag -// - IRC_User -// - IRC_Buffer diff --git a/src/memory/struct.c b/src/memory/struct.c index ca384f3..4b3c405 100644 --- a/src/memory/struct.c +++ b/src/memory/struct.c @@ -20,7 +20,7 @@ #include "types.h" // IRC_* #include // assert() -#include // malloc_string() +#include // stringext_strmalloc() #include #include // free() #include // strlen() @@ -54,8 +54,8 @@ uirc_struct_copy(const void* src, IRC_Struct_Type type) const IRC_Tag* c_src = src; c_ret->clientbound = c_src->clientbound; - if (((c_ret->key = malloc_string(c_src->key, strlen(c_src->key))) == NULL) - || (c_src->value != NULL && (c_ret->value = malloc_string(c_src->value, strlen(c_src->value))) == NULL)) + if (((c_ret->key = stringext_strmalloc(c_src->key, strlen(c_src->key))) == NULL) + || (c_src->value != NULL && (c_ret->value = stringext_strmalloc(c_src->value, strlen(c_src->value))) == NULL)) break; return ret; @@ -65,7 +65,7 @@ uirc_struct_copy(const void* src, IRC_Struct_Type type) const IRC_Capability* c_src = src; c_ret->active = c_src->active; - if ((c_ret->name = malloc_string(c_src->name, strlen(c_src->name))) == NULL) break; + if ((c_ret->name = stringext_strmalloc(c_src->name, strlen(c_src->name))) == NULL) break; return ret; } @@ -76,10 +76,10 @@ uirc_struct_copy(const void* src, IRC_Struct_Type type) c_ret->modes = c_src->modes; c_ret->is_service = c_src->is_service; - if ((c_src->nick != NULL && (c_ret->nick = malloc_string(c_src->nick, strlen(c_src->nick))) == NULL) - || (c_src->user != NULL && (c_ret->user = malloc_string(c_src->user, strlen(c_src->user))) == NULL) - || (c_src->real != NULL && (c_ret->real = malloc_string(c_src->real, strlen(c_src->real))) == NULL) - || (c_src->host != NULL && (c_ret->host = malloc_string(c_src->host, strlen(c_src->host))) == NULL)) + if ((c_src->nick != NULL && (c_ret->nick = stringext_strmalloc(c_src->nick, strlen(c_src->nick))) == NULL) + || (c_src->user != NULL && (c_ret->user = stringext_strmalloc(c_src->user, strlen(c_src->user))) == NULL) + || (c_src->real != NULL && (c_ret->real = stringext_strmalloc(c_src->real, strlen(c_src->real))) == NULL) + || (c_src->host != NULL && (c_ret->host = stringext_strmalloc(c_src->host, strlen(c_src->host))) == NULL)) break; return ret; @@ -89,10 +89,10 @@ uirc_struct_copy(const void* src, IRC_Struct_Type type) const IRC_Message* c_src = src; c_ret->trailing = c_src->trailing; - if ((c_ret->command = malloc_string(c_src->command, strlen(c_src->command))) == NULL) break; + if ((c_ret->command = stringext_strmalloc(c_src->command, strlen(c_src->command))) == NULL) break; for (unsigned short i = 0; i < IRC_MAXARGS && c_src->args[i] != NULL; i++) - if ((c_ret->args[i] = malloc_string(c_src->args[i], strlen(c_src->args[i]))) == NULL) break; + if ((c_ret->args[i] = stringext_strmalloc(c_src->args[i], strlen(c_src->args[i]))) == NULL) break; return ret; } @@ -102,9 +102,9 @@ uirc_struct_copy(const void* src, IRC_Struct_Type type) c_ret->modes = c_src->modes; c_ret->subscribed = c_src->subscribed; - if ((c_ret->name = malloc_string(c_src->name, strlen(c_src->name))) == NULL - || (c_src->topic != NULL && (c_ret->topic = malloc_string(c_src->topic, strlen(c_src->topic))) == NULL) - || (c_src->key != NULL && (c_ret->key = malloc_string(c_src->key, strlen(c_src->key))) == NULL)) + if ((c_ret->name = stringext_strmalloc(c_src->name, strlen(c_src->name))) == NULL + || (c_src->topic != NULL && (c_ret->topic = stringext_strmalloc(c_src->topic, strlen(c_src->topic))) == NULL) + || (c_src->key != NULL && (c_ret->key = stringext_strmalloc(c_src->key, strlen(c_src->key))) == NULL)) break; return ret; } @@ -112,9 +112,9 @@ uirc_struct_copy(const void* src, IRC_Struct_Type type) IRC_Network* c_ret = ret; const IRC_Network* c_src = src; - if ((c_ret->addr = malloc_string(c_src->addr, strlen(c_src->addr))) == NULL - || (c_src->svc != NULL && (c_ret->svc = malloc_string(c_src->svc, strlen(c_src->svc))) == NULL) - || (c_src->pass != NULL && (c_ret->pass = malloc_string(c_src->pass, strlen(c_src->pass))) == NULL)) + if ((c_ret->addr = stringext_strmalloc(c_src->addr, strlen(c_src->addr))) == NULL + || (c_src->svc != NULL && (c_ret->svc = stringext_strmalloc(c_src->svc, strlen(c_src->svc))) == NULL) + || (c_src->pass != NULL && (c_ret->pass = stringext_strmalloc(c_src->pass, strlen(c_src->pass))) == NULL)) break; return ret; @@ -200,7 +200,7 @@ uirc_struct_assm_tag(bool clientbound, const char* key, const char* value) memset(t, 0, sizeof(*t)); t->clientbound = clientbound; - if ((t->key = malloc_string(key, strlen(key))) == NULL || (value != NULL && (t->value = malloc_string(value, strlen(value))) == NULL)) { + if ((t->key = stringext_strmalloc(key, strlen(key))) == NULL || (value != NULL && (t->value = stringext_strmalloc(value, strlen(value))) == NULL)) { uirc_struct_free(t, IRC_STRUCT_TAG); free(t); return NULL; @@ -216,7 +216,7 @@ uirc_struct_assm_capability(bool active, const char* name) memset(c, 0, sizeof(*c)); c->active = active; - if ((c->name = malloc_string(name, strlen(name))) == NULL) { + if ((c->name = stringext_strmalloc(name, strlen(name))) == NULL) { uirc_struct_free(c, IRC_STRUCT_CAPABILITY); free(c); return NULL; @@ -233,10 +233,10 @@ uirc_struct_assm_user(bool service, IRC_Modes modes, const char* nick, const cha u->is_service = service; u->modes = modes; - if ((nick != NULL && (u->nick = malloc_string(nick, strlen(nick))) == NULL) - || (user != NULL && (u->user = malloc_string(user, strlen(user))) == NULL) - || (real != NULL && (u->real = malloc_string(real, strlen(real))) == NULL) - || (host != NULL && (u->host = malloc_string(host, strlen(host))) == NULL)) { + if ((nick != NULL && (u->nick = stringext_strmalloc(nick, strlen(nick))) == NULL) + || (user != NULL && (u->user = stringext_strmalloc(user, strlen(user))) == NULL) + || (real != NULL && (u->real = stringext_strmalloc(real, strlen(real))) == NULL) + || (host != NULL && (u->host = stringext_strmalloc(host, strlen(host))) == NULL)) { uirc_struct_free(u, IRC_STRUCT_USER); free(u); return NULL; @@ -252,7 +252,7 @@ uirc_struct_assm_message(const char* cmd, bool trailing, unsigned int argc, ...) memset(m, 0, sizeof(*m)); m->trailing = trailing; - if (cmd != NULL && (m->command = malloc_string(cmd, strlen(cmd))) == NULL) { + if (cmd != NULL && (m->command = stringext_strmalloc(cmd, strlen(cmd))) == NULL) { uirc_struct_free(m, IRC_STRUCT_MESSAGE); free(m); return NULL; @@ -261,7 +261,7 @@ uirc_struct_assm_message(const char* cmd, bool trailing, unsigned int argc, ...) va_start(ap, argc); for (unsigned short i = 0; i < IRC_MAXARGS && i < argc; i++) { const char* carg = va_arg(ap, const char*); - if ((m->args[i] = malloc_string(carg, strlen(carg))) == NULL) { + if ((m->args[i] = stringext_strmalloc(carg, strlen(carg))) == NULL) { uirc_struct_free(m, IRC_STRUCT_MESSAGE); free(m); return NULL; @@ -281,8 +281,8 @@ uirc_struct_assm_buffer(IRC_Buffer_Type type, IRC_Modes modes, bool subscribed, b->subscribed = subscribed; b->modes = modes; b->type = type; - if ((b->name = malloc_string(name, strlen(name))) == NULL || (key != NULL && (b->name = malloc_string(key, strlen(key))) == NULL) - || (topic != NULL && (b->topic = malloc_string(topic, strlen(topic))) == NULL)) { + if ((b->name = stringext_strmalloc(name, strlen(name))) == NULL || (key != NULL && (b->name = stringext_strmalloc(key, strlen(key))) == NULL) + || (topic != NULL && (b->topic = stringext_strmalloc(topic, strlen(topic))) == NULL)) { uirc_struct_free(b, IRC_STRUCT_BUFFER); free(b); return NULL; @@ -296,9 +296,9 @@ uirc_struct_assm_network(const char* addr, const char* svc, const char* pass) IRC_Network* n = malloc(sizeof(*n)); memset(n, 0, sizeof(*n)); - if ((addr != NULL && (n->addr = malloc_string(addr, strlen(addr))) == NULL) - || (svc != NULL && (n->svc = malloc_string(svc, strlen(svc))) == NULL) - || (pass != NULL && (n->pass = malloc_string(pass, strlen(pass))) == NULL)) { + if ((addr != NULL && (n->addr = stringext_strmalloc(addr, strlen(addr))) == NULL) + || (svc != NULL && (n->svc = stringext_strmalloc(svc, strlen(svc))) == NULL) + || (pass != NULL && (n->pass = stringext_strmalloc(pass, strlen(pass))) == NULL)) { uirc_struct_free(n, IRC_STRUCT_NETWORK); free(n); return NULL; diff --git a/src/tokenizers/message.c b/src/tokenizers/message.c index 658349a..7cd7e71 100644 --- a/src/tokenizers/message.c +++ b/src/tokenizers/message.c @@ -21,7 +21,7 @@ #include "types.h" // IRC_Message #include // assert() -#include // malloc_string() strtok_mr() +#include // stringext_strmalloc() stringext_strtok_mr() #include // isalnum() #include // NULL #include // malloc() @@ -43,7 +43,7 @@ uirc_tokenizer_message(const char* str) len--; if (str[len - 1] == '\r') len--; } - char* const ws = malloc_string(str, len); // NOTE: Some compilers might warn you about modifying contents of p because it points to ws which + char* const ws = stringext_strmalloc(str, len); // NOTE: Some compilers might warn you about modifying contents of p because it points to ws which // is "immutable". This is safe to ignore as the purpose of it is to not use ws for tokenizing and // to save the original pointer which can be freed @@ -61,7 +61,7 @@ uirc_tokenizer_message(const char* str) if (*p == '@') { p++; const char* tmp = NULL; - if ((tmp = strtok_mr(&p, " ")) == NULL || (m->tag_list = uirc_tokenizer_tag_list(tmp)) == NULL) { + if ((tmp = stringext_strtok_mr(&p, " ")) == NULL || (m->tag_list = uirc_tokenizer_tag_list(tmp)) == NULL) { free_ctx(m, ws); return NULL; } @@ -72,7 +72,7 @@ uirc_tokenizer_message(const char* str) if (*p == ':') { const char* tmp = NULL; p++; - if ((tmp = strtok_mr(&p, " ")) == NULL || (m->source = uirc_tokenizer_user(tmp)) == NULL) { + if ((tmp = stringext_strtok_mr(&p, " ")) == NULL || (m->source = uirc_tokenizer_user(tmp)) == NULL) { free_ctx(m, ws); return NULL; } @@ -81,7 +81,7 @@ uirc_tokenizer_message(const char* str) if (isalnum(*p)) { const char* tmp = NULL; - if ((tmp = strtok_mr(&p, " ")) == NULL || (m->command = malloc_string(tmp, strlen(tmp))) == NULL) { + if ((tmp = stringext_strtok_mr(&p, " ")) == NULL || (m->command = stringext_strmalloc(tmp, strlen(tmp))) == NULL) { free_ctx(m, ws); return NULL; } @@ -99,14 +99,14 @@ uirc_tokenizer_message(const char* str) // trailing is supposed to represent a early ending of spaced arguments, not if there's any arguments at all m->trailing = true; } - if ((m->args[i++] = malloc_string(p, strlen(p))) == NULL) { + if ((m->args[i++] = stringext_strmalloc(p, strlen(p))) == NULL) { free_ctx(m, ws); return NULL; } break; } else { const char* tmp = NULL; - if ((tmp = strtok_mr(&p, " ")) == NULL || (m->args[i++] = malloc_string(tmp, strlen(tmp))) == NULL) { + if ((tmp = stringext_strtok_mr(&p, " ")) == NULL || (m->args[i++] = stringext_strmalloc(tmp, strlen(tmp))) == NULL) { free_ctx(m, ws); return NULL; } diff --git a/src/tokenizers/tag.c b/src/tokenizers/tag.c index 1dff7bc..d39c722 100644 --- a/src/tokenizers/tag.c +++ b/src/tokenizers/tag.c @@ -21,8 +21,8 @@ #include "types.h" // IRC_Tag #include // assert() -#include // allocate_linked_list_elem() connect_linked_list_elem() remove_linked_list_elem() -#include // malloc_string() +#include // llist_elem_alloc() llist_elem_conn() llist_elem_rm() +#include // stringext_strmalloc() #include // true #include // free() #include // strchr() @@ -34,14 +34,14 @@ uirc_tokenizer_tag_list(const char* str) { assert(str != NULL); - char* const ws = malloc_string(str, strlen(str)); + char* const ws = stringext_strmalloc(str, strlen(str)); char * p = ws, *tmp; llist_t * pl = NULL, *l = NULL; if (ws == NULL) return NULL; - while ((tmp = strtok_mr(&p, ";")) != NULL) { + while ((tmp = stringext_strtok_mr(&p, ";")) != NULL) { llist_t* cl; - if ((cl = allocate_linked_list_elem(0)) == NULL) { + if ((cl = llist_elem_alloc(0)) == NULL) { free_ctx(l, NULL, ws); return NULL; } @@ -52,7 +52,7 @@ uirc_tokenizer_tag_list(const char* str) if (l == NULL) l = cl; else - connect_linked_list_elem(pl, cl); + llist_elem_conn(pl, cl); pl = cl; } @@ -65,7 +65,7 @@ uirc_tokenizer_tag(const char* str) { assert(str != NULL); - char* const ws = malloc_string(str, strlen(str)); + char* const ws = stringext_strmalloc(str, strlen(str)); IRC_Tag* t = malloc(sizeof(IRC_Tag)); char* ckey = ws; @@ -84,12 +84,12 @@ uirc_tokenizer_tag(const char* str) char* cval = strchr(ckey, '='); if (cval != NULL) { *(cval++) = '\0'; - if ((t->value = malloc_string(cval, strlen(cval))) == NULL) { + if ((t->value = stringext_strmalloc(cval, strlen(cval))) == NULL) { free_ctx(NULL, t, ws); return NULL; } } - if ((t->key = malloc_string(ckey, strlen(ckey))) == NULL) { + if ((t->key = stringext_strmalloc(ckey, strlen(ckey))) == NULL) { free_ctx(NULL, t, ws); return NULL; } @@ -105,7 +105,7 @@ free_ctx(llist_t* list, IRC_Tag* t, char* s) llist_t* l = c; c = c->next; if (l->content != NULL) uirc_struct_free(l->content, IRC_STRUCT_TAG); - remove_linked_list_elem(l); + llist_elem_rm(l); } uirc_struct_free(t, IRC_STRUCT_TAG); free(t); diff --git a/src/tokenizers/user.c b/src/tokenizers/user.c index d5ed967..385daf1 100644 --- a/src/tokenizers/user.c +++ b/src/tokenizers/user.c @@ -21,7 +21,7 @@ #include "types.h" // IRC_Message #include // assert() -#include // malloc_string() +#include // stringext_strmalloc() #include // bool #include // malloc() #include // strchr() @@ -34,7 +34,7 @@ uirc_tokenizer_user(const char* str) assert(str != NULL); IRC_User* u = malloc(sizeof(IRC_User)); - char* const ws = malloc_string(str, strlen(str)); + char* const ws = stringext_strmalloc(str, strlen(str)); char* tmp; if (u == NULL || ws == NULL) { @@ -47,19 +47,19 @@ uirc_tokenizer_user(const char* str) if ((tmp = strchr(ws, '@')) != NULL) { *(tmp++) = '\0'; - if ((u->host = malloc_string(tmp, strlen(tmp))) == NULL) { + if ((u->host = stringext_strmalloc(tmp, strlen(tmp))) == NULL) { free_ctx(u, ws); return NULL; } } if ((tmp = strchr(ws, '!')) != NULL) { *(tmp++) = '\0'; - if ((u->user = malloc_string(tmp, strlen(tmp))) == NULL) { + if ((u->user = stringext_strmalloc(tmp, strlen(tmp))) == NULL) { free_ctx(u, ws); return NULL; } } - if ((u->nick = malloc_string(ws, strlen(ws))) == NULL) { + if ((u->nick = stringext_strmalloc(ws, strlen(ws))) == NULL) { free_ctx(u, ws); return NULL; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a207c46..fb859d8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,8 +11,8 @@ target_link_libraries(earlytrail uirc) add_executable(optcrlf optcrlf.c common.c) target_link_libraries(optcrlf uirc) -#add_executable(manassm manassm.c common.c) -#target_link_libraries(manassm uirc) +add_executable(manassm manassm.c common.c) +target_link_libraries(manassm uirc) add_executable(allocs allocs.c common.c) target_link_libraries(allocs uirc) diff --git a/tests/manassm.c b/tests/manassm.c new file mode 100644 index 0000000..4a833ee --- /dev/null +++ b/tests/manassm.c @@ -0,0 +1,54 @@ +/* + * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC) + * Copyright (c) 2019-2021 Alex-David Denes + * + * uIRC is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * uIRC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with uIRC. If not, see . + */ + +#include "common.h" // expect() print_irc_message() +#include "uirc.h" // uirc_* IRC_* + +#include // fprintf() +#include // EXIT_* +#include // strcmp() + +#define TAGKEY "wow" +#define TAGKEY2 "wowcum" +#define TAGVAL "wow2" + +int +main(void) +{ + IRC_Message* m = uirc_struct_assm_message("NONE", false, 0); + m->tag_list = uirc_list_append(NULL, uirc_struct_assm_tag(false, TAGKEY, TAGVAL)); + uirc_list_append(m->tag_list, uirc_struct_assm_tag(false, TAGKEY2, NULL)); + + IRC_Tag* t = m->tag_list->next->content; + if (strcmp(TAGKEY2, t->key) != 0 || t->value != NULL) { + fprintf(stderr, "List allocator didn't allocate things right\n"); + return EXIT_FAILURE; + } + + t = m->tag_list->content; + if (strcmp(TAGKEY, t->key) != 0 || strcmp(TAGVAL, t->value) != 0) { + fprintf(stderr, "List allocator didn't allocate things right\n"); + return EXIT_FAILURE; + } + + print_irc_message(m); + uirc_struct_free(m, IRC_STRUCT_MESSAGE); + free(m); + + return EXIT_SUCCESS; +}