diff --git a/.clang-tidy b/.clang-tidy
index 6511921..c0cc988 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,180 +1,6 @@
---
-Checks: 'clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*,clang-diagnostic-*,clang-analyzer-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-readability-isolate-declaration,-readability-else-after-return,-readability-braces-around-statements,-*,clang-analyzer-core.*,clang-analyzer-optin.performance.*,clang-analyzer-optin.portability.*,clang-analyzer-nullability.*,clang-analyzer-security.*,clang-analyzer-unix.*,bugprone-*,misc-*,performance-*,readability-*,-readability-isolate-declaration,-readability-else-after-return,-readability-braces-around-statements,-readability-magic-numbers'
+Checks: 'bugprone-*,performance-*,portability-*,readability-*,-readability-braces-around-statements,-readability-isolate-declaration,-readability-else-after-return,-readability-braces-around-statements,misc-*,modernize-*,clang-analyzer-core.*,clang-analyzer-security.*,clang-analyzer-unix.*,clang-analyzer-optin.portability.UnixAPI,clang-analyzer-optin.performance.Padding'
WarningsAsErrors: ''
HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false
FormatStyle: file
-User: caskd
-CheckOptions:
- - key: bugprone-argument-comment.CommentBoolLiterals
- value: '0'
- - key: bugprone-argument-comment.CommentCharacterLiterals
- value: '0'
- - key: bugprone-argument-comment.CommentFloatLiterals
- value: '0'
- - key: bugprone-argument-comment.CommentIntegerLiterals
- value: '0'
- - key: bugprone-argument-comment.CommentNullPtrs
- value: '0'
- - key: bugprone-argument-comment.CommentStringLiterals
- value: '0'
- - key: bugprone-argument-comment.CommentUserDefinedLiterals
- value: '0'
- - key: bugprone-argument-comment.IgnoreSingleArgument
- value: '0'
- - key: bugprone-argument-comment.StrictMode
- value: '0'
- - key: bugprone-assert-side-effect.AssertMacros
- value: assert
- - key: bugprone-assert-side-effect.CheckFunctionCalls
- value: '0'
- - key: bugprone-dangling-handle.HandleClasses
- value: 'std::basic_string_view;std::experimental::basic_string_view'
- - key: bugprone-dynamic-static-initializers.HeaderFileExtensions
- value: ',h,hh,hpp,hxx'
- - key: bugprone-exception-escape.FunctionsThatShouldNotThrow
- value: ''
- - key: bugprone-exception-escape.IgnoredExceptions
- value: ''
- - key: bugprone-misplaced-widening-cast.CheckImplicitCasts
- value: '0'
- - key: bugprone-not-null-terminated-result.WantToUseSafeFunctions
- value: '1'
- - key: bugprone-signed-char-misuse.CharTypdefsToIgnore
- value: ''
- - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant
- value: '1'
- - key: bugprone-sizeof-expression.WarnOnSizeOfConstant
- value: '1'
- - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression
- value: '0'
- - key: bugprone-sizeof-expression.WarnOnSizeOfThis
- value: '1'
- - key: bugprone-string-constructor.LargeLengthThreshold
- value: '8388608'
- - key: bugprone-string-constructor.WarnOnLargeLength
- value: '1'
- - key: bugprone-suspicious-enum-usage.StrictMode
- value: '0'
- - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens
- value: '5'
- - key: bugprone-suspicious-missing-comma.RatioThreshold
- value: '0.200000'
- - key: bugprone-suspicious-missing-comma.SizeThreshold
- value: '5'
- - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions
- value: ''
- - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison
- value: '1'
- - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison
- value: '0'
- - key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit
- value: '16'
- - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField
- value: '1'
- - key: bugprone-unused-return-value.CheckedFunctions
- value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty'
- - key: cert-dcl16-c.NewSuffixes
- value: 'L;LL;LU;LLU'
- - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
- value: '0'
- - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
- value: '1'
- - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
- value: '1'
- - key: google-readability-braces-around-statements.ShortStatementLines
- value: '1'
- - key: google-readability-function-size.StatementThreshold
- value: '800'
- - key: google-readability-namespace-comments.ShortNamespaceLines
- value: '10'
- - key: google-readability-namespace-comments.SpacesBeforeComments
- value: '2'
- - key: misc-definitions-in-headers.HeaderFileExtensions
- value: ',h,hh,hpp,hxx'
- - key: misc-definitions-in-headers.UseHeaderFileExtension
- value: '1'
- - key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries
- value: '1'
- - key: misc-unused-parameters.StrictMode
- value: '0'
- - key: modernize-loop-convert.MaxCopySize
- value: '16'
- - key: modernize-loop-convert.MinConfidence
- value: reasonable
- - key: modernize-loop-convert.NamingStyle
- value: CamelCase
- - key: modernize-pass-by-value.IncludeStyle
- value: llvm
- - key: modernize-replace-auto-ptr.IncludeStyle
- value: llvm
- - key: modernize-use-nullptr.NullMacros
- value: 'NULL'
- - key: performance-faster-string-find.StringLikeClasses
- value: 'std::basic_string'
- - key: performance-for-range-copy.AllowedTypes
- value: ''
- - key: performance-for-range-copy.WarnOnAllAutoCopies
- value: '0'
- - key: performance-inefficient-string-concatenation.StrictMode
- value: '0'
- - key: performance-inefficient-vector-operation.EnableProto
- value: '0'
- - key: performance-inefficient-vector-operation.VectorLikeClasses
- value: '::std::vector'
- - key: performance-move-const-arg.CheckTriviallyCopyableMove
- value: '1'
- - key: performance-move-constructor-init.IncludeStyle
- value: llvm
- - key: performance-no-automatic-move.AllowedTypes
- value: ''
- - key: performance-type-promotion-in-math-fn.IncludeStyle
- value: llvm
- - key: performance-unnecessary-copy-initialization.AllowedTypes
- value: ''
- - key: performance-unnecessary-value-param.AllowedTypes
- value: ''
- - key: performance-unnecessary-value-param.IncludeStyle
- value: llvm
- - key: readability-function-size.BranchThreshold
- value: '4294967295'
- - key: readability-function-size.LineThreshold
- value: '4294967295'
- - key: readability-function-size.NestingThreshold
- value: '4294967295'
- - key: readability-function-size.ParameterThreshold
- value: '4294967295'
- - key: readability-function-size.StatementThreshold
- value: '800'
- - key: readability-function-size.VariableThreshold
- value: '4294967295'
- - key: readability-identifier-naming.IgnoreFailedSplit
- value: '0'
- - key: readability-implicit-bool-conversion.AllowIntegerConditions
- value: '0'
- - key: readability-implicit-bool-conversion.AllowPointerConditions
- value: '0'
- - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros
- value: '1'
- - key: readability-inconsistent-declaration-parameter-name.Strict
- value: '0'
- - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors
- value: '0'
- - key: readability-redundant-smartptr-get.IgnoreMacros
- value: '1'
- - key: readability-redundant-string-init.StringNames
- value: '::std::basic_string'
- - key: readability-simplify-boolean-expr.ChainedConditionalAssignment
- value: '0'
- - key: readability-simplify-boolean-expr.ChainedConditionalReturn
- value: '0'
- - key: readability-simplify-subscript-expr.Types
- value: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array'
- - key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold
- value: '3'
- - key: readability-uppercase-literal-suffix.IgnoreMacros
- value: '1'
- - key: readability-uppercase-literal-suffix.NewSuffixes
- value: ''
-...
-
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 468b804..f139cf4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.16)
project(
uIRC
- VERSION 2021.01.24
+ VERSION 0.1
DESCRIPTION "Simple and lightweight IRC protocol helper"
LANGUAGES C
)
@@ -11,92 +11,80 @@ include(GNUInstallDirs)
set(UIRC_VERSION "${PROJECT_VERSION}")
add_compile_definitions(UIRC_VERSION="${UIRC_VERSION}")
-OPTION(BUILD_HELPERS "Build message helpers" ON )
-OPTION(BUILD_VALIDATORS "Build message validators" ON )
-OPTION(BUILD_IRCV3 "Build IRCv3 components" ON )
+OPTION(BUILD_IRCV3 "Build IRCv3 components" OFF)
+OPTION(BUILD_VALIDATORS "Build message validators" OFF)
OPTION(BUILD_TESTS "Build tests for ctest" OFF)
OPTION(BUILD_DOCS "Build documentation with doxygen" OFF)
OPTION(CODE_ANALYZER "Analyze the code statically" OFF)
OPTION(CODE_COVERAGE "Build with coverage tools" OFF)
set(UIRC_SOURCE
- src/assemblers.c
- src/commands.c
- src/converters.c
- src/memory.c
- src/string.c
- src/tokenizers.c
+ src/assemblers/message.c
+ src/assemblers/user.c
+ src/tokenizers/message.c
+ src/tokenizers/user.c
+ src/memory/memory.c
)
set(UIRC_HEADERS
- src/public/assemblers.h
- src/public/commands.h
- src/public/converters.h
- src/public/errors.h
- src/public/modes.h
- src/public/replies.h
- src/public/tokenizers.h
- src/public/types.h
- src/public/uirc.h
+ src/uirc.h
+ src/ctcp.h
+ src/errors.h
+ src/modes.h
+ src/replies.h
+ src/types.h
+ src/assemblers/assemblers.h
+ src/tokenizers/tokenizers.h
)
+# Libraries used
+find_library(LLIST_PATH NAMES llist REQUIRED)
+find_library(STRINGEXT_PATH NAMES stringext REQUIRED)
+set(UIRC_LIBS ${STRINGEXT_PATH} ${LLIST_PATH})
+
#
# Features
#
if (BUILD_IRCV3)
- message(STATUS "IRCv3 capabilities are going to be built.")
- add_compile_definitions(UIRC_IRCV3)
- set(UIRC_SOURCE ${UIRC_SOURCE}
- src/tags.c
- src/capabilities.c
- )
- set(UIRC_HEADERS ${UIRC_HEADERS}
- src/public/tags.h
- src/public/capabilities.h
+ message(STATUS "IRCv3 capabilities enabled")
+ add_compile_definitions(UIRC_FEATURE_IRCV3)
+ set(UIRC_SOURCE
+ ${UIRC_SOURCE}
+ src/assemblers/tag.c
+ src/tokenizers/tags.c
)
endif()
if (BUILD_VALIDATORS)
- message(STATUS "Message validators are going to be built.")
- add_compile_definitions(UIRC_VALIDATORS)
- set(UIRC_SOURCE ${UIRC_SOURCE}
- src/validators.c
+ message(STATUS "Message validators enabled")
+ add_compile_definitions(UIRC_FEATURE_VALIDATORS)
+ set(UIRC_SOURCE
+ ${UIRC_SOURCE}
+ src/validators/validators.c
)
- set(UIRC_HEADERS ${UIRC_HEADERS}
- src/public/validators.h
+ set(UIRC_HEADERS
+ ${UIRC_HEADERS}
+ src/validators/validators.h
)
endif()
-if (BUILD_HELPERS)
- message(STATUS "Helper functions are going to be built.")
- add_compile_definitions(UIRC_HELPERS)
-endif()
if (BUILD_TESTS)
message(STATUS "Tests are going to be built.")
enable_testing()
- macro(buildtest name source)
- add_executable(${source} src/tests/${source}.c)
- target_link_libraries(${source} uirc)
- add_test(NAME ${name} COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${source})
+ macro(buildtest categ name)
+ add_executable("uirc-test-${categ}-${name}" "src/tests/${categ}/${name}.c" src/tests/common.c)
+ target_link_libraries("uirc-test-${categ}-${name}" uirc)
+ add_test(NAME "${categ}/${name}" COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/uirc-test-${categ}-${name}")
endmacro()
- buildtest(Tokenizer tokenizer)
- buildtest(Overflow overflow)
- buildtest(PrefixAssembler prefixassm)
- buildtest(MessageAssembler msgassm)
- buildtest(NumericCmds numericmds)
- buildtest(IncorrectTrailing notrail)
- buildtest(SpacedArguments spacedargs)
- buildtest(StrTokMoveSave strtokmr)
- buildtest(Junk junk)
+ buildtest(tokenizers tag)
+ buildtest(tokenizers user)
+ buildtest(tokenizers message)
- if (BUILD_IRCV3)
- buildtest(TagParser tagtok)
- buildtest(TagAssembler tagassm)
- if (BUILD_HELPERS)
- buildtest(TimestampAssembly timestamp)
- buildtest(TagBitMaskTknzr capbitmask)
- endif()
- endif()
+ buildtest(assemblers tag)
+ buildtest(assemblers user)
+ buildtest(assemblers message)
+
+ buildtest(general fullloop)
endif()
if(BUILD_DOCS)
find_package(Doxygen REQUIRED)
@@ -105,11 +93,10 @@ if(BUILD_DOCS)
set(DOXYGEN_MACRO_EXPANSION YES)
set(DOXYGEN_EXPAND_ONLY_PREDEF YES)
set(DOXYGEN_PREDEFINED
- "UIRC_HELPERS"
- "UIRC_IRCV3"
+ "UIRC_FEATURE_IRCV3"
+ "UIRC_FEATURE_VALIDATORS"
)
doxygen_add_docs(docgen
- src/public
src/doc/main.doc
README.md
ALL
@@ -119,6 +106,21 @@ endif()
add_library(uirc ${UIRC_SOURCE})
+target_link_libraries(uirc ${UIRC_LIBS})
+
+separate_arguments(UIRC_HEADERS)
+set_target_properties(uirc PROPERTIES
+ C_STANDARD 99
+ VERSION ${PROJECT_VERSION}
+ SOVERSION ${PROJECT_VERSION_MAJOR}
+ PUBLIC_HEADER "${UIRC_HEADERS}"
+)
+
+install(
+ TARGETS uirc
+ LIBRARY
+ PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/uirc"
+)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Werror")
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
@@ -133,16 +135,3 @@ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
endif()
endif()
-separate_arguments(UIRC_HEADERS)
-set_target_properties(uirc PROPERTIES
- C_STANDARD 99
- VERSION ${UIRC_VERSION}
- SOVERSION ${UIRC_VERSION}
- PUBLIC_HEADER "${UIRC_HEADERS}"
-)
-
-install(
- TARGETS uirc
- LIBRARY
- PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/uirc"
-)
diff --git a/src/assemblers.c b/src/assemblers.c
deleted file mode 100644
index 0bff421..0000000
--- a/src/assemblers.c
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "public/assemblers.h"
-
-#include "private/mappings.h"
-#include "private/memory.h"
-#include "public/commands.h"
-#include "public/errors.h"
-#include "public/modes.h"
-#include "public/tags.h"
-#include "public/types.h"
-
-#include
-#include
-#include
-#include
-#include
-
-#ifdef UIRC_HELPERS
-#define RESERVED "*"
-void clear_assm(IRC_Message* imassm_mesg);
-#endif /* UIRC_HELPERS */
-
-signed long
-Assm_user(char* buf, IRC_User* in, size_t len, bool useorig)
-{
- assert(buf != NULL);
- assert(in != NULL);
- char* pos = buf;
- if (in->nick == NULL && in->host != NULL) {
- if (!safe_strcpy(&pos, in->host, len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- } else if (in->nick != NULL) {
- if (!safe_strcpy(&pos, in->nick, len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- if (in->user != NULL) {
- if (!safe_charcpy(&pos, '!', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- if (!safe_strcpy(&pos, in->user, len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
- if (useorig && in->orig != NULL) {
- if (!safe_charcpy(&pos, '%', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- if (!safe_strcpy(&pos, in->orig, len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
- if (in->host != NULL) {
- if (!safe_charcpy(&pos, '@', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- if (!safe_strcpy(&pos, in->host, len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
- } else
- return ERR_UIRC_INVALID_FORMAT;
- return pos - buf;
-}
-
-#ifdef UIRC_IRCV3
-signed long
-Assm_tags(char* buf, IRC_Tags* in, size_t len)
-{
- assert(buf != NULL);
- assert(in != NULL);
- char* pos = buf;
- struct tagmapping tagmps[] = { { .name = "time", .assg = &in->time }, { .name = "account", .assg = &in->account },
- { .name = "batch", .assg = &in->batch }, { .name = "label", .assg = &in->label },
- { .name = "msgid", .assg = &in->msgid }, { .name = "multiline-concat", .assg = &in->multiline_concat },
- { .name = "typing", .assg = &in->typing }, { .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).value != NULL) {
- if (pos == buf) {
- if (!safe_charcpy(&pos, '@', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- } else {
- if (!safe_charcpy(&pos, ';', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
- if ((*tagmps[i].assg).clientbound) {
- if (!safe_charcpy(&pos, '+', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
- if (!safe_strcpy(&pos, tagmps[i].name, len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- if (*(*tagmps[i].assg).value != '\0') {
- if (!safe_charcpy(&pos, '=', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- if (!safe_strcpy(&pos, (*tagmps[i].assg).value, len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
- }
- }
- return pos - buf;
-}
-#endif /* UIRC_IRCV3 */
-
-signed long
-Assm_mesg(char* buf, IRC_Message* in, size_t len)
-{
- assert(buf != NULL);
- assert(in != NULL);
- char* pos = buf;
- signed long cnt, ret;
-#ifdef UIRC_IRCV3
- if ((ret = Assm_tags(pos, &in->tags, len - (size_t)(pos - buf))) < 0) return ret;
- else if (ret != 0) {
- pos += ret;
- if (!safe_charcpy(&pos, ' ', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
-#endif /* UIRC_IRCV3 */
- if (in->name.nick != NULL || in->name.host != NULL) {
- if (!safe_charcpy(&pos, ':', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- if ((ret = Assm_user(pos, &in->name, len - (size_t)(pos - buf), false)) <= 0) return ret;
- else
- pos += ret;
- if (!safe_charcpy(&pos, ' ', len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- }
- if (in->cmd < UIRC_FCMD || in->cmd > UIRC_LCMD) {
- if ((cnt = snprintf(pos, 4, "%.3i", in->cmd)) == 3) pos += cnt;
- else
- return ERR_UIRC_UNKNOWN_TOKEN;
- } else {
- if (IRC_Cmds[in->cmd] != NULL) {
- size_t cmdlen = strlen(IRC_Cmds[in->cmd]);
- if (len - (size_t)(pos - buf) > cmdlen && strcpy(pos, IRC_Cmds[in->cmd]) != NULL) pos += cmdlen;
- else
- return ERR_UIRC_UNKNOWN_TOKEN;
- }
- }
- for (unsigned int i = 0; in->args[i] != NULL; i++) {
- if (len - (size_t)(pos - buf) > strlen(in->args[i]) + 2
- && (cnt = snprintf(pos, len - (size_t)(pos - buf), (in->args[i + 1] == NULL && in->trailing) ? " :%s" : " %s", in->args[i])) > 0)
- pos += cnt;
- else
- return ERR_UIRC_BUFFER_ERR;
- }
- if (!safe_strcpy(&pos, "\r\n", len - (size_t)(pos - buf))) return ERR_UIRC_BUFFER_ERR;
- return pos - buf;
-}
-
-#ifdef UIRC_HELPERS
-
-void
-clear_assm(IRC_Message* imassm_mesg)
-{
- memset((void*) imassm_mesg, '\0', sizeof(IRC_Message));
-}
-
-IRC_Message*
-Assm_AUTO(IRC_Message* imassm_mesg, IRC_Command cmd, bool trailing, char** args, int req)
-{
- clear_assm(imassm_mesg);
- int i;
- for (i = 0; args[i] != NULL && i < 15; i++) { imassm_mesg->args[i] = args[i]; }
- if (i < req) return NULL;
- imassm_mesg->trailing = trailing;
- imassm_mesg->cmd = cmd;
- return imassm_mesg;
-}
-
-IRC_Message*
-Assm_cmd_USER(IRC_Message* imassm_mesg, char* user, char* realname, int modes)
-{
- if (user == NULL || modes < 0 || modes > (MBMASK_INVIS | MBMASK_WALLOPS)) return NULL;
- clear_assm(imassm_mesg);
- static char local_mode[2];
- snprintf(local_mode, 2, "%i", modes);
- imassm_mesg->args[0] = user;
- imassm_mesg->args[1] = local_mode;
- imassm_mesg->args[2] = RESERVED;
- imassm_mesg->args[3] = realname;
- imassm_mesg->trailing = true;
- imassm_mesg->cmd = USER;
- return imassm_mesg;
-}
-
-IRC_Message*
-Assm_cmd_LINKS(IRC_Message* imassm_mesg, char* remoteserv, char* servmask)
-{
- if (remoteserv != NULL && servmask == NULL) return NULL;
- clear_assm(imassm_mesg);
- imassm_mesg->args[0] = (remoteserv == NULL) ? servmask : remoteserv;
- imassm_mesg->args[1] = (remoteserv == NULL) ? NULL : servmask;
- imassm_mesg->cmd = LINKS;
- return imassm_mesg;
-}
-
-IRC_Message*
-Assm_cmd_WHO(IRC_Message* imassm_mesg, char* mask, bool oper)
-{
- static char* operator= "o";
- if (oper && mask == NULL) return NULL;
- clear_assm(imassm_mesg);
- imassm_mesg->args[0] = mask;
- imassm_mesg->args[1] = (oper) ? operator: NULL;
- imassm_mesg->cmd = WHO;
- return imassm_mesg;
-}
-
-IRC_Message*
-Assm_cmd_WHOIS(IRC_Message* imassm_mesg, char* target, char* mask)
-{
- if (mask == NULL) return NULL;
- clear_assm(imassm_mesg);
- imassm_mesg->args[0] = (target == NULL) ? mask : target;
- imassm_mesg->args[1] = (target == NULL) ? NULL : mask;
- imassm_mesg->cmd = WHOIS;
- return imassm_mesg;
-}
-
-IRC_Message*
-Assm_cmd_WHOWAS(IRC_Message* imassm_mesg, char* nick, char* count, char* target)
-{
- if (nick == NULL || (target != NULL && count == NULL)) return NULL;
- clear_assm(imassm_mesg);
- imassm_mesg->args[0] = nick;
- imassm_mesg->args[1] = count;
- imassm_mesg->args[2] = target;
- imassm_mesg->cmd = WHOWAS;
- return imassm_mesg;
-}
-
-/* NOTE: This is what implementation you have to live with
- * I would've just used the prefix to set the source but whatever
- */
-IRC_Message*
-Assm_cmd_PING(IRC_Message* imassm_mesg, char* source, char* target)
-{
- if (source == NULL && target == NULL) return NULL;
- clear_assm(imassm_mesg);
- imassm_mesg->args[0] = (source != NULL) ? source : target;
- imassm_mesg->args[1] = (source != NULL && target != NULL) ? target : NULL;
- imassm_mesg->trailing = (source != NULL && target == NULL) ? true : false;
- imassm_mesg->cmd = PING;
- return imassm_mesg;
-}
-
-IRC_Message*
-Assm_cmd_SUMMON(IRC_Message* imassm_mesg, char* user, char* target, char* channel)
-{
- if (user == NULL || (channel != NULL && target == NULL)) return NULL;
- clear_assm(imassm_mesg);
- imassm_mesg->args[0] = user;
- imassm_mesg->args[1] = target;
- imassm_mesg->args[2] = channel;
- imassm_mesg->cmd = SUMMON;
- return imassm_mesg;
-}
-
-IRC_Message*
-Assm_cmd_USERHOST(IRC_Message* imassm_mesg, char* users[])
-{
- if (users[0] == NULL) return NULL;
- clear_assm(imassm_mesg);
- for (unsigned int i = 0; i < 5 && users[i] != NULL; i++) imassm_mesg->args[i] = users[i];
- imassm_mesg->cmd = USERHOST;
- return imassm_mesg;
-}
-/* NOTE: Limited to 14 nicks per command */
-
-IRC_Message*
-Assm_cmd_ISON(IRC_Message* imassm_mesg, char* users[])
-{
- if (users[0] == NULL) return NULL;
- clear_assm(imassm_mesg);
- for (unsigned int i = 0; i < 14 && users[i] != NULL; i++) { imassm_mesg->args[i] = users[i]; }
- imassm_mesg->cmd = ISON;
- return imassm_mesg;
-}
-
-#endif /* UIRC_HELPERS */
diff --git a/src/assemblers/assemblers.h b/src/assemblers/assemblers.h
new file mode 100644
index 0000000..4356068
--- /dev/null
+++ b/src/assemblers/assemblers.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 .
+ */
+
+/*! \file */
+
+#include "../types.h" // IRC_User IRC_Message
+
+#include // bool
+#include // size_t
+
+#ifndef UIRC_GUARD_PUBLIC_ASSEMBLERS
+#define UIRC_GUARD_PUBLIC_ASSEMBLERS
+
+signed long uirc_assembler_user(char* buf, IRC_User* u, size_t len);
+
+#ifdef UIRC_FEATURE_IRCV3
+signed long uirc_assembler_tag(char* buf, const IRC_Tag* t, size_t len);
+#endif /* UIRC_FEATURE_IRCV3*/
+
+/*!
+ * \brief IRC_Message to string converter
+ *
+ * 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[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
+ */
+signed long uirc_assembler_message(char* buf, IRC_Message* m, size_t len);
+#endif /* UIRC_GUARD_PUBLIC_ASSEMBLERS */
+
diff --git a/src/assemblers/message.c b/src/assemblers/message.c
new file mode 100644
index 0000000..6d3bb0c
--- /dev/null
+++ b/src/assemblers/message.c
@@ -0,0 +1,112 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../errors.h" // ERR_UIRC_*
+#include "../types.h" // IRC_Message
+#include "assemblers.h" // Assm_mesg() Assm_tags() Assm_user()
+
+#include // assert()
+#include // false
+#include // NULL, snprintf()
+#include // strlen()
+#include // size_t
+
+signed long
+uirc_assembler_message(char* buf, IRC_Message* m, size_t len)
+{
+ assert(buf != NULL);
+ assert(m != NULL);
+
+ char* const sv = buf;
+ signed long ret;
+
+#ifdef UIRC_FEATURE_IRCV3
+ if (m->tag_list != NULL && m->tag_list->content != NULL) {
+ for (llist_t* l = m->tag_list; l != NULL && l->content != NULL && ((IRC_Tag*) l->content)->key != NULL;) {
+ if (m->tag_list == l) {
+ if (len > 1) {
+ *(buf++) = '@';
+ len--;
+ } else
+ return UIRC_ERR_BUFFER_FULL;
+ } else {
+ if (len > 1) {
+ *(buf++) = ';';
+ len--;
+ } else
+ return UIRC_ERR_BUFFER_FULL;
+ }
+
+ if ((ret = uirc_assembler_tag(buf, l->content, len)) >= 0) {
+ buf += (size_t) ret;
+ len -= (size_t) ret;
+ } else
+ return ret;
+
+ if ((l = l->next) == NULL) {
+ if (len > 1) {
+ *(buf++) = ' ';
+ len--;
+ } else
+ return UIRC_ERR_BUFFER_FULL;
+ }
+ }
+ }
+#endif /* UIRC_FEATURE_IRCV3 */
+ if (m->source != NULL && (m->source->nick != NULL || m->source->host != NULL)) {
+ if (len > 1) {
+ *(buf++) = ':';
+ len--;
+ } else
+ return UIRC_ERR_BUFFER_FULL;
+
+ if ((ret = uirc_assembler_user(buf, m->source, len)) >= 0) {
+ buf += (size_t) ret;
+ len -= (size_t) ret;
+ } else
+ return ret;
+
+ if (len > 1) {
+ *(buf++) = ' ';
+ len--;
+ } else
+ return UIRC_ERR_BUFFER_FULL;
+ }
+
+ if (m->command != NULL) {
+ if (len < 2) return UIRC_ERR_BUFFER_FULL;
+ if ((ret = snprintf(buf, len, "%s ", m->command)) >= 0) {
+ buf += (size_t) ret;
+ len -= (size_t) ret;
+ } else
+ return UIRC_ERR_BUFFER_ERR;
+ } else
+ return UIRC_ERR_INVALID_FORMAT;
+
+ for (unsigned int i = 0; i < IRC_MAXARGS && m->args[i] != NULL; i++) {
+ if (len < 2) return UIRC_ERR_BUFFER_FULL;
+ if ((ret = snprintf(buf, len, (i + 1 == IRC_MAXARGS || (m->args[i + 1] == NULL && m->trailing)) ? ":%s" : "%s ", m->args[i])) >= 0) {
+ buf += (size_t) ret;
+ len -= (size_t) ret;
+ } else
+ return UIRC_ERR_BUFFER_ERR;
+ }
+
+ return (buf += ret) - sv;
+}
+
diff --git a/src/assemblers/tag.c b/src/assemblers/tag.c
new file mode 100644
index 0000000..5b42455
--- /dev/null
+++ b/src/assemblers/tag.c
@@ -0,0 +1,64 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../errors.h" // ERR_UIRC_*
+#include "../types.h" // IRC_Tag
+#include "assemblers.h" // Assm_user()
+
+#include // assert()
+#include // bool
+#include // size_t
+#include // NULL
+
+signed long
+uirc_assembler_tag(char* buf, const IRC_Tag* t, size_t len)
+{
+ assert(buf != NULL);
+ assert(t != NULL);
+ assert(t->key != NULL);
+
+ char* const sv = buf;
+ int res;
+
+ if (t->clientbound) {
+ if (len > 1) {
+ *(buf++) = '+';
+ len--;
+ } else
+ return UIRC_ERR_BUFFER_FULL;
+ }
+
+ if (len < 1) return UIRC_ERR_BUFFER_FULL;
+ if ((res = snprintf(buf, len, "%s", t->key)) >= 0) {
+ buf += (size_t) res;
+ len -= (size_t) res;
+ } else
+ return UIRC_ERR_BUFFER_ERR;
+
+ if (t->value != NULL) {
+ if (len < 1) return UIRC_ERR_BUFFER_FULL;
+ if ((res = snprintf(buf, len, "=%s", t->value)) >= 0) {
+ buf += (size_t) res;
+ len -= (size_t) res;
+ } else
+ return UIRC_ERR_BUFFER_ERR;
+ }
+
+ return buf - sv;
+}
+
diff --git a/src/assemblers/user.c b/src/assemblers/user.c
new file mode 100644
index 0000000..2c6f188
--- /dev/null
+++ b/src/assemblers/user.c
@@ -0,0 +1,63 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../errors.h" // ERR_UIRC_*
+#include "../types.h" // IRC_User
+#include "assemblers.h" // Assm_user()
+
+#include // assert()
+#include // bool
+#include // NULL
+#include // size_t
+
+signed long
+uirc_assembler_user(char* buf, IRC_User* u, size_t len)
+{
+ assert(buf != NULL);
+ assert(u != NULL);
+
+ ssize_t res;
+ char* const sv = buf;
+
+ if (u->nick != NULL) {
+ if (len < 1) return UIRC_ERR_BUFFER_FULL;
+ if ((res = snprintf(buf, len, "%s", u->nick)) >= 0) {
+ buf += (size_t) res;
+ len -= (size_t) res;
+ } else
+ return UIRC_ERR_BUFFER_ERR;
+ }
+ if (u->user != NULL) {
+ if (len < 1) return UIRC_ERR_BUFFER_FULL;
+ if ((res = snprintf(buf, len, "!%s", u->user)) >= 0) {
+ buf += (size_t) res;
+ len -= (size_t) res;
+ } else
+ return UIRC_ERR_BUFFER_ERR;
+ }
+ if (u->host != NULL) {
+ if (len < 1) return UIRC_ERR_BUFFER_FULL;
+ if ((res = snprintf(buf, len, (u->nick != NULL || u->user != NULL) ? "@%s" : "%s", u->host)) >= 0) {
+ buf += (size_t) res;
+ len -= (size_t) res;
+ } else
+ return UIRC_ERR_BUFFER_ERR;
+ }
+ return buf - sv;
+}
+
diff --git a/src/capabilities.c b/src/capabilities.c
deleted file mode 100644
index b11483d..0000000
--- a/src/capabilities.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "public/capabilities.h"
-
-#include "public/errors.h"
-
-#include
-#include
-#include
-
-const char* const IRC_v3_Caps[] = {
- [CAP_ACCOUNT_NOTIFY] = "account-notify",
- [CAP_ACCOUNT_TAG] = "account-tag",
- [CAP_AWAY_NOTIFY] = "away-notify",
- [CAP_BATCH] = "batch",
- [CAP_CAP_NOTIFY] = "cap-notify",
- [CAP_CHANNEL_RENAME] = "channel-rename",
- [CAP_CHGHOST] = "chghost",
- [CAP_ECHO_MESSAGE] = "echo-message",
- [CAP_EXTENDED_JOIN] = "extended-join",
- [CAP_INVITE_NOTIFY] = "invite-notify",
- [CAP_LABELED_RESPONSE] = "labeled-response",
- [CAP_MESSAGE_TAGS] = "message-tags",
- [CAP_MONITOR] = "monitor",
- [CAP_MULTI_PREFIX] = "multi-prefix",
- [CAP_MULTILINE] = "multiline",
- [CAP_SASL] = "sasl",
- [CAP_SERVER_TIME] = "server-time",
- [CAP_SETNAME] = "setname",
- [CAP_TLS] = "tls",
- [CAP_USERHOST_IN_NAMES] = "userhost-in-names",
-};
-
-#ifdef UIRC_HELPERS
-signed int
-Tok_CAPS(char* caps)
-{
- assert(caps != NULL);
- int temp = 0;
- char* cur = NULL;
- if ((cur = strtok(caps, " ")) != NULL) {
- do {
- for (int i = 1; (unsigned long) i < (sizeof(IRC_v3_Caps) / sizeof(*IRC_v3_Caps)); i++) {
- if (strcmp(IRC_v3_Caps[i], cur) == 0) {
- temp |= CAPBIT(i);
- break;
- }
- }
- } while ((cur = strtok(NULL, " ")) != NULL);
- }
- return temp;
-}
-#endif /* UIRC_HELPERS */
-
diff --git a/src/commands.c b/src/commands.c
deleted file mode 100644
index a97abda..0000000
--- a/src/commands.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "public/commands.h"
-
-const char* const IRC_Cmds[] = { [ADMIN] = "ADMIN", [AWAY] = "AWAY", [CONNECT] = "CONNECT", [DIE] = "DIE",
- [ERROR] = "ERROR", [INFO] = "INFO", [INVITE] = "INVITE", [ISON] = "ISON",
- [JOIN] = "JOIN", [KICK] = "KICK", [KILL] = "KILL", [LINKS] = "LINKS",
- [LIST] = "LIST", [LUSERS] = "LUSERS", [MODE] = "MODE", [MOTD] = "MOTD",
- [NAMES] = "NAMES", [NICK] = "NICK", [NOTICE] = "NOTICE", [OPER] = "OPER",
- [PART] = "PART", [PASS] = "PASS", [PING] = "PING", [PONG] = "PONG",
- [PRIVMSG] = "PRIVMSG", [QUIT] = "QUIT", [REHASH] = "REHASH", [RESTART] = "RESTART",
- [SERVER] = "SERVER", [SERVICE] = "SERVICE", [SERVLIST] = "SERVLIST", [SQUERY] = "SQUERY",
- [SQUIT] = "SQUIT", [STATS] = "STATS", [SUMMON] = "SUMMON", [TIME] = "TIME",
- [TOPIC] = "TOPIC", [TRACE] = "TRACE", [USERHOST] = "USERHOST", [USERS] = "USERS",
- [USER] = "USER", [VERSION] = "VERSION", [WALLOPS] = "WALLOPS", [WHOIS] = "WHOIS",
- [WHOWAS] = "WHOWAS", [WHO] = "WHO",
-#ifdef UIRC_IRCV3
- [ACCOUNT] = "ACCOUNT", [ACC] = "ACC", [ACK] = "ACK", [AUTHENTICATE] = "AUTHENTICATE",
- [BATCH] = "BATCH", [CAP] = "CAP", [CHGHOST] = "CHGHOST", [FAIL] = "FAIL",
- [MONITOR] = "MONITOR", [NOTE] = "NOTE", [RENAME] = "RENAME", [RESUME] = "RESUME",
- [SETNAME] = "SETNAME", [WARN] = "WARN", [WEBIRC] = "WEBIRC"
-#endif /* UIRC_IRCV3 */
-};
diff --git a/src/converters.c b/src/converters.c
deleted file mode 100644
index b9fd9fe..0000000
--- a/src/converters.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "public/converters.h"
-
-#include "public/commands.h"
-#include "public/errors.h"
-
-#include
-#include
-
-signed short
-Ircmd_stoi(const char* str)
-{
- assert(str != NULL);
- for (signed short i = UIRC_FCMD; i <= (signed short) UIRC_LCMD; i++) {
- if (IRC_Cmds[i] != NULL && strcmp(IRC_Cmds[i], str) == 0) return i;
- }
- return ERR_UIRC_UNKNOWN_TOKEN;
-}
diff --git a/src/ctcp.h b/src/ctcp.h
new file mode 100644
index 0000000..7359c58
--- /dev/null
+++ b/src/ctcp.h
@@ -0,0 +1,165 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 .
+ */
+
+/*! \file */
+#ifndef UIRC_GUARD_PUBLIC_CTCP
+#define UIRC_GUARD_PUBLIC_CTCP
+
+#ifdef UIRC_FEATURE_CTCP
+enum formatting {
+ IRC_CTCP_BOLD = 0x02,
+ IRC_CTCP_COLOR = 0x03,
+ IRC_CTCP_COLOR_HEX = 0x04,
+ IRC_CTCP_RESET = 0x0F,
+ IRC_CTCP_MONOSPACE = 0x11,
+ IRC_CTCP_REVERSE = 0x16,
+ IRC_CTCP_ITALICS = 0x1D,
+ IRC_CTCP_STRIKETHROUGH = 0x1E,
+ IRC_CTCP_UNDERLINE = 0x1F,
+};
+enum colors {
+ IRC_CTCP_COLORS_WHITE = 0,
+ IRC_CTCP_COLORS_BLACK = 1,
+ IRC_CTCP_COLORS_BLUE,
+ IRC_CTCP_COLORS_GREEN,
+ IRC_CTCP_COLORS_RED,
+ IRC_CTCP_COLORS_BROWN,
+ IRC_CTCP_COLORS_MAGENTA,
+ IRC_CTCP_COLORS_ORANGE,
+ IRC_CTCP_COLORS_YELLOW,
+ IRC_CTCP_COLORS_LIGHT_GREEN,
+ IRC_CTCP_COLORS_CYAN,
+ IRC_CTCP_COLORS_LIGHT_CYAN,
+ IRC_CTCP_COLORS_LIGHT_BLUE,
+ IRC_CTCP_COLORS_PINK,
+ IRC_CTCP_COLORS_GREY,
+ IRC_CTCP_COLORS_LIGHT_GREY,
+ IRC_CTCP_COLORS_DEFAULT = 99,
+};
+short UIRC_FORMAT_ANSI[] = {
+ [IRC_CTCP_COLORS_WHITE] = 97,
+ [IRC_CTCP_COLORS_BLACK] = 30,
+ [IRC_CTCP_COLORS_BLUE] = 34,
+ [IRC_CTCP_COLORS_GREEN] = 32,
+ [IRC_CTCP_COLORS_RED] = 31,
+ [IRC_CTCP_COLORS_BROWN] = 94,
+ [IRC_CTCP_COLORS_MAGENTA] = 35,
+ [IRC_CTCP_COLORS_ORANGE] = 166,
+ [IRC_CTCP_COLORS_YELLOW] = 33,
+ [IRC_CTCP_COLORS_LIGHT_GREEN] = 92,
+ [IRC_CTCP_COLORS_CYAN] = 36,
+ [IRC_CTCP_COLORS_LIGHT_CYAN] = 96,
+ [IRC_CTCP_COLORS_LIGHT_BLUE] = 94,
+ [IRC_CTCP_COLORS_PINK] = 127,
+ [IRC_CTCP_COLORS_GREY] = 90,
+ [IRC_CTCP_COLORS_LIGHT_GREY] = 37,
+ [IRC_CTCP_COLORS_DEFAULT] = 39,
+ [IRC_CTCP_BOLD] = 1,
+ [IRC_CTCP_RESET] = 0,
+ [IRC_CTCP_REVERSE] = 7,
+ [IRC_CTCP_ITALICS] = 3,
+ [IRC_CTCP_STRIKETHROUGH] = 9,
+ [IRC_CTCP_UNDERLINE] = 4,
+ [16] = 52, /* See https://modern.ircdocs.horse/formatting.html */
+ [17] = 94,
+ [18] = 100,
+ [19] = 58,
+ [20] = 22,
+ [21] = 29,
+ [22] = 23,
+ [23] = 24,
+ [24] = 17,
+ [25] = 54,
+ [26] = 53,
+ [27] = 89,
+ [28] = 88,
+ [29] = 130,
+ [30] = 142,
+ [31] = 64,
+ [32] = 28,
+ [33] = 35,
+ [34] = 30,
+ [35] = 25,
+ [36] = 18,
+ [37] = 91,
+ [38] = 90,
+ [39] = 125,
+ [40] = 124,
+ [41] = 166,
+ [42] = 184,
+ [43] = 106,
+ [44] = 34,
+ [45] = 49,
+ [46] = 37,
+ [47] = 33,
+ [48] = 19,
+ [49] = 129,
+ [50] = 127,
+ [51] = 161,
+ [52] = 196,
+ [53] = 208,
+ [54] = 226,
+ [55] = 154,
+ [56] = 46,
+ [57] = 86,
+ [58] = 51,
+ [59] = 75,
+ [60] = 21,
+ [61] = 171,
+ [62] = 201,
+ [63] = 198,
+ [64] = 203,
+ [65] = 215,
+ [66] = 227,
+ [67] = 191,
+ [68] = 83,
+ [69] = 122,
+ [70] = 87,
+ [71] = 111,
+ [72] = 63,
+ [73] = 177,
+ [74] = 207,
+ [75] = 205,
+ [76] = 217,
+ [77] = 223,
+ [78] = 229,
+ [79] = 193,
+ [80] = 157,
+ [81] = 158,
+ [82] = 159,
+ [83] = 153,
+ [84] = 147,
+ [85] = 183,
+ [86] = 219,
+ [87] = 212,
+ [88] = 16,
+ [89] = 233,
+ [90] = 235,
+ [91] = 237,
+ [92] = 239,
+ [93] = 241,
+ [94] = 244,
+ [95] = 247,
+ [96] = 250,
+ [97] = 254,
+ [98] = 231,
+};
+#endif /* UIRC_FEATURE_CTCP */
+
+#endif /* UIRC_GUARD_PUBLIC_CTCP */
+
diff --git a/src/public/errors.h b/src/errors.h
similarity index 76%
rename from src/public/errors.h
rename to src/errors.h
index beb04e7..0f71212 100644
--- a/src/public/errors.h
+++ b/src/errors.h
@@ -18,16 +18,15 @@
/*! \file */
-#ifndef UIRC_GUARD_ERRORS
-#define UIRC_GUARD_ERRORS
+#ifndef UIRC_GUARD_PUBLIC_ERRORS
+#define UIRC_GUARD_PUBLIC_ERRORS
enum uirc_errors {
- ERR_UIRC_GENERIC = -1,
- ERR_UIRC_INVALID_FORMAT = -2,
- ERR_UIRC_BUFFER_ERR = -3,
- ERR_UIRC_UNKNOWN_TOKEN = -4,
- ERR_UIRC_VAL_FAILED = -5,
+ UIRC_ERROR_GENERIC = -1,
+ UIRC_ERR_BUFFER_FULL = -2,
+ UIRC_ERR_BUFFER_ERR = -3,
+ UIRC_ERR_INVALID_FORMAT = -4,
};
-#endif /* UIRC_GUARD_ERRORS */
+#endif /* UIRC_GUARD_PUBLIC_ERRORS */
diff --git a/src/memory.c b/src/memory.c
deleted file mode 100644
index 3aad0c5..0000000
--- a/src/memory.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "private/memory.h"
-
-#include
-#include
-#include
-
-size_t
-safe_strcpy(char** dest, const char* src, size_t lef)
-{
- size_t cnt;
- if (lef > (cnt = strlen(src)) + 1) {
- strcpy(*dest, src);
- *dest += cnt;
- return cnt;
- } else
- return 0;
-}
-
-bool
-safe_charcpy(char** dest, const char c, size_t lef)
-{
- if (lef > 1) {
- *(*dest)++ = c;
- **dest = '\0';
- return 1;
- } else
- return 0;
-}
diff --git a/src/memory/memory.c b/src/memory/memory.c
new file mode 100644
index 0000000..bc1fe3f
--- /dev/null
+++ b/src/memory/memory.c
@@ -0,0 +1,91 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "memory.h"
+
+#include "../types.h" // IRC_*
+
+#include // assert()
+#include // llist_t remove_linked_list_elem()
+#include // malloc_string()
+#include // free()
+#include // strcpy()
+
+// TODO: Indicate failure of this at any step and free previous if that happens
+IRC_User*
+uirc_malloc_user(const char* nick, const char* user, const char* real)
+{
+ IRC_User* ret;
+ if ((ret = malloc(sizeof(IRC_User))) != NULL) {
+ ret->nick = (nick == NULL) ? NULL : malloc_string(nick, strlen(nick));
+ ret->user = (user == NULL) ? NULL : malloc_string(user, strlen(user));
+ ret->real = (real == NULL) ? NULL : malloc_string(real, strlen(real));
+ return ret;
+ } else
+ return NULL;
+}
+
+llist_t*
+uirc_malloc_tag(llist_t* prev, const char* key, const char* value)
+{
+ llist_t* tmp = NULL;
+ if ((tmp = allocate_linked_list_elem(sizeof(IRC_Tag))) == NULL) return NULL;
+ if (prev != NULL) prev->next = tmp;
+ ((IRC_Tag*) tmp->content)->key = malloc_string(key, strlen(key));
+ ((IRC_Tag*) tmp->content)->value = malloc_string(value, strlen(value));
+ return tmp;
+}
+
+void
+uirc_free_tag(IRC_Tag* t)
+{
+ assert(t != NULL);
+ free(t->key);
+ free(t->value);
+}
+
+void
+uirc_free_user(IRC_User* u)
+{
+ assert(u != NULL);
+ free(u->user);
+ free(u->nick);
+ free(u->real);
+}
+
+void
+uirc_free_message(IRC_Message* m)
+{
+ assert(m != NULL);
+
+ free(m->command);
+
+ for (unsigned short i = 0; m->args[i] != NULL; i++) free(m->args[i]);
+
+ llist_t* t = m->tag_list;
+ for (; t != NULL; t = t->next) {
+ uirc_free_tag(t->content);
+ remove_linked_list_elem(t);
+ }
+
+ if (m->source != NULL) {
+ uirc_free_user(m->source);
+ free(m->source);
+ }
+}
+
diff --git a/src/public/tags.h b/src/memory/memory.h
similarity index 61%
rename from src/public/tags.h
rename to src/memory/memory.h
index 72fc4ce..3116755 100644
--- a/src/public/tags.h
+++ b/src/memory/memory.h
@@ -18,13 +18,18 @@
/*! \file */
-#include
+#include "../types.h" // IRC_Tag IRC_User IRC_Meesage
-#ifndef UIRC_GUARD_TAGS
-#define UIRC_GUARD_TAGS
+#include // llist_t
-#ifdef UIRC_HELPERS
-size_t Assm_tag_timestamp(char* buf, size_t len, time_t time);
-#endif /* UIRC_HELPERS */
+#ifndef UIRC_GUARD_PUBLIC_MEMORY
+#define UIRC_GUARD_PUBLIC_MEMORY
+
+IRC_User* uirc_malloc_user(const char* nick, const char* user, const char* real);
+llist_t* uirc_malloc_tag(llist_t* prev, const char* key, const char* value);
+void uirc_free_tag(IRC_Tag* t);
+void uirc_free_user(IRC_User* u);
+void uirc_free_message(IRC_Message* m);
+
+#endif /* UIRC_GUARD_PUBLIC_MEMORY */
-#endif /* UIRC_GUARD_TAGS */
diff --git a/src/public/modes.h b/src/modes.h
similarity index 74%
rename from src/public/modes.h
rename to src/modes.h
index a67877c..eab46e8 100644
--- a/src/public/modes.h
+++ b/src/modes.h
@@ -18,12 +18,15 @@
/*! \file */
-#ifndef UIRC_GUARD_MODES
-#define UIRC_GUARD_MODES
+#ifndef UIRC_GUARD_PUBLIC_MODES
+#define UIRC_GUARD_PUBLIC_MODES
-/* Mode bitmask values */
-#define MBMASK_WALLOPS 1 << 1 /* 010 */
-#define MBMASK_INVIS 1 << 2 /* 100 */
+/* Mode bitmask positions */
+// TODO: Add all modes in this bitmask
+#define IRC_MODE_WALLOPS 1
+#define IRC_MODE_INVIS 2
-#endif /* UIRC_GUARD_MODES */
+#define MBMASK(MODEBIT) (1 << MODEBIT)
+
+#endif /* UIRC_GUARD_PUBLIC_MODES */
diff --git a/src/private/mappings.h b/src/private/mappings.h
deleted file mode 100644
index ae13096..0000000
--- a/src/private/mappings.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/types.h"
-
-#include
-#include
-#include
-
-#ifndef UIRC_GUARD_MAPPINGS
-#define UIRC_GUARD_MAPPINGS
-
-#ifdef UIRC_IRCV3
-struct tagmapping {
- const char* const name;
- IRC_Tag* assg;
-};
-#endif /* UIRC_IRCV3 */
-
-#endif /* UIRC_GUARD_MAPPINGS */
diff --git a/src/private/string.h b/src/private/string.h
deleted file mode 100644
index 8639f02..0000000
--- a/src/private/string.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 .
- */
-
-#ifndef UIRC_GUARD_STRING
-#define UIRC_GUARD_STRING
-
-void skip_spaces(char** addr);
-char* strtok_mr(char** addr, const char* tokens);
-
-#endif /* UIRC_GUARD_STRING */
-
diff --git a/src/public/assemblers.h b/src/public/assemblers.h
deleted file mode 100644
index dfe8bd6..0000000
--- a/src/public/assemblers.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 .
- */
-
-/*! \file */
-
-#include "types.h"
-
-#include
-
-#ifndef UIRC_GUARD_ASSEMBLERS
-#define UIRC_GUARD_ASSEMBLERS
-
-signed long Assm_user(char* buf, IRC_User* in, size_t len, bool useorig);
-
-#ifdef UIRC_IRCV3
-signed long Assm_tags(char* buf, IRC_Tags* in, size_t len);
-#endif /* UIRC_IRCV3*/
-
-/*!
- * \brief IRC_Message to string converter
- *
- * 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[in] in 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
- */
-signed long Assm_mesg(char* buf, IRC_Message* in, size_t len);
-
-#ifdef UIRC_HELPERS
-IRC_Message* Assm_AUTO(IRC_Message* imassm_mesg, IRC_Command cmd, bool trailing, char** args, int req);
-IRC_Message* Assm_cmd_USER(IRC_Message* imassm_mesg, char* user, char* realname, int modes);
-IRC_Message* Assm_cmd_LINKS(IRC_Message* imassm_mesg, char* remoteserv, char* servmask);
-IRC_Message* Assm_cmd_WHO(IRC_Message* imassm_mesg, char* mask, bool oper);
-IRC_Message* Assm_cmd_WHOIS(IRC_Message* imassm_mesg, char* target, char* mask);
-IRC_Message* Assm_cmd_WHOWAS(IRC_Message* imassm_mesg, char* nick, char* count, char* target);
-IRC_Message* Assm_cmd_PING(IRC_Message* imassm_mesg, char* source, char* target);
-IRC_Message* Assm_cmd_SUMMON(IRC_Message* imassm_mesg, char* user, char* target, char* channel);
-IRC_Message* Assm_cmd_USERHOST(IRC_Message* imassm_mesg, char* users[]);
-IRC_Message* Assm_cmd_ISON(IRC_Message* imassm_mesg, char* users[]);
-
-#define Assm_cmd_REHASH(mesg) Assm_AUTO(mesg, REHASH, false, (char*[]) { NULL }, 0)
-#define Assm_cmd_DIE(mesg) Assm_AUTO(mesg, DIE, false, (char*[]) { NULL }, 0)
-#define Assm_cmd_RESTART(mesg) Assm_AUTO(mesg, RESTART, false, (char*[]) { NULL }, 0)
-
-#define Assm_cmd_QUIT(mesg, message) Assm_AUTO(mesg, QUIT, true, (char*[]) { message, NULL }, 0)
-#define Assm_cmd_MOTD(mesg, target) Assm_AUTO(mesg, MOTD, false, (char*[]) { target, NULL }, 0)
-#define Assm_cmd_VERSION(mesg, target) Assm_AUTO(mesg, VERSION, false, (char*[]) { target, NULL }, 0)
-#define Assm_cmd_TIME(mesg, target) Assm_AUTO(mesg, TIME, false, (char*[]) { target, NULL }, 0)
-#define Assm_cmd_TRACE(mesg, target) Assm_AUTO(mesg, TRACE, false, (char*[]) { target, NULL }, 0)
-#define Assm_cmd_ADMIN(mesg, target) Assm_AUTO(mesg, ADMIN, false, (char*[]) { target, NULL }, 0)
-#define Assm_cmd_INFO(mesg, target) Assm_AUTO(mesg, INFO, false, (char*[]) { target, NULL }, 0)
-#define Assm_cmd_AWAY(mesg, message) Assm_AUTO(mesg, AWAY, false, (char*[]) { message, NULL }, 0)
-
-#define Assm_cmd_PASS(mesg, password) Assm_AUTO(mesg, PASS, true, (char*[]) { password, NULL }, 1)
-#define Assm_cmd_ERROR(mesg, message) Assm_AUTO(mesg, ERROR, true, (char*[]) { message, NULL }, 1)
-#define Assm_cmd_WALLOPS(mesg, text) Assm_AUTO(mesg, WALLOPS, true, (char*[]) { text, NULL }, 1)
-#define Assm_cmd_NICK(mesg, nickname) Assm_AUTO(mesg, NICK, false, (char*[]) { nickname, NULL }, 1)
-#define Assm_cmd_USERS(mesg, target) Assm_AUTO(mesg, USERS, false, (char*[]) { target, NULL }, 1)
-
-#define Assm_cmd_NAMES(mesg, channels, target) Assm_AUTO(mesg, NAMES, false, (char*[]) { channels, target, NULL }, 0)
-#define Assm_cmd_LIST(mesg, channels, target) Assm_AUTO(mesg, LIST, false, (char*[]) { channels, target, NULL }, 0)
-#define Assm_cmd_LUSERS(mesg, mask, target) Assm_AUTO(mesg, LUSERS, false, (char*[]) { mask, target, NULL }, 0)
-#define Assm_cmd_STATS(mesg, query, target) Assm_AUTO(mesg, STATS, false, (char*[]) { query, target, NULL }, 0)
-#define Assm_cmd_SERVLIST(mesg, mask, type) Assm_AUTO(mesg, SERVLIST, false, (char*[]) { mask, type, NULL }, 0)
-
-#define Assm_cmd_JOIN(mesg, channels, keys) Assm_AUTO(mesg, JOIN, false, (char*[]) { channels, keys, NULL }, 1)
-#define Assm_cmd_PART(mesg, channel, message) Assm_AUTO(mesg, PART, false, (char*[]) { channel, message, NULL }, 1)
-/* NOTE: Use a non-NULL address (pointing at a "\0") as the topic to clear it and use a NULL address to check it
- * Blame the protocol, not this >:C */
-#define Assm_cmd_TOPIC(mesg, channel, topic) Assm_AUTO(mesg, TOPIC, true, (char*[]) { channel, topic, NULL }, 1)
-#define Assm_cmd_PONG(mesg, source, target) Assm_AUTO(mesg, PONG, true, (char*[]) { source, target, NULL }, 1)
-
-#define Assm_cmd_OPER(mesg, name, password) Assm_AUTO(mesg, OPER, true, (char*[]) { name, password, NULL }, 2)
-#define Assm_cmd_SQUIT(mesg, server, comment) Assm_AUTO(mesg, SQUIT, true, (char*[]) { server, comment, NULL }, 2)
-#define Assm_cmd_PRIVMSG(mesg, target, message) Assm_AUTO(mesg, PRIVMSG, true, (char*[]) { target, message, NULL }, 2)
-#define Assm_cmd_NOTICE(mesg, target, text) Assm_AUTO(mesg, NOTICE, true, (char*[]) { target, text, NULL }, 2)
-#define Assm_cmd_SQUERY(mesg, servicename, text) Assm_AUTO(mesg, SQUERY, true, (char*[]) { servicename, text, NULL }, 2)
-#define Assm_cmd_KILL(mesg, nick, comment) Assm_AUTO(mesg, KILL, true, (char*[]) { nick, comment, NULL }, 2)
-#define Assm_cmd_INVITE(mesg, nick, channel) Assm_AUTO(mesg, INVITE, false, (char*[]) { nick, channel, NULL }, 2)
-
-#define Assm_cmd_MODE(mesg, nickname, modes, modeparams) Assm_AUTO(mesg, MODE, false, (char*[]) { nickname, modes, modeparams, NULL }, 1)
-
-#define Assm_cmd_KICK(mesg, channels, users, comment) Assm_AUTO(mesg, KICK, true, (char*[]) { channels, users, comment, NULL }, 2)
-#define Assm_cmd_CONNECT(mesg, target, port, remote) Assm_AUTO(mesg, CONNECT, false, (char*[]) { target, port, remote, NULL }, 2)
-
-#define Assm_cmd_SERVICE(mesg, nickname, distribution, type, info) \
- Assm_AUTO(mesg, SERVICE, true, (char*[]) { nickname, RESERVED, distribution, "0", RESERVED, info, NULL }, 6)
-
-#ifdef UIRC_IRCV3
-#define Assm_cmd_CAP_END(mesg) Assm_AUTO(mesg, CAP, false, (char*[]) { "END", NULL }, 0)
-#define Assm_cmd_CAP_LIST(mesg) Assm_AUTO(mesg, CAP, false, (char*[]) { "LIST", NULL }, 0)
-
-#define Assm_cmd_CAP_LS(mesg, version) Assm_AUTO(mesg, CAP, false, (char*[]) { "LS", version, NULL }, 0)
-#define Assm_cmd_CAP_REQ(mesg, caps) Assm_AUTO(mesg, CAP, true, (char*[]) { "REQ", caps, NULL }, 1)
-
-#define Assm_cmd_CAP_NEW(mesg, nick, caps) Assm_AUTO(mesg, CAP, true, (char*[]) { "NEW", nick, caps, NULL }, 2)
-#define Assm_cmd_CAP_DEL(mesg, nick, caps) Assm_AUTO(mesg, CAP, true, (char*[]) { "DEL", nick, caps, NULL }, 2)
-#endif /* UIRC_IRCV3 */
-#endif /* UIRC_HELPERS */
-
-#endif /* UIRC_GUARD_ASSEMBLERS */
-
diff --git a/src/public/capabilities.h b/src/public/capabilities.h
deleted file mode 100644
index 731af18..0000000
--- a/src/public/capabilities.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 .
- */
-
-/*! \file */
-
-#ifndef UIRC_GUARD_CAPABILITIES
-#define UIRC_GUARD_CAPABILITIES
-
-/*!
- * \brief Converts capability to bitmask value
- *
- * \param[in] cap Capability bit from \link caps \endlink
- */
-#define CAPBIT(cap) (1 << (cap))
-
-/*!
- * \brief List of capabilities to be used as a bitmask
- *
- * \sa CAPBIT
- * \sa https://ircv3.net/registry#capabilities
- */
-enum caps {
- CAP_ACCOUNT_NOTIFY,
- CAP_ACCOUNT_TAG,
- CAP_AWAY_NOTIFY,
- CAP_BATCH,
- CAP_CAP_NOTIFY,
- CAP_CHANNEL_RENAME,
- CAP_CHGHOST,
- CAP_ECHO_MESSAGE,
- CAP_EXTENDED_JOIN,
- CAP_INVITE_NOTIFY,
- CAP_LABELED_RESPONSE,
- CAP_MESSAGE_TAGS,
- CAP_MONITOR,
- CAP_MULTI_PREFIX,
- CAP_MULTILINE,
- CAP_SASL,
- CAP_SERVER_TIME,
- CAP_SETNAME,
- CAP_TLS,
- CAP_USERHOST_IN_NAMES,
-};
-#ifdef UIRC_HELPERS
-/*!
- * \brief Converts a string of capabilities to a bitmask
- *
- * This function converts all the capabilities from \link IRC_v3_Caps \endlink to a bitmask
- * \param[in] caps String of capabilities separated by space
- * \sa CAPBIT
- * \sa caps
- * \sa https://ircv3.net/registry#capabilities
- */
-signed int Tok_CAPS(char* caps);
-#endif /* UIRC_HELPERS */
-
-/*!
- * \brief String representations of IRCv3 capabilities
- *
- * This contains the capabilities from \link caps \endlink in their string form.
- * \sa https://ircv3.net/registry#capabilities
- */
-extern const char* const IRC_v3_Caps[];
-
-#endif /* UIRC_GUARD_CAPABILITIES */
-
diff --git a/src/public/commands.h b/src/public/commands.h
deleted file mode 100644
index 030c3f5..0000000
--- a/src/public/commands.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 .
- */
-
-/*! \file */
-
-#ifndef UIRC_GUARD_COMMANDS
-#define UIRC_GUARD_COMMANDS
-
-#define UIRC_FCMD ADMIN
-/*!
- * \brief List of possible string commands
- *
- * This contains all the commands defined by RFC2812 (LIST, TIME, NAMES, QUIT ...) and extra ones defined by submodules
- * It is used for mapping string commands to integers instead of storing them as strings
- */
-enum commands {
- /*! Used to find information about the administrator of the given server, or current server */
- ADMIN = 10,
- /*! Clients can set an automatic reply string for any PRIVMSG commands directed at them */
- AWAY,
- /*! Used to request a server to try to establish a new connection to another server immediately */
- CONNECT,
- /*! Shutdown the server */
- DIE,
- /*! Used by servers when reporting a serious or fatal error to its peers */
- ERROR,
- /*! Return information describing the server */
- INFO,
- /*! Invite a user to a channel */
- INVITE,
- /*! Checks whether a given nickname is currently on IRC */
- ISON,
- /*! Request to start listening to the specific channel */
- JOIN,
- /*! Request the forced removal of a user from a channel */
- KICK,
- /*! Closes client-server connection */
- KILL,
- /*! List all servernames */
- LINKS,
- /*! List channels and their topics */
- LIST,
- /*! Get statistics about the size of the IRC network */
- LUSERS,
- /*! Query and change the characteristics of a channel */
- MODE,
- /*! Get the "Message Of The Day" of the given server */
- MOTD,
- /*! List all nicknames that are visible to him */
- NAMES,
- /*! Give user a nickname or change the existing one */
- NICK,
- /*! Similar to PRIVMSG but without automatic replies
- * \sa PRIVMSG */
- NOTICE,
- /*! Obtain operator privileges */
- OPER,
- /*! User sending the message is removed from the list of active members */
- PART,
- /*! Set connection password */
- PASS,
- /*! Test the presence of an active client or server at the other end of the connection
- * \sa PING */
- PING,
- /*! Reply to ping message
- * \sa PONG */
- PONG,
- /*! Send private messages between users or channels
- * \sa NOTICE */
- PRIVMSG,
- // TODO: Document the lines below
- QUIT,
- REHASH,
- RESTART,
- SERVER,
- SERVICE,
- SERVLIST,
- SQUERY,
- SQUIT,
- STATS,
- SUMMON,
- TIME,
- TOPIC,
- TRACE,
- USER,
- USERHOST,
- USERS,
- VERSION,
- WALLOPS,
- WHO,
- WHOIS,
- WHOWAS,
-#ifdef UIRC_IRCV3
- /*! \sa https://github.com/ircv3/ircv3-specifications/pull/276 */
- ACC,
- /*! \sa https://ircv3.net/specs/extensions/account-notify-3.1 */
- ACCOUNT,
- /*! \sa https://ircv3.net/specs/extensions/labeled-response */
- ACK,
- /*! \sa https://ircv3.net/specs/extensions/sasl-3.1 */
- AUTHENTICATE,
- /*! \sa https://ircv3.net/specs/extensions/batch-3.2 */
- BATCH,
- /*! \sa https://ircv3.net/specs/core/capability-negotiation */
- CAP,
- /*! \sa https://ircv3.net/specs/extensions/chghost-3.2 */
- CHGHOST,
- /*! \sa https://ircv3.net/specs/extensions/standard-replies */
- FAIL,
- /*! \sa https://ircv3.net/specs/core/monitor-3.2 */
- MONITOR,
- /*! \sa https://ircv3.net/specs/extensions/standard-replies */
- NOTE,
- /*! \sa https://github.com/ircv3/ircv3-specifications/pull/420 */
- RENAME,
- /*! \sa https://github.com/ircv3/ircv3-specifications/pull/306 */
- RESUME,
- /*! \sa https://ircv3.net/specs/extensions/setname */
- SETNAME,
- /*! \sa https://ircv3.net/specs/extensions/standard-replies */
- WARN,
- /*! \sa https://ircv3.net/specs/extensions/webirc */
- WEBIRC,
-#define UIRC_LCMD WEBIRC
-#else /* UIRC_IRCV3 */
-#define UIRC_LCMD WHOWAS
-#endif /* UIRC_IRCV3 */
-};
-extern const char* const IRC_Cmds[];
-
-#endif /* UIRC_GUARD_COMMANDS */
diff --git a/src/public/converters.h b/src/public/converters.h
deleted file mode 100644
index 63f4135..0000000
--- a/src/public/converters.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 .
- */
-
-/*! \file */
-
-#ifndef UIRC_GUARD_CONVERTERS
-#define UIRC_GUARD_CONVERTERS
-
-signed short Ircmd_stoi(const char* str);
-
-#endif /* UIRC_GUARD_CONVERTERS */
diff --git a/src/public/replies.h b/src/public/replies.h
deleted file mode 100644
index 757a979..0000000
--- a/src/public/replies.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 .
- */
-
-/*! \file */
-
-#ifndef UIRC_GUARD_REPLIES
-#define UIRC_GUARD_REPLIES
-
-enum replies {
- RPL_WELCOME = 1,
- RPL_YOURHOST = 2,
- RPL_CREATED = 3,
- RPL_MYINFO = 4,
- RPL_BOUNCE = 5,
-
-#ifdef UIRC_IRCV3
- /* TO IRCv3 WG:
- * Please, stop complicating implementations
- * Get people in the WG that actually care about the protocol and understand why and how standards are written
- *
- * TO LIBRARY USERS:
- * Read the above and go speak with them, or just don't use IRCv3 :)
- */
- RPL_ISUPPORT = 5,
-#endif /* UIRC_IRCV3 */
-
- RPL_TRACELINK = 200,
- RPL_TRACECONNECTING = 201,
- RPL_TRACEHANDSHAKE = 202,
- RPL_TRACEUNKNOWN = 203,
- RPL_TRACEOPERATOR = 204,
- RPL_TRACEUSER = 205,
- RPL_TRACESERVER = 206,
- RPL_TRACENEWTYPE = 208,
- RPL_STATSLINKINFO = 211,
- RPL_STATSCOMMANDS = 212,
- RPL_STATSCLINE = 213,
- RPL_STATSNLINE = 214,
- RPL_STATSILINE = 215,
- RPL_STATSKLINE = 216,
- RPL_STATSYLINE = 218,
- RPL_ENDOFSTATS = 219,
- RPL_UMODEIS = 221,
- RPL_STATSLLINE = 241,
- RPL_STATSUPTIME = 242,
- RPL_STATSOLINE = 243,
- RPL_STATSHLINE = 244,
- RPL_LUSERCLIENT = 251,
- RPL_LUSEROP = 252,
- RPL_LUSERUNKNOWN = 253,
- RPL_LUSERCHANNELS = 254,
- RPL_LUSERME = 255,
- RPL_ADMINME = 256,
- RPL_ADMINLOC1 = 257,
- RPL_ADMINLOC2 = 258,
- RPL_ADMINEMAIL = 259,
- RPL_TRACELOG = 261,
- RPL_NONE = 300,
- RPL_AWAY = 301,
- RPL_USERHOST = 302,
- RPL_ISON = 303,
- RPL_UNAWAY = 305,
- RPL_NOWAWAY = 306,
- RPL_WHOISUSER = 311,
- RPL_WHOISSERVER = 312,
- RPL_WHOISOPERATOR = 313,
- RPL_WHOWASUSER = 314,
- RPL_ENDOFWHO = 315,
- RPL_WHOISIDLE = 317,
- RPL_ENDOFWHOIS = 318,
- RPL_WHOISCHANNELS = 319,
- RPL_LISTSTART = 321,
- RPL_LIST = 322,
- RPL_LISTEND = 323,
- RPL_CHANNELMODEIS = 324,
- RPL_NOTOPIC = 331,
- RPL_TOPIC = 332,
- RPL_INVITING = 341,
- RPL_SUMMONING = 342,
- RPL_VERSION = 351,
- RPL_WHOREPLY = 352,
- RPL_NAMREPLY = 353,
- RPL_LINKS = 364,
- RPL_ENDOFLINKS = 365,
- RPL_ENDOFNAMES = 366,
- RPL_BANLIST = 367,
- RPL_ENDOFBANLIST = 368,
- RPL_ENDOFWHOWAS = 369,
- RPL_INFO = 371,
- RPL_MOTD = 372,
- RPL_ENDOFINFO = 374,
- RPL_MOTDSTART = 375,
- RPL_ENDOFMOTD = 376,
- RPL_YOUREOPER = 381,
- RPL_REHASHING = 382,
- RPL_TIME = 391,
- RPL_USERSSTART = 392,
- RPL_USERS = 393,
- RPL_ENDOFUSERS = 394,
- RPL_NOUSERS = 395,
-
- ERR_NOSUCHNICK = 401,
- ERR_NOSUCHSERVER = 402,
- ERR_NOSUCHCHANNEL = 403,
- ERR_CANNOTSENDTOCHAN = 404,
- ERR_TOOMANYCHANNELS = 405,
- ERR_WASNOSUCHNICK = 406,
- ERR_TOOMANYTARGETS = 407,
- ERR_NOORIGIN = 409,
- ERR_NORECIPIENT = 411,
- ERR_NOTEXTTOSEND = 412,
- ERR_NOTOPLEVEL = 413,
- ERR_WILDTOPLEVEL = 414,
- ERR_UNKNOWNCOMMAND = 421,
- ERR_NOMOTD = 422,
- ERR_NOADMININFO = 423,
- ERR_FILEERROR = 424,
- ERR_NONICKNAMEGIVEN = 431,
- ERR_ERRONEUSNICKNAME = 432,
- ERR_NICKNAMEINUSE = 433,
- ERR_NICKCOLLISION = 436,
- ERR_USERNOTINCHANNEL = 441,
- ERR_NOTONCHANNEL = 442,
- ERR_USERONCHANNEL = 443,
- ERR_NOLOGIN = 444,
- ERR_SUMMONDISABLED = 445,
- ERR_USERSDISABLED = 446,
- ERR_NOTREGISTERED = 451,
- ERR_NEEDMOREPARAMS = 461,
- ERR_ALREADYREGISTRED = 462,
- ERR_NOPERMFORHOST = 463,
- ERR_PASSWDMISMATCH = 464,
- ERR_YOUREBANNEDCREEP = 465,
- ERR_KEYSET = 467,
- ERR_CHANNELISFULL = 471,
- ERR_UNKNOWNMODE = 472,
- ERR_INVITEONLYCHAN = 473,
- ERR_BANNEDFROMCHAN = 474,
- ERR_BADCHANNELKEY = 475,
- ERR_NOPRIVILEGES = 481,
- ERR_CHANOPRIVSNEEDED = 482,
- ERR_CANTKILLSERVER = 483,
- ERR_NOOPERHOST = 491,
- ERR_UMODEUNKNOWNFLAG = 501,
- ERR_USERSDONTMATCH = 502,
-
-#ifdef UIRC_IRCV3
- /* https://ircv3.net/registry */
- RPL_STARTTLS = 670,
- ERR_STARTTLS = 691,
-
- RPL_MONONLINE = 730,
- RPL_MONOFFLINE = 731,
- RPL_MONLIST = 732,
- RPL_ENDOFMONLIST = 733,
- ERR_MOLISTFULL = 734,
-
- RPL_LOGGEDIN = 900,
- RPL_LOGGEDOUT = 901,
- ERR_NICKLOCKED = 902,
- RPL_SASLSUCCESS = 903,
- ERR_SASLFAIL = 904,
- ERR_SASLTOOLONG = 905,
- ERR_SASLABORTED = 906,
- ERR_SASLALREADY = 907,
- ERR_SASLMECHS = 908,
-#endif /* UIRC_IRCV3 */
-};
-
-#endif /* UIRC_GUARD_REPLIES */
-
diff --git a/src/public/types.h b/src/public/types.h
deleted file mode 100644
index 35fa1fc..0000000
--- a/src/public/types.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 .
- */
-
-/*! \file */
-
-#include
-
-#ifndef UIRC_GUARD_TYPES
-#define UIRC_GUARD_TYPES
-
-/*!
- */
-typedef unsigned short IRC_Command;
-
-#ifdef UIRC_IRCV3
-typedef struct {
- char* value; /* if present, it isn't NULL and if it has no value, it is "" */
- bool clientbound;
-} IRC_Tag;
-typedef struct {
- /* See https://ircv3.net/registry#tags for more information */
- IRC_Tag account, batch, label, msgid, multiline_concat, time, typing, react, reply;
-} IRC_Tags;
-#endif /* UIRC_IRCV3 */
-
-typedef struct {
- char *nick, *user, *host, *orig, *real;
-} IRC_User;
-typedef struct {
-#ifdef UIRC_IRCV3
- IRC_Tags tags;
-#endif /* UIRC_IRCV3 */
- IRC_User name;
- char* args[16]; /* 0-13 + trailing + NULL */
- bool trailing; /* Tells if the last argument is trailing */
- IRC_Command cmd;
-} IRC_Message;
-
-#endif /* UIRC_GUARD_TYPES */
-
diff --git a/src/replies.h b/src/replies.h
new file mode 100644
index 0000000..aabf015
--- /dev/null
+++ b/src/replies.h
@@ -0,0 +1,186 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 .
+ */
+
+/*! \file */
+
+#ifndef UIRC_GUARD_PUBLIC_REPLIES
+#define UIRC_GUARD_PUBLIC_REPLIES
+
+enum replies {
+ IRC_RPL_WELCOME = 1,
+ IRC_RPL_YOURHOST = 2,
+ IRC_RPL_CREATED = 3,
+ IRC_RPL_MYINFO = 4,
+ IRC_RPL_BOUNCE = 5,
+
+#ifdef UIRC_FEATURE_IRCV3
+ /* TO IRCv3 WG:
+ * Please, stop complicating implementations
+ * Get people in the WG that actually care about the protocol and understand why and how standards are written
+ *
+ * TO LIBRARY USERS:
+ * Read the above and go speak with them, or just don't use IRCv3 :)
+ */
+ IRC_RPL_ISUPPORT = 5,
+#endif /* UIRC_FEATURE_IRCV3 */
+
+ IRC_RPL_TRACELINK = 200,
+ IRC_RPL_TRACECONNECTING = 201,
+ IRC_RPL_TRACEHANDSHAKE = 202,
+ IRC_RPL_TRACEUNKNOWN = 203,
+ IRC_RPL_TRACEOPERATOR = 204,
+ IRC_RPL_TRACEUSER = 205,
+ IRC_RPL_TRACESERVER = 206,
+ IRC_RPL_TRACENEWTYPE = 208,
+ IRC_RPL_STATSLINKINFO = 211,
+ IRC_RPL_STATSCOMMANDS = 212,
+ IRC_RPL_STATSCLINE = 213,
+ IRC_RPL_STATSNLINE = 214,
+ IRC_RPL_STATSILINE = 215,
+ IRC_RPL_STATSKLINE = 216,
+ IRC_RPL_STATSYLINE = 218,
+ IRC_RPL_ENDOFSTATS = 219,
+ IRC_RPL_UMODEIS = 221,
+ IRC_RPL_STATSLLINE = 241,
+ IRC_RPL_STATSUPTIME = 242,
+ IRC_RPL_STATSOLINE = 243,
+ IRC_RPL_STATSHLINE = 244,
+ IRC_RPL_LUSERCLIENT = 251,
+ IRC_RPL_LUSEROP = 252,
+ IRC_RPL_LUSERUNKNOWN = 253,
+ IRC_RPL_LUSERCHANNELS = 254,
+ IRC_RPL_LUSERME = 255,
+ IRC_RPL_ADMINME = 256,
+ IRC_RPL_ADMINLOC1 = 257,
+ IRC_RPL_ADMINLOC2 = 258,
+ IRC_RPL_ADMINEMAIL = 259,
+ IRC_RPL_TRACELOG = 261,
+ IRC_RPL_NONE = 300,
+ IRC_RPL_AWAY = 301,
+ IRC_RPL_USERHOST = 302,
+ IRC_RPL_ISON = 303,
+ IRC_RPL_UNAWAY = 305,
+ IRC_RPL_NOWAWAY = 306,
+ IRC_RPL_WHOISUSER = 311,
+ IRC_RPL_WHOISSERVER = 312,
+ IRC_RPL_WHOISOPERATOR = 313,
+ IRC_RPL_WHOWASUSER = 314,
+ IRC_RPL_ENDOFWHO = 315,
+ IRC_RPL_WHOISIDLE = 317,
+ IRC_RPL_ENDOFWHOIS = 318,
+ IRC_RPL_WHOISCHANNELS = 319,
+ IRC_RPL_LISTSTART = 321,
+ IRC_RPL_LIST = 322,
+ IRC_RPL_LISTEND = 323,
+ IRC_RPL_CHANNELMODEIS = 324,
+ IRC_RPL_NOTOPIC = 331,
+ IRC_RPL_TOPIC = 332,
+ IRC_RPL_INVITING = 341,
+ IRC_RPL_SUMMONING = 342,
+ IRC_RPL_VERSION = 351,
+ IRC_RPL_WHOREPLY = 352,
+ IRC_RPL_NAMREPLY = 353,
+ IRC_RPL_LINKS = 364,
+ IRC_RPL_ENDOFLINKS = 365,
+ IRC_RPL_ENDOFNAMES = 366,
+ IRC_RPL_BANLIST = 367,
+ IRC_RPL_ENDOFBANLIST = 368,
+ IRC_RPL_ENDOFWHOWAS = 369,
+ IRC_RPL_INFO = 371,
+ IRC_RPL_MOTD = 372,
+ IRC_RPL_ENDOFINFO = 374,
+ IRC_RPL_MOTDSTART = 375,
+ IRC_RPL_ENDOFMOTD = 376,
+ IRC_RPL_YOUREOPER = 381,
+ IRC_RPL_REHASHING = 382,
+ IRC_RPL_TIME = 391,
+ IRC_RPL_USERSSTART = 392,
+ IRC_RPL_USERS = 393,
+ IRC_RPL_ENDOFUSERS = 394,
+ IRC_RPL_NOUSERS = 395,
+
+ IRC_ERR_NOSUCHNICK = 401,
+ IRC_ERR_NOSUCHSERVER = 402,
+ IRC_ERR_NOSUCHCHANNEL = 403,
+ IRC_ERR_CANNOTSENDTOCHAN = 404,
+ IRC_ERR_TOOMANYCHANNELS = 405,
+ IRC_ERR_WASNOSUCHNICK = 406,
+ IRC_ERR_TOOMANYTARGETS = 407,
+ IRC_ERR_NOORIGIN = 409,
+ IRC_ERR_NORECIPIENT = 411,
+ IRC_ERR_NOTEXTTOSEND = 412,
+ IRC_ERR_NOTOPLEVEL = 413,
+ IRC_ERR_WILDTOPLEVEL = 414,
+ IRC_ERR_UNKNOWNCOMMAND = 421,
+ IRC_ERR_NOMOTD = 422,
+ IRC_ERR_NOADMININFO = 423,
+ IRC_ERR_FILEIRC_ERROR = 424,
+ IRC_ERR_NONICKNAMEGIVEN = 431,
+ IRC_ERR_IRC_ERRONEUSNICKNAME = 432,
+ IRC_ERR_NICKNAMEINUSE = 433,
+ IRC_ERR_NICKCOLLISION = 436,
+ IRC_ERR_USERNOTINCHANNEL = 441,
+ IRC_ERR_NOTONCHANNEL = 442,
+ IRC_ERR_USERONCHANNEL = 443,
+ IRC_ERR_NOLOGIN = 444,
+ IRC_ERR_SUMMONDISABLED = 445,
+ IRC_ERR_USERSDISABLED = 446,
+ IRC_ERR_NOTREGISTERED = 451,
+ IRC_ERR_NEEDMOREPARAMS = 461,
+ IRC_ERR_ALREADYREGISTRED = 462,
+ IRC_ERR_NOPERMFORHOST = 463,
+ IRC_ERR_PASSWDMISMATCH = 464,
+ IRC_ERR_YOUREBANNEDCREEP = 465,
+ IRC_ERR_KEYSET = 467,
+ IRC_ERR_CHANNELISFULL = 471,
+ IRC_ERR_UNKNOWNMODE = 472,
+ IRC_ERR_INVITEONLYCHAN = 473,
+ IRC_ERR_BANNEDFROMCHAN = 474,
+ IRC_ERR_BADCHANNELKEY = 475,
+ IRC_ERR_NOPRIVILEGES = 481,
+ IRC_ERR_CHANOPRIVSNEEDED = 482,
+ IRC_ERR_CANTKILLSERVER = 483,
+ IRC_ERR_NOOPERHOST = 491,
+ IRC_ERR_UMODEUNKNOWNFLAG = 501,
+ IRC_ERR_USERSDONTMATCH = 502,
+
+#ifdef UIRC_FEATURE_IRCV3
+ /* https://ircv3.net/registry */
+ IRC_RPL_STARTTLS = 670,
+ IRC_ERR_STARTTLS = 691,
+
+ IRC_RPL_MONONLINE = 730,
+ IRC_RPL_MONOFFLINE = 731,
+ IRC_RPL_MONLIST = 732,
+ IRC_RPL_ENDOFMONLIST = 733,
+ IRC_ERR_MOLISTFULL = 734,
+
+ IRC_RPL_LOGGEDIN = 900,
+ IRC_RPL_LOGGEDOUT = 901,
+ IRC_ERR_NICKLOCKED = 902,
+ IRC_RPL_SASLSUCCESS = 903,
+ IRC_ERR_SASLFAIL = 904,
+ IRC_ERR_SASLTOOLONG = 905,
+ IRC_ERR_SASLABORTED = 906,
+ IRC_ERR_SASLALREADY = 907,
+ IRC_ERR_SASLMECHS = 908,
+#endif /* UIRC_FEATURE_IRCV3 */
+};
+
+#endif /* UIRC_GUARD_PUBLIC_REPLIES */
+
diff --git a/src/string.c b/src/string.c
deleted file mode 100644
index becaebb..0000000
--- a/src/string.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "private/string.h"
-
-#include
-
-void
-skip_spaces(char** addr)
-{
- for (; **addr == ' '; (*addr)++)
- ;
-}
-
-char*
-strtok_mr(char** addr, const char* tokens)
-{
- if (addr == NULL || *addr == NULL || !**addr || tokens == NULL) return NULL;
- char* save = *addr;
- const char* tok = NULL;
- do {
- if (!**addr) return save;
- for (tok = tokens; *tok; tok++) {
- if (**addr == *tok) {
- **addr = '\0';
- break;
- }
- }
- } while (*(*addr)++);
- return save;
-}
-
diff --git a/src/tags.c b/src/tags.c
deleted file mode 100644
index 66ea48d..0000000
--- a/src/tags.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "public/tags.h"
-
-#include
-#include
-
-#ifdef UIRC_HELPERS
-size_t
-Assm_tag_timestamp(char* buf, size_t len, time_t time)
-{
- assert(buf != NULL);
- return strftime(buf, len, "%Y-%m-%dT%H:%M:%S.000Z", gmtime(&time));
-}
-#endif /* UIRC_HELPERS */
-
diff --git a/src/tests/assemblers/message.c b/src/tests/assemblers/message.c
new file mode 100644
index 0000000..44258dd
--- /dev/null
+++ b/src/tests/assemblers/message.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../../assemblers/assemblers.h" // Assm_mesg()
+#include "../../types.h" // IRC_*
+#include "../common.h" // expect()
+
+#include // assert()
+#include // bool
+#include // EXIT_SUCCESS
+
+#define KEY1 "msgid"
+#define VAL1 "lol"
+#define KEY2 "wow"
+#define NICK "bazinga"
+#define HOST "monke.uk"
+#define COMMAND "NOTICE"
+#define ARG1 "urmomgay"
+#define TRAILING "what's up retard"
+
+int
+main(void)
+{
+ IRC_Message m[] = {
+ { .command = COMMAND, .args = { ARG1, TRAILING, NULL }, .trailing = true },
+ { .tag_list = &(llist_t) { .content = &(IRC_Tag) { .key = KEY1, .value = VAL1, .clientbound = true },
+ .next = &(llist_t) { .content = &(IRC_Tag) { .key = KEY2 } } },
+ .source = &(IRC_User) { .nick = NICK, .host = HOST },
+ .command = COMMAND,
+ .args = { ARG1, TRAILING, NULL },
+ .trailing = true },
+ };
+ const char* str[] = { COMMAND " " ARG1 " :" TRAILING, "@+" KEY1 "=" VAL1 ";" KEY2 " :" NICK "@" HOST " " COMMAND " " ARG1 " :" TRAILING };
+
+ char buf[513];
+ signed long ret;
+ for (unsigned long i = 0; i < sizeof(str) / sizeof(*str); i++) {
+ if ((ret = uirc_assembler_message(buf, &m[i], sizeof(buf) / sizeof(char))) <= 0) {
+ printf("Failed to convert IRC_User struct to a string. %li\n", ret);
+ return EXIT_FAILURE;
+ }
+ expect(buf, str[i]);
+ print_irc_message(&m[i]);
+ }
+ return EXIT_SUCCESS;
+}
+
diff --git a/src/tests/numericmds.c b/src/tests/assemblers/tag.c
similarity index 50%
rename from src/tests/numericmds.c
rename to src/tests/assemblers/tag.c
index 1bda666..d9f87e1 100644
--- a/src/tests/numericmds.c
+++ b/src/tests/assemblers/tag.c
@@ -16,32 +16,30 @@
* along with uIRC. If not, see .
*/
-#include "../public/assemblers.h"
-#include "../public/replies.h"
-#include "../public/types.h"
+#include "../../assemblers/assemblers.h" // Assm_mesg()
+#include "../common.h" // expect()
-#include
-#include
-#include
+#include // EXIT_SUCCESS EXIT_FAILURE
+
+#define key1 "msgid"
+#define val1 "30"
+#define key2 "time"
+#define key3 "x"
+#define val3 "spx"
int
main(void)
{
- char mesg[513] = { 0 };
- IRC_Message input = {
- .cmd = RPL_WELCOME,
- .args = { "hello", NULL },
- .trailing = true,
- };
- signed long res;
- if ((res = Assm_mesg(mesg, &input, 512)) <= 0) {
- printf("Failed to assemble message. (%li)\n", res);
- return EXIT_FAILURE;
- }
- char* expect = "001 :hello\r\n";
- if (strcmp(expect, mesg) != 0) {
- printf("Assembled message mismatch.\nGot:\n%s\nbut expected:\n%s\n", mesg, expect);
- return EXIT_FAILURE;
+ const char* str[] = { "+" key1 "=" val1, key2, key3 "=" val3 };
+ const IRC_Tag tag[] = { { .key = key1, .value = val1, .clientbound = true }, { .key = key2 }, { .key = key3, .value = val3 } };
+ char buf[513];
+ signed long ret;
+ for (unsigned long i = 0; i < sizeof(str) / sizeof(*str); i++) {
+ if ((ret = uirc_assembler_tag(buf, &tag[i], sizeof(buf) / sizeof(char))) < 0) {
+ printf("Failed to convert tag %lu to \"%s\". Error %li\n", i, str[i], ret);
+ return EXIT_FAILURE;
+ }
+ expect(buf, str[i]);
}
return EXIT_SUCCESS;
}
diff --git a/src/tests/junk.c b/src/tests/assemblers/user.c
similarity index 54%
rename from src/tests/junk.c
rename to src/tests/assemblers/user.c
index c040b72..7e11c9e 100644
--- a/src/tests/junk.c
+++ b/src/tests/assemblers/user.c
@@ -16,25 +16,29 @@
* along with uIRC. If not, see .
*/
-#include "../public/tokenizers.h"
-#include "../public/types.h"
+#include "../../assemblers/assemblers.h" // Assm_user()
+#include "../common.h" // expect()
-#include
-#include
-#include
+#include // EXIT_SUCCESS EXIT_FAILURE
+
+#define NICK "bruh"
+#define USER "sound"
+#define HOST "numero.dos"
int
main(void)
{
- char mesg[][513] = {
- "", "NO ", "CM:", "@:", "@ ", "@ N", "@ N:", "\n", "\r", "AA x :\r", "9A x :\r", "XA x :\r",
- };
- IRC_Message out = { 0 };
- for (unsigned long i = 0; i < sizeof(mesg) / sizeof(*mesg); i++) {
- if (Tok_mesg(mesg[i], &out) == 1) {
- printf("Message was parsed successfuly when it was junk.\nTest failed: #%lu %s\n", i, mesg[i]);
+ const char* str[] = { NICK "!" USER "@" HOST, HOST };
+ IRC_User u[] = { { .nick = NICK, .user = USER, .host = HOST }, { .host = HOST } };
+ char buf[513];
+ signed long ret;
+ for (unsigned long i = 0; i < sizeof(str) / sizeof(*str); i++) {
+ if ((ret = uirc_assembler_user(buf, &u[i], sizeof(buf) / sizeof(char))) <= 0) {
+ printf("Failed to convert IRC_User struct to a string. %li\n", ret);
return EXIT_FAILURE;
}
+ expect(buf, str[i]);
+ print_irc_user(&u[i]);
}
return EXIT_SUCCESS;
}
diff --git a/src/tests/common.c b/src/tests/common.c
new file mode 100644
index 0000000..7da349a
--- /dev/null
+++ b/src/tests/common.c
@@ -0,0 +1,82 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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"
+
+#include "../types.h" // IRC_Message
+
+#include // printf()
+#include // exit()
+#include // strcmp()
+
+#define DELIMITER "-------------\n"
+#define PRINTVARORNULL(VAR) ((VAR != NULL) ? VAR : "NULL")
+
+void
+expect(const char* var, const char* exp)
+{
+ if (strcmp(var, exp) != 0) {
+ printf("Expected \"%s\" but got \"%s\" instead.\n", exp, var);
+ exit(EXIT_FAILURE);
+ }
+}
+
+void
+print_irc_message(IRC_Message* ptr)
+{
+#ifdef UIRC_FEATURE_IRCV3
+ printf(DELIMITER);
+
+ llist_t* tmp = ptr->tag_list;
+ for (; tmp != NULL; tmp = tmp->next) { print_irc_tag((IRC_Tag*) tmp->content); }
+#endif /* UIRC_FEATURE_IRCV3 */
+
+ if (ptr->source != NULL) { print_irc_user(ptr->source); }
+
+ if (ptr->command != NULL) printf("mc: %s\n", ptr->command);
+
+ for (short i = 0; i < IRC_MAXARGS && ptr->args[i] != NULL; i++) { printf("marg[%i]: %s\n", i, ptr->args[i]); }
+
+ printf(DELIMITER);
+}
+
+#ifdef UIRC_FEATURE_IRCV3
+void
+print_irc_tag(IRC_Tag* tag)
+{
+ printf(DELIMITER "tn: %s\n"
+ "tv: %s\n"
+ "tc: %i\n" DELIMITER,
+ PRINTVARORNULL(tag->key),
+ PRINTVARORNULL(tag->value),
+ tag->clientbound);
+}
+#endif /* UIRC_FEATURE_IRCV3 */
+
+void
+print_irc_user(IRC_User* user)
+{
+ printf(DELIMITER "un: %s\n"
+ "uu: %s\n"
+ "ur: %s\n"
+ "uh: %s\n" DELIMITER,
+ PRINTVARORNULL(user->nick),
+ PRINTVARORNULL(user->user),
+ PRINTVARORNULL(user->real),
+ PRINTVARORNULL(user->host));
+}
diff --git a/src/private/memory.h b/src/tests/common.h
similarity index 58%
rename from src/private/memory.h
rename to src/tests/common.h
index 22d4c0a..d5350c7 100644
--- a/src/private/memory.h
+++ b/src/tests/common.h
@@ -16,14 +16,25 @@
* along with uIRC. If not, see .
*/
-#include
-#include
+#include "../types.h" // IRC_*
-#ifndef UIRC_GUARD_MEMORY
-#define UIRC_GUARD_MEMORY
+#include // printf()
+#include // exit()
+#include // strcmp()
-size_t safe_strcpy(char** dest, const char* src, size_t lef);
-bool safe_charcpy(char** dest, char c, size_t lef);
+#ifndef UIRC_GUARD_PRIVATE_COMMONTESTS
+#define UIRC_GUARD_PRIVATE_COMMONTESTS
-#endif /* UIRC_GUARD_MEMORY */
+#define ERRIFNULL(VAR, ...) \
+ if (VAR == NULL) printf(__VA_ARGS__)
+
+void expect(const char* var, const char* exp);
+
+void print_irc_message(IRC_Message* ptr);
+#ifdef UIRC_FEATURE_IRCV3
+void print_irc_tag(IRC_Tag* tag);
+#endif /* UIRC_FEATURE_IRCV3 */
+void print_irc_user(IRC_User* user);
+
+#endif /* UIRC_GUARD_PRIVATE_COMMONTESTS */
diff --git a/src/tests/general/fullloop.c b/src/tests/general/fullloop.c
new file mode 100644
index 0000000..53fd823
--- /dev/null
+++ b/src/tests/general/fullloop.c
@@ -0,0 +1,52 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../../assemblers/assemblers.h" // Assm_mesg()
+#include "../../tokenizers/tokenizers.h" // Tok_mesg()
+#include "../../types.h" // IRC_User
+#include "../common.h" // expect()
+
+#include // assert()
+#include // EXIT_SUCCESS
+
+int
+main(void)
+{
+ const char* str[] = { ":buddy@hostnet.com PRIVMSG #general :login hunter12",
+ "NOTICE * :nice cock bro",
+ "@day=13;willtolive=0 PRIVMSG you :helo",
+ ":mom!mother@localhost NOTICE #netadmin :johnny, your pizza is done" };
+
+ for (unsigned long i = 0; i < sizeof(str) / sizeof(*str); i++) {
+ IRC_Message* m = NULL;
+ if ((m = uirc_tokenizer_message(str[i])) == NULL) {
+ printf("Failed to convert string to IRC_Message struct.\n");
+ return EXIT_FAILURE;
+ }
+ signed long ret;
+ char buf[513];
+ if ((ret = uirc_assembler_message(buf, m, sizeof(buf) / sizeof(char))) <= 0) {
+ printf("Failed to convert IRC_Message struct to a string. (%li)\n", ret);
+ return EXIT_FAILURE;
+ }
+ expect(buf, str[i]);
+ print_irc_message(m);
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/tests/msgassm.c b/src/tests/msgassm.c
deleted file mode 100644
index b7353ee..0000000
--- a/src/tests/msgassm.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/assemblers.h"
-#include "../public/commands.h"
-#include "../public/types.h"
-
-#include
-#include
-#include
-
-int
-main(void)
-{
- char mesg[513] = { 0 };
- IRC_Message input = {
-#ifdef UIRC_IRCV3
- .tags = { .msgid = { .value = "10" } },
-#endif
- .name = { .nick = "dad", .user = "dad-door", .host = "home.localhost" },
- .cmd = PRIVMSG,
- .args = { "(You)", "are ya winning son?", NULL },
- .trailing = true,
- };
- signed long res;
- if ((res = Assm_mesg(mesg, &input, 512)) <= 0) {
- printf("Failed to assemble message. (%li)\n", res);
- return EXIT_FAILURE;
- }
- char* expect =
-#ifdef UIRC_IRCV3
- "@msgid=10 "
-#endif
- ":dad!dad-door@home.localhost PRIVMSG (You) :are ya winning son?\r\n";
- if (strcmp(expect, mesg) != 0) {
- printf("Assembled message mismatch.\nGot:\n%s\nbut expected:\n%s\n", mesg, expect);
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/notrail.c b/src/tests/notrail.c
deleted file mode 100644
index bb1e75c..0000000
--- a/src/tests/notrail.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/tokenizers.h"
-#include "../public/types.h"
-
-#include
-#include
-#include
-
-int
-main(void)
-{
- char mesg[513] = ":nick!user@host QUIT arg1 ";
- IRC_Message parseout = { 0 };
- int res = 0;
- if ((res = Tok_mesg(mesg, &parseout)) <= 0) {
- printf("String could not be tokenized. %i\n", res);
- return EXIT_FAILURE;
- }
- if (parseout.trailing) {
- printf("Got unexpected trailing.");
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/overflow.c b/src/tests/overflow.c
deleted file mode 100644
index 573cf20..0000000
--- a/src/tests/overflow.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/assemblers.h"
-#include "../public/commands.h"
-#include "../public/types.h"
-
-#include
-#include
-#include
-
-int
-main(void)
-{
- char mesg[513] = { 0 };
- IRC_Message input = {
- .cmd = NOTICE,
- .args = { "*",
- "Cock and ball torture (CBT), penis torture or dick torture is a sexual activity involving application of pain or constriction to "
- "the penis or testicles. This may involve directly painful activities, such as genital piercing, wax play, genital spanking, "
- "squeezing, ball-busting, genital flogging, urethral play, tickle torture, erotic electrostimulation, kneeing or kicking. The "
- "recipient of such activities may receive direct physical pleasure via masochism, or emotional pleasure through erotic humiliation, "
- "or knowledge that the play is pleasing to a sadistic dominant. Many of these practices carry significant health risks.",
- NULL },
- .trailing = true
- };
- signed long i;
- if ((i = Assm_mesg(mesg, &input, 512)) > 0) {
- fprintf(stderr, "Got %li instead of < 0", i);
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/spacedargs.c b/src/tests/spacedargs.c
deleted file mode 100644
index 6f81275..0000000
--- a/src/tests/spacedargs.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/commands.h"
-#include "../public/tokenizers.h"
-#include "../public/types.h"
-
-#include
-#include
-#include
-
-#define cmd "QUIT"
-#define arg1 "arg1"
-#define arg2 "arg2"
-#define trailing "Finished!"
-
-int
-main(void)
-{
- char mesg[513] = cmd " " arg1 " " arg2 " :" trailing;
- IRC_Message parseout;
- int res = 0;
- if ((res = Tok_mesg(mesg, &parseout)) <= 0) {
- printf("String could not be tokenized. %i\n", res);
- return EXIT_FAILURE;
- }
- if (strcmp(parseout.args[0], arg1) != 0) {
- printf("Arg1 didn't match, got \"%s\" instead of \"%s\"\n", parseout.args[0], arg1);
- return EXIT_FAILURE;
- }
- if (strcmp(parseout.args[1], arg2) != 0) {
- printf("Arg2 didn't match, got \"%s\" instead of \"%s\"\n", parseout.args[1], arg2);
- return EXIT_FAILURE;
- }
- if (strcmp(parseout.args[2], trailing) != 0) {
- printf("Trailing didn't match, got \"%s\" instead of \"%s\"\n", parseout.args[2], trailing);
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/strtokmr.c b/src/tests/strtokmr.c
deleted file mode 100644
index 196336a..0000000
--- a/src/tests/strtokmr.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../private/string.h"
-
-#include
-#include
-#include
-
-int
-main(void)
-{
- char* pointer = NULL;
- if (strtok_mr(&pointer, "!") != NULL) return EXIT_FAILURE;
- if (pointer != NULL) return EXIT_FAILURE;
-
- char test2[] = "hello";
- pointer = test2;
- if (strtok_mr(&pointer, "!") == NULL) return EXIT_FAILURE;
- if (*pointer != '\0') return EXIT_FAILURE;
-
- char test3[] = "hi!# hello!";
- pointer = test3;
- if (strtok_mr(&pointer, "!#") == NULL) return EXIT_FAILURE;
- if (pointer != test3 + 3) /* MUST point at # right after ! */
- return EXIT_FAILURE;
- if (test3[2] != '\0') /* MUST replace ! with \0 */
- return EXIT_FAILURE;
- if (strtok_mr(&pointer, "!#") == NULL) return EXIT_FAILURE;
- if (pointer != test3 + 4) /* MUST point at whitespace right after # */
- return EXIT_FAILURE;
- if (test3[3] != '\0') /* MUST replace # with \0 */
- return EXIT_FAILURE;
- if (strtok_mr(&pointer, "!#") == NULL) return EXIT_FAILURE;
- if (strtok_mr(&pointer, "!#") != NULL) return EXIT_FAILURE;
-
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/tagassm.c b/src/tests/tagassm.c
deleted file mode 100644
index 60b3724..0000000
--- a/src/tests/tagassm.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/assemblers.h"
-#include "../public/types.h"
-
-#include
-#include
-#include
-
-int
-main(void)
-{
- char mesg[513] = { 0 };
- IRC_Tags input = { .time = { .value = "now", .clientbound = true }, .msgid = { .value = "", .clientbound = false } };
- signed long res = 0;
- if ((res = Assm_tags(mesg, &input, 512)) <= 0) {
- printf("String could not be assembled. %li\n", res);
- return EXIT_FAILURE;
- }
- if (strcmp(mesg, "@+time=now;msgid") != 0 && strcmp(mesg, "@msgid;+time=now") != 0) {
- printf("String was not assembled properly. Have %s\n", mesg);
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/tagtok.c b/src/tests/tagtok.c
deleted file mode 100644
index 0ea4dfb..0000000
--- a/src/tests/tagtok.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/tokenizers.h"
-#include "../public/types.h"
-
-#include
-#include
-#include
-
-int
-main(void)
-{
- char mesg[513] = "@msgid=1s32;+time QUIT";
- IRC_Message parseout;
- int res = 0;
- if ((res = Tok_mesg(mesg, &parseout)) <= 0) {
- printf("String could not be tokenized. %i\n", res);
- return EXIT_FAILURE;
- }
- if (parseout.tags.msgid.value == NULL || strcmp(parseout.tags.msgid.value, "1s32") != 0) {
- printf("Message ID was not properly parsed.\n");
- return EXIT_FAILURE;
- }
- if (parseout.tags.time.value == NULL || *parseout.tags.time.value != '\0' || !parseout.tags.time.clientbound) {
- printf("Time was not properly parsed.\n");
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/timestamp.c b/src/tests/timestamp.c
deleted file mode 100644
index f414963..0000000
--- a/src/tests/timestamp.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/tags.h"
-#include "../public/types.h"
-
-#include
-#include
-#include
-#include
-
-int
-main(void)
-{
- char buffer[26];
- time_t res = 1130620230;
- if (Assm_tag_timestamp(buffer, sizeof(buffer), res) && strcmp("2005-10-29T21:10:30.000Z", buffer) == 0) return EXIT_SUCCESS;
- return EXIT_FAILURE;
-}
-
diff --git a/src/tests/tokenizer.c b/src/tests/tokenizer.c
deleted file mode 100644
index 500bd1f..0000000
--- a/src/tests/tokenizer.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "../public/commands.h"
-#include "../public/tokenizers.h"
-
-#include
-#include
-#include
-
-#define nickname "nick"
-#define username "user"
-#define hostname "host"
-#define arg2 "Finished!"
-
-int
-main(void)
-{
- char mesg[2][513] = {
-#ifdef UIRC_IRCV3
- "@+msgid=1s32;time;+reply;account=x "
-#endif
- ":" nickname "!" username "@" hostname " QUIT arg1 :" arg2,
- "001 hell :sup cj"
- };
- IRC_Message parseout = { 0 };
- int res = 0;
- if ((res = Tok_mesg(mesg[0], &parseout)) <= 0) {
- printf("String could not be tokenized. %i\n", res);
- return EXIT_FAILURE;
- }
- if (parseout.args[1] == NULL || strcmp(parseout.args[1], arg2) != 0) {
- printf("Unexpected result. Got %s instead of %s\n", parseout.args[1], arg2);
- return EXIT_FAILURE;
- }
- if (parseout.name.user == NULL || strcmp(parseout.name.user, username) != 0) {
- printf("Unexpected result. Got %s instead of %s\n", parseout.name.user, username);
- return EXIT_FAILURE;
- }
- if (parseout.cmd != QUIT) {
- printf("Unexpected command result. Got %i instead of %i\n", parseout.cmd, QUIT);
- return EXIT_FAILURE;
- }
- if ((res = Tok_mesg(mesg[1], &parseout)) <= 0) {
- printf("String could not be tokenized. %i\n", res);
- return EXIT_FAILURE;
- }
- if (parseout.cmd != 1) {
- printf("Unexpected command result. Got %i instead of %i\n", parseout.cmd, 1);
- return EXIT_FAILURE;
- }
- return EXIT_SUCCESS;
-}
-
diff --git a/src/tests/prefixassm.c b/src/tests/tokenizers/message.c
similarity index 55%
rename from src/tests/prefixassm.c
rename to src/tests/tokenizers/message.c
index 91a958b..5f2d6d3 100644
--- a/src/tests/prefixassm.c
+++ b/src/tests/tokenizers/message.c
@@ -16,27 +16,30 @@
* along with uIRC. If not, see .
*/
-#include "../public/assemblers.h"
-#include "../public/types.h"
+#include "../../tokenizers/tokenizers.h" // Tok_user()
+#include "../../types.h" // IRC_User
+#include "../common.h" // expect()
-#include
-#include
-#include
+#include // assert()
+#include // EXIT_SUCCESS
+
+#define COMMAND "NOTICE"
+#define ARG1 "urmomgay"
+#define TRAILING "what's up retard"
int
main(void)
{
- char mesg[513] = { 0 };
- IRC_User input = { .nick = "durov", .user = "pavel", .host = "telegram.org" };
- signed long res = 0;
- if ((res = Assm_user(mesg, &input, 512, false)) <= 0) {
- printf("String could not be assembled. %li\n", res);
- return EXIT_FAILURE;
- }
- if (strcmp(mesg, "durov!pavel@telegram.org") != 0) {
- printf("String was not assembled properly. Have %s\n", mesg);
+ IRC_Message* m = uirc_tokenizer_message(COMMAND " " ARG1 " :" TRAILING);
+ ERRIFNULL(m, "Message wasn't tokenized successfully.\n");
+ expect(m->command, COMMAND);
+ expect(m->args[0], ARG1);
+ expect(m->args[1], TRAILING);
+ if (!m->trailing) {
+ printf("Message wasn't trailing when it should've been.\n");
return EXIT_FAILURE;
}
+ print_irc_message(m);
return EXIT_SUCCESS;
}
diff --git a/src/tests/tokenizers/tag.c b/src/tests/tokenizers/tag.c
new file mode 100644
index 0000000..f9efa93
--- /dev/null
+++ b/src/tests/tokenizers/tag.c
@@ -0,0 +1,63 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../../tokenizers/tokenizers.h" // Tok_tags()
+#include "../common.h" // expect()
+
+#include // assert()
+#include // llist_t
+#include // EXIT_SUCCESS
+
+#define key1 "msgid"
+#define val1 "30"
+#define key2 "time"
+#define key3 "x"
+#define val3 "spx"
+
+int
+main(void)
+{
+ IRC_Tag* cur = NULL;
+ llist_t* tags = uirc_tokenizer_tags("+" key1 "=" val1 ";" key2 ";" key3 "=" val3);
+ ERRIFNULL(tags, "Tags weren't tokenized successfully.\n");
+
+ cur = tags->content;
+ expect(cur->key, key1);
+ expect(cur->value, val1);
+ if (!cur->clientbound) {
+ printf("Tag #1 wasn't clientbound.\n");
+ return EXIT_FAILURE;
+ }
+ print_irc_tag(cur);
+
+ cur = (tags = tags->next)->content;
+ expect(cur->key, key2);
+ if (cur->clientbound) {
+ printf("Tag #2 was clientbound.\n");
+ return EXIT_FAILURE;
+ }
+ print_irc_tag(cur);
+
+ cur = (tags = tags->next)->content;
+ expect(cur->key, key3);
+ expect(cur->value, val3);
+ print_irc_tag(cur);
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/src/tests/capbitmask.c b/src/tests/tokenizers/user.c
similarity index 59%
rename from src/tests/capbitmask.c
rename to src/tests/tokenizers/user.c
index 756c286..b7e923d 100644
--- a/src/tests/capbitmask.c
+++ b/src/tests/tokenizers/user.c
@@ -16,21 +16,26 @@
* along with uIRC. If not, see .
*/
-#include "../public/capabilities.h"
+#include "../../tokenizers/tokenizers.h" // Tok_user()
+#include "../../types.h" // IRC_User
+#include "../common.h" // expect()
-#include
-#include
-#include
+#include // assert()
+#include // EXIT_SUCCESS
+
+#define NICK "minion"
+#define USER "banana"
+#define HOST "freebanana.com"
int
main(void)
{
- char wcps[] = "multi-prefix sasl";
- if ((Tok_CAPS(wcps)) != (CAPBIT(CAP_MULTI_PREFIX) | CAPBIT(CAP_SASL))) return EXIT_FAILURE;
- char multicaps[] = "sasl echo-message echo-message";
- if ((Tok_CAPS(multicaps)) != (CAPBIT(CAP_ECHO_MESSAGE) | CAPBIT(CAP_SASL))) return EXIT_FAILURE;
- char nocaps[] = "random-cap unknown-cap wow";
- if ((Tok_CAPS(nocaps)) != 0) return EXIT_FAILURE;
+ IRC_User* user = uirc_tokenizer_user(NICK "!" USER "@" HOST);
+ ERRIFNULL(user, "User wasn't successfully tokenized.\n");
+ expect(user->nick, NICK);
+ expect(user->user, USER);
+ expect(user->host, HOST);
+ print_irc_user(user);
return EXIT_SUCCESS;
}
diff --git a/src/tokenizers.c b/src/tokenizers.c
deleted file mode 100644
index 99065ef..0000000
--- a/src/tokenizers.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
- * Copyright (c) 2019, 2020 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 "public/tokenizers.h"
-
-#include "private/mappings.h"
-#include "private/string.h"
-#include "public/commands.h"
-#include "public/converters.h"
-#include "public/errors.h"
-#include "public/tags.h"
-#include "public/types.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#ifdef UIRC_IRCV3
-signed int
-Tok_tags(char* str, IRC_Tags* out)
-{
- assert(str != NULL);
- assert(out != NULL);
- char * cval, *cpos = str, *ctag = NULL;
- bool clientbound;
- const struct tagmapping tagmps[] = {
- { .name = "time", .assg = &out->time }, { .name = "account", .assg = &out->account },
- { .name = "batch", .assg = &out->batch }, { .name = "label", .assg = &out->label },
- { .name = "msgid", .assg = &out->msgid }, { .name = "multiline-concat", .assg = &out->multiline_concat },
- { .name = "typing", .assg = &out->typing }, { .name = "react", .assg = &out->react },
- { .name = "reply", .assg = &out->reply }
- };
- if (*cpos == '@') cpos++;
- while ((ctag = strtok_mr(&cpos, "; ")) != NULL) {
- clientbound = false;
- if (*ctag == '+') {
- ctag++;
- clientbound = true;
- }
- if ((cval = strchr(ctag, '=')) != NULL) *(cval++) = '\0';
- for (unsigned int i = 0; i < sizeof(tagmps) / sizeof(struct tagmapping); i++) {
- if (!strcmp(ctag, tagmps[i].name)) {
- /* 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;
- }
- }
- }
- return 1;
-}
-#endif /* UIRC_IRCV3 */
-
-signed int
-Tok_user(char* str, IRC_User* out, bool useorig)
-{
- assert(str != NULL);
- assert(out != NULL);
- char* pos = (*str == ':') ? str + 1 : str;
- if ((out->host = strchr(pos, '@')) != NULL) *(out->host++) = '\0';
- if (useorig && (out->orig = strchr(pos, '%')) != NULL) *(out->orig++) = '\0';
- if ((out->user = strchr(pos, '!'))
- != NULL) /* RFC2812 says this cannot be here without the host but RFC1459 says it can, we accept both options */
- *(out->user++) = '\0';
- if (!*(out->nick = pos)) return ERR_UIRC_INVALID_FORMAT;
- /* NOTE: De-facto standard below
- * This assumes that every prefix without a '@host' and '!user' is itself a host prefix only
- * It might be a actual nickname, but this is the most common around every network
- * It is left to the user to decide and handle the result accordingly
- */
- if (out->host == NULL && out->user == NULL) {
- out->host = out->nick;
- out->nick = NULL;
- }
- return 1;
-}
-
-signed int
-Tok_mesg(char* str, IRC_Message* out)
-{
- assert(str != NULL);
- assert(out != NULL);
- int ret;
- char *progr = str, *command;
-#ifdef UIRC_IRCV3
- if (*progr == '@') {
- char* tags;
- if ((tags = strtok_mr(&progr, " ")) != NULL) {
- if ((ret = Tok_tags(tags, &out->tags)) < 0) return ret;
- } else
- return ERR_UIRC_INVALID_FORMAT;
- }
- skip_spaces(&progr);
-#endif /* UIRC_IRCV3 */
- if (*progr == ':') {
- char* prefix;
- if ((prefix = strtok_mr(&progr, " ")) != NULL) {
- if ((ret = Tok_user(prefix, &out->name, false)) < 0) return ret;
- } else
- return ERR_UIRC_INVALID_FORMAT;
- skip_spaces(&progr);
- }
-
- if (isalnum(*progr) && (command = strtok_mr(&progr, " ")) != NULL) {
- signed short temp;
- if (isalpha(*command)) {
- if ((temp = Ircmd_stoi(command)) < UIRC_FCMD || temp > UIRC_LCMD) return ERR_UIRC_UNKNOWN_TOKEN;
- out->cmd = (IRC_Command) temp;
- } else {
- for (size_t l = 0; command[l]; l++) {
- if (!isdigit(command[l])) return ERR_UIRC_INVALID_FORMAT;
- }
- out->cmd = (IRC_Command) atoi(command);
- }
- } else
- return ERR_UIRC_INVALID_FORMAT;
- skip_spaces(&progr);
-
- short i;
- for (i = 0; i < 15 && *progr;) {
- if (i == 14 || *progr == ':') {
- out->args[i++] = (*progr == ':') ? progr + 1 : progr;
- out->trailing = true;
- break;
- } else {
- if ((out->args[i++] = strtok_mr(&progr, " ")) == NULL) return ERR_UIRC_INVALID_FORMAT;
- skip_spaces(&progr);
- }
- }
- out->args[i] = NULL;
- return 1;
-}
-
-#ifdef UIRC_HELPERS
-void
-Tok_cmd_PING(const IRC_Message* mesg, char** source, char** target)
-{
- assert(mesg != NULL);
- assert(source != NULL);
- assert(target != NULL);
- *source = (mesg->args[0] == NULL && mesg->trailing) ? mesg->args[2] : (mesg->args[1] != NULL) ? mesg->args[0] : NULL;
- *target = (mesg->args[1] == NULL) ? mesg->args[0] : mesg->args[1];
-}
-/* Use with WHOIS/LINKS
- * (stands for first argument optional)
- * [ ]
- */
-
-void
-Tok_FArgOpt(const IRC_Message* mesg, char** optarg, char** reqarg)
-{
- assert(mesg != NULL);
- assert(optarg != NULL);
- assert(reqarg != NULL);
- *optarg = (mesg->args[1] != NULL) ? mesg->args[0] : NULL;
- *reqarg = (mesg->args[1] != NULL) ? mesg->args[1] : mesg->args[0];
-}
-#endif /* UIRC_HELPERS */
-
diff --git a/src/tokenizers/message.c b/src/tokenizers/message.c
new file mode 100644
index 0000000..2fcc870
--- /dev/null
+++ b/src/tokenizers/message.c
@@ -0,0 +1,119 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../memory/memory.h" // Free_IRC_Message()
+#include "../types.h" // IRC_Message
+#include "tokenizers.h" // Tok_mesg() Tok_user() Tok_tags()
+
+#include // assert()
+#include // malloc_string() strtok_mr()
+#include // isalnum()
+#include // NULL
+#include // malloc()
+#include // strlen()
+
+static void free_ctx(IRC_Message* msg, char* str);
+static void skip_spaces(char** addr);
+
+IRC_Message*
+uirc_tokenizer_message(const char* s)
+{
+ assert(s != NULL);
+
+ IRC_Message* m = malloc(sizeof(IRC_Message));
+ char* const ws = malloc_string(s, strlen(s));
+ char* p = ws;
+ if (ws == NULL || m == NULL) {
+ free(ws);
+ free(m);
+ return NULL;
+ }
+ memset(m, 0, sizeof(IRC_Message));
+ strcpy(ws, s);
+
+#ifdef UIRC_FEATURE_IRCV3
+ if (*p == '@') {
+ p++;
+ const char* tmp = NULL;
+ if ((tmp = strtok_mr(&p, " ")) == NULL || (m->tag_list = uirc_tokenizer_tags(tmp)) == NULL) {
+ free_ctx(m, ws);
+ return NULL;
+ }
+ }
+ skip_spaces(&p);
+#endif /* UIRC_FEATURE_IRCV3 */
+
+ if (*p == ':') {
+ const char* tmp = NULL;
+ p++;
+ if ((tmp = strtok_mr(&p, " ")) == NULL || (m->source = uirc_tokenizer_user(tmp)) == NULL) {
+ free_ctx(m, ws);
+ return NULL;
+ }
+ skip_spaces(&p);
+ }
+
+ if (isalnum(*p)) {
+ const char* tmp = NULL;
+ if ((tmp = strtok_mr(&p, " ")) == NULL || (m->command = malloc_string(tmp, strlen(tmp))) == NULL) {
+ free_ctx(m, ws);
+ return NULL;
+ }
+ } else
+ return NULL;
+ skip_spaces(&p);
+
+ short i;
+ for (i = 0; i < IRC_MAXARGS && *p;) {
+ if (i == IRC_MAXARGS - 1 || *p == ':') {
+ if (*p == ':') p++;
+ if ((m->args[i++] = malloc_string(p, strlen(p))) == NULL) {
+ free_ctx(m, ws);
+ return NULL;
+ }
+ m->trailing = true;
+ break;
+ } else {
+ const char* tmp = NULL;
+ if ((tmp = strtok_mr(&p, " ")) == NULL || (m->args[i++] = malloc_string(tmp, strlen(tmp))) == NULL) {
+ free_ctx(m, ws);
+ return NULL;
+ }
+ skip_spaces(&p);
+ }
+ m->args[i] = NULL;
+ }
+ free(ws);
+ return m;
+}
+
+static void
+free_ctx(IRC_Message* msg, char* str)
+{
+ uirc_free_message(msg);
+ free(msg);
+ free(str);
+}
+
+static void
+skip_spaces(char** addr)
+{
+ for (; **addr == ' '; (*addr)++)
+ ;
+}
+
diff --git a/src/tokenizers/tags.c b/src/tokenizers/tags.c
new file mode 100644
index 0000000..05e6483
--- /dev/null
+++ b/src/tokenizers/tags.c
@@ -0,0 +1,87 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../memory/memory.h" // Free_IRC_Tag()
+#include "../types.h" // IRC_Tag
+#include "tokenizers.h" // uirc_tokenizer_tags()
+
+#include // assert()
+#include // allocate_linked_list_elem() connect_linked_list_elem() remove_linked_list_elem()
+#include // malloc_string()
+#include // true
+#include // free()
+#include // strchr()
+
+static void free_ctx(llist_t* list, char* s);
+
+// TODO: Only tokenizer IRC_Tag and put the looping logic in uirc_tokenizer_message()
+
+llist_t*
+uirc_tokenizer_tags(const char* s)
+{
+ assert(s != NULL);
+
+ char* const ws = malloc_string(s, strlen(s));
+ char * p = ws, *tmp;
+ llist_t * pl = NULL, *l = NULL;
+
+ while ((tmp = strtok_mr(&p, ";")) != NULL) {
+ llist_t* cl;
+ if ((cl = allocate_linked_list_elem(sizeof(IRC_Tag))) == NULL) {
+ free_ctx(l, ws);
+ return NULL;
+ }
+ IRC_Tag* tag = (IRC_Tag*) cl->content;
+
+ char* ckey = tmp;
+ if (*tmp == '+') {
+ ckey++;
+ tag->clientbound = true;
+ }
+ char* cval = strchr(ckey, '=');
+ if (cval != NULL) {
+ *(cval++) = '\0';
+ if ((tag->value = malloc_string(cval, strlen(cval))) == NULL) {
+ free_ctx(l, ws);
+ return NULL;
+ }
+ }
+ if ((tag->key = malloc_string(ckey, strlen(ckey))) == NULL) {
+ free_ctx(l, ws);
+ return NULL;
+ }
+
+ if (l == NULL) l = cl;
+ else
+ connect_linked_list_elem(pl, cl);
+ pl = cl;
+ }
+ return l;
+}
+
+static void
+free_ctx(llist_t* list, char* s)
+{
+ for (llist_t* c = list; c != NULL;) {
+ llist_t* l = c;
+ c = c->next;
+ uirc_free_tag(l->content);
+ remove_linked_list_elem(l);
+ }
+ free(s);
+}
diff --git a/src/public/tokenizers.h b/src/tokenizers/tokenizers.h
similarity index 50%
rename from src/public/tokenizers.h
rename to src/tokenizers/tokenizers.h
index adaba1c..090950f 100644
--- a/src/public/tokenizers.h
+++ b/src/tokenizers/tokenizers.h
@@ -18,63 +18,39 @@
/*! \file */
-#include "types.h"
+#include "../types.h" // IRC_User
-#include
+#include // llist_t
+#include // bool
-#ifndef UIRC_GUARD_TOKENIZERS
-#define UIRC_GUARD_TOKENIZERS
+#ifndef UIRC_GUARD_PUBLIC_TOKENIZERS
+#define UIRC_GUARD_PUBLIC_TOKENIZERS
-#ifdef UIRC_IRCV3
+#ifdef UIRC_FEATURE_IRCV3
/*!
* \brief Tokenize IRCv3 tags
*
* This function parses IRCv3 tags according to the specification at
* \param[in] str String containing a IRC source with or without the ':' prefix
- * \param[out] out Allocated IRC_User structure
*/
-signed int Tok_tags(char* str, IRC_Tags* out);
-#endif /* UIRC_IRCV3 */
+llist_t* uirc_tokenizer_tags(const char* str);
+#endif /* UIRC_FEATURE_IRCV3 */
/*!
* \brief Tokenize a IRC message source.
*
* This function takes the source part of a message, pointing struct elements to parts of it.
* \param[in] str String containing a IRC source with or without the ':' prefix
- * \param[out] out Allocated IRC_User structure
- * \param[in] useorig If '\%orig' should be considered in the parsing
*/
-signed int Tok_user(char* str, IRC_User* out, bool useorig);
+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
* \param[in] str String containing a IRC message without the ending '\\r\\n'
- * \param[out] out Allocated IRC_Message structure
*/
-signed int Tok_mesg(char* str, IRC_Message* out);
+IRC_Message* uirc_tokenizer_message(const char* str);
-#ifdef UIRC_HELPERS
-/*!
- * \brief A PING tokenizer/parser
- *
- * This function is a simple helper to get the source and target of a PING since the RFC has a "interesting" implementation
- * \param[in] mesg IRC_Message struct containing the PING message
- * \param[out] source Source of the PING (server)
- * \param[out] target Target of the PING (server or client)
- */
-void Tok_cmd_PING(const IRC_Message* mesg, char** source, char** target);
-/*!
- * \brief Tokenizer for cases where the first argument is optional
- *
- * This function is a private helper for cases where the first argument might be missing but the second isn't
- * \param[in] mesg IRC_Message struct
- * \param[out] optarg Optional argument if found or NULL
- * \param[out] reqarg Required argument
- */
-void Tok_FArgOpt(const IRC_Message* mesg, char** optarg, char** reqarg);
-#endif /* UIRC_HELPERS */
-
-#endif /* UIRC_GUARD_TOKENIZERS */
+#endif /* UIRC_GUARD_PUBLIC_TOKENIZERS */
diff --git a/src/tokenizers/user.c b/src/tokenizers/user.c
new file mode 100644
index 0000000..0121968
--- /dev/null
+++ b/src/tokenizers/user.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 "../errors.h" // ERR_UIRC_*
+#include "../memory/memory.h" // Free_IRC_User()
+#include "../types.h" // IRC_User
+#include "tokenizers.h" // Tok_user()
+
+#include // assert()
+#include // malloc_string()
+#include // bool
+#include // malloc()
+#include // strchr()
+
+static void free_ctx(IRC_User* u, char* s);
+
+IRC_User*
+uirc_tokenizer_user(const char* s)
+{
+ assert(s != NULL);
+
+ IRC_User* u = malloc(sizeof(IRC_User));
+ char* const ws = malloc_string(s, strlen(s));
+ char* tmp;
+ if (u == NULL || ws == NULL) {
+ free(u);
+ free(ws);
+ return NULL;
+ }
+
+ if ((tmp = strchr(ws, '@')) != NULL) {
+ *(tmp++) = '\0';
+ if ((u->host = malloc_string(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) {
+ free_ctx(u, ws);
+ return NULL;
+ }
+ }
+ if ((u->nick = malloc_string(ws, strlen(ws))) == NULL) {
+ free_ctx(u, ws);
+ return NULL;
+ }
+
+ free(ws);
+ return u;
+}
+
+static void
+free_ctx(IRC_User* u, char* s)
+{
+ uirc_free_user(u);
+ free(u);
+ free(s);
+}
diff --git a/src/types.h b/src/types.h
new file mode 100644
index 0000000..34c40a1
--- /dev/null
+++ b/src/types.h
@@ -0,0 +1,81 @@
+/*
+ * This file is part of uIRC. (https://git.redxen.eu/caskd/uIRC)
+ * Copyright (c) 2019, 2020 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 .
+ */
+
+/*! \file */
+
+#include // llist_t
+#include // uintmax_t
+#include // bool
+
+#ifndef UIRC_GUARD_PUBLIC_TYPES
+#define UIRC_GUARD_PUBLIC_TYPES
+
+enum IRC_Buffer_Types { IRC_DIRECT, IRC_CHANNEL, IRC_GLOBAL };
+
+typedef unsigned short IRC_Modes;
+typedef uintmax_t IRC_Counter;
+
+#ifdef UIRC_FEATURE_IRCV3
+typedef struct {
+ char *key, *value;
+ bool clientbound;
+} IRC_Tag;
+
+typedef struct {
+ char* name;
+ bool active;
+} IRC_Capability;
+#endif /* UIRC_FEATURE_IRCV3 */
+
+typedef struct {
+ char * nick, *user, *host, *real;
+ IRC_Modes modes;
+ bool is_service;
+} IRC_User;
+
+#define IRC_MAXARGS 15
+
+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 */
+#ifdef UIRC_FEATURE_IRCV3
+ llist_t* tag_list;
+#endif /* UIRC_FEATURE_IRCV3 */
+} IRC_Message;
+
+typedef struct {
+ enum IRC_Buffer_Types type;
+ char * name, *topic, *key;
+ bool subscribed;
+ IRC_Modes modes;
+ llist_t * user_list, *message_list;
+} IRC_Buffer;
+
+typedef struct {
+ char * addr, *svc;
+ IRC_User* user;
+ IRC_Buffer* buf_list;
+#ifdef UIRC_FEATURE_IRCV3
+ llist_t* cap_list;
+#endif /* UIRC_FEATURE_IRCV3 */
+} IRC_Network;
+
+#endif /* UIRC_GUARD_PUBLIC_TYPES */
+
diff --git a/src/public/uirc.h b/src/uirc.h
similarity index 82%
rename from src/public/uirc.h
rename to src/uirc.h
index e308194..ac58b83 100644
--- a/src/public/uirc.h
+++ b/src/uirc.h
@@ -17,19 +17,13 @@
*/
#include "assemblers.h"
-#include "commands.h"
-#include "converters.h"
#include "errors.h"
#include "modes.h"
#include "replies.h"
#include "tokenizers.h"
#include "types.h"
-#ifdef UIRC_VALIDATORS
+#ifdef UIRC_FEATURE_VALIDATORS
#include "validators.h"
-#endif /* UIRC_VALIDATORS */
+#endif /* UIRC_FEATURE_VALIDATORS */
-#ifdef UIRC_IRCV3
-#include "capabilities.h"
-#include "tags.h"
-#endif /* UIRC_IRCV3 */
diff --git a/src/validators.c b/src/validators/validators.c
similarity index 72%
rename from src/validators.c
rename to src/validators/validators.c
index 59bd700..6ee093f 100644
--- a/src/validators.c
+++ b/src/validators/validators.c
@@ -16,17 +16,16 @@
* along with uIRC. If not, see .
*/
-#include "public/validators.h"
+#include "validators.h"
-#include "public/errors.h"
-#include "public/types.h"
+#include "../errors.h" // ERR_UIRC_*
-#include
-#include
-#include
+#include // assert()
+#include // NULL
+#include // strchr()
size_t
-Val_type_nocrlf(const char* str)
+uirc_validator_string_nocrlf(const char* str)
{
assert(str != NULL);
const char* save = str;
@@ -37,7 +36,7 @@ Val_type_nocrlf(const char* str)
}
size_t
-Val_type_nospcl(const char* str)
+uirc_validator_string_nospcl(const char* str)
{
assert(str != NULL);
const char* save = str;
@@ -48,7 +47,7 @@ Val_type_nospcl(const char* str)
}
size_t
-Val_type_noblcm(const char* str)
+uirc_validator_string_noblcm(const char* str)
{
assert(str != NULL);
const char* save = str;
@@ -58,8 +57,10 @@ Val_type_noblcm(const char* str)
return (size_t)(str - save);
}
+// TODO: Make this read only
+// TODO: Improve the logic for this
size_t
-Val_channame(char* chan)
+uirc_validator_buffer_channel(char* chan)
{
assert(chan != NULL);
if (*chan != '#' && *chan != '+' && *chan != '!' && *chan != '&') return 0;
@@ -67,20 +68,20 @@ Val_channame(char* chan)
char* clps = ++chan;
if ((clps = strchr(chan, ':')) != NULL) {
*clps = '\0';
- if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1) {
+ if (uirc_validator_string_nospcl(chan) != 1 || uirc_validator_string_nocrlf(chan) != 1 || uirc_validator_string_noblcm(chan) != 1) {
*clps = ':';
return 0;
}
*clps = ':';
chan = ++clps;
}
- if (Val_type_nospcl(chan) != 1 || Val_type_nocrlf(chan) != 1 || Val_type_noblcm(chan) != 1) return 0;
+ if (uirc_validator_string_nospcl(chan) != 1 || uirc_validator_string_nocrlf(chan) != 1 || uirc_validator_string_noblcm(chan) != 1) return 0;
return (size_t)(save - chan);
}
// TODO: Work on the logic for this
signed short
-Val_mesg(IRC_Message* mesg)
+uirc_validator_message(IRC_Message* mesg)
{
assert(mesg != NULL);
for (unsigned int i = 0; mesg->args[i] != NULL; i++) {
diff --git a/src/public/validators.h b/src/validators/validators.h
similarity index 63%
rename from src/public/validators.h
rename to src/validators/validators.h
index 2608022..053c15b 100644
--- a/src/public/validators.h
+++ b/src/validators/validators.h
@@ -18,18 +18,18 @@
/*! \file */
-#include "types.h"
+#include "../types.h" // IRC_Message
#include
-#ifndef UIRC_GUARD_VALIDATORS
-#define UIRC_GUARD_VALIDATORS
+#ifndef UIRC_GUARD_PUBLIC_VALIDATORS
+#define UIRC_GUARD_PUBLIC_VALIDATORS
-size_t Val_type_nocrlf(const char* str);
-size_t Val_type_nospcl(const char* str);
-size_t Val_type_noblcm(const char* str);
-size_t Val_channame(char* chan);
-signed short Val_mesg(IRC_Message* mesg);
+size_t uirc_validator_string_nocrlf(const char* str);
+size_t uirc_validator_string_nospcl(const char* str);
+size_t uirc_validator_string_noblcm(const char* str);
+size_t uirc_validator_buffer_channel(char* chan);
+signed short uirc_validator_message(IRC_Message* mesg);
-#endif /* UIRC_GUARD_VALIDATORS */
+#endif /* UIRC_GUARD_PUBLIC_VALIDATORS */