| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-04-22 21:33:47 +0200 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-04-22 21:33:47 +0200 | 
| commit | 1d32728b9712702c9bca90d6dac370ff5fe2c214 (patch) | |
| tree | 25755963d66e842490eb4d4be8094b7674a85ae0 /src/sequence/sequence_append.c | |
Initial Commit
Diffstat (limited to 'src/sequence/sequence_append.c')
| -rw-r--r-- | src/sequence/sequence_append.c | 241 | 
1 files changed, 241 insertions, 0 deletions
| diff --git a/src/sequence/sequence_append.c b/src/sequence/sequence_append.c new file mode 100644 index 0000000..7206c19 --- /dev/null +++ b/src/sequence/sequence_append.c @@ -0,0 +1,241 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> /* defines SIZE_MAX */ + +#include "../core/index.h" + +#include "../error/error.h" + +#include "sequence.h" + +/******************************************************************************/ +/** MEMORY (RE)ALLOCATION *****************************************************/ +/******************************************************************************/ + +/*@ +   requires \valid(required_capacity); +   requires \valid(io); +   requires +      \separated +      ( +         (required_capacity+ (0 .. \block_length(required_capacity))), +         (io+ (0 .. \block_length(io))) +      ); + +   assigns \result; +   assigns (*required_capacity); + +   ensures ((\result == 0) || (\result == -1)); + +   ensures \valid(required_capacity); +   ensures \valid(io); + +   ensures +      \separated +      ( +         (required_capacity+ (0 .. \block_length(required_capacity))), +         (io+ (0 .. \block_length(io))) +      ); + +   ensures +      ( +         (\result == 0) <==> +               ((*required_capacity) == (\old(*required_capacity) + 1)) +      ); + +   ensures +      ( +         (\result == 0) ==> +            ((*required_capacity) * sizeof(JH_index)) <= SIZE_MAX +      ); + +   ensures +      ( +         (\result == -1) <==> +            ((*required_capacity) == \old(*required_capacity)) +      ); + +@*/ +static int increment_required_capacity +( +   size_t required_capacity [const restrict static 1], +   FILE io [const restrict static 1] +) +{ +   if +   ( +      (*required_capacity == SIZE_MAX) +      || ((SIZE_MAX / sizeof(JH_index)) <= (*required_capacity + 1)) +   ) +   { +      /*@ assert \valid(io); @*/ + +      #ifndef JH_RUNNING_FRAMA_C +      JH_S_ERROR +      ( +         io, +         "Sequence capacity increment aborted, as the new size would not fit " +         "in a size_t variable." +      ); +      #endif + +      return -1; +   } + +   /*@ assert ((*required_capacity) < SIZE_MAX); @*/ +   /*@ assert \valid(required_capacity); @*/ +   *required_capacity = (*required_capacity + 1); + +   /* assert (((*required_capacity) * sizeof(JH_index)) <= SIZE_MAX); @*/ + +   return 0; +} + +/******************************************************************************/ +/** EXPORTED ******************************************************************/ +/******************************************************************************/ + +int JH_sequence_ensure_capacity +( +   JH_index * sequence [const restrict static 1], +   size_t sequence_capacity [const restrict static 1], +   const size_t sequence_required_capacity, +   FILE io [const restrict static 1] +) +{ +   JH_index * new_sequence; + +   /*@ assert \valid(sequence_capacity); @*/ +   if (sequence_required_capacity <= *sequence_capacity) +   { +      return 0; +   } + +   /*@ +      assert +      ( +         sequence_required_capacity +         <= (SIZE_MAX / sizeof(JH_index)) +      ); +   @*/ +   /*@ assert \valid(sequence); @*/ +   /*@ assert \valid(*sequence); @*/ +   new_sequence = +      (JH_index *) realloc +      ( +         (void *) *sequence, +         (sequence_required_capacity * sizeof(JH_index)) +      ); + +   if (new_sequence == (JH_index *) NULL) +   { +      /*@ assert \valid(io); @*/ + +      #ifndef JH_RUNNING_FRAMA_C +      JH_S_ERROR +      ( +         io, +         "Unable to reallocate memory to match sequence's required size." +      ); +      #endif + +      return -1; +   } + +   *sequence_capacity = sequence_required_capacity; +   *sequence = new_sequence; + +   return 1; +} + +int JH_sequence_append_left +( +   const JH_index word_id, +   JH_index * sequence [const restrict static 1], +   size_t sequence_capacity [const restrict static 1], +   size_t sequence_length [const restrict static 1], +   FILE io [const restrict static 1] +) +{ +   if (increment_required_capacity(sequence_length, io) < 0) +   { +      return -1; +   } + +   /*@ assert (((*sequence_length) * sizeof(JH_index)) <= SIZE_MAX); @*/ +   if +   ( +      JH_sequence_ensure_capacity +      ( +         sequence, +         sequence_capacity, +         *sequence_length, +         io +      ) < 0 +   ) +   { +      *sequence_length -= 1; + +      return -1; +   } + +   /*@ assert (*sequence_length) >= 0; @*/ + +   if ((*sequence_length) > 1) +   { +      /*@ assert(((*sequence_length) * sizeof(JH_index)) <= SIZE_MAX); @*/ + +      #ifndef JH_RUNNING_FRAMA_C +      memmove +      ( +         (void *) ((*sequence) + 1), +         (const void *) (*sequence), +         (((*sequence_length) - 1) * sizeof(JH_index)) +      ); +      #endif +   } + +   (*sequence)[0] = word_id; + +   return 0; +} + +int JH_sequence_append_right +( +   JH_index * sequence [const restrict static 1], +   const JH_index word_id, +   size_t sequence_capacity [const restrict static 1], +   size_t sequence_length [const restrict static 1], +   FILE io [const restrict static 1] +) +{ +   if (increment_required_capacity(sequence_length, io) < 0) +   { +      return -1; +   } + +   /*@ assert (((*sequence_length) * sizeof(JH_index)) <= SIZE_MAX); @*/ + +   if +   ( +      JH_sequence_ensure_capacity +      ( +         sequence, +         sequence_capacity, +         *sequence_length, +         io +      ) < 0 +   ) +   { +      *sequence_length -= 1; + +      return -1; +   } + +   /*@ assert ((*sequence_length) >= 1); @*/ +   (*sequence)[(*sequence_length) - 1] = word_id; +   /*@ assert ((*sequence_length) >= 1); @*/ + +   return 0; +} | 


