Add back functions for generating structs in memory

This commit is contained in:
Alex D. 2021-03-12 16:09:37 +00:00
parent 95a7dbc4f4
commit 2775d6128d
Signed by: caskd
GPG Key ID: F92BA85F61F4C173
7 changed files with 154 additions and 80 deletions

View File

@ -89,6 +89,11 @@ if (BUILD_TESTS)
message(STATUS "Tests are going to be built.")
add_subdirectory(tests)
enable_testing()
add_test(NAME "FullLoop" COMMAND "fullloop")
add_test(NAME "EarlyTrail" COMMAND "earlytrail")
add_test(NAME "OptCRLF" COMMAND "optcrlf")
add_test(NAME "Allocators" COMMAND "allocs")
#add_test(NAME "ManualAssemblers" COMMAND "manassm")
endif()
add_library(uirc ${UIRC_SOURCE})

View File

@ -25,9 +25,18 @@
#ifndef UIRC_GUARD_PUBLIC_MEMORY
#define UIRC_GUARD_PUBLIC_MEMORY
void* uirc_struct_malloc(const void* src, 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);
ptrdiff_t uirc_list_free(llist_t* list, IRC_Struct_Type type);
#ifdef UIRC_FEATURE_IRCV3
IRC_Tag* uirc_struct_assm_tag(bool clientbound, const char* key, const char* value);
IRC_Capability* uirc_struct_assm_capability(bool active, const char* name);
#endif /* UIRC_FEATURE_IRCV3 */
IRC_User* uirc_struct_assm_user(bool service, IRC_Modes modes, const char* nick, const char* user, const char* real, const char* host);
IRC_Message* uirc_struct_assm_message(const char* cmd, bool trailing, unsigned int argc, ...);
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);
#endif /* UIRC_GUARD_PUBLIC_MEMORY */

View File

@ -36,3 +36,9 @@ uirc_list_free(llist_t* list, IRC_Struct_Type type)
}
return cnt;
}
// TODO
// - List assemblers with va_arg()
// - IRC_Tag
// - IRC_User
// - IRC_Buffer

View File

@ -21,11 +21,12 @@
#include <assert.h> // assert()
#include <corelibs/stringext.h> // malloc_string()
#include <stdlib.h> // free()
#include <string.h> // strlen()
#include <stdarg.h>
#include <stdlib.h> // free()
#include <string.h> // strlen()
void*
uirc_struct_malloc(const void* src, IRC_Struct_Type type)
uirc_struct_copy(const void* src, IRC_Struct_Type type)
{
assert(src != NULL);
@ -189,3 +190,118 @@ 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)
{
assert(key != NULL);
IRC_Tag* t = malloc(sizeof(*t));
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)) {
uirc_struct_free(t, IRC_STRUCT_TAG);
free(t);
return NULL;
}
return t;
}
IRC_Capability*
uirc_struct_assm_capability(bool active, const char* name)
{
assert(name != NULL);
IRC_Capability* c = malloc(sizeof(*c));
memset(c, 0, sizeof(*c));
c->active = active;
if ((c->name = malloc_string(name, strlen(name))) == NULL) {
uirc_struct_free(c, IRC_STRUCT_CAPABILITY);
free(c);
return NULL;
}
return c;
}
#endif /* UIRC_FEATURE_IRCV3 */
IRC_User*
uirc_struct_assm_user(bool service, IRC_Modes modes, const char* nick, const char* user, const char* real, const char* host)
{
IRC_User* u = malloc(sizeof(*u));
memset(u, 0, sizeof(*u));
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)) {
uirc_struct_free(u, IRC_STRUCT_USER);
free(u);
return NULL;
}
return u;
}
IRC_Message*
uirc_struct_assm_message(const char* cmd, bool trailing, unsigned int argc, ...)
{
assert(cmd != NULL);
IRC_Message* m = malloc(sizeof(*m));
memset(m, 0, sizeof(*m));
m->trailing = trailing;
if (cmd != NULL && (m->command = malloc_string(cmd, strlen(cmd))) == NULL) {
uirc_struct_free(m, IRC_STRUCT_MESSAGE);
free(m);
return NULL;
}
va_list ap;
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) {
uirc_struct_free(m, IRC_STRUCT_MESSAGE);
free(m);
return NULL;
}
}
va_end(ap);
return m;
}
IRC_Buffer*
uirc_struct_assm_buffer(IRC_Buffer_Type type, IRC_Modes modes, bool subscribed, const char* name, const char* key, const char* topic)
{
assert(name != NULL);
IRC_Buffer* b = malloc(sizeof(*b));
memset(b, 0, sizeof(*b));
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)) {
uirc_struct_free(b, IRC_STRUCT_BUFFER);
free(b);
return NULL;
}
return b;
}
IRC_Network*
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)) {
uirc_struct_free(n, IRC_STRUCT_NETWORK);
free(n);
return NULL;
}
return n;
}

View File

@ -4,20 +4,15 @@ include_directories(${uIRC_SOURCE_DIR}/include)
add_executable(fullloop fullloop.c common.c)
target_link_libraries(fullloop uirc)
add_test(NAME "FullLoop" COMMAND "fullloop")
add_executable(earlytrail earlytrail.c common.c)
target_link_libraries(earlytrail uirc)
add_test(NAME "EarlyTrail" COMMAND "earlytrail")
add_executable(optcrlf optcrlf.c common.c)
target_link_libraries(optcrlf uirc)
add_test(NAME "OptCRLF" COMMAND "optcrlf")
#add_executable(manassm manassm.c common.c)
#target_link_libraries(manassm uirc)
#add_test(NAME "ManualAssemblers" COMMAND "manassm")
#add_executable(allocs allocs.c common.c)
#target_link_libraries(allocs uirc)
#add_test(NAME "Allocators" COMMAND "allocs")
add_executable(allocs allocs.c common.c)
target_link_libraries(allocs uirc)

View File

@ -36,29 +36,34 @@
int
main(void)
{
IRC_User* u = uirc_malloc_user(NICKN, USERN, NULL, HOSTN);
IRC_User* u = uirc_struct_assm_user(false, 0, NICKN, USERN, NULL, HOSTN);
if (u == NULL) {
fprintf(stderr, "Memory allocation failed\n");
return EXIT_FAILURE;
}
if (strcmp(NICKN, u->nick) != 0 || strcmp(USERN, u->user) != 0 || strcmp(HOSTN, u->host) != 0) {
fprintf(stderr, "User allocator returned unexpected results\n");
return EXIT_FAILURE;
}
uirc_free_user(u);
uirc_struct_free(u, IRC_STRUCT_USER);
free(u);
IRC_Tag* t = uirc_malloc_tag(TAGKEY, TAGVAL);
#ifdef UIRC_FEATURE_IRCV3
IRC_Tag* t = uirc_struct_assm_tag(false, TAGKEY, TAGVAL);
if (strcmp(TAGKEY, t->key) != 0 || strcmp(TAGVAL, t->value) != 0) {
fprintf(stderr, "Tag allocator returned unexpected results\n");
return EXIT_FAILURE;
}
uirc_free_tag(t);
uirc_struct_free(t, IRC_STRUCT_TAG);
free(t);
#endif /* UIRC_FEATURE_IRCV3 */
IRC_Message* m = uirc_malloc_message(CMD, 2, ARG1, ARG2);
m->trailing = true;
IRC_Message* m = uirc_struct_assm_message(CMD, true, 2, ARG1, ARG2);
if (strcmp(m->command, CMD) != 0 || strcmp(m->args[0], ARG1) != 0 || strcmp(m->args[1], ARG2) != 0) {
fprintf(stderr, "Message allocator returned unexpected results\n");
return EXIT_FAILURE;
}
uirc_free_message(m);
uirc_struct_free(m, IRC_STRUCT_MESSAGE);
free(m);
return EXIT_SUCCESS;

View File

@ -1,62 +0,0 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "common.h" // expect() print_irc_message()
#include "uirc.h" // uirc_* IRC_*
#include <stdio.h> // fprintf()
#include <stdlib.h> // EXIT_*
#include <string.h> // strcmp()
#define TAGKEY "wow"
#define TAGKEY2 "wowcum"
#define TAGVAL "wow2"
#define TAGVAL2 "wow3rd"
int
main(void)
{
IRC_Message* m = uirc_malloc_message("NONE", 0);
uirc_list_add_tag(m, uirc_malloc_tag(TAGKEY, TAGVAL));
uirc_list_add_tag(m, uirc_malloc_tag(TAGKEY2, TAGVAL2));
IRC_Tag* t = m->tag_list->next->content;
if (strcmp(TAGKEY2, t->key) != 0 || strcmp(TAGVAL2, t->value) != 0) {
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;
}
uirc_list_remove_tag(m, m->tag_list->content);
t = m->tag_list->content;
if (strcmp(TAGKEY2, t->key) != 0 || strcmp(TAGVAL2, t->value) != 0) {
fprintf(stderr, "List remover fucked up\n");
return EXIT_FAILURE;
}
uirc_free_message(m);
free(m);
return EXIT_SUCCESS;
}