| summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src')
41 files changed, 1058 insertions, 2418 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 594b14f..147f2d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,9 @@ add_subdirectory(cli) add_subdirectory(core) -add_subdirectory(file) -add_subdirectory(irc) add_subdirectory(knowledge) -add_subdirectory(tool) +add_subdirectory(pipe) +add_subdirectory(server) +add_subdirectory(storage) set( SRC_FILES ${SRC_FILES} diff --git a/src/cli/parameters.c b/src/cli/parameters.c index 77c33aa..82ac9d1 100644 --- a/src/cli/parameters.c +++ b/src/cli/parameters.c @@ -1,148 +1,38 @@ -#include <stdlib.h> #include <stdio.h> -#include <string.h> +#include <stdlib.h> #include <errno.h> -#include "../pervasive.h" - -#include "error.h" +#include "../core/index.h" #include "parameters.h" -static void load_default_parameters -( - struct ZoO_parameters param [const restrict static 1] -) -{ - param->data_filename = ZoO_DEFAULT_DATA_FILENAME; - param->new_data_filename = (char *) NULL; - - param->irc_server_addr = ZoO_DEFAULT_IRC_SERVER_ADDR; - param->irc_server_port = ZoO_DEFAULT_IRC_SERVER_PORT; - param->irc_server_channel = ZoO_DEFAULT_IRC_SERVER_CHANNEL; - param->irc_username = ZoO_DEFAULT_IRC_USERNAME; - param->irc_realname = ZoO_DEFAULT_IRC_REALNAME; - - param->reply_rate = ZoO_DEFAULT_REPLY_RATE; - - param->aliases_count = 0; - param->aliases = NULL; -} - -static void print_help (const char exec [const restrict static 1]) -{ - printf - ( - "Usage: %s [option_1 option_2 ...] NICKNAME [ALIAS_1 ALIAS_2 ...] \n" - "NICKNAME is used as the IRC nickname value.\n" - "If NICKNAME or any ALIAS is found in an event, the program will reply.\n" - "\nAvailable options:\n" - " [--data-filename | -df] FILENAME\n" - " Learn content from FILENAME before connecting.\n" - " Default: %s.\n" - " [--new-data-filename | -ndf] FILENAME\n" - " Store new data learned in FILENAME.\n" - " Default: value of the --data-filename param.\n" - " [--irc-server-addr | -isa] IRC_SERVER_ADDR\n" - " Connect to this server address.\n" - " Default: %s.\n" - " [--irc-server-port | -isp] IRC_SERVER_PORT\n" - " Connect to this server port.\n" - " Default: %s.\n" - " [--irc-server-channel | -isc] IRC_SERVER_CHANNEL\n" - " Connect to this server's channel.\n" - " Default: %s.\n" - " [--irc-username | -iu] USERNAME\n" - " Connect using this as 'username' (shown in WHOIS).\n" - " Default: %s.\n" - " [--irc-realname | -ir] REALNAME\n" - " Connect using this as 'realname' (shown in WHOIS).\n" - " Default: %s.\n" - " [--reply-rate | -rr] REPLY_RATE\n" - " Chance to reply to an event (integer, range [0, 100]).\n" - " Default: %d.\n", - exec, - ZoO_DEFAULT_DATA_FILENAME, - ZoO_DEFAULT_IRC_SERVER_ADDR, - ZoO_DEFAULT_IRC_SERVER_PORT, - ZoO_DEFAULT_IRC_SERVER_CHANNEL, - ZoO_DEFAULT_IRC_USERNAME, - ZoO_DEFAULT_IRC_REALNAME, - ZoO_DEFAULT_REPLY_RATE - ); -} - -static int parse_string_arg -( - const char * restrict dest [const restrict static 1], - int const i, - const char * restrict argv [const restrict static 1], - int const argc -) -{ - if (i == argc) - { - ZoO_FATAL - ( - "Missing value for parameter '%s'.", - /* Safe: i > 1 */ - argv[i - 1] - ); - - return -1; - } - - *dest = argv[i]; - - return 0; -} - -static int parse_integer_arg +static int parse_markov_order ( - int dest [const restrict static 1], - int const i, - const char * argv [const restrict static 1], - int const argc, - int const min_val, - int const max_val + struct ZoO_parameters param [const restrict static 1], + const char argv [const restrict] ) { - long int result; - char * endptr; - const int old_errno = errno; - - if (i == argc) - { - ZoO_FATAL - ( - "Missing value for parameter '%s'.", - /* Safe: i > 1 */ - argv[i - 1] - ); - - return -1; - } + long long int input; + const int old_errno = errno; - errno = 0; + errno = 0; - result = strtol(argv[i], &endptr, 10); + input = strtoll(argv, (char **) NULL, 10); if ( (errno != 0) - || ((*endptr) == '\n') - || (result < min_val) - || (result > max_val) + || (input > (long long int) ZoO_INDEX_MAX) + || (input < 1) ) { - ZoO_FATAL + fprintf ( - "Invalid or missing value for parameter '%s', accepted range is " - "[%d, %d] (integer).", - /* Safe: i > 1 */ - argv[i - 1], - min_val, - max_val + stderr, + "[F] Invalid or value for parameter 'MARKOV_ORDER', accepted" + "range is " + "[1, %lli] (integer).", + (long long int) ZoO_INDEX_MAX ); errno = old_errno; @@ -150,236 +40,45 @@ static int parse_integer_arg return -1; } - *dest = (int) result; + param->markov_order = (ZoO_index) input; errno = old_errno; return 0; } -int ZoO_parameters_initialize +enum ZoO_invocation_objective ZoO_parameters_initialize ( struct ZoO_parameters param [const restrict static 1], int const argc, - const char * argv [const restrict static argc] + const char * argv [const static argc] ) { - int i; + param->session = (const char *) NULL; + param->markov_order = 1; + param->storage = (const char *) NULL; - load_default_parameters(param); - - for (i = 1; i < argc; ++i) + switch (argc) { - if - ( - (strcmp(argv[i], "--data-filename") == 0) - || (strcmp(argv[i], "-df") == 0) - ) - { - i += 1; - - if - ( - parse_string_arg - ( - &(param->data_filename), - i, - argv, - argc - ) < 0 - ) - { - return -1; - } - } - else if - ( - (strcmp(argv[i], "--new-data-filename") == 0) - || (strcmp(argv[i], "-ndf") == 0) - ) - { - i += 1; - - if - ( - parse_string_arg - ( - &(param->new_data_filename), - i, - argv, - argc - ) < 0 - ) - { - return -1; - } - } - else if - ( - (strcmp(argv[i], "--irc-server-addr") == 0) - || (strcmp(argv[i], "-isa") == 0) - ) - { - i += 1; - - if - ( - parse_string_arg - ( - &(param->irc_server_addr), - i, - argv, - argc - ) < 0 - ) - { - return -1; - } - } - else if - ( - (strcmp(argv[i], "--irc-server-port") == 0) - || (strcmp(argv[i], "-isp") == 0) - ) - { - i += 1; - - if - ( - parse_string_arg - ( - &(param->irc_server_port), - i, - argv, - argc - ) < 0 - ) - { - return -1; - } - } - else if - ( - (strcmp(argv[i], "--irc-server-channel") == 0) - || (strcmp(argv[i], "-isc") == 0) - ) - { - i += 1; - - if - ( - parse_string_arg - ( - &(param->irc_server_channel), - i, - argv, - argc - ) < 0 - ) - { - return -1; - } - } - else if - ( - (strcmp(argv[i], "--irc-username") == 0) - || (strcmp(argv[i], "-iu") == 0) - ) - { - i += 1; + case 4: + param->session = argv[1]; + param->storage = argv[3]; - if - ( - parse_string_arg - ( - &(param->irc_username), - i, - argv, - argc - ) < 0 - ) + if (parse_markov_order(param, argv[2]) < 0) { - return -1; + return ZoO_PRINTS_HELP; } - } - else if - ( - (strcmp(argv[i], "--irc-realname") == 0) - || (strcmp(argv[i], "-in") == 0) - ) - { - i += 1; - - if - ( - parse_string_arg - ( - &(param->irc_realname), - i, - argv, - argc - ) < 0 - ) + else { - return -1; + return ZoO_RUNS; } - } - else if - ( - (strcmp(argv[i], "--reply-rate") == 0) - || (strcmp(argv[i], "-rr") == 0) - ) - { - i += 1; - if - ( - parse_integer_arg - ( - &(param->reply_rate), - i, - argv, - argc, - 0, - 100 - ) < 0 - ) - { - return -1; - } - } - else if - ( - (strcmp(argv[i], "--help") == 0) - || (strcmp(argv[i], "-h") == 0) - ) - { - print_help(argv[0]); + case 3: + param->session = argv[1]; - return 0; - } - else - { - break; - } - } + return ZoO_CLEANS_UP; - if (i == argc) - { - ZoO_S_FATAL("Missing argument: NICKNAME"); - - print_help(argv[0]); - - return -1; + default: + return ZoO_PRINTS_HELP; } - - param->aliases_count = (argc - i); - param->aliases = (argv + i); - - if (param->new_data_filename == (char *) NULL) - { - param->new_data_filename = param->data_filename; - } - - return 1; } diff --git a/src/cli/parameters.h b/src/cli/parameters.h index 1011e2b..7927ef7 100644 --- a/src/cli/parameters.h +++ b/src/cli/parameters.h @@ -1,11 +1,16 @@ -#ifndef _ZoO_IO_PARAMETERS_H_ -#define _ZoO_IO_PARAMETERS_H_ +#ifndef _ZoO_CLI_PARAMETERS_H_ +#define _ZoO_CLI_PARAMETERS_H_ #include "parameters_types.h" -int ZoO_parameters_initialize +char * ZoO_parameters_get_session_name ( - struct ZoO_parameters param [const static 1], + const struct ZoO_parameters param [const restrict static 1] +); + +enum ZoO_invocation_objective ZoO_parameters_initialize +( + struct ZoO_parameters param [const restrict static 1], int const argc, const char * argv [const static argc] ); diff --git a/src/cli/parameters_types.h b/src/cli/parameters_types.h index 15b5254..f9ca88b 100644 --- a/src/cli/parameters_types.h +++ b/src/cli/parameters_types.h @@ -1,67 +1,18 @@ -#ifndef _ZoO_IO_PARAMETERS_TYPES_H_ -#define _ZoO_IO_PARAMETERS_TYPES_H_ +#ifndef _ZoO_CLI_PARAMETERS_TYPES_H_ +#define _ZoO_CLI_PARAMETERS_TYPES_H_ -#include "../pervasive.h" - -/******************************************************************************/ -/** DEFAULT VALUES ************************************************************/ -/******************************************************************************/ - -#ifndef ZoO_DEFAULT_DATA_FILENAME - #define ZoO_DEFAULT_DATA_FILENAME "./memory.txt" -#endif - -#ifndef ZoO_DEFAULT_IRC_SERVER_ADDR - #define ZoO_DEFAULT_IRC_SERVER_ADDR "irc.foonetic.net" -#endif - -#ifndef ZoO_DEFAULT_IRC_SERVER_PORT - #define ZoO_DEFAULT_IRC_SERVER_PORT "6667" -#endif - -#ifndef ZoO_DEFAULT_IRC_SERVER_CHANNEL - #define ZoO_DEFAULT_IRC_SERVER_CHANNEL "#theborghivemind" -#endif - -#ifndef ZoO_DEFAULT_IRC_USERNAME - #define ZoO_DEFAULT_IRC_USERNAME "zeroofone" -#endif - -#ifndef ZoO_DEFAULT_IRC_REALNAME - #define ZoO_DEFAULT_IRC_REALNAME "Zero of One (bot)" -#endif - -#ifndef ZoO_DEFAULT_REPLY_RATE - #define ZoO_DEFAULT_REPLY_RATE 8 -#endif - -/******************************************************************************/ -/** DEBUG LEVELS **************************************************************/ -/******************************************************************************/ - -#ifndef ZoO_DEBUG_PARAMETERS - #define ZoO_DEBUG_PARAMETERS (0 || ZoO_DEBUG_ALL) -#endif - -/******************************************************************************/ -/** FUNCTIONS *****************************************************************/ -/******************************************************************************/ +enum ZoO_invocation_objective +{ + ZoO_PRINTS_HELP, + ZoO_CLEANS_UP, + ZoO_RUNS +}; struct ZoO_parameters { - const char * restrict data_filename; - const char * restrict new_data_filename; - - const char * restrict irc_server_addr; - const char * restrict irc_server_port; - const char * restrict irc_server_channel; - const char * restrict irc_username; - const char * restrict irc_realname; - - int reply_rate; - - int aliases_count; - const char * restrict * restrict aliases; + const char * restrict session; + ZoO_index markov_order; + const char * restrict storage; }; #endif diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1e1daa8..bc722d7 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -5,6 +5,7 @@ set( ${CMAKE_CURRENT_SOURCE_DIR}/sequence.c ${CMAKE_CURRENT_SOURCE_DIR}/sequence_creation.c ${CMAKE_CURRENT_SOURCE_DIR}/sequence_from_string.c + ${CMAKE_CURRENT_SOURCE_DIR}/sequence_to_string.c ) set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) diff --git a/src/core/index_types.h b/src/core/index_types.h index ad56d52..a71121c 100644 --- a/src/core/index_types.h +++ b/src/core/index_types.h @@ -1,6 +1,8 @@ #ifndef _ZoO_CORE_INDEX_TYPES_H_ #define _ZoO_CORE_INDEX_TYPES_H_ +#include <limits.h> + /* Must be unsigned. */ typedef unsigned int ZoO_index; diff --git a/src/core/sequence.h b/src/core/sequence.h index 77ecd6c..1e286ab 100644 --- a/src/core/sequence.h +++ b/src/core/sequence.h @@ -3,6 +3,9 @@ #include "../core/char_types.h" #include "../core/index_types.h" + +#include "../pipe/pipe.h" + #include "../knowledge/knowledge_types.h" #include "sequence_types.h" @@ -13,7 +16,8 @@ int ZoO_sequence_from_undercase_string const ZoO_index string_length, struct ZoO_knowledge k [const restrict static 1], ZoO_index * sequence [const restrict static 1], - ZoO_index sequence_length [const restrict static 1] + ZoO_index sequence_length [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); /* @@ -44,7 +48,8 @@ int ZoO_sequence_create_from const struct ZoO_knowledge k [const restrict static 1], const ZoO_index markov_order, ZoO_index * sequence [const restrict static 1], - size_t sequence_size [const restrict static 1] + size_t sequence_size [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); /* diff --git a/src/core/sequence_creation.c b/src/core/sequence_creation.c index f460629..c5ca6af 100644 --- a/src/core/sequence_creation.c +++ b/src/core/sequence_creation.c @@ -3,10 +3,11 @@ #include <string.h> #include <stdint.h> /* defines SIZE_MAX */ -#include "../io/error.h" - #include "../core/index.h" -#include "../core/knowledge.h" + +#include "../pipe/pipe.h" + +#include "../knowledge/knowledge.h" #include "sequence.h" @@ -66,7 +67,8 @@ static int left_append ( const ZoO_index word_id, ZoO_index * sequence [const restrict], - const size_t sequence_size + const size_t sequence_size, + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index * new_sequence; @@ -75,6 +77,7 @@ static int left_append { ZoO_S_ERROR ( + io, "Left side append aborted, as the new sequence's size would overflow." ); @@ -87,6 +90,7 @@ static int left_append { ZoO_S_ERROR ( + io, "Left side append aborted, as memory for the new sequence could not be" " allocated." ); @@ -118,6 +122,8 @@ static int left_append * to fit there. * This requires the reallocation of {sequence}. The freeing of the previous * memory space is handled. If an error happened, {*sequence} remains untouched. + * Semaphore: + * Takes then releases access for {k}. * Returns: * 0 on success. * -1 iff nothing fitting was found. @@ -133,13 +139,16 @@ static int extend_left ZoO_index * sequence [const restrict static 1], const size_t sequence_size, const ZoO_index markov_order, - const struct ZoO_knowledge k [const restrict static 1] + const struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { const ZoO_index * restrict preceding_words; const ZoO_index * restrict preceding_words_weights; ZoO_index preceding_words_weights_sum; + (void) ZoO_knowledge_lock_access(k, io); + if ( ZoO_knowledge_find_preceding_words @@ -149,10 +158,13 @@ static int extend_left markov_order, &preceding_words, &preceding_words_weights, - &preceding_words_weights_sum + &preceding_words_weights_sum, + io ) < 0 ) { + (void) ZoO_knowledge_unlock_access(k, io); + return -1; } @@ -168,13 +180,18 @@ static int extend_left preceding_words_weights_sum ), sequence, - sequence_size + sequence_size, + io ) < 0 ) { + (void) ZoO_knowledge_unlock_access(k, io); + return -3; } + (void) ZoO_knowledge_unlock_access(k, io); + return 0; } @@ -206,14 +223,15 @@ static int complete_left_part_of_sequence size_t sequence_size [const restrict static 1], const ZoO_index markov_order, ZoO_index credits [const restrict], - const struct ZoO_knowledge k [const restrict static 1] + const struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { for (;;) { if ((credits == (ZoO_index *) NULL) || (*credits > 0)) { - if (extend_left(sequence, *sequence_size, markov_order, k) < 0) + if (extend_left(sequence, *sequence_size, markov_order, k, io) < 0) { /* We are sure *sequence[0] is defined. */ if (*sequence[0] == ZoO_START_OF_SEQUENCE_ID) @@ -255,6 +273,7 @@ static int complete_left_part_of_sequence case ZoO_END_OF_SEQUENCE_ID: ZoO_S_WARNING ( + io, "END OF LINE was added at the left part of an sequence." ); @@ -291,7 +310,8 @@ static int right_append ZoO_index * sequence [const restrict], const ZoO_index word_id, const size_t sequence_size, - const ZoO_index sequence_length + const ZoO_index sequence_length, + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index * new_sequence; @@ -300,6 +320,7 @@ static int right_append { ZoO_S_ERROR ( + io, "Right side append aborted, as the new sequence's size would overflow." ); @@ -317,6 +338,7 @@ static int right_append { ZoO_S_ERROR ( + io, "Right side append aborted, as memory for the new sequence could not " "be allocated." ); @@ -336,6 +358,8 @@ static int right_append * to fit there. * This requires the reallocation of {sequence}. The freeing of the previous * memory space is handled. If an error happened, {*sequence} remains untouched. + * Semaphore: + * Takes then releases access for {k}. * Returns: * 0 on success. * -1 iff nothing fitting was found. @@ -352,7 +376,8 @@ static int extend_right const size_t sequence_size, const ZoO_index markov_order, const ZoO_index sequence_length, - const struct ZoO_knowledge k [const restrict static 1] + const struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { const ZoO_index * restrict following_words; @@ -360,6 +385,8 @@ static int extend_right ZoO_index following_words_weights_sum; + (void) ZoO_knowledge_lock_access(k, io); + if ( ZoO_knowledge_find_following_words @@ -374,6 +401,8 @@ static int extend_right ) < 0 ) { + (void) ZoO_knowledge_unlock_access(k, io); + return -1; } @@ -390,13 +419,18 @@ static int extend_right following_words_weights_sum ), sequence_size, - sequence_length + sequence_length, + io ) < 0 ) { + (void) ZoO_knowledge_unlock_access(k, io); + return -3; } + (void) ZoO_knowledge_unlock_access(k, io); + return 0; } @@ -428,7 +462,8 @@ static int complete_right_part_of_sequence size_t sequence_size [const restrict static 1], const ZoO_index markov_order, ZoO_index credits [const restrict], - const struct ZoO_knowledge k [const restrict static 1] + const struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index sequence_length; @@ -447,7 +482,8 @@ static int complete_right_part_of_sequence *sequence_size, markov_order, sequence_length, - k + k, + io ) < 0 ) { @@ -492,6 +528,7 @@ static int complete_right_part_of_sequence case ZoO_START_OF_SEQUENCE_ID: ZoO_S_WARNING ( + io, "END OF LINE was added at the right part of an sequence." ); @@ -525,13 +562,15 @@ static int allocate_initial_sequence ( ZoO_index * sequence [const restrict static 1], size_t sequence_size [const restrict static 1], - const ZoO_index markov_order + const ZoO_index markov_order, + const struct ZoO_pipe io [const restrict static 1] ) { if ((SIZE_MAX / sizeof(ZoO_index)) > ((size_t) markov_order)) { ZoO_S_ERROR ( + io, "Unable to store size of the initial sequence in a size_t variable." "Either reduce the size of a ZoO_index or the markovian order." ); @@ -551,6 +590,7 @@ static int allocate_initial_sequence ZoO_S_ERROR ( + io, "Unable to allocate the memory required for an new sequence." ); @@ -581,7 +621,8 @@ static int initialize_sequence ZoO_index sequence [const restrict static 1], const ZoO_index initial_word, const ZoO_index markov_order, - const struct ZoO_knowledge k [const static 1] + const struct ZoO_knowledge k [const static 1], + const struct ZoO_pipe io [const restrict static 1] ) { const ZoO_index * restrict following_sequences_ref; @@ -596,6 +637,9 @@ static int initialize_sequence return 0; } + /* TODO */ + (void) ZoO_knowledge_lock_access(k, io); + if ( ZoO_knowledge_get_following_sequences_ref @@ -604,12 +648,16 @@ static int initialize_sequence initial_word, &following_sequences_ref, &following_sequences_weights, - &following_sequences_weights_sum + &following_sequences_weights_sum, + io ) < 0 ) { + (void) ZoO_knowledge_unlock_access(k, io); + ZoO_S_ERROR ( + io, "Unable to find any sequence that would precede the initial word." ); @@ -628,7 +676,8 @@ static int initialize_sequence following_sequences_weights_sum ) ], - &chosen_sequence + &chosen_sequence, + io ); /* Safe if 'allocate_initial_sequence' succeeded. */ @@ -639,6 +688,8 @@ static int initialize_sequence ((((size_t) markov_order) - 1) * sizeof(ZoO_index)) ); + (void) ZoO_knowledge_unlock_access(k, io); + return 0; } @@ -654,15 +705,16 @@ int ZoO_sequence_create_from const struct ZoO_knowledge k [const restrict static 1], const ZoO_index markov_order, ZoO_index * sequence [const restrict static 1], - size_t sequence_size [const restrict static 1] + size_t sequence_size [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { - if (allocate_initial_sequence(sequence, sequence_size, markov_order) < 0) + if (allocate_initial_sequence(sequence, sequence_size, markov_order, io) < 0) { return -1; } - if (initialize_sequence(*sequence, initial_word, markov_order, k) < 0) + if (initialize_sequence(*sequence, initial_word, markov_order, k, io) < 0) { free((void *) *sequence); *sequence_size = 0; @@ -678,7 +730,8 @@ int ZoO_sequence_create_from sequence_size, markov_order, credits, - k + k, + io ) < 0 ) { @@ -696,7 +749,8 @@ int ZoO_sequence_create_from sequence_size, markov_order, credits, - k + k, + io ) < 0 ) { @@ -709,7 +763,7 @@ int ZoO_sequence_create_from if ((*sequence_size / sizeof(ZoO_index)) < 3) { /* 2 elements, for start and stop. */ - ZoO_S_ERROR("Created sequence was empty."); + ZoO_S_ERROR(io, "Created sequence was empty."); free((void *) *sequence); *sequence_size = 0; diff --git a/src/core/sequence_from_string.c b/src/core/sequence_from_string.c index 51d7049..deaec86 100644 --- a/src/core/sequence_from_string.c +++ b/src/core/sequence_from_string.c @@ -6,7 +6,7 @@ #include "../core/char.h" #include "../core/index.h" -#include "../cli/cli.h" +#include "../pipe/pipe.h" #include "../knowledge/knowledge.h" @@ -16,7 +16,8 @@ static int add_word_id_to_sequence ( const ZoO_index word_id, ZoO_index * sequence [const restrict static 1], - ZoO_index sequence_length [const restrict static 1] + ZoO_index sequence_length [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index * new_sequence; @@ -32,7 +33,7 @@ static int add_word_id_to_sequence if (new_sequence == (ZoO_index *) NULL) { - ZoO_S_ERROR("Unable to reallocate a sequence to add word ids to it."); + ZoO_S_ERROR(io, "Unable to reallocate a sequence to add word ids to it."); return -1; } @@ -43,13 +44,19 @@ static int add_word_id_to_sequence /******************************************************************************/ /** HANDLING PUNCTUATION ******************************************************/ /******************************************************************************/ + +/* + * Semaphore: + * Takes then releases access for {k}. + */ static int add_punctuation_to_sequence ( const ZoO_char string [const restrict static 1], const ZoO_char punctuation, ZoO_index * sequence [const restrict static 1], ZoO_index sequence_length [const restrict static 1], - const struct ZoO_knowledge k [const restrict static 1] + const struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index word_id; @@ -58,10 +65,15 @@ static int add_punctuation_to_sequence as_word[0] = punctuation; as_word[1] = '\0'; - if (ZoO_knowledge_find_word_id(k, as_word, 2, &word_id) < 0) + (void) ZoO_knowledge_lock_access(k, io); + + if (ZoO_knowledge_find_word_id(k, as_word, 2, &word_id, io) < 0) { + (void) ZoO_knowledge_unlock_access(k, io); + ZoO_PROG_ERROR ( + io, "'%s' was defined as a punctuation, was found in a string, yet is not" " defined in the knowledge database.", as_word @@ -70,7 +82,9 @@ static int add_punctuation_to_sequence return -1; } - if (add_word_id_to_sequence(word_id, sequence, sequence_length) < 0) + (void) ZoO_knowledge_unlock_access(k, io); + + if (add_word_id_to_sequence(word_id, sequence, sequence_length, io) < 0) { return -1; } @@ -91,6 +105,11 @@ static int word_is_punctuation_terminated /******************************************************************************/ /** HANDLING WORDS ************************************************************/ /******************************************************************************/ + +/* + * Semaphore: + * Takes then releases access for {k}. + */ static int add_word_to_sequence ( const ZoO_char string [const restrict static 1], @@ -98,7 +117,8 @@ static int add_word_to_sequence const ZoO_index word_length, ZoO_index * sequence [const restrict static 1], ZoO_index sequence_length [const restrict static 1], - struct ZoO_knowledge k [const restrict static 1] + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index word_id; @@ -109,6 +129,8 @@ static int add_word_to_sequence return 0; } + (void) ZoO_knowledge_lock_access(k, io); + if ( ZoO_knowledge_learn_word @@ -116,14 +138,19 @@ static int add_word_to_sequence k, (string + word_start), word_length, - &word_id + &word_id, + io ) < 0 ) { + (void) ZoO_knowledge_unlock_access(k, io); + return -1; } - if (add_word_id_to_sequence(word_id, sequence, sequence_length) < 0) + (void) ZoO_knowledge_unlock_access(k, io); + + if (add_word_id_to_sequence(word_id, sequence, sequence_length, io) < 0) { return -1; } @@ -138,7 +165,8 @@ static int add_finding_to_sequence const ZoO_index word_length, ZoO_index * sequence [const restrict static 1], ZoO_index sequence_length [const restrict static 1], - struct ZoO_knowledge k [const restrict static 1] + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index punctuation; @@ -161,7 +189,8 @@ static int add_finding_to_sequence (word_length - punctuation), sequence, sequence_length, - k + k, + io ) < 0 ) { @@ -179,7 +208,8 @@ static int add_finding_to_sequence string[word_start + word_length - 1], sequence, sequence_length, - k + k, + io ) < 0 ) ) @@ -232,14 +262,17 @@ static int find_word /******************************************************************************/ /** EXPORTED ******************************************************************/ -/******************************************************************************/ +/******************************************************************************/a + +/* See: "sequence.h" */ int ZoO_sequence_from_undercase_string ( const ZoO_char string [const restrict], const ZoO_index string_length, struct ZoO_knowledge k [const restrict static 1], ZoO_index * sequence [const restrict static 1], - ZoO_index sequence_length [const restrict static 1] + ZoO_index sequence_length [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index word_start, word_length; @@ -256,7 +289,8 @@ int ZoO_sequence_from_undercase_string ( ZoO_START_OF_SEQUENCE_ID, sequence, - sequence_length + sequence_length, + io ) < 0 ) { @@ -279,7 +313,8 @@ int ZoO_sequence_from_undercase_string word_length, sequence, sequence_length, - k + k, + io ) < 0 ) { @@ -299,7 +334,8 @@ int ZoO_sequence_from_undercase_string ( ZoO_END_OF_SEQUENCE_ID, sequence, - sequence_length + sequence_length, + io ) < 0 ) { diff --git a/src/core/sequence_to_string.c b/src/core/sequence_to_string.c new file mode 100644 index 0000000..16fc859 --- /dev/null +++ b/src/core/sequence_to_string.c @@ -0,0 +1,97 @@ +#define _POSIX_C_SOURCE 200809L +#include <stdlib.h> +#include <string.h> +#include <stdint.h> /* defines SIZE_MAX */ + +#include "../core/char.h" +#include "../core/index.h" + +#include "../cli/cli.h" + +#include "../knowledge/knowledge.h" + +#include "sequence.h" + +/* TODO */ +static int add_word +( + const ZoO_index word_id, + const size_t destination_size, + struct ZoO_knowledge k [const restrict static 1], + ZoO_char destination [const restrict static max_destination_length], + size_t destination_used_size [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + const ZoO_char * word; + size_t word_size; + + (void) ZoO_knowledge_lock_access(k, io); + ZoO_knowledge_get_word(k, word_id, &word, &word_size, io); + (void) ZoO_knowledge_unlock_access(k, io); + + if ((destination_used_size + word_size) > max_destination_length) + { + } + + if + ( + (word_size == 2) + && ZoO_char_is_punctuation(word[0]) + ) + { + snprintf + ( + (destination + *destination_used_size), + word_size, + ZoO_CHAR_STRING_SYMBOL, + current_sentence + ); + } + else + { + } + + return 0; +} +/******************************************************************************/ +/** EXPORTED ******************************************************************/ +/******************************************************************************/ + +int ZoO_sequence_to_undercase_string +( + const ZoO_index sequence [const restrict static 1], + const ZoO_index sequence_length, + const ZoO_index max_destination_length, + struct ZoO_knowledge k [const restrict static 1], + ZoO_char destination [const restrict static max_destination_length], + ZoO_index destination_length [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + ZoO_index i; + const ZoO_index actual_length = (sequence_length - 1); + + for (i = 0; i < actual_length; ++i) + { + if + ( + add_word + ( + sequence[i], + max_destination_length, + k, + destination, + destination_length, + io + ) < 0 + ) + { + *destination_length = 0; + + return -1; + } + } + + return 0; +} diff --git a/src/file/data_input.c b/src/file/data_input.c deleted file mode 100644 index e31d33b..0000000 --- a/src/file/data_input.c +++ /dev/null @@ -1,98 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <stdlib.h> -#include <string.h> -#include <stdint.h> /* defines SIZE_MAX */ - -#include "error.h" - -#include "data_input.h" - -int ZoO_data_input_open -( - struct ZoO_data_input di [const static 1], - const char filename [const restrict static 1] -) -{ - /* prevents di [restrict] */ - ZoO_strings_initialize(&(di->string)); - - di->file = fopen(filename, "r"); - - if (di->file == (FILE *) NULL) - { - ZoO_ERROR - ( - "Could not open file '%s' in readonly mode.", - filename - ); - - return -1; - } - - return 0; -} - -int ZoO_data_input_read_line -( - struct ZoO_data_input di [const static 1], - ZoO_index const punctuations_count, - const ZoO_char punctuations [const restrict static punctuations_count] -) -{ - size_t line_size, i, w_start; - ZoO_char * line; - - /* prevents di [restrict] */ - ZoO_strings_finalize(&(di->string)); - - line = (ZoO_char *) NULL; - line_size = 0; - - /* XXX: assumed compatible with ZoO_char */ - - if (getline(&line, &line_size, di->file) < 1) - { - free((void *) line); - - return -1; - } - - line_size = strlen(line); - line[line_size - 1] = '\0'; - - --line_size; /* removed '\n' */ - - if - ( - ZoO_strings_parse - ( - &(di->string), - line_size, - line, - punctuations_count, - punctuations - ) < 0 - ) - { - free((void *) line); - - return -1; - } - - free((void *) line); - - return 0; -} - -void ZoO_data_input_close (struct ZoO_data_input di [const static 1]) -{ - if (di->file != (FILE *) NULL) - { - fclose(di->file); - - di->file = (FILE *) NULL; - } - - /* prevents di [restrict] */ - ZoO_strings_finalize(&(di->string)); -} diff --git a/src/file/data_input.h b/src/file/data_input.h deleted file mode 100644 index a2f004b..0000000 --- a/src/file/data_input.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef _ZoO_IO_DATA_INPUT_H_ -#define _ZoO_IO_DATA_INPUT_H_ - -#include "data_input_types.h" - -int ZoO_data_input_open -( - struct ZoO_data_input di [const static 1], - const char filename [const restrict static 1] -); - -int ZoO_data_input_read_line -( - struct ZoO_data_input di [const static 1], - ZoO_index const punctuations_count, - const ZoO_char punctuations [const restrict static punctuations_count] -); - -void ZoO_data_input_close (struct ZoO_data_input di [const static 1]); - -#endif diff --git a/src/file/data_input_types.h b/src/file/data_input_types.h deleted file mode 100644 index bd2709b..0000000 --- a/src/file/data_input_types.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _ZoO_IO_DATA_INPUT_TYPES_H_ -#define _ZoO_IO_DATA_INPUT_TYPES_H_ - -#include <stdio.h> - -#include "../pervasive.h" - -#include "../tool/strings.h" - -struct ZoO_data_input -{ - FILE * restrict file; - struct ZoO_strings string; -}; - -#endif diff --git a/src/file/data_output.h b/src/file/data_output.h deleted file mode 100644 index ef963a0..0000000 --- a/src/file/data_output.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _ZoO_IO_DATA_OUTPUT_H_ -#define _ZoO_IO_DATA_OUTPUT_H_ - -int ZoO_data_output_write_line -( - const char filename [const restrict static 1], - char line [const restrict static 1], - size_t const line_size -); - -#endif diff --git a/src/irc/network.c b/src/irc/network.c deleted file mode 100644 index edafd4f..0000000 --- a/src/irc/network.c +++ /dev/null @@ -1,568 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -/* "POSIX.1 does not require the inclusion of <sys/types.h>" */ -/* - man page for setsockopt */ -/* #include <sys/types.h> */ -#include <sys/socket.h> -#include <sys/time.h> - -#include "error.h" - -#include "network.h" - -static int re_create_socket (struct ZoO_network net [const restrict static 1]) -{ - struct timeval timeout; - const int old_errno = errno; - - errno = 0; - timeout.tv_sec = ZoO_NETWORK_TIMEOUT; - timeout.tv_usec = 0; - - if (net->connection != -1) - { - close(net->connection); - } - - net->connection = - socket - ( - net->addrinfo->ai_family, - net->addrinfo->ai_socktype, - net->addrinfo->ai_protocol - ); - - if (net->connection == -1) - { - ZoO_ERROR("Could not create socket: %s.", strerror(errno)); - - goto RETURN_FAILED; - } - - if - ( - ( - setsockopt - ( - net->connection, - SOL_SOCKET, - SO_RCVTIMEO, - (const void *) &timeout, - (socklen_t) sizeof(struct timeval) - ) < 0 - ) - || - ( - setsockopt - ( - net->connection, - SOL_SOCKET, - SO_SNDTIMEO, - (const void *) &timeout, - (socklen_t) sizeof(struct timeval) - ) < 0 - ) - ) - { - ZoO_ERROR("Could not set timeout on network socket: %s", strerror(errno)); - - goto RETURN_FAILED; - } - - ZoO_S_DEBUG(ZoO_DEBUG_NETWORK, "(Re)connecting to network..."); - - if - ( - connect - ( - net->connection, - net->addrinfo->ai_addr, - net->addrinfo->ai_addrlen - ) != 0 - ) - { - ZoO_ERROR("Could not establish connection: %s", strerror(errno)); - - goto RETURN_FAILED; - } - - errno = old_errno; - - return 0; - -RETURN_FAILED: - errno = old_errno; - - return -1; -} - -static int reconnect (struct ZoO_network net [const restrict static 1]) -{ - const int old_errno = errno; - - memset(net->in, 0, (sizeof(ZoO_char) * 513)); - memset(net->out, 0, (sizeof(ZoO_char) * 513)); - memset(net->buffer, 0, (sizeof(ZoO_char) * 513)); - - net->buffer_index = 0; - net->buffer_remaining = 0; - - if (re_create_socket(net) < 0) - { - return -1; - } - - snprintf(net->out, 512, "USER %s 8 * :%s\r\n", net->user, net->name); - - if (write(net->connection, net->out, strlen(net->out)) < 1) - { - goto RETURN_WRITE_FAILED; - } - - snprintf(net->out, 512, "NICK %s\r\n", net->nick); - - if (write(net->connection, net->out, strlen(net->out)) < 1) - { - goto RETURN_WRITE_FAILED; - } - - net->buffer_remaining = 0; - net->buffer_index = 0; - - ZoO_S_DEBUG(ZoO_DEBUG_NETWORK, "(Re)connected."); - - errno = old_errno; - - return 0; - -RETURN_WRITE_FAILED: - ZoO_ERROR - ( - "Unable to write to the network: %s", - strerror(errno) - ); - - errno = old_errno; - - return -1; -} - -int ZoO_network_connect -( - struct ZoO_network net [const static 1], - const char host [const restrict static 1], - const char port [const restrict static 1], - const char channel [const restrict static 1], - const char user [const restrict static 1], - const char name [const restrict static 1], - const char nick [const restrict static 1] -) -{ - int error; - struct addrinfo hints; - const int old_errno = errno; - - net->connection = -1; - net->channel = channel; - net->user = user; - net->name = name; - net->nick = nick; - net->buffer_index = 0; - net->buffer_remaining = 0; - - memset(&hints, 0, sizeof(struct addrinfo)); - memset(net->in, 0, (sizeof(ZoO_char) * 513)); - memset(net->out, 0, (sizeof(ZoO_char) * 513)); - memset(net->buffer, 0, (sizeof(ZoO_char) * 513)); - - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - - errno = 0; - - error = getaddrinfo(host, port, &hints, &(net->addrinfo)); - - if (error != 0) - { - if (error == EAI_SYSTEM) - { - ZoO_ERROR - ( - "Could not retrieve server information: %s.", - strerror(errno) - ); - } - else - { - ZoO_FATAL - ( - "Could not retrieve server information: %s.", - gai_strerror(error) - ); - } - - errno = old_errno; - - return -1; - } - - errno = old_errno; - - reconnect(net); - - return 0; -} - -static void buffer_msg -( - struct ZoO_network net [const static 1] -) -{ - ssize_t in_count, i; - - if (net->buffer_remaining > 0) - { - in_count = net->buffer_remaining; - net->buffer_remaining = 0; - - goto PARSE_READ; - } - -READ_MORE: - in_count = read(net->connection, net->buffer, 512); - - if (in_count <= 0) - { - ZoO_ERROR("Could not read from network: %s", strerror(errno)); - - while (reconnect(net) < 0) - { - ZoO_S_DEBUG - ( - ZoO_DEBUG_NETWORK, - "Attempting new connection in 5s." - ); - sleep(5); - } - - goto READ_MORE; - } - -PARSE_READ: - for (i = 0; i < in_count; ++i) - { - net->in[net->buffer_index] = net->buffer[i]; - - if - ( - (net->buffer_index > 0) - && (net->in[net->buffer_index - 1] == '\r') - && (net->in[net->buffer_index] == '\n') - ) - { - net->buffer_remaining = (in_count - (i + 1)); - net->in_length = (net->buffer_index - 1); - net->buffer_index = 0; - - if (net->buffer_remaining > 0) - { - memmove - ( - (void *) net->buffer, - (const void *) (net->buffer + (i + 1)), - net->buffer_remaining - ); - } - - return; - } - - net->buffer_index += 1; - - if (net->buffer_index > 512) - { - ZoO_S_WARNING("Incoming message is too long. Discarded."); - - net->buffer_index = 0; - net->buffer_remaining = 0; - - break; - } - } - - goto READ_MORE; -} - -void handle_ping (struct ZoO_network net [const restrict static 1]) -{ - const int old_errno = errno; - - #if ZoO_RANDOMLY_IGNORE_PING == 1 - if ((rand() % 10) < 3) - { - ZoO_S_DEBUG(ZoO_DEBUG_NETWORK, "Ping request ignored."); - - return; - } - - #endif - - #if ZoO_DEBUG_NETWORK_PING == 1 - net->in[net->in_length] = '\0'; - - ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->in] %s", net->in); - - net->in[net->in_length] = '\r'; - #endif - - net->in[1] = 'O'; - - errno = 0; - - if (write(net->connection, net->in, (net->in_length + 2)) < 1) - { - ZoO_ERROR("Could not reply to PING request: %s", strerror(errno)); - - errno = old_errno; - - while (reconnect(net) < 0) - { - ZoO_S_DEBUG - ( - ZoO_DEBUG_NETWORK, - "Attempting new connection in 5s." - ); - sleep(5); - } - - return; - } - - errno = old_errno; - -#if ZoO_DEBUG_NETWORK_PING == 1 - net->in[net->in_length] = '\0'; - - ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->in); -#endif - -} - -int ZoO_network_receive -( - struct ZoO_network net [const restrict static 1], - size_t msg_offset [const restrict static 1], - size_t msg_size [const restrict static 1], - enum ZoO_msg_type type [const restrict static 1] -) -{ - const int old_errno = errno; - ssize_t cmd, i; - -READ_NEW_MSG: - buffer_msg(net); - - net->in[net->in_length + 2] = '\0'; - - /* XXX: doesn't that prevent net [restrict]? */ - if (ZoO_IS_PREFIX("PING", net->in)) - { - - handle_ping(net); - - goto READ_NEW_MSG; - } - - if (net->in_length == 0) - { - goto READ_NEW_MSG; - } - - net->in[net->in_length] = '\0'; - - ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->in] %s", net->in); - - if (net->in[0] == ':') - { - cmd = 0; - - for (i = 1; i < 512; i++) - { - if (net->in[i] == ' ') - { - cmd = (i + 1); - - break; - } - } - - if (ZoO_IS_PREFIX("001", (net->in + cmd))) - { - snprintf - ( - net->out, - 512, - "JOIN :%s\r\n", - net->channel - ); - - errno = 0; - - if (write(net->connection, net->out, strlen(net->out)) < 1) - { - ZoO_ERROR - ( - "Could not send JOIN request: %s", - strerror(errno) - ); - - errno = old_errno; - - if (reconnect(net) < 0) - { - return -1; - } - } - - errno = old_errno; - - ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->out); - - goto READ_NEW_MSG; - } - - if (ZoO_IS_PREFIX("JOIN", (net->in + cmd))) - { - for (i = 1; (i < 512) && (net->in[i] != '!'); ++i) - { - } - - if ((i == 512) || (i == 1)) - { - ZoO_ERROR("Could not find JOIN username: %s", net->in); - - goto READ_NEW_MSG; - } - - *msg_offset = 1; - *msg_size = (i - 1); - net->in[i] = '\0'; - - *type = ZoO_JOIN; - - return 0; - } - - if (ZoO_IS_PREFIX("PRIVMSG", (net->in + cmd))) - { - - for (; i < 512; i++) - { - if (net->in[i] == ':') - { - cmd = (i + 1); - - break; - } - } - - *msg_offset = cmd; - *msg_size = (net->in_length - cmd); - - /*net->in[*msg_size - 1] = '\0'; */ - - *type = ZoO_PRIVMSG; - - return 0; - } - } - - if (ZoO_IS_PREFIX("ERROR", (net->in + cmd))) - { - while (reconnect(net) < 0) - { - ZoO_S_DEBUG - ( - ZoO_DEBUG_NETWORK, - "Attempting new connection in 5s." - ); - sleep(5); - } - } - - goto READ_NEW_MSG; -} - -int ZoO_network_send (struct ZoO_network net [const restrict static 1]) -{ - int const old_errno = errno; - - if (ZoO_IS_PREFIX("\001action", net->out)) - { - - net->out[1] = 'A'; - net->out[2] = 'C'; - net->out[3] = 'T'; - net->out[4] = 'I'; - net->out[5] = 'O'; - net->out[6] = 'N'; - - snprintf - ( - net->in, - 512, - "PRIVMSG %s :%s\001\r\n", - net->channel, - net->out - ); - } - else - { - snprintf - ( - net->in, - 512, - "PRIVMSG %s :%s\r\n", - net->channel, - net->out - ); - } - - errno = 0; - - if (write(net->connection, net->in, strlen(net->in)) < 1) - { - ZoO_ERROR - ( - "Could not send PRIVMSG: %s.", - strerror(errno) - ); - - errno = old_errno; - - if (reconnect(net) < 0) - { - return -2; - } - else - { - return -1; - } - } - - errno = old_errno; - - ZoO_DEBUG(ZoO_DEBUG_NETWORK, "[NET->out] %s", net->in); - - return 0; -} - -void ZoO_network_disconnect (struct ZoO_network net [const restrict static 1]) -{ - freeaddrinfo(net->addrinfo); - close(net->connection); -} - diff --git a/src/irc/network.h b/src/irc/network.h deleted file mode 100644 index 647b19c..0000000 --- a/src/irc/network.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _ZoO_IO_NETWORK_H_ -#define _ZoO_IO_NETWORK_H_ -#include "network_types.h" - -int ZoO_network_connect -( - struct ZoO_network net [const static 1], - const char host [const restrict static 1], - const char port [const restrict static 1], - const char channel [const restrict static 1], - const char user [const restrict static 1], - const char name [const restrict static 1], - const char nick [const restrict static 1] -); - -int ZoO_network_receive -( - struct ZoO_network net [const static 1], - size_t msg_offset [const restrict static 1], - size_t msg_size [const restrict static 1], - enum ZoO_msg_type type [const restrict static 1] -); - -int ZoO_network_send (struct ZoO_network net [const restrict static 1]); - -void ZoO_network_disconnect (struct ZoO_network net [const restrict static 1]); - -#endif diff --git a/src/irc/network_types.h b/src/irc/network_types.h deleted file mode 100644 index 9a328a7..0000000 --- a/src/irc/network_types.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _ZoO_IO_NETWORK_TYPES_H_ -#define _ZoO_IO_NETWORK_TYPES_H_ - -#define POSIX_C_SOURCE - -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> - -#include "../pervasive.h" - -enum ZoO_msg_type -{ - ZoO_PRIVMSG, - ZoO_JOIN -}; - -struct ZoO_network -{ - size_t buffer_index; - size_t buffer_remaining; - size_t in_length; - struct addrinfo * addrinfo; - ZoO_char buffer [513]; - ZoO_char in [513]; - ZoO_char out [513]; - int connection; - const char * restrict channel; - const char * restrict user; - const char * restrict name; - const char * restrict nick; -}; - -#endif diff --git a/src/knowledge/knowledge.c b/src/knowledge/knowledge.c index a72969e..95683b9 100644 --- a/src/knowledge/knowledge.c +++ b/src/knowledge/knowledge.c @@ -2,7 +2,7 @@ #include <string.h> #include <stdint.h> /* defines SIZE_MAX */ -#include "../cli/cli.h" +#include "../pipe/pipe.h" #include "knowledge.h" @@ -19,3 +19,20 @@ void ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1]) k->sequences_length = 0; k->sequences_sorted = (ZoO_index *) NULL; } + +int ZoO_knowledge_lock_access +( + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + return 0; +} + +void ZoO_knowledge_unlock_access +( + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ +} diff --git a/src/knowledge/knowledge.h b/src/knowledge/knowledge.h index 51d94c4..872bb94 100644 --- a/src/knowledge/knowledge.h +++ b/src/knowledge/knowledge.h @@ -4,9 +4,26 @@ #include "../core/char_types.h" #include "../core/index_types.h" +#include "../pipe/pipe_types.h" + #include "knowledge_types.h" -void ZoO_knowledge_initialize (struct ZoO_knowledge k [const restrict static 1]); +int ZoO_knowledge_lock_access +( + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +); + +void ZoO_knowledge_unlock_access +( + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +); + +void ZoO_knowledge_initialize +( + struct ZoO_knowledge k [const restrict static 1] +); void ZoO_knowledge_finalize (struct ZoO_knowledge k [const restrict static 1]); @@ -25,7 +42,8 @@ int ZoO_knowledge_learn_word struct ZoO_knowledge k [const static 1], const ZoO_char word [const restrict static 1], const ZoO_index word_length, - ZoO_index result [const restrict static 1] + ZoO_index result [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); int ZoO_knowledge_learn_sequence @@ -33,7 +51,8 @@ int ZoO_knowledge_learn_sequence struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], const ZoO_index sequence_length, - const ZoO_index markov_order + const ZoO_index markov_order, + const struct ZoO_pipe io [const restrict static 1] ); int ZoO_knowledge_learn_markov_sequence @@ -41,7 +60,9 @@ int ZoO_knowledge_learn_markov_sequence struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], const ZoO_index sequence_length, - const ZoO_index markov_order + const ZoO_index markov_order, + ZoO_index sequence_id [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); int ZoO_knowledge_get_following_sequences_ref @@ -50,14 +71,16 @@ int ZoO_knowledge_get_following_sequences_ref const ZoO_index initial_word, const ZoO_index * restrict following_sequences_ref [const restrict static 1], const ZoO_index * restrict following_sequences_weights [const restrict static 1], - ZoO_index following_sequences_weights_sum [const static 1] + ZoO_index following_sequences_weights_sum [const static 1], + const struct ZoO_pipe io [const restrict static 1] ); int ZoO_knowledge_get_sequence ( const struct ZoO_knowledge k [const static 1], const ZoO_index sequences_ref, - const ZoO_index * restrict sequence [const restrict static 1] + const ZoO_index * restrict sequence [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); int ZoO_knowledge_get_word @@ -65,7 +88,8 @@ int ZoO_knowledge_get_word const struct ZoO_knowledge k [const static 1], const ZoO_index word_ref, const ZoO_char * word [const restrict static 1], - size_t word_size [const restrict static 1] + size_t word_size [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); /* @@ -93,7 +117,8 @@ int ZoO_knowledge_find_preceding_words const ZoO_index markov_order, const ZoO_index * restrict preceding_words [const restrict static 1], const ZoO_index * restrict preceding_words_weights [const restrict static 1], - ZoO_index preceding_words_weights_sum [const restrict static 1] + ZoO_index preceding_words_weights_sum [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); int ZoO_knowledge_find_following_words @@ -104,7 +129,8 @@ int ZoO_knowledge_find_following_words const ZoO_index markov_order, const ZoO_index * restrict following_words [const restrict static 1], const ZoO_index * restrict following_words_weights [const restrict static 1], - ZoO_index following_words_weights_sum [const restrict static 1] + ZoO_index following_words_weights_sum [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ); #endif diff --git a/src/knowledge/knowledge_learn_markov_sequence.c b/src/knowledge/knowledge_learn_markov_sequence.c new file mode 100644 index 0000000..ec71254 --- /dev/null +++ b/src/knowledge/knowledge_learn_markov_sequence.c @@ -0,0 +1,398 @@ +#include <stdlib.h> +#include <string.h> +#include <stdint.h> /* defines SIZE_MAX */ + +#include "../core/sequence.h" + +#include "../pipe/pipe.h" + +#include "knowledge.h" + +/******************************************************************************/ +/** INITIALIZE ****************************************************************/ +/******************************************************************************/ +static void set_nth_sequence +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index sorted_sequence_id, + const ZoO_index sequence_id +) +{ + /* Safe: (> k->sequences_length 1) */ + if (sorted_sequence_id < (k->sequences_length - 1)) + { + memmove + ( + /* Safe: (=< (+ sorted_sequence_id 1) k->sequences_length) */ + (void *) (k->sequences_sorted + (sorted_sequence_id + 1)), + (const void *) (k->sequences_sorted + sorted_sequence_id), + ((k->sequences_length - 1) - sorted_sequence_id) + ); + } + + k->sequences_sorted[sorted_sequence_id] = sequence_id; +} + +/******************************************************************************/ +/** ALLOCATING MEMORY *********************************************************/ +/******************************************************************************/ +static int reallocate_sequences_list +( + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + ZoO_index ** new_sequences; + + if ((SIZE_MAX / sizeof(ZoO_index *)) > (size_t) k->sequences_length) + { + ZoO_S_ERROR + ( + io, + "Unable to store the size of the sequences list, as it would overflow" + "size_t variables." + ); + + return -1; + } + + new_sequences = + (ZoO_index **) realloc + ( + (void *) k->sequences, + (((size_t) k->sequences_length) * sizeof(ZoO_index *)) + ); + + if (new_sequences == (ZoO_index **) NULL) + { + ZoO_S_ERROR + ( + io, + "Unable to allocate the memory required for the new sequence list." + ); + + return -1; + } + + k->sequences = new_sequences; + + return 0; +} + +static int reallocate_sequences_sorted_list +( + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + ZoO_index * new_sequences_sorted; + + if ((SIZE_MAX / sizeof(ZoO_index)) > (size_t) k->sequences_length) + { + ZoO_S_ERROR + ( + io, + "Unable to store the size of the sorted sequences list, as it would" + " overflow size_t variables." + ); + + return -1; + } + + new_sequences_sorted = + (ZoO_index *) realloc + ( + (void *) k->sequences_sorted, + ((size_t) k->sequences_length) * sizeof(ZoO_index) + ); + + if (new_sequences_sorted == (ZoO_index *) NULL) + { + ZoO_S_ERROR + ( + io, + "Unable to allocate the memory required for the new sorted sequences" + " list." + ); + + return -1; + } + + k->sequences_sorted = new_sequences_sorted; + + return 0; +} + +/* Pre: (=< ZoO_INDEX_MAX SIZE_MAX) */ +/*@ + requires + ( + (base_length == destination_length) + || + ( + (base_length < destination_length) + && + ( + (base[0] == ZoO_START_OF_SEQUENCE) + (base[base_length - 1] == ZoO_END_OF_SEQUENCE) + ) + ) + ); +@*/ +static ZoO_index * copy_sequence +( + const ZoO_index base [const restrict static 1], + const ZoO_index base_length, + const ZoO_index destination_length, + const struct ZoO_pipe io [const restrict static 1] +) +{ + ZoO_index i, diff; + ZoO_index * result; + + result = + (ZoO_index *) calloc + ( + (size_t) (destination_length), + sizeof(ZoO_index) + ); + + if (result == (ZoO_index *) NULL) + { + ZoO_S_ERROR + ( + io, + "Unable to allocate the memory required to store a new sequence." + ); + + return (ZoO_index *) NULL; + } + + if (base_length == destination_length) + { + memcpy + ( + (void *) result, + (const void *) base, + (((size_t) base_length) * sizeof(ZoO_index)) + ); + } + else if (base[0] == ZoO_START_OF_SEQUENCE_ID) + { + diff = (destination_length - base_length); + + memcpy + ( + (void *) (result + diff), + (const void *) base, + (((size_t) base_length) * sizeof(ZoO_index)) + ); + + for (i = 0; i < diff; ++i) + { + result[i] = ZoO_START_OF_SEQUENCE_ID; + } + } + else if (base[(base_length - 1)] == ZoO_END_OF_SEQUENCE_ID) + { + memcpy + ( + (void *) result, + (const void *) base, + (((size_t) base_length) * sizeof(ZoO_index)) + ); + + for (i = base_length; i < destination_length; ++i) + { + result[i] = ZoO_END_OF_SEQUENCE_ID; + } + } + + return result; +} + +/******************************************************************************/ +/** ADD A NEW SEQUENCE ********************************************************/ +/******************************************************************************/ + +static int add_sequence +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index sequence [const restrict static 1], + const ZoO_index sequence_length, + const ZoO_index markov_order, /* Pre (> markov_order 1) */ + const ZoO_index sequence_id, + const ZoO_index sorted_sequence_id, + const struct ZoO_pipe io [const restrict static 1] +) +{ + ZoO_index * stored_sequence; + + if (k->sequences_length == ZoO_INDEX_MAX) + { + ZoO_S_ERROR + ( + io, + "Unable to add sequence: the variable that stores the number of known " + "sequences would overflow." + ); + + return -1; + } + + stored_sequence = copy_sequence(sequence, sequence_length, markov_order, io); + + if (stored_sequence == (ZoO_index *) NULL) + { + return -1; + } + + k->sequences_length += 1; + + if (reallocate_sequences_list(k, io) < 0) + { + k->sequences_length -= 1; + + free((void *) stored_sequence); + + return -1; + } + + k->sequences[sequence_id] = stored_sequence; + + if (reallocate_sequences_sorted_list(k, io) < 0) + { + k->sequences_length -= 1; + + free((void *) stored_sequence); + + return -1; + } + + set_nth_sequence(k, sorted_sequence_id, sequence_id); + + return 0; +} + +/******************************************************************************/ +/** SEARCH EXISTING SEQUENCES *************************************************/ +/******************************************************************************/ + +static int find_sequence +( + const struct ZoO_knowledge k [const static 1], + const ZoO_index sequence [const restrict static 1], + const ZoO_index sequence_length, + const ZoO_index markov_order, /* Pre: (> 1) */ + ZoO_index sequence_id [const restrict static 1] +) +{ + /* This is a binary search */ + int cmp; + ZoO_index i, current_min, current_max; + const ZoO_index markov_sequence_length = (markov_order - 1); + + /* Handles the case where the list is empty ********************************/ + current_max = k->sequences_length; + + if (current_max == 0) + { + *sequence_id = 0; + + return -1; + } + /***************************************************************************/ + + current_min = 0; + current_max -= 1; + + for (;;) + { + i = (current_min + ((current_max - current_min) / 2)); + + cmp = + ZoO_sequence_cmp + ( + k->sequences[k->sequences_sorted[i]], + markov_sequence_length, + sequence, + sequence_length + ); + + if (cmp > 0) + { + current_min = (i + 1); + + if (current_min > current_max) + { + *sequence_id = current_min; + + return -1; + } + } + else if (cmp < 0) + { + if ((current_min > current_max) || (i == 0)) + { + *sequence_id = i; + + return -1; + } + + current_max = (i - 1); + } + else + { + *sequence_id = k->sequences_sorted[i]; + + return 0; + } + } +} + +/******************************************************************************/ +/** EXPORTED ******************************************************************/ +/******************************************************************************/ + +int ZoO_knowledge_learn_markov_sequence +( + struct ZoO_knowledge k [const restrict static 1], + const ZoO_index sequence [const restrict static 1], + const ZoO_index sequence_length, + const ZoO_index markov_order, /* Pre (> markov_order 1) */ + ZoO_index sequence_id [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + ZoO_index sorted_id; + + if + ( + find_sequence + ( + k, + sequence, + sequence_length, + markov_order, + sequence_id + ) == 0 + ) + { + return 0; + } + + sorted_id = *sequence_id; + *sequence_id = k->sequences_length; + + return + add_sequence + ( + k, + sequence, + sequence_length, + markov_order, + *sequence_id, + sorted_id, + io + ); +} diff --git a/src/knowledge/knowledge_learn_sequence.c b/src/knowledge/knowledge_learn_sequence.c index 23a5ca7..7696fbc 100644 --- a/src/knowledge/knowledge_learn_sequence.c +++ b/src/knowledge/knowledge_learn_sequence.c @@ -4,321 +4,87 @@ #include "../core/sequence.h" -#include "../cli/cli.h" +#include "../pipe/pipe.h" #include "knowledge.h" /******************************************************************************/ -/** INITIALIZE ****************************************************************/ +/** LEARN FOLLOWING SEQUENCE **************************************************/ /******************************************************************************/ -static void set_nth_sequence -( - struct ZoO_knowledge k [const restrict static 1], - const ZoO_index sorted_sequence_id, - const ZoO_index sequence_id -) -{ - /* Safe: (> k->sequences_length 1) */ - if (sorted_sequence_id < (k->sequences_length - 1)) - { - memmove - ( - /* Safe: (=< (+ sorted_sequence_id 1) k->sequences_length) */ - (void *) (k->sequences_sorted + (sorted_sequence_id + 1)), - (const void *) (k->sequences_sorted + sorted_sequence_id), - ((k->sequences_length - 1) - sorted_sequence_id) - ); - } - - k->sequences_sorted[sorted_sequence_id] = sequence_id; -} - -/******************************************************************************/ -/** ALLOCATING MEMORY *********************************************************/ -/******************************************************************************/ -static int reallocate_sequences_list -( - struct ZoO_knowledge k [const restrict static 1] -) -{ - ZoO_index ** new_sequences; - - if ((SIZE_MAX / sizeof(ZoO_index *)) > (size_t) k->sequences_length) - { - ZoO_S_ERROR - ( - "Unable to store the size of the sequences list, as it would overflow" - "size_t variables." - ); - - return -1; - } - - new_sequences = - (ZoO_index **) realloc - ( - (void *) k->sequences, - (((size_t) k->sequences_length) * sizeof(ZoO_index *)) - ); - - if (new_sequences == (ZoO_index **) NULL) - { - ZoO_S_ERROR - ( - "Unable to allocate the memory required for the new sequence list." - ); - - return -1; - } - - k->sequences = new_sequences; - - return 0; -} - -static int reallocate_sequences_sorted_list -( - struct ZoO_knowledge k [const restrict static 1] -) -{ - ZoO_index * new_sequences_sorted; - - if ((SIZE_MAX / sizeof(ZoO_index)) > (size_t) k->sequences_length) - { - ZoO_S_ERROR - ( - "Unable to store the size of the sorted sequences list, as it would" - " overflow size_t variables." - ); - - return -1; - } - - new_sequences_sorted = - (ZoO_index *) realloc - ( - (void *) k->sequences_sorted, - ((size_t) k->sequences_length) * sizeof(ZoO_index) - ); - - if (new_sequences_sorted == (ZoO_index *) NULL) - { - ZoO_S_ERROR - ( - "Unable to allocate the memory required for the new sorted sequences" - " list." - ); - - return -1; - } - - k->sequences_sorted = new_sequences_sorted; - - return 0; -} - -/* Pre: (=< ZoO_INDEX_MAX SIZE_MAX) */ -static ZoO_index * copy_sequence -( - const ZoO_index base [const restrict static 1], - const ZoO_index base_length, - const ZoO_index markov_order -) -{ - ZoO_index * result; - - result = (ZoO_index *) calloc((size_t) base_length, sizeof(ZoO_index)); - - if (result == (ZoO_index *) NULL) - { - ZoO_S_ERROR - ( - "Unable to allocate the memory required to store a new sequence." - ); - - return (ZoO_index *) NULL; - } - - memcpy - ( - (void *) result, - (const void *) base, - (((size_t) base_length) * sizeof(ZoO_index)) - ); - - return result; -} - -static int add_sequence +static int add_following_sequence ( struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], + const ZoO_index index, const ZoO_index sequence_length, - const ZoO_index markov_order, /* Pre (> markov_order 1) */ - const ZoO_index sequence_id, - const ZoO_index sorted_sequence_id -) -{ - ZoO_index * stored_sequence; - - if (k->sequences_length == ZoO_INDEX_MAX) - { - ZoO_S_ERROR - ( - "Unable to add sequence: the variable that stores the number of known " - "sequences would overflow." - ); - - return -1; - } - - stored_sequence = copy_sequence(sequence, sequence_length, markov_order); - - if (stored_sequence == (ZoO_index *) NULL) - { - return -1; - } - - k->sequences_length += 1; - - if (reallocate_sequences_list(k) < 0) - { - k->sequences_length -= 1; - - return -1; - } - - k->sequences[sequence_id] = stored_sequence; - - if (reallocate_sequences_sorted_list(k) < 0) - { - k->sequences_length -= 1; - - return -1; - } - - set_nth_sequence(k, sorted_sequence_id, sequence_id); - - return -1; -} + const ZoO_index markov_order, + const struct ZoO_pipe io [const restrict static 1] +); /******************************************************************************/ -/** SEARCH ********************************************************************/ +/** LEARN PRECEDING SEQUENCE **************************************************/ /******************************************************************************/ - -static int find_sequence +static int add_preceding_sequence ( - const struct ZoO_knowledge k [const static 1], + struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], + const ZoO_index index, const ZoO_index sequence_length, - const ZoO_index markov_order, /* Pre: (> 1) */ - ZoO_index sequence_id [const restrict static 1] + const ZoO_index markov_order, + const struct ZoO_pipe io [const restrict static 1] ) { - /* This is a binary search */ - int cmp; - ZoO_index i, current_min, current_max; - const ZoO_index markov_sequence_length = (markov_order - 1); - - /* Handles the case where the list is empty ********************************/ - current_max = k->sequences_length; - - if (current_max == 0) - { - *sequence_id = 0; - - return -1; - } - /***************************************************************************/ - - current_min = 0; - current_max -= 1; - - for (;;) - { - i = (current_min + ((current_max - current_min) / 2)); - - cmp = - ZoO_sequence_cmp - ( - k->sequences[k->sequences_sorted[i]], - markov_sequence_length, - sequence, - sequence_length - ); - - if (cmp > 0) - { - current_min = (i + 1); - - if (current_min > current_max) - { - *sequence_id = current_min; - - return -1; - } - } - else if (cmp < 0) - { - if ((current_min > current_max) || (i == 0)) - { - *sequence_id = i; - - return -1; - } - - current_max = (i - 1); - } - else - { - *sequence_id = k->sequences_sorted[i]; - - return 0; - } - } } /******************************************************************************/ /** EXPORTED ******************************************************************/ /******************************************************************************/ -int ZoO_knowledge_learn_markov_sequence +int ZoO_knowledge_learn_sequence ( struct ZoO_knowledge k [const restrict static 1], const ZoO_index sequence [const restrict static 1], const ZoO_index sequence_length, - const ZoO_index markov_order, /* Pre (> markov_order 1) */ - ZoO_index sequence_id [const restrict static 1] + const ZoO_index markov_order, + const struct ZoO_pipe io [const restrict static 1] ) { - ZoO_index sorted_id; + ZoO_index * buffer; + ZoO_index i; + const ZoO_index buffer_length = (markov_order - 1); - if - ( - find_sequence + /* TODO */ + + for (i = 0; i < sequence_length; ++i) + { + k->words[sequence[i]].occurrences += 1; + + add_preceding_sequence ( k, sequence, + i, sequence_length, - markov_order, - sequence_id - ) == 0 - ) - { - return 0; - } - - sorted_id = *sequence_id; - *sequence_id = k->sequences_length; + buffer_length, + io + ); - return - add_sequence + add_following_sequence ( k, sequence, + i, sequence_length, markov_order, - *sequence_id, - sorted_id + io ); + + /* + * TODO: in case of failure, undo part of the word done so far: instead + * of unlearning, just remove the occurrence count of sequences and + * words so that {k} remains coherent. + */ + } + + return 0; } diff --git a/src/knowledge/knowledge_learn_word.c b/src/knowledge/knowledge_learn_word.c index f55ac5b..e6979dc 100644 --- a/src/knowledge/knowledge_learn_word.c +++ b/src/knowledge/knowledge_learn_word.c @@ -2,7 +2,7 @@ #include <string.h> #include <stdint.h> /* defines SIZE_MAX */ -#include "../cli/cli.h" +#include "../pipe/pipe.h" #include "knowledge.h" @@ -43,7 +43,8 @@ static void initialize_word static ZoO_char * copy_word ( const ZoO_char original [const restrict static 1], - const ZoO_index original_length + const ZoO_index original_length, + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_char * result; @@ -58,7 +59,7 @@ static ZoO_char * copy_word if (result == (ZoO_char *) NULL) { - ZoO_S_ERROR("Unable to allocate memory to store new word."); + ZoO_S_ERROR(io, "Unable to allocate memory to store new word."); return (ZoO_char *) NULL; } @@ -77,7 +78,8 @@ static ZoO_char * copy_word static int reallocate_words_list ( - struct ZoO_knowledge k [const restrict static 1] + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { struct ZoO_knowledge_word * new_words; @@ -89,6 +91,7 @@ static int reallocate_words_list { ZoO_S_ERROR ( + io, "Unable to store the size of the words list, as it would overflow" "size_t variables." ); @@ -107,6 +110,7 @@ static int reallocate_words_list { ZoO_S_ERROR ( + io, "Unable to allocate the memory required for the new words list." ); @@ -120,7 +124,8 @@ static int reallocate_words_list static int reallocate_words_sorted_list ( - struct ZoO_knowledge k [const restrict static 1] + struct ZoO_knowledge k [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index * new_words_sorted; @@ -153,6 +158,7 @@ static int reallocate_words_sorted_list { ZoO_S_ERROR ( + io, "Unable to allocate the memory required for the new sorted words list." ); @@ -192,7 +198,8 @@ static int add_word const ZoO_char word [const restrict static 1], const ZoO_index word_length, const ZoO_index word_id, - const ZoO_index sorted_word_id + const ZoO_index sorted_word_id, + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_char * stored_word; @@ -201,6 +208,7 @@ static int add_word { ZoO_S_ERROR ( + io, "Unable to add word: the variable that stores the number of known " "words would overflow." ); @@ -208,7 +216,7 @@ static int add_word return -1; } - stored_word = copy_word(word, word_length); + stored_word = copy_word(word, word_length, io); if (stored_word == (ZoO_char *) NULL) { @@ -217,7 +225,7 @@ static int add_word k->words_length += 1; - if (reallocate_words_list(k) < 0) + if (reallocate_words_list(k, io) < 0) { k->words_length -= 1; @@ -229,7 +237,7 @@ static int add_word k->words[word_id].word = stored_word; k->words[word_id].word_size = ((word_length + 1) * sizeof(ZoO_char)); - if (reallocate_words_sorted_list(k) < 0) + if (reallocate_words_sorted_list(k, io) < 0) { k->words_length -= 1; @@ -250,7 +258,8 @@ int ZoO_knowledge_learn_word struct ZoO_knowledge k [const restrict static 1], const ZoO_char word [const restrict static 1], const ZoO_index word_length, - ZoO_index word_id [const restrict static 1] + ZoO_index word_id [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { ZoO_index sorted_id; @@ -262,7 +271,8 @@ int ZoO_knowledge_learn_word k, word, (word_length * sizeof(ZoO_char)), - word_id + word_id, + io ) == 0 ) { @@ -272,5 +282,5 @@ int ZoO_knowledge_learn_word sorted_id = *word_id; *word_id = k->words_length; - return add_word(k, word, word_length, *word_id, sorted_id); + return add_word(k, word, word_length, *word_id, sorted_id, io); } diff --git a/src/knowledge/knowledge_search.c b/src/knowledge/knowledge_search.c index a48585b..23aab71 100644 --- a/src/knowledge/knowledge_search.c +++ b/src/knowledge/knowledge_search.c @@ -4,7 +4,7 @@ #include "../core/index.h" #include "../core/sequence.h" -#include "../cli/cli.h" +#include "../pipe/pipe.h" #include "knowledge.h" @@ -80,7 +80,8 @@ int ZoO_knowledge_find_preceding_words const ZoO_index markov_order, /* Pre: (> 0) */ const ZoO_index * restrict preceding_words [const restrict static 1], const ZoO_index * restrict preceding_words_weights [const restrict static 1], - ZoO_index preceding_words_weights_sum [const restrict static 1] + ZoO_index preceding_words_weights_sum [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { /* This is a binary search */ @@ -94,6 +95,7 @@ int ZoO_knowledge_find_preceding_words { ZoO_S_ERROR ( + io, "Attempting to find the preceding words of an unknown word." ); @@ -129,6 +131,7 @@ int ZoO_knowledge_find_preceding_words ZoO_S_ERROR ( + io, "Attempting to find the preceding words of a sequence that never had " "any." ); @@ -150,7 +153,8 @@ int ZoO_knowledge_find_preceding_words ( k, k->words[word].preceded.sequences_ref[local_sequence], - &candidate + &candidate, + io ); cmp = @@ -211,7 +215,8 @@ int ZoO_knowledge_find_following_words const ZoO_index markov_order, const ZoO_index * restrict following_words [const restrict static 1], const ZoO_index * restrict following_words_weights [const restrict static 1], - ZoO_index following_words_weights_sum [const restrict static 1] + ZoO_index following_words_weights_sum [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] ) { /* This is a binary search */ @@ -261,6 +266,7 @@ int ZoO_knowledge_find_following_words ZoO_S_WARNING ( + io, "Attempting to find the following words of a sequence that never had " "any." ); @@ -282,7 +288,8 @@ int ZoO_knowledge_find_following_words ( k, k->words[word].followed.sequences_ref[local_sequence], - &candidate + &candidate, + io ); cmp = @@ -1,436 +1,44 @@ -#include <stdlib.h> #include <stdio.h> -#include <string.h> -#include <time.h> -#include <signal.h> -#include "../tool/strings.h" +#include "cli/parameters.h" -#include "../io/error.h" -#include "../io/parameters.h" -#include "../io/data_input.h" -#include "../io/data_output.h" -#include "../io/network.h" +#include "server/server.h" -#include "knowledge.h" +#include "pervasive.h" -#include "state_types.h" - -static int run = 1; - -static void request_termination (int const signo) -{ - if ((signo == SIGINT) || (signo == SIGTERM)) - { - run = 0; - } -} - -static int initialize -( - struct ZoO_state s [const static 1], - int const argc, - const char * argv [const static argc] -) -{ - ZoO_S_DEBUG(ZoO_DEBUG_PROGRAM_FLOW, "Zero of One is initializing..."); - - srand(time(NULL)); - - /* prevents s [restrict] */ - if (ZoO_knowledge_initialize(&(s->knowledge)) < 0) - { - return -1; - } - - if (ZoO_parameters_initialize(&(s->param), argc, argv) < 1) - { - ZoO_knowledge_finalize(&(s->knowledge)); - - return -1; - } - - return 0; -} - -static int load_data_file (struct ZoO_state s [const static 1]) -{ - struct ZoO_data_input input; - char * result; - - if (ZoO_data_input_open(&input, s->param.data_filename) < 0) - { - return -1; - } - - while - ( - ZoO_data_input_read_line - ( - &input, - ZoO_knowledge_punctuation_chars_count, - ZoO_knowledge_punctuation_chars - ) == 0 - ) - { - (void) ZoO_knowledge_assimilate - ( - &(s->knowledge), - &(input.string), - s->param.aliases_count, - s->param.aliases - ); - } - - ZoO_data_input_close(&input); - - return 0; -} - -static int finalize (struct ZoO_state s [const static 1]) -{ - int error; - - ZoO_S_DEBUG(ZoO_DEBUG_PROGRAM_FLOW, "Zero of One is finalizing..."); - - error = 0; - - /* prevents s [restrict] */ - ZoO_knowledge_finalize(&(s->knowledge)); - - return error; -} - -static int network_connect (struct ZoO_state s [const static 1]) -{ - return - ZoO_network_connect - ( - &(s->network), - s->param.irc_server_addr, - s->param.irc_server_port, - s->param.irc_server_channel, - s->param.irc_username, - s->param.irc_realname, - s->param.aliases[0] - ); -} - -static int should_reply -( - struct ZoO_parameters param [const restrict static 1], - struct ZoO_strings string [const restrict static 1], - int should_learn [const restrict static 1] -) -{ - ZoO_index i, j; - - for (i = 0; i < param->aliases_count; ++i) - { - if (ZoO_IS_PREFIX(param->aliases[i], string->words[0])) - { - *should_learn = 0; - - return 1; - } - - for (j = 1; j < string->words_count; ++j) - { - if (ZoO_IS_PREFIX(param->aliases[i], string->words[j])) - { - *should_learn = 1; - - return 1; - } - } - } - - *should_learn = 1; - - return (param->reply_rate >= (rand() % 100)); -} - -static void handle_user_join -( - struct ZoO_state s [const static 1], - struct ZoO_strings string [const restrict static 1], - ssize_t const msg_offset, - ssize_t const msg_size -) -{ - ZoO_char * line; - ZoO_index loc; - - if (s->param.reply_rate < (rand() % 100)) - { - return; - } - - if - ( - ZoO_strings_parse - ( - string, - (size_t) msg_size, - (s->network.in + msg_offset), - ZoO_knowledge_punctuation_chars_count, - ZoO_knowledge_punctuation_chars - ) < 0 - ) - { - ZoO_S_DEBUG(ZoO_DEBUG_PROGRAM_FLOW, "Could not dissect join username."); - - return; - } - - if - ( - ( - ZoO_knowledge_find - ( - &(s->knowledge), - string->words[0], - &loc - ) < 0 - ) - || (s->knowledge.words[loc].backward_links_count <= 3) - || (s->knowledge.words[loc].forward_links_count <= 3) - ) - { - if - ( - ZoO_knowledge_extend - ( - &(s->knowledge), - (struct ZoO_strings *) NULL, - 0, - (const char **) NULL, - &line - ) == 0 - ) - { - if (line[0] == ' ') - { - strcpy((s->network.out), (line + 1)); - } - else - { - strcpy((s->network.out), line); - } - - free((void *) line); - - ZoO_network_send(&(s->network)); - } - } - else - { - if - ( - ZoO_knowledge_extend - ( - &(s->knowledge), - string, - 0, - (const char **) NULL, - &line - ) == 0 - ) - { - if (line[0] == ' ') - { - strcpy((s->network.out), (line + 1)); - } - else - { - strcpy((s->network.out), line); - } - - free((void *) line); - - ZoO_network_send(&(s->network)); - } - } -} - -static void handle_message -( - struct ZoO_state s [const static 1], - struct ZoO_strings string [const restrict static 1], - ssize_t const msg_offset, - /* FIXME: somehow we end up using (msg_size + 1), meaning there's a mixup - * between size and length. - */ - ssize_t const msg_size -) -{ - ZoO_char * line; - int reply, learn; - - if - ( - ZoO_strings_parse - ( - string, - (size_t) msg_size, - (s->network.in + msg_offset), - ZoO_knowledge_punctuation_chars_count, - ZoO_knowledge_punctuation_chars - ) < 0 - ) - { - ZoO_S_DEBUG(ZoO_DEBUG_PROGRAM_FLOW, "Could not dissect msg."); - - return; - } - - if (string->words_count == 0) - { - return; - } - - reply = should_reply(&(s->param), string, &learn); - - if (learn) - { - /* - * It would be best to do that after replying, but by then we no longer - * have the string in 's->network.in'. - */ - (void) ZoO_data_output_write_line - ( - s->param.new_data_filename, - (s->network.in + msg_offset), - (size_t) (msg_size + 1) - ); - } - - if - ( - reply - && - ( - ZoO_knowledge_extend - ( - &(s->knowledge), - string, - s->param.aliases_count, - s->param.aliases, - &line - ) == 0 - ) - ) - { - if (line[0] == ' ') - { - strcpy((s->network.out), (line + 1)); - } - else - { - strcpy((s->network.out), line); - } - - free((void *) line); - - ZoO_network_send(&(s->network)); - } - - if (learn) - { - (void) ZoO_knowledge_assimilate - ( - &(s->knowledge), - string, - s->param.aliases_count, - s->param.aliases - ); - } -} - -static int main_loop (struct ZoO_state s [const static 1]) +static void print_help () { - struct ZoO_strings string; - ssize_t msg_offset, msg_size; - enum ZoO_msg_type msg_type; - - msg_offset = 0; - msg_size = 0; - - ZoO_strings_initialize(&string); - - while (run) - { - if - ( - ZoO_network_receive - ( - &(s->network), - &msg_offset, - &msg_size, - &msg_type - ) == 0 - ) - { - switch (msg_type) - { - case ZoO_JOIN: - handle_user_join(s, &string, msg_offset, msg_size); - break; - - case ZoO_PRIVMSG: - handle_message(s, &string, msg_offset, msg_size); - break; - } - } - } - - ZoO_strings_finalize(&string); - - ZoO_network_disconnect(&(s->network)); - - return 0; + printf + ( + "Zero of One - server version %d - protocol version %d\n" + "\nUsages:\n" + " SERVER:\tzero_of_one_server SESSION_NAME MARKOV_ORDER STORAGE_FILE\n" + " CLEAN UP:\tzero_of_one_server -c SESSION_NAME\n" + " SHOW HELP:\tAnything else\n" + "\nParameters:\n" + " SESSION_NAME: valid POSIX message queue filename.\n" + " MARKOV_ORDER: non-null positive integer.\n" + " STORAGE_FILE: file in which the knowledge will be stored.", + ZoO_SERVER_VERSION, + ZoO_PROTOCOL_VERSION + ); } int main (int const argc, const char * argv [const static argc]) { - struct ZoO_state s; - - if (initialize(&s, argc, argv) < 0) - { - return -1; - } - - if (load_data_file(&s) < 0) - { - goto CRASH; - } - - if (network_connect(&s) < 0) - { - goto CRASH; - } - - if (main_loop(&s) < 0) - { - goto CRASH; - } - - (void) finalize(&s); - - ZoO_S_DEBUG(ZoO_DEBUG_PROGRAM_FLOW, "Zero of One terminated normally."); - - return 0; + struct ZoO_parameters params; - CRASH: + switch (ZoO_parameters_initialize(¶ms, argc, argv)) { - (void) finalize(&s); + case ZoO_CLEANS_UP: + return ZoO_server_cleanup_session(params.session); - ZoO_S_DEBUG - ( - ZoO_DEBUG_PROGRAM_FLOW, - "Zero of One terminated by crashing." - ); + case ZoO_RUNS: + return ZoO_server_main(params); - return -1; + default: + case ZoO_PRINTS_HELP: + print_help(); + return 0; } } diff --git a/src/pervasive.h b/src/pervasive.h index c7c53a2..e5cda3b 100644 --- a/src/pervasive.h +++ b/src/pervasive.h @@ -1,7 +1,10 @@ #ifndef _ZoO_PERVASIVE_H_ #define _ZoO_PERVASIVE_H_ -#include <limits.h> +#include <string.h> + +#define ZoO_SERVER_VERSION 1 +#define ZoO_PROTOCOL_VERSION 1 #define ZoO_DEBUG_ALL 1 diff --git a/src/pipe/CMakeLists.txt b/src/pipe/CMakeLists.txt new file mode 100644 index 0000000..03456ed --- /dev/null +++ b/src/pipe/CMakeLists.txt @@ -0,0 +1,6 @@ +set( + SRC_FILES ${SRC_FILES} + ${CMAKE_CURRENT_SOURCE_DIR}/pipe.c +) +set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) + diff --git a/src/pipe/pipe.c b/src/pipe/pipe.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/pipe/pipe.c diff --git a/src/cli/cli.h b/src/pipe/pipe.h index 5aec25b..ea31b55 100644 --- a/src/cli/cli.h +++ b/src/pipe/pipe.h @@ -1,10 +1,11 @@ -#ifndef _ZoO_CLI_CLI_H_ -#define _ZoO_CLI_CLI_H_ +#ifndef _ZoO_PIPE_PIPE_H_ +#define _ZoO_PIPE_PIPE_H_ #include <stdio.h> #include "../pervasive.h" +#include "pipe_types.h" #ifndef ZoO_DEBUG_PROGRAM_FLOW #define ZoO_DEBUG_PROGRAM_FLOW (0 || ZoO_DEBUG_ALL) @@ -37,8 +38,8 @@ #define ZoO_LOCATION "" #endif -#define ZoO_PRINT_STDERR(symbol, str, ...)\ - fprintf(stderr, "[" symbol "]" ZoO_LOCATION " " str "\n", __VA_ARGS__); +#define ZoO_PRINT_STDERR(pipe, symbol, str, ...)\ + fprintf(pipe->out, "E [" symbol "]" ZoO_LOCATION " " str "\n", __VA_ARGS__); /* * Given that we use preprocessor contants as flags, we can expect the compilers @@ -46,99 +47,99 @@ * allowing many debug options. */ -#define ZoO_DEBUG(flag, str, ...)\ +#define ZoO_DEBUG(pipe, flag, str, ...)\ ZoO_ISOLATE\ (\ if (flag)\ {\ - ZoO_PRINT_STDERR("D", str, __VA_ARGS__);\ + ZoO_PRINT_STDERR(pipe, "D", str, __VA_ARGS__);\ }\ ) -#define ZoO_WARNING(str, ...)\ +#define ZoO_WARNING(pipe, str, ...)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_WARNINGS_OUTPUT)\ {\ - ZoO_PRINT_STDERR("W", str, __VA_ARGS__);\ + ZoO_PRINT_STDERR(pipe, "W", str, __VA_ARGS__);\ }\ ) -#define ZoO_ERROR(str, ...)\ +#define ZoO_ERROR(pipe, str, ...)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_RUNTIME_ERRORS_OUTPUT)\ {\ - ZoO_PRINT_STDERR("E", str, __VA_ARGS__);\ + ZoO_PRINT_STDERR(pipe, "E", str, __VA_ARGS__);\ }\ ) -#define ZoO_PROG_ERROR(str, ...)\ +#define ZoO_PROG_ERROR(pipe, str, ...)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_PROGRAMMING_ERRORS_OUTPUT)\ {\ - ZoO_PRINT_STDERR("P", str, __VA_ARGS__);\ + ZoO_PRINT_STDERR(pipe, "P", str, __VA_ARGS__);\ }\ ) -#define ZoO_FATAL(str, ...)\ +#define ZoO_FATAL(pipe, str, ...)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_FATAL_ERROR_OUTPUT)\ {\ - ZoO_PRINT_STDERR("F", str, __VA_ARGS__);\ + ZoO_PRINT_STDERR(pipe, "F", str, __VA_ARGS__);\ }\ ) /* For outputs without dynamic content (static). ******************************/ -#define ZoO_PRINT_S_STDERR(symbol, str)\ - fprintf(stderr, "[" symbol "]" ZoO_LOCATION " " str "\n"); +#define ZoO_PRINT_S_STDERR(pipe, symbol, str)\ + fprintf(pipe->out, "E [" symbol "]" ZoO_LOCATION " " str "\n"); -#define ZoO_S_DEBUG(flag, str)\ +#define ZoO_S_DEBUG(pipe, flag, str)\ ZoO_ISOLATE\ (\ if (flag)\ {\ - ZoO_PRINT_S_STDERR("D", str);\ + ZoO_PRINT_S_STDERR(pipe, "D", str);\ }\ ) -#define ZoO_S_WARNING(str)\ +#define ZoO_S_WARNING(pipe, str)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_WARNINGS_OUTPUT)\ {\ - ZoO_PRINT_S_STDERR("W", str);\ + ZoO_PRINT_S_STDERR(pipe, "W", str);\ }\ ) -#define ZoO_S_ERROR(str)\ +#define ZoO_S_ERROR(pipe, str)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_RUNTIME_ERRORS_OUTPUT)\ {\ - ZoO_PRINT_S_STDERR("E", str);\ + ZoO_PRINT_S_STDERR(pipe, "E", str);\ }\ ) -#define ZoO_S_PROG_ERROR(str)\ +#define ZoO_S_PROG_ERROR(pipe, str)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_PROGRAMMING_ERRORS_OUTPUT)\ {\ - ZoO_PRINT_S_STDERR("P", str);\ + ZoO_PRINT_S_STDERR(pipe, "P", str);\ }\ ) -#define ZoO_S_FATAL(str)\ +#define ZoO_S_FATAL(pipe, str)\ ZoO_ISOLATE\ (\ if (ZoO_ENABLE_FATAL_ERROR_OUTPUT)\ {\ - ZoO_PRINT_S_STDERR("F", str);\ + ZoO_PRINT_S_STDERR(pipe, "F", str);\ }\ ) diff --git a/src/pipe/pipe_types.h b/src/pipe/pipe_types.h new file mode 100644 index 0000000..15b4a54 --- /dev/null +++ b/src/pipe/pipe_types.h @@ -0,0 +1,13 @@ +#ifndef _ZoO_PIPE_PIPE_TYPES_H_ +#define _ZoO_PIPE_PIPE_TYPESH_ + +#include <stdio.h> + +struct ZoO_pipe +{ + FILE * out; + FILE * in; +}; + const struct ZoO_pipe io [const restrict static 1] + +#endif diff --git a/src/server/server.c b/src/server/server.c new file mode 100644 index 0000000..3ded7cc --- /dev/null +++ b/src/server/server.c @@ -0,0 +1,59 @@ +#include <signal.h> + +#include "../cli/parameters.h" + +#include "server.h" + +volatile char ZoO_SERVER_IS_RUNNING = (char) 1; + +static void request_termination (int const signo) +{ + if ((signo == SIGINT) || (signo == SIGTERM)) + { + ZoO_SERVER_IS_RUNNING = (char) 0; + } +} + +int ZoO_server_main (const struct ZoO_parameters params) +{ + struct ZoO_server server; + struct ZoO_server_message msg_buffer; + + if + ( + ZoO_server_initialize + ( + &server, + ZoO_parameters_get_session_name(¶ms) + ) < 0 + ) + { + return -1; + } + + while ((ZoO_SERVER_IS_RUNNING == (char) 1) || (server.running_threads > 0)) + { + if (ZoO_server_receive_message(&server, &msg_buffer) < 0) + { + ZoO_server_no_mq_termination(&server); + + break; + } + + switch (msg_buffer.type) + { + case 'C': + ZoO_server_new_client(&server, &msg_buffer); + + case 'J': + ZoO_server_join_thread(&server, &msg_buffer); + + default: + break; + } + } + + ZoO_server_finalize(&server); + + return 0; +} diff --git a/src/server/server.h b/src/server/server.h new file mode 100644 index 0000000..a75c6e7 --- /dev/null +++ b/src/server/server.h @@ -0,0 +1,39 @@ +#ifndef _ZoO_SERVER_SERVER_H_ +#define _ZoO_SERVER_SERVER_H_ + +#include "../cli/parameters_types.h" + +#include "server_types.h" + +int ZoO_server_cleanup_session (const char * session); + +int ZoO_server_initialize +( + struct ZoO_server [const restrict static 1], + const char * session +); + +int ZoO_server_main (const struct ZoO_parameters params); +int ZoO_server_finalize (struct ZoO_server [const restrict static 1]); + +void ZoO_server_no_mq_termination (struct ZoO_server [const restrict static 1]); + +int ZoO_server_receive_message +( + struct ZoO_server [const restrict static 1], + struct ZoO_server_message msg_buffer [const restrict static 1] +); + +int ZoO_server_new_client +( + struct ZoO_server [const restrict static 1], + struct ZoO_server_message msg_buffer [const restrict static 1] +); + +int ZoO_server_join_thread +( + struct ZoO_server [const restrict static 1], + struct ZoO_server_message msg_buffer [const restrict static 1] +); + +#endif diff --git a/src/server/server_types.h b/src/server/server_types.h new file mode 100644 index 0000000..75016d4 --- /dev/null +++ b/src/server/server_types.h @@ -0,0 +1,30 @@ +#ifndef _ZoO_SERVER_SERVER_TYPES_H_ +#define _ZoO_SERVER_SERVER_TYPES_H_ + +#include <mqueue.h> + +#include "../core/index.h" + +struct ZoO_server_pipes_data +{ + char request_pipe[255]; + char reply_pipe[255]; +}; + +struct ZoO_server_message +{ + char type; + union + { + struct ZoO_server_pipes_data pipes_name; + ZoO_index pthread_id; + } data; +}; + +struct ZoO_server +{ + mqd_t mailbox; + ZoO_index running_threads; +}; + +#endif diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt new file mode 100644 index 0000000..782a234 --- /dev/null +++ b/src/storage/CMakeLists.txt @@ -0,0 +1,7 @@ +set( + SRC_FILES ${SRC_FILES} + ${CMAKE_CURRENT_SOURCE_DIR}/storage.c +) + +set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) + diff --git a/src/file/data_output.c b/src/storage/storage.c index 04e3964..22c5c49 100644 --- a/src/file/data_output.c +++ b/src/storage/storage.c @@ -6,15 +6,16 @@ #include <stdint.h> /* defines SIZE_MAX */ #include <stdio.h> -#include "error.h" +#include "../pipe/pipe.h" -#include "data_output.h" +#include "storage.h" -int ZoO_data_output_write_line +int ZoO_storage_write_line ( const char filename [const restrict static 1], char line [const restrict static 1], - size_t const line_size + size_t const line_size, + const struct ZoO_pipe io [const restrict static 1] ) { const int old_errno = errno; @@ -26,6 +27,7 @@ int ZoO_data_output_write_line { ZoO_ERROR ( + io, "Could not open file '%s' in appending mode.", filename ); @@ -50,6 +52,7 @@ int ZoO_data_output_write_line ZoO_ERROR ( + io, "Could not store line '%s' in %s.", line, filename diff --git a/src/storage/storage.h b/src/storage/storage.h new file mode 100644 index 0000000..c287b23 --- /dev/null +++ b/src/storage/storage.h @@ -0,0 +1,14 @@ +#ifndef _ZoO_STORAGE_STORAGE_H_ +#define _ZoO_STORAGE_STORAGE_H_ + +#include "../pipe/pipe_types.h" + +int ZoO_storage_write_line +( + const char filename [const restrict static 1], + char line [const restrict static 1], + size_t const line_size, + const struct ZoO_pipe io [const restrict static 1] +); + +#endif diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt deleted file mode 100644 index 3ad122b..0000000 --- a/src/tool/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -set( - SRC_FILES ${SRC_FILES} - ${CMAKE_CURRENT_SOURCE_DIR}/strings.c - ${CMAKE_CURRENT_SOURCE_DIR}/sorted_list.c -) - -set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) - diff --git a/src/tool/sorted_list.c b/src/tool/sorted_list.c deleted file mode 100644 index 5252c9e..0000000 --- a/src/tool/sorted_list.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "./sorted_list.h" - -int ZoO_sorted_list_index_of -( - ZoO_index const list_length, - const void * const sorted_list, - const void * const elem, - size_t const type_size, - int (*compare) (const void *, const void *, const void *), - const void * const other, - ZoO_index result [const restrict static 1] -) -{ - int cmp; - ZoO_index i, current_min, current_max; - const char * sorted_list_access; - - sorted_list_access = (char *) sorted_list; - - /* This is a binary search. */ - - if (list_length == 0) - { - *result = 0; - - return -1; - } - - current_min = 0; - - current_max = (list_length - 1); - - for (;;) - { - /* FIXME: overflow-safe? */ - /* No: (and (> current_min (/ Max 2)) (> current_max (/ Max 2))) */ - i = ((current_min + current_max) / 2); - - if (i == list_length) - { - /* FIXME: I don't see how this one can be true */ - *result = list_length; - - return -1; - } - - cmp = compare(elem, (sorted_list_access + (i * type_size)), other); - - if (cmp > 0) - { - if ((current_min > current_max)) - { - *result = (i + 1); - - return -1; - } - - /* FIXME: overflow-safe? */ - current_min = (i + 1); - } - else if (cmp < 0) - { - if ((current_min > current_max) || (i == 0)) - { - *result = i; - - return -1; - } - - /* overflow-safe */ - current_max = (i - 1); - } - else - { - *result = i; - - return 0; - } - } -} diff --git a/src/tool/sorted_list.h b/src/tool/sorted_list.h deleted file mode 100644 index 72bd893..0000000 --- a/src/tool/sorted_list.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ZoO_TOOL_SORTED_LIST_H_ -#define _ZoO_TOOL_SORTED_LIST_H_ - -#include <stdlib.h> - -#include "../pervasive.h" - -int ZoO_sorted_list_index_of -( - ZoO_index const list_length, - const void * const sorted_list, - const void * const elem, - size_t const type_size, - int (*compare) (const void *, const void *, const void *), - const void * const other, - ZoO_index result [const restrict static 1] -); - -#endif diff --git a/src/tool/strings.c b/src/tool/strings.c deleted file mode 100644 index 73a5cdd..0000000 --- a/src/tool/strings.c +++ /dev/null @@ -1,300 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include <stdlib.h> -#include <string.h> -#include <stdint.h> /* defines SIZE_MAX */ - -#include "../io/error.h" - -#include "strings.h" - - -void ZoO_strings_initialize (struct ZoO_strings s [const restrict static 1]) -{ - s->words_count = 0; - s->words = (ZoO_char **) NULL; - s->word_sizes = (size_t *) NULL; -} - -void ZoO_strings_finalize (struct ZoO_strings s [const restrict static 1]) -{ - if (s->words_count != 0) - { - ZoO_index i; - - for (i = 0; i < s->words_count; ++i) - { - free((void *) s->words[i]); - } - - s->words_count = 0; - - free((void *) s->words); - free((void *) s->word_sizes); - - s->words = (ZoO_char **) NULL; - s->word_sizes = (size_t *) NULL; - } -} - -static int add_word -( - struct ZoO_strings s [const restrict static 1], - size_t const line_size, - const ZoO_char line [const restrict static line_size] -) -{ - size_t * new_s_word_sizes; - ZoO_char * new_word, ** new_s_words; - - if (s->words_count == ZoO_INDEX_MAX) - { - ZoO_S_WARNING("Data input sentence has too many words."); - - return -1; - } - - /* overflow-safe, as line_size < SIZE_MAX */ - new_word = (ZoO_char *) calloc((line_size + 1), sizeof(ZoO_char)); - - if (new_word == (ZoO_char *) NULL) - { - ZoO_S_WARNING("Unable to allocate memory to extract new word."); - - return -1; - } - - memcpy((void *) new_word, (const void *) line, line_size); - - new_word[line_size] = '\0'; - - new_s_words = - (ZoO_char **) realloc - ( - (void *) s->words, - /* XXX: (sizeof() * _) assumed overflow-safe. */ - /* (di->words_count + 1) overflow-safe */ - (sizeof(ZoO_char *) * (s->words_count + 1)) - ); - - if (new_s_words == (ZoO_char **) NULL) - { - ZoO_S_WARNING("Unable to reallocate memory to extract new word."); - - free((void *) new_word); - - return -1; - } - - s->words = new_s_words; - - new_s_word_sizes = - (size_t *) realloc - ( - (void *) s->word_sizes, - /* XXX: (sizeof() * _) assumed overflow-safe. */ - /* (di->words_count + 1) overflow-safe */ - (sizeof(size_t) * (s->words_count + 1)) - ); - - if (new_s_word_sizes == (size_t *) NULL) - { - ZoO_S_WARNING("Unable to reallocate memory to extract new word."); - - free((void *) new_word); - - return -1; - } - - s->word_sizes = new_s_word_sizes; - - s->words[s->words_count] = new_word; - s->word_sizes[s->words_count] = (line_size + 1); - - s->words_count += 1; - - return 0; -} - -static int parse_word -( - struct ZoO_strings s [const restrict static 1], - ZoO_index const punctuations_count, - const ZoO_char punctuations [const restrict static punctuations_count], - size_t const line_size, - ZoO_char line [const static line_size] -) -{ - ZoO_index j; - - if (line_size == 0) - { - return 0; - } - - for (j = 0; j < line_size; ++j) - { - switch (line[j]) - { - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - line[j] = 'z' - ('Z' - line[j]); - break; - - default: - break; - } - } - - for (j = 0; j < punctuations_count; ++j) - { - /* overflow-safe: line_size > 1 */ - if (line[line_size - 1] == punctuations[j]) - { - if (line_size > 1) - { - if - ( - /* overflow-safe: line_size > 1 */ - (add_word(s, (line_size - 1), line) < 0) - /* overflow-safe: line_size > 1 */ - /* prevents line[restrict] */ - || (add_word(s, 1, (line + (line_size - 1))) < 0) - ) - { - return -1; - } - - return 0; - } - } - } - - return add_word(s, line_size, line); -} - -int ZoO_strings_parse -( - struct ZoO_strings s [const restrict static 1], - size_t input_size, - ZoO_char input [const restrict], - ZoO_index const punctuations_count, - const ZoO_char punctuations [const restrict static punctuations_count] -) -{ - size_t i, w_start; - - ZoO_strings_finalize(s); - - if (input == NULL) - { - return 0; - } - - i = 0; - - /* overflow-safe: input is '\0' terminated. */ - while (input[i] == ' ') - { - ++i; - } - - w_start = i; - - if (input[i] == '\001') - { - /* This is an CTCP command. */ - /* We'll remove the trailing '\001' so that only the first word */ - /* indicates the need for CTCP (uppercase) syntax. */ - - if ((input_size >= 1) && (input[input_size - 1] == '\001')) - { - input[input_size - 1] = ' '; - } - else - { - ZoO_WARNING - ( - "CTCP sequence '%s' did not end with a \\001 character.", - input - ); - } - } - - for (; i < input_size; ++i) - { - if (input[i] == ' ') - { - if - ( - parse_word - ( - s, - punctuations_count, - punctuations, - /* overflow-safe: w_start < i */ - (i - w_start), - (input + w_start) - ) < 0 - ) - { - ZoO_strings_finalize(s); - - return -1; - } - - ++i; - - /* safe, as input is terminated by '\0' */ - while (input[i] == ' ') - { - ++i; - } - - w_start = i; - } - } - - if - ( - parse_word - ( - s, - punctuations_count, - punctuations, - /* overflow-safe: w_start =< i */ - (i - w_start), - (input + w_start) - ) < 0 - ) - { - ZoO_strings_finalize(s); - - return -1; - } - - return 0; -} diff --git a/src/tool/strings.h b/src/tool/strings.h deleted file mode 100644 index 6fbecf7..0000000 --- a/src/tool/strings.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ZoO_TOOL_STRINGS_H_ -#define _ZoO_TOOL_STRINGS_H_ - -#include "strings_types.h" - -void ZoO_strings_initialize (struct ZoO_strings s [const restrict static 1]); - -void ZoO_strings_finalize (struct ZoO_strings s [const restrict static 1]); - -int ZoO_strings_parse -( - struct ZoO_strings s [const static 1], - size_t input_size, - ZoO_char input [const restrict], - ZoO_index const punctuations_count, - const ZoO_char punctuations [const restrict static punctuations_count] -); - -#endif diff --git a/src/tool/strings_types.h b/src/tool/strings_types.h deleted file mode 100644 index f74dcc8..0000000 --- a/src/tool/strings_types.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _ZoO_TOOL_STRINGS_TYPES_H_ -#define _ZoO_TOOL_STRINGS_TYPES_H_ - -#include <stdio.h> - -#include "../pervasive.h" - -struct ZoO_strings -{ - ZoO_index words_count; - ZoO_char * restrict * restrict words; - size_t * restrict word_sizes; -}; - -#endif |


