| summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/sequence/sequence_append.c')
| -rw-r--r-- | src/sequence/sequence_append.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/sequence/sequence_append.c b/src/sequence/sequence_append.c new file mode 100644 index 0000000..a119d8b --- /dev/null +++ b/src/sequence/sequence_append.c @@ -0,0 +1,212 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdint.h> /* defines SIZE_MAX */ + +#include "../core/index.h" + +#include "../pipe/pipe.h" + +#include "sequence.h" + +/******************************************************************************/ +/** MEMORY (RE)ALLOCATION *****************************************************/ +/******************************************************************************/ + +/*@ + requires \valid(required_capacity); + requires \valid(io); + requires (*required_capacity >= 0); + requires (*required_capacity <= SIZE_MAX); + requires \separated(required_capacity, io); + + assigns \result; + + ensures (*required_capacity >= 0); + + behavior success: + assigns (*required_capacity); + + ensures (\result >= 0); + ensures ((*required_capacity) == (\old(*required_capacity) + 1)); + ensures (((*required_capacity) * sizeof(ZoO_index)) <= SIZE_MAX); + + behavior failure: + assigns \nothing; + + ensures (\result < 0); + + complete behaviors; + disjoint behaviors; +@*/ +static int increment_required_capacity +( + size_t required_capacity [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + if + ( + (*required_capacity == SIZE_MAX) + || ((SIZE_MAX / sizeof(ZoO_index)) <= (*required_capacity + 1)) + ) + { + /*@ assert \valid(io); @*/ + /*@ ghost return -1; @*/ + ZoO_S_ERROR + ( + io, + "Sequence capacity increment aborted, as the new size would not fit" + " in a size_t variable." + ); + + return -1; + } + + /*@ assert ((*required_capacity) < SIZE_MAX); @*/ + /*@ assert \valid(required_capacity); @*/ + *required_capacity = (*required_capacity + 1); + + /* assert (((*required_capacity) * sizeof(ZoO_index)) <= SIZE_MAX); @*/ + + return 0; +} + +/******************************************************************************/ +/** EXPORTED ******************************************************************/ +/******************************************************************************/ + +int ZoO_sequence_ensure_capacity +( + ZoO_index * sequence [const restrict static 1], + size_t sequence_capacity [const restrict static 1], + const size_t sequence_required_capacity, + const struct ZoO_pipe io [const restrict static 1] +) +{ + ZoO_index * new_sequence; + + if (sequence_required_capacity <= *sequence_capacity) + { + return 0; + } + + /*@ + assert + ( + sequence_required_capacity + <= (SIZE_MAX / sizeof(ZoO_index)) + ); + @*/ + /*@ assert \valid(sequence); @*/ + /*@ assert \valid(*sequence); @*/ + + new_sequence = + (ZoO_index *) realloc + ( + (void *) *sequence, + (sequence_required_capacity * sizeof(ZoO_index)) + ); + + if (new_sequence == (ZoO_index *) NULL) + { + /*@ assert \valid(io); @*/ + /*@ ghost return -1; @*/ + + ZoO_S_ERROR + ( + io, + "Unable to reallocate memory to match sequence's required size." + ); + + return -1; + } + + *sequence_capacity = sequence_required_capacity; + *sequence = new_sequence; + + return 1; +} + +int ZoO_sequence_append_left +( + const ZoO_index word_id, + ZoO_index * sequence [const restrict static 1], + size_t sequence_capacity [const restrict static 1], + size_t sequence_length [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + if (increment_required_capacity(sequence_length, io) < 0) + { + return -1; + } + + /*@ assert (((*sequence_length) * sizeof(ZoO_index)) <= SIZE_MAX); @*/ + if + ( + /* Appears to make Frama-C forget everything about *sequence_length. */ + ZoO_sequence_ensure_capacity + ( + sequence, + sequence_capacity, + *sequence_length, + io + ) < 0 + ) + { + return -2; + } + /*@ assert *sequence_length >= 0; @*/ + + if (*sequence_length > 1) + { + /*@ assert(((*sequence_length) * sizeof(ZoO_index)) <= SIZE_MAX); @*/ + + memmove + ( + (void *) (*sequence + 1), + (const void *) sequence, + (((*sequence_length) - 1) * sizeof(ZoO_index)) + ); + } + + (*sequence)[0] = word_id; + + return 0; +} + +int ZoO_sequence_append_right +( + ZoO_index * sequence [const restrict static 1], + const ZoO_index word_id, + size_t sequence_capacity [const restrict static 1], + size_t sequence_length [const restrict static 1], + const struct ZoO_pipe io [const restrict static 1] +) +{ + if (increment_required_capacity(sequence_length, io) < 0) + { + return -1; + } + + /*@ assert ((*sequence_length * sizeof(ZoO_index)) < SIZE_MAX); @*/ + if + ( + ZoO_sequence_ensure_capacity + ( + sequence, + sequence_capacity, + *sequence_length, + io + ) < 0 + ) + { + return -1; + } + + /* assert (*sequence_length >= 1) */ + (*sequence)[*sequence_length - 1] = word_id; + + return 0; +} |


