Remove struct copy and document some more things
This commit is contained in:
parent
423f7bc021
commit
91f370fa58
|
@ -1,7 +1,7 @@
|
||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
project(
|
project(
|
||||||
uIRC
|
uIRC
|
||||||
VERSION 0.3.0
|
VERSION 0.3.1
|
||||||
DESCRIPTION "Simple and lightweight IRC protocol helper"
|
DESCRIPTION "Simple and lightweight IRC protocol helper"
|
||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
)
|
)
|
||||||
|
@ -81,6 +81,7 @@ if(BUILD_DOCS)
|
||||||
doxygen_add_docs(docgen
|
doxygen_add_docs(docgen
|
||||||
src/doc/main.doc
|
src/doc/main.doc
|
||||||
README.md
|
README.md
|
||||||
|
${UIRC_HEADERS}
|
||||||
ALL
|
ALL
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -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
|
* 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
|
* 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] m IRC_Message struct that contains at least a command
|
||||||
* \param[in] len Maximum lenght of string
|
* \param[in] len Maximum lenght of string
|
||||||
* \param[out] buf String representation of message (if successful)
|
* \warning in and buf SHOULD NOT be NULL
|
||||||
* \warning in and buf SHOULD NOT be NULL, this will trigger a ASSERT so it's required to check it where needed
|
|
||||||
*/
|
*/
|
||||||
ssize_t uirc_assembler_message(char* buf, const IRC_Message* m, size_t len);
|
ssize_t uirc_assembler_message(char* buf, const IRC_Message* m, size_t len);
|
||||||
#endif /* UIRC_GUARD_PUBLIC_ASSEMBLERS */
|
#endif /* UIRC_GUARD_PUBLIC_ASSEMBLERS */
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#ifndef UIRC_GUARD_PUBLIC_MEMORY
|
#ifndef UIRC_GUARD_PUBLIC_MEMORY
|
||||||
#define 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
|
#ifdef UIRC_FEATURE_IRCV3
|
||||||
|
|
|
@ -48,7 +48,7 @@ IRC_User* uirc_tokenizer_user(const char* str);
|
||||||
/*!
|
/*!
|
||||||
* \brief Tokenize a IRC message string.
|
* \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'
|
* \param[in] str String containing a IRC message without the ending '\\r\\n'
|
||||||
*/
|
*/
|
||||||
IRC_Message* uirc_tokenizer_message(const char* str);
|
IRC_Message* uirc_tokenizer_message(const char* str);
|
||||||
|
|
109
include/types.h
109
include/types.h
|
@ -29,62 +29,115 @@ typedef unsigned short IRC_Modes;
|
||||||
typedef uintmax_t IRC_Counter;
|
typedef uintmax_t IRC_Counter;
|
||||||
|
|
||||||
#ifdef UIRC_FEATURE_IRCV3
|
#ifdef UIRC_FEATURE_IRCV3
|
||||||
|
/*!
|
||||||
|
* \brief Capability status structure
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *key, *value;
|
char *key, /*!< Name of the tag */
|
||||||
bool clientbound;
|
*value; /*!< Value of the tag
|
||||||
|
* \warning may be NULL
|
||||||
|
*/
|
||||||
|
bool clientbound; /*!< true if the tag is sent by the client */
|
||||||
} IRC_Tag;
|
} IRC_Tag;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Capability status structure
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* name;
|
char* name; /*!< Name of the capability */
|
||||||
bool active;
|
bool active; /*!< Status of the capability */
|
||||||
} IRC_Capability;
|
} IRC_Capability;
|
||||||
#endif /* UIRC_FEATURE_IRCV3 */
|
#endif /* UIRC_FEATURE_IRCV3 */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief User information structure
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char * nick, *user, *host, *real;
|
char *nick, /*!< Nickname of the user */
|
||||||
IRC_Modes modes;
|
*user, /*!< Username of the user */
|
||||||
bool is_service;
|
*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;
|
} 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
|
#define IRC_MAXARGS 15
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Message information structure
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
IRC_User* source;
|
IRC_User* source; /*!< Where the message originates from */
|
||||||
char* command;
|
char* command; /*!< Command of the message */
|
||||||
char* args[IRC_MAXARGS]; /* 0-13 + trailing, ended early with a NULL */
|
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 */
|
bool trailing; /*!< Tells if the last argument is trailing */
|
||||||
#ifdef UIRC_FEATURE_IRCV3
|
#ifdef UIRC_FEATURE_IRCV3
|
||||||
llist_t* tag_list;
|
llist_t* tag_list; /*!< Linked list of \ref IRC_Tag for the message */
|
||||||
#endif /* UIRC_FEATURE_IRCV3 */
|
#endif /* UIRC_FEATURE_IRCV3 */
|
||||||
} IRC_Message;
|
} 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 {
|
typedef struct {
|
||||||
IRC_Buffer_Type type;
|
IRC_Buffer_Type type; /*!< Type of the buffer */
|
||||||
char * name, *topic, *key;
|
char * name, /*!< Name of the buffer, usually channel name or nickname */
|
||||||
bool subscribed;
|
*topic, /*!< Topic of the buffer (only applies to channels) */
|
||||||
IRC_Modes modes;
|
*key; /*!< Password required to subscribe to the buffer (to be used with PASS) */
|
||||||
llist_t * user_list, *message_list;
|
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;
|
} 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 {
|
typedef struct {
|
||||||
char * addr, *svc, *pass;
|
char *addr, /*!< Address of the server (usually IP address for TCP) */
|
||||||
IRC_User* user;
|
*svc, /*!< Service description (port for TCP) */
|
||||||
llist_t* buf_list;
|
*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
|
#ifdef UIRC_FEATURE_IRCV3
|
||||||
llist_t* cap_list;
|
llist_t* cap_list; /*!< Linked list of \ref IRC_Capability for this network */
|
||||||
#endif /* UIRC_FEATURE_IRCV3 */
|
#endif /* UIRC_FEATURE_IRCV3 */
|
||||||
} IRC_Network;
|
} 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 {
|
typedef enum {
|
||||||
#ifdef UIRC_FEATURE_IRCV3
|
#ifdef UIRC_FEATURE_IRCV3
|
||||||
IRC_STRUCT_TAG,
|
IRC_STRUCT_TAG, /*!< \ref IRC_Tag */
|
||||||
IRC_STRUCT_CAPABILITY,
|
IRC_STRUCT_CAPABILITY, /*!< \ref IRC_Capability */
|
||||||
#endif /* UIRC_FEATURE_IRCV3 */
|
#endif /* UIRC_FEATURE_IRCV3 */
|
||||||
IRC_STRUCT_USER,
|
IRC_STRUCT_USER, /*!< \ref IRC_User */
|
||||||
IRC_STRUCT_MESSAGE,
|
IRC_STRUCT_MESSAGE, /*!< \ref IRC_Message */
|
||||||
IRC_STRUCT_BUFFER,
|
IRC_STRUCT_BUFFER, /*!< \ref IRC_Buffer */
|
||||||
IRC_STRUCT_NETWORK
|
IRC_STRUCT_NETWORK /*!< \ref IRC_Network */
|
||||||
} IRC_Struct_Type;
|
} IRC_Struct_Type;
|
||||||
|
|
||||||
#endif /* UIRC_GUARD_PUBLIC_TYPES */
|
#endif /* UIRC_GUARD_PUBLIC_TYPES */
|
||||||
|
|
|
@ -1,30 +1,2 @@
|
||||||
/// ***************************************************************************
|
/// ***************************************************************************
|
||||||
/// @mainpage MicroIRC library
|
/// @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
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// ***************************************************************************
|
|
||||||
|
|
|
@ -21,110 +21,10 @@
|
||||||
|
|
||||||
#include <assert.h> // assert()
|
#include <assert.h> // assert()
|
||||||
#include <corelibs/stringext.h> // stringext_strmalloc()
|
#include <corelibs/stringext.h> // stringext_strmalloc()
|
||||||
#include <stdarg.h>
|
#include <stdarg.h> // va_*
|
||||||
#include <stdlib.h> // free()
|
#include <stdlib.h> // free()
|
||||||
#include <string.h> // strlen()
|
#include <string.h> // 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
uirc_struct_free(void* obj, IRC_Struct_Type type)
|
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));
|
memset(t, 0, sizeof(*t));
|
||||||
|
|
||||||
t->clientbound = clientbound;
|
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);
|
uirc_struct_free(t, IRC_STRUCT_TAG);
|
||||||
free(t);
|
free(t);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Reference in New Issue