| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-01-20 22:19:09 +0100 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-01-20 22:19:09 +0100 | 
| commit | df3657b2a99ef20da99ac3c6c02f43cc23e70fca (patch) | |
| tree | 86a9e72bbbbaf7296b2d7cd2725a8bc42611a1f3 /src | |
| parent | 0d49fb74eadcf933f696420cd182077927680d26 (diff) | |
Moving towards a server/clients structure.
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 | 


