summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-01-29 19:54:26 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-01-29 19:54:26 +0100
commit1373211465c34015ee900e097aa87fbffb401187 (patch)
tree8ffa1f9296097c91627c05874fcf4559cac45de7 /src/sequence/sequence_to_string.c
parentdf3657b2a99ef20da99ac3c6c02f43cc23e70fca (diff)
Trying out ACSL, continuing implementation.
Diffstat (limited to 'src/sequence/sequence_to_string.c')
-rw-r--r--src/sequence/sequence_to_string.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/src/sequence/sequence_to_string.c b/src/sequence/sequence_to_string.c
new file mode 100644
index 0000000..cec3af8
--- /dev/null
+++ b/src/sequence/sequence_to_string.c
@@ -0,0 +1,189 @@
+#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 "../pipe/pipe.h"
+
+#include "../knowledge/knowledge.h"
+
+#include "sequence.h"
+
+/******************************************************************************/
+/** MEMORY ALLOCATION *********************************************************/
+/******************************************************************************/
+static int ensure_string_capacity
+(
+ ZoO_char * string [const restrict static 1],
+ size_t string_capacity [const restrict static 1],
+ const size_t string_required_capacity,
+ const struct ZoO_pipe io [const restrict static 1]
+)
+{
+ ZoO_char * new_string;
+
+ if (string_required_capacity <= *string_capacity)
+ {
+ return 0;
+ }
+
+ new_string =
+ (ZoO_char *) realloc
+ (
+ (void *) *string,
+ ((size_t) string_required_capacity) * sizeof(ZoO_char)
+ );
+
+ if (new_string== (ZoO_char *) NULL)
+ {
+ ZoO_S_ERROR
+ (
+ io,
+ "Unable to reallocate memory to match string's required size."
+ );
+
+ return -1;
+ }
+
+ *string_capacity = string_required_capacity;
+ *string = new_string;
+
+ return 1;
+}
+
+/******************************************************************************/
+/** ADD WORD ******************************************************************/
+/******************************************************************************/
+static int increment_required_capacity
+(
+ size_t current_capacity [const restrict static 1],
+ const size_t increase_factor,
+ const struct ZoO_pipe io [const restrict static 1]
+)
+{
+ if ((ZoO_INDEX_MAX - increase_factor) > *current_capacity)
+ {
+ ZoO_S_ERROR
+ (
+ io,
+ "String capacity increment aborted, as the new capacity would not"
+ " fit in a ZoO_index variable."
+ );
+
+ return -1;
+ }
+
+ *current_capacity += increase_factor;
+
+ if ((SIZE_MAX / sizeof(ZoO_char)) > *current_capacity)
+ {
+ *current_capacity -= increase_factor;
+
+ ZoO_S_ERROR
+ (
+ io,
+ "String capacity increment aborted, as the new size would not fit"
+ " in a size_t variable."
+ );
+
+ return -2;
+ }
+
+ return 0;
+}
+
+static int add_word
+(
+ const ZoO_index word_id,
+ struct ZoO_knowledge k [const restrict static 1],
+ ZoO_char * destination [const restrict static 1],
+ size_t destination_capacity [const restrict static 1],
+ size_t destination_length [const restrict static 1],
+ const struct ZoO_pipe io [const restrict static 1]
+)
+{
+ const ZoO_char * word;
+ ZoO_index word_size;
+ size_t insertion_point;
+
+ (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);
+
+ insertion_point = *destination_length;
+
+ /* word_size includes '\n', which will be replaced by a space. */
+ /* (word_size == ZoO_INDEX_MAX) ==> could not have learned word. */
+ if (increment_required_capacity(destination_length, (word_size + 1), io) < 0)
+ {
+ return -1;
+ }
+
+ if
+ (
+ ensure_string_capacity
+ (
+ destination,
+ destination_capacity,
+ *destination_length,
+ io
+ ) < 0
+ )
+ {
+ return -2;
+ }
+
+ memcpy
+ (
+ (*destination + insertion_point),
+ (const void *) word,
+ word_size
+ );
+
+ (*destination)[*destination_length - 1] = ' ';
+
+ return 0;
+}
+
+/******************************************************************************/
+/** EXPORTED ******************************************************************/
+/******************************************************************************/
+int ZoO_sequence_to_undercase_string
+(
+ const ZoO_index sequence [const restrict static 1],
+ const size_t sequence_length,
+ ZoO_char * destination [const restrict static 1],
+ struct ZoO_knowledge k [const restrict static 1],
+ size_t destination_capacity [const restrict static 1],
+ size_t destination_length [const restrict static 1],
+ const struct ZoO_pipe io [const restrict static 1]
+)
+{
+ size_t i;
+
+ for (i = 0; i < sequence_length; ++i)
+ {
+ if
+ (
+ add_word
+ (
+ sequence[i],
+ k,
+ destination,
+ destination_capacity,
+ destination_length,
+ io
+ ) < 0
+ )
+ {
+ *destination_length = 0;
+
+ return -1;
+ }
+ }
+
+ return 0;
+}