From 91f370fa5818623044739862f459eb74a47a844c Mon Sep 17 00:00:00 2001 From: Alex Denes Date: Sun, 14 Mar 2021 16:35:38 +0000 Subject: [PATCH] Remove struct copy and document some more things --- CMakeLists.txt | 3 +- include/assemblers.h | 4 +- include/memory.h | 3 +- include/tokenizers.h | 2 +- include/types.h | 115 +++++++++++++++++++++++++++++++------------ src/doc/main.doc | 28 ----------- src/memory/struct.c | 109 ++-------------------------------------- 7 files changed, 95 insertions(+), 169 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f7a7b5..94b2c7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.16) project( uIRC - VERSION 0.3.0 + VERSION 0.3.1 DESCRIPTION "Simple and lightweight IRC protocol helper" LANGUAGES C ) @@ -81,6 +81,7 @@ if(BUILD_DOCS) doxygen_add_docs(docgen src/doc/main.doc README.md + ${UIRC_HEADERS} ALL ) endif() diff --git a/include/assemblers.h b/include/assemblers.h index 908f555..30b0d9c 100644 --- a/include/assemblers.h +++ b/include/assemblers.h @@ -38,10 +38,10 @@ ssize_t uirc_assembler_tag_list(char* buf, const llist_t* t, size_t len); * * This assembles a IRC_Message struct to a string representation of a most size len * The return value is either the lenght of the string or any of the uirc_errors errors + * \param[out] buf String representation of message * \param[in] m IRC_Message struct that contains at least a command * \param[in] len Maximum lenght of string - * \param[out] buf String representation of message (if successful) - * \warning in and buf SHOULD NOT be NULL, this will trigger a ASSERT so it's required to check it where needed + * \warning in and buf SHOULD NOT be NULL */ ssize_t uirc_assembler_message(char* buf, const IRC_Message* m, size_t len); #endif /* UIRC_GUARD_PUBLIC_ASSEMBLERS */ diff --git a/include/memory.h b/include/memory.h index df470b7..9926c53 100644 --- a/include/memory.h +++ b/include/memory.h @@ -25,8 +25,7 @@ #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); +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); diff --git a/include/tokenizers.h b/include/tokenizers.h index 63852e4..19256b3 100644 --- a/include/tokenizers.h +++ b/include/tokenizers.h @@ -48,7 +48,7 @@ IRC_User* uirc_tokenizer_user(const char* str); /*! * \brief Tokenize a IRC message string. * - * This function takes a IRC Message and attempts to tokenize/parse it, pointing every element found to it's respective struct element + * This function takes a IRC message and attempts to tokenize/parse it, pointing every element found to it's respective struct element * \param[in] str String containing a IRC message without the ending '\\r\\n' */ IRC_Message* uirc_tokenizer_message(const char* str); diff --git a/include/types.h b/include/types.h index 6faba7f..6e32bc3 100644 --- a/include/types.h +++ b/include/types.h @@ -29,62 +29,115 @@ typedef unsigned short IRC_Modes; typedef uintmax_t IRC_Counter; #ifdef UIRC_FEATURE_IRCV3 +/*! + * \brief Capability status structure + */ typedef struct { - char *key, *value; - bool clientbound; + char *key, /*!< Name of the tag */ + *value; /*!< Value of the tag + * \warning may be NULL + */ + bool clientbound; /*!< true if the tag is sent by the client */ } IRC_Tag; +/*! + * \brief Capability status structure + */ typedef struct { - char* name; - bool active; + char* name; /*!< Name of the capability */ + bool active; /*!< Status of the capability */ } IRC_Capability; #endif /* UIRC_FEATURE_IRCV3 */ +/*! + * \brief User information structure + */ typedef struct { - char * nick, *user, *host, *real; - IRC_Modes modes; - bool is_service; + char *nick, /*!< Nickname of the user */ + *user, /*!< Username of the user */ + *host, /*!< Hostname of the user */ + *real; /*!< Real name of the user + * \note It is only used in USER registrations + */ + IRC_Modes modes; /*!< Modes that the user has active on the network */ + bool is_service; /*!< Whether the user is a service or not */ } IRC_User; +/*! + * \brief The maximum amount of arguments in a message (including trailing) + * + * See *params* at \ref https://tools.ietf.org/html/rfc2812#section-2.3.1 + * \warning This should remain as it is unless you deal with a special implementation that can handle more + */ #define IRC_MAXARGS 15 +/*! + * \brief Message information structure + */ typedef struct { - IRC_User* source; - char* command; - char* args[IRC_MAXARGS]; /* 0-13 + trailing, ended early with a NULL */ - bool trailing; /* Tells if the last argument is trailing */ + IRC_User* source; /*!< Where the message originates from */ + char* command; /*!< Command of the message */ + char* args[IRC_MAXARGS]; /*!< Array of arguments up to \ref IRC_MAXARGS, ended early by a NULL */ + bool trailing; /*!< Tells if the last argument is trailing */ #ifdef UIRC_FEATURE_IRCV3 - llist_t* tag_list; -#endif /* UIRC_FEATURE_IRCV3 */ + llist_t* tag_list; /*!< Linked list of \ref IRC_Tag for the message */ +#endif /* UIRC_FEATURE_IRCV3 */ } IRC_Message; -typedef enum { IRC_DIRECT, IRC_CHANNEL, IRC_GLOBAL } IRC_Buffer_Type; +/*! + * \brief List of possible buffer types + */ +typedef enum { + IRC_DIRECT, /*!< Private buffer (direct messages) */ + IRC_CHANNEL, /*!< Channel buffer (group of people) */ + IRC_GLOBAL /*!< Anything else that doesn't fit in the other categories */ +} IRC_Buffer_Type; +/*! + * \brief Buffer information structure + * + * This structure contains lists and information about a buffer + */ typedef struct { - IRC_Buffer_Type type; - char * name, *topic, *key; - bool subscribed; - IRC_Modes modes; - llist_t * user_list, *message_list; + IRC_Buffer_Type type; /*!< Type of the buffer */ + char * name, /*!< Name of the buffer, usually channel name or nickname */ + *topic, /*!< Topic of the buffer (only applies to channels) */ + *key; /*!< Password required to subscribe to the buffer (to be used with PASS) */ + bool subscribed; /*!< Subscription status (eg. being part of a channel) */ + IRC_Modes modes; /*!< Modes for the buffer (not to be confused to modes of a user) */ + llist_t * user_list, /*!< Linked list of \ref IRC_User participating in a buffer (channel usually) */ + *message_list; /*!< Linked list of \ref IRC_Message received on that buffer */ } IRC_Buffer; +/*! + * \brief Network information structure + * + * This structure contains all the information related to a network and inherits all the other structures directly or indirectly + */ typedef struct { - char * addr, *svc, *pass; - IRC_User* user; - llist_t* buf_list; + char *addr, /*!< Address of the server (usually IP address for TCP) */ + *svc, /*!< Service description (port for TCP) */ + *pass; /*!< Password for the service */ + IRC_User* user; /*!< User that registers on the network (self) */ + llist_t* buf_list; /*!< Linked list of \ref IRC_Buffer open to this network */ #ifdef UIRC_FEATURE_IRCV3 - llist_t* cap_list; -#endif /* UIRC_FEATURE_IRCV3 */ + llist_t* cap_list; /*!< Linked list of \ref IRC_Capability for this network */ +#endif /* UIRC_FEATURE_IRCV3 */ } IRC_Network; +/*! + * \brief List of structure types available + * + * This is used to signal what kind of structure was passed to a function which accepts multiple types or is a void pointer + */ typedef enum { #ifdef UIRC_FEATURE_IRCV3 - IRC_STRUCT_TAG, - IRC_STRUCT_CAPABILITY, -#endif /* UIRC_FEATURE_IRCV3 */ - IRC_STRUCT_USER, - IRC_STRUCT_MESSAGE, - IRC_STRUCT_BUFFER, - IRC_STRUCT_NETWORK + IRC_STRUCT_TAG, /*!< \ref IRC_Tag */ + IRC_STRUCT_CAPABILITY, /*!< \ref IRC_Capability */ +#endif /* UIRC_FEATURE_IRCV3 */ + IRC_STRUCT_USER, /*!< \ref IRC_User */ + IRC_STRUCT_MESSAGE, /*!< \ref IRC_Message */ + IRC_STRUCT_BUFFER, /*!< \ref IRC_Buffer */ + IRC_STRUCT_NETWORK /*!< \ref IRC_Network */ } IRC_Struct_Type; #endif /* UIRC_GUARD_PUBLIC_TYPES */ diff --git a/src/doc/main.doc b/src/doc/main.doc index 895b39f..caf4631 100644 --- a/src/doc/main.doc +++ b/src/doc/main.doc @@ -1,30 +1,2 @@ /// *************************************************************************** /// @mainpage MicroIRC library -/// -/// @section Core -/// @subsection Assemblers -/// Assemblers are a quick way to convert structs to a string representation -/// -/// - \ref Assm_mesg -/// - \ref Assm_user -/// -/// @subsection Tokenizers -/// Tokenizers tokenize and point struct elements to the matching substrings in the string given -/// -/// - \ref Tok_mesg -/// - \ref Tok_user -/// -/// @section Additions -/// -/// @subsection Validators -/// - \ref Val_mesg -/// -/// @subsection IRCv3 -/// @subsubsection Tags -/// - \ref Assm_tags -/// - \ref Tok_tags -/// -/// @subsubsection Capabilities -/// -/// -/// *************************************************************************** diff --git a/src/memory/struct.c b/src/memory/struct.c index 4b3c405..49799bd 100644 --- a/src/memory/struct.c +++ b/src/memory/struct.c @@ -21,109 +21,9 @@ #include // assert() #include // stringext_strmalloc() -#include -#include // free() -#include // strlen() - -void* -uirc_struct_copy(const void* src, IRC_Struct_Type type) -{ - assert(src != NULL); - - void* ret = NULL; - size_t structsize = 0; - - switch (type) { -#ifdef UIRC_FEATURE_IRCV3 - case IRC_STRUCT_TAG: structsize = sizeof(IRC_Tag); break; - case IRC_STRUCT_CAPABILITY: structsize = sizeof(IRC_Capability); break; -#endif /* UIRC_FEATURE_IRCV3 */ - case IRC_STRUCT_USER: structsize = sizeof(IRC_User); break; - case IRC_STRUCT_MESSAGE: structsize = sizeof(IRC_Message); break; - case IRC_STRUCT_BUFFER: structsize = sizeof(IRC_Buffer); break; - case IRC_STRUCT_NETWORK: structsize = sizeof(IRC_Network); break; - } - - if ((ret = malloc(structsize)) == NULL) return NULL; - memset(ret, 0, structsize); - - switch (type) { -#ifdef UIRC_FEATURE_IRCV3 - case IRC_STRUCT_TAG: { - IRC_Tag* c_ret = ret; - const IRC_Tag* c_src = src; - - c_ret->clientbound = c_src->clientbound; - 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; - } - case IRC_STRUCT_CAPABILITY: { - IRC_Capability* c_ret = ret; - const IRC_Capability* c_src = src; - - c_ret->active = c_src->active; - if ((c_ret->name = stringext_strmalloc(c_src->name, strlen(c_src->name))) == NULL) break; - - return ret; - } -#endif /* UIRC_FEATURE_IRCV3 */ - case IRC_STRUCT_USER: { - IRC_User* c_ret = ret; - const IRC_User* c_src = src; - - c_ret->modes = c_src->modes; - c_ret->is_service = c_src->is_service; - 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; - } - case IRC_STRUCT_MESSAGE: { - IRC_Message* c_ret = ret; - const IRC_Message* c_src = src; - - c_ret->trailing = c_src->trailing; - 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] = stringext_strmalloc(c_src->args[i], strlen(c_src->args[i]))) == NULL) break; - - return ret; - } - case IRC_STRUCT_BUFFER: { - IRC_Buffer* c_ret = ret; - const IRC_Buffer* c_src = src; - - c_ret->modes = c_src->modes; - c_ret->subscribed = c_src->subscribed; - 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; - } - case IRC_STRUCT_NETWORK: { - IRC_Network* c_ret = ret; - const IRC_Network* c_src = src; - - 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; - } - } - uirc_struct_free(ret, type); - free(ret); - return NULL; -} +#include // va_* +#include // free() +#include // strlen() void uirc_struct_free(void* obj, IRC_Struct_Type type) @@ -200,7 +100,8 @@ uirc_struct_assm_tag(bool clientbound, const char* key, const char* value) memset(t, 0, sizeof(*t)); t->clientbound = clientbound; - if ((t->key = stringext_strmalloc(key, strlen(key))) == NULL || (value != NULL && (t->value = stringext_strmalloc(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;