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_append.c
parentdf3657b2a99ef20da99ac3c6c02f43cc23e70fca (diff)
Trying out ACSL, continuing implementation.
Diffstat (limited to 'src/sequence/sequence_append.c')
-rw-r--r--src/sequence/sequence_append.c212
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;
+}