deque: check HAVE_STATEMENT_EXPR, tweaks from feedback
authorDan Good <dan@dancancode.com>
Tue, 5 Jan 2016 01:07:19 +0000 (01:07 +0000)
committerDan Good <dan@dancancode.com>
Tue, 5 Jan 2016 01:07:19 +0000 (01:07 +0000)
Thanks to the detailed feedback from David Gibson, I made the
following improvements:

* add missing includes
* check for statement expression support, give an error if absent
* ccanlint directive to skip "without features" steps
* add license ref to top of source files
* rename run1.c test to api1.c

Signed-off-by: Dan Good <dan@dancancode.com>
ccan/deque/_info
ccan/deque/deque.c
ccan/deque/deque.h
ccan/deque/test/api1.c [new file with mode: 0644]
ccan/deque/test/run1.c [deleted file]
ccan/deque/test/run2.c

index b1a47bbbb8e6f5d832f1b79f0a621562451e1aa3..63687b7421e96ef8e68336ea42e93318b7c788f2 100644 (file)
@@ -16,7 +16,7 @@
  * Example:
  *     // Evaluates arithmetic expressions using Dijkstra's two-stack algorithm.
  *     // Original: http://algs4.cs.princeton.edu/13stacks/EvaluateDeluxe.java.html
  * Example:
  *     // Evaluates arithmetic expressions using Dijkstra's two-stack algorithm.
  *     // Original: http://algs4.cs.princeton.edu/13stacks/EvaluateDeluxe.java.html
- *     #define _XOPEN_SOURCE 700
+ *     #define _XOPEN_SOURCE 700 // only for getline(3) in this demo
  *     #include <stdio.h>
  *     #include <stdlib.h>
  *     #include <ctype.h>
  *     #include <stdio.h>
  *     #include <stdlib.h>
  *     #include <ctype.h>
  *
  * License: APACHE-2
  * Author: Dan Good <dan@dancancode.com>
  *
  * License: APACHE-2
  * Author: Dan Good <dan@dancancode.com>
+ *
+ * Ccanlint:
+ *     // uses statement expressions
+ *     // supported by gcc, clang, icc, and some others, but not msvc
+ *     // (see https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html)
+ *     objects_build_without_features FAIL
  */
 int main(int argc, char *argv[])
 {
  */
 int main(int argc, char *argv[])
 {
index cb628d37c2ef6995cac7a1bec959466e6a772934..548b4efa53f53cae1c3cd49250b3dcac51cbd136 100644 (file)
@@ -1,3 +1,5 @@
+/* Licensed under Apache License v2.0 - see LICENSE file for details */
+#include "config.h"
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
index 1e5b4e8eb1167f4f9aedd1acfdc558ea2217dbdf..ffd6c2a5ced59273cce4d5cdd974a4c0298dc9e2 100644 (file)
@@ -1,7 +1,13 @@
-#ifndef _DEQUE_H
-#define _DEQUE_H
-
+/* Licensed under Apache License v2.0 - see LICENSE file for details */
+#ifndef CCAN_DEQUE_H
+#define CCAN_DEQUE_H
+#include "config.h"
+#if !HAVE_STATEMENT_EXPR
+#error "This code needs compiler support for statement expressions. Try using gcc or clang."
+#endif
 #include <assert.h>
 #include <assert.h>
+#include <stdlib.h>
+#include <string.h>
 
 /**
  * struct deq - deque metadata
 
 /**
  * struct deq - deque metadata
@@ -87,7 +93,7 @@ int deq_resize_(struct deq *q, unsigned n);
  *     //later
  *     deq_free(z);
  *
  *     //later
  *     deq_free(z);
  *
- * Returns: pointer on success, NULL on error
+ * Returns: 0 on success, -1 on error
  */
 #define deq_new(w, min, shrink) ({                     \
        w = malloc(sizeof(*w));                         \
  */
 #define deq_new(w, min, shrink) ({                     \
        w = malloc(sizeof(*w));                         \
diff --git a/ccan/deque/test/api1.c b/ccan/deque/test/api1.c
new file mode 100644 (file)
index 0000000..faa8724
--- /dev/null
@@ -0,0 +1,138 @@
+#include <ccan/deque/deque.h>
+#include <ccan/tap/tap.h>
+
+int main(void)
+{
+       char t, *save;
+
+       plan_tests(64);
+
+       DEQ_WRAP(char) *a;
+       ok1(deq_new(a, 4, DEQ_SHRINK_AT_20PCT) == 0);
+       ok1(a->v && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 0 && a->deq.cap == 4 &&
+           a->deq.min == 4 && a->deq.esz == 1 && a->deq.shrink == DEQ_SHRINK_AT_20PCT);
+       save = a->v;
+       memset(a->v, 0, a->deq.cap);
+       ok1(deq_len(a) == 0 && deq_cap(a) == 4);
+
+       ok1(deq_push(a, 'a') == 1);
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 1 && a->deq.len == 1 && a->deq.cap == 4);
+       ok1(a->v[0] == 'a');
+       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
+       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'a');
+       ok1(deq_len(a) == 1 && deq_cap(a) == 4);
+
+       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'a');
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 0 && a->deq.cap == 4);
+
+       ok1(deq_unshift(a, 'a') == 1);
+       ok1(a->v == save && a->deq.head == 3 && a->deq.tail == 0 && a->deq.len == 1 && a->deq.cap == 4);
+       ok1(a->v[3] == 'a');
+       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
+       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'a');
+
+       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'a');
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 0 && a->deq.cap == 4);
+
+       memset(a->v, 0, a->deq.cap);
+       deq_push(a, 'a');
+       deq_push(a, 'b');
+       deq_push(a, 'c');
+       deq_push(a, 'd');
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 4 && a->deq.cap == 4);
+       ok1(strncmp("abcd", a->v + a->deq.head, a->deq.len) == 0);
+       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
+       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'd');
+
+       deq_push(a, 'e');
+       ok1(a->v != save);
+       save = a->v;
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 5 && a->deq.len == 5 && a->deq.cap == 8);
+       ok1(strncmp("abcde", a->v + a->deq.head, a->deq.len) == 0);
+       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
+       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'e');
+       ok1(deq_len(a) == 5 && deq_cap(a) == 8);
+
+
+       deq_push(a, 'f');
+       deq_push(a, 'g');
+       deq_push(a, 'h');
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 8 && a->deq.cap == 8);
+       ok1(strncmp("abcdefgh", a->v + a->deq.head, a->deq.len) == 0);
+
+       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'a');
+       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'b');
+       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'c');
+       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'd');
+       ok1(a->v == save && a->deq.head == 4 && a->deq.tail == 0 && a->deq.len == 4 && a->deq.cap == 8);
+       ok1(strncmp("efgh", a->v + a->deq.head, a->deq.len) == 0);
+       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'e');
+       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'h');
+
+       deq_push(a, 'i');
+       deq_push(a, 'j');
+       deq_push(a, 'k');
+       deq_push(a, 'l');
+       ok1(a->v == save && a->deq.head == 4 && a->deq.tail == 4 && a->deq.len == 8 && a->deq.cap == 8);
+       ok1(strncmp("ijklefgh", a->v, a->deq.len) == 0);
+
+       deq_push(a, 'm');
+       ok1(a->v != save);
+       save = a->v;
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 9 && a->deq.len == 9 && a->deq.cap == 16);
+       ok1(strncmp("efghijklm", a->v + a->deq.head, a->deq.len) == 0);
+
+       int i;
+       for (i = 9, t = '!'; i <= 128; i++, t = (t == '~' ? '!' : t + 1))
+               deq_push(a, t);
+
+       save = a->v;
+       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 129 && a->deq.len == 129 && a->deq.cap == 256);
+       int j;
+       for(j = 0; i > 52; i--, j++)
+               deq_shift(a, &t);
+       ok1(a->v == save && a->deq.head == j && a->deq.tail == 129 && a->deq.len == 52 && a->deq.cap == 256);
+       deq_shift(a, &t);
+       ok1(a->v != save);
+       save = a->v;
+       ok1(a->v == save && a->deq.head == 1 && a->deq.tail == 52 && a->deq.len == 51 && a->deq.cap == 128);
+       ok1(strncmp("fghijklmnopqrstuvwxyz{|}~!\"#$%&'()*+,-./0123456789:", a->v + a->deq.head, a->deq.len) == 0);
+
+       a->deq.shrink = DEQ_SHRINK_IF_EMPTY;
+       for(i = a->deq.len; i > 1; i--)
+               deq_shift(a, &t);
+       ok1(a->v == save && a->deq.head == 51 && a->deq.tail == 52 && a->deq.len == 1 && a->deq.cap == 128);
+       deq_shift(a, &t);
+       ok1(a->v != save);
+       save = a->v;
+       ok1(a->v == save && a->deq.head == 1 && a->deq.tail == 1 && a->deq.len == 0 && a->deq.cap == a->deq.min);
+
+       deq_reset(a);
+       ok1(!a->v);
+       ok1(deq_unshift(a, 'a') == 1);
+       save = a->v;
+       memset(a->v, 0, a->deq.cap - 1);
+       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'a');
+       ok1(a->v == save && a->deq.head == 3 && a->deq.tail == 3 && a->deq.len == 0 && a->deq.cap == 4);
+
+       deq_reset(a);
+       deq_push(a, 'A');
+       save = a->v;
+       deq_unshift(a, 'B');
+       deq_push(a, 'C');
+       deq_unshift(a, 'D');
+       ok1(strncmp("ACDB", a->v, 4) == 0);
+       ok1(a->v == save && a->deq.head == 2 && a->deq.tail == 2 && a->deq.len == 4 && a->deq.cap == 4);
+       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'C');
+       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'D');
+       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'B');
+       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'A');
+
+       ok1(deq_pop(a, &t) == 0);
+       ok1(deq_shift(a, &t) == 0);
+
+       deq_free(a);
+       ok1(!a);
+
+       return exit_status();
+}
diff --git a/ccan/deque/test/run1.c b/ccan/deque/test/run1.c
deleted file mode 100644 (file)
index 8d953ea..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-#include <ccan/deque/deque.h>
-/* Include the C files directly. */
-#include <ccan/deque/deque.c>
-#include <ccan/tap/tap.h>
-
-int main(void)
-{
-       char t, *save;
-
-       plan_tests(64);
-
-       DEQ_WRAP(char) *a;
-       ok1(deq_new(a, 4, DEQ_SHRINK_AT_20PCT) == 0);
-       ok1(a->v && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 0 && a->deq.cap == 4 &&
-           a->deq.min == 4 && a->deq.esz == 1 && a->deq.shrink == DEQ_SHRINK_AT_20PCT);
-       save = a->v;
-       memset(a->v, 0, a->deq.cap);
-       ok1(deq_len(a) == 0 && deq_cap(a) == 4);
-
-       ok1(deq_push(a, 'a') == 1);
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 1 && a->deq.len == 1 && a->deq.cap == 4);
-       ok1(a->v[0] == 'a');
-       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
-       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'a');
-       ok1(deq_len(a) == 1 && deq_cap(a) == 4);
-
-       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'a');
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 0 && a->deq.cap == 4);
-
-       ok1(deq_unshift(a, 'a') == 1);
-       ok1(a->v == save && a->deq.head == 3 && a->deq.tail == 0 && a->deq.len == 1 && a->deq.cap == 4);
-       ok1(a->v[3] == 'a');
-       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
-       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'a');
-
-       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'a');
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 0 && a->deq.cap == 4);
-
-       memset(a->v, 0, a->deq.cap);
-       deq_push(a, 'a');
-       deq_push(a, 'b');
-       deq_push(a, 'c');
-       deq_push(a, 'd');
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 4 && a->deq.cap == 4);
-       ok1(strncmp("abcd", a->v + a->deq.head, a->deq.len) == 0);
-       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
-       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'd');
-
-       deq_push(a, 'e');
-       ok1(a->v != save);
-       save = a->v;
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 5 && a->deq.len == 5 && a->deq.cap == 8);
-       ok1(strncmp("abcde", a->v + a->deq.head, a->deq.len) == 0);
-       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'a');
-       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'e');
-       ok1(deq_len(a) == 5 && deq_cap(a) == 8);
-
-
-       deq_push(a, 'f');
-       deq_push(a, 'g');
-       deq_push(a, 'h');
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 0 && a->deq.len == 8 && a->deq.cap == 8);
-       ok1(strncmp("abcdefgh", a->v + a->deq.head, a->deq.len) == 0);
-
-       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'a');
-       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'b');
-       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'c');
-       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'd');
-       ok1(a->v == save && a->deq.head == 4 && a->deq.tail == 0 && a->deq.len == 4 && a->deq.cap == 8);
-       ok1(strncmp("efgh", a->v + a->deq.head, a->deq.len) == 0);
-       ok1(t = '~' && deq_first(a, &t) == 1 && t == 'e');
-       ok1(t = '~' && deq_last(a, &t)  == 1 && t == 'h');
-
-       deq_push(a, 'i');
-       deq_push(a, 'j');
-       deq_push(a, 'k');
-       deq_push(a, 'l');
-       ok1(a->v == save && a->deq.head == 4 && a->deq.tail == 4 && a->deq.len == 8 && a->deq.cap == 8);
-       ok1(strncmp("ijklefgh", a->v, a->deq.len) == 0);
-
-       deq_push(a, 'm');
-       ok1(a->v != save);
-       save = a->v;
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 9 && a->deq.len == 9 && a->deq.cap == 16);
-       ok1(strncmp("efghijklm", a->v + a->deq.head, a->deq.len) == 0);
-
-       int i;
-       for (i = 9, t = '!'; i <= 128; i++, t = (t == '~' ? '!' : t + 1))
-               deq_push(a, t);
-
-       save = a->v;
-       ok1(a->v == save && a->deq.head == 0 && a->deq.tail == 129 && a->deq.len == 129 && a->deq.cap == 256);
-       int j;
-       for(j = 0; i > 52; i--, j++)
-               deq_shift(a, &t);
-       ok1(a->v == save && a->deq.head == j && a->deq.tail == 129 && a->deq.len == 52 && a->deq.cap == 256);
-       deq_shift(a, &t);
-       ok1(a->v != save);
-       save = a->v;
-       ok1(a->v == save && a->deq.head == 1 && a->deq.tail == 52 && a->deq.len == 51 && a->deq.cap == 128);
-       ok1(strncmp("fghijklmnopqrstuvwxyz{|}~!\"#$%&'()*+,-./0123456789:", a->v + a->deq.head, a->deq.len) == 0);
-
-       a->deq.shrink = DEQ_SHRINK_IF_EMPTY;
-       for(i = a->deq.len; i > 1; i--)
-               deq_shift(a, &t);
-       ok1(a->v == save && a->deq.head == 51 && a->deq.tail == 52 && a->deq.len == 1 && a->deq.cap == 128);
-       deq_shift(a, &t);
-       ok1(a->v != save);
-       save = a->v;
-       ok1(a->v == save && a->deq.head == 1 && a->deq.tail == 1 && a->deq.len == 0 && a->deq.cap == a->deq.min);
-
-       deq_reset(a);
-       ok1(!a->v);
-       ok1(deq_unshift(a, 'a') == 1);
-       save = a->v;
-       memset(a->v, 0, a->deq.cap - 1);
-       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'a');
-       ok1(a->v == save && a->deq.head == 3 && a->deq.tail == 3 && a->deq.len == 0 && a->deq.cap == 4);
-
-       deq_reset(a);
-       deq_push(a, 'A');
-       save = a->v;
-       deq_unshift(a, 'B');
-       deq_push(a, 'C');
-       deq_unshift(a, 'D');
-       ok1(strncmp("ACDB", a->v, 4) == 0);
-       ok1(a->v == save && a->deq.head == 2 && a->deq.tail == 2 && a->deq.len == 4 && a->deq.cap == 4);
-       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'C');
-       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'D');
-       ok1(t = '~' && deq_shift(a, &t) == 1 && t == 'B');
-       ok1(t = '~' && deq_pop(a, &t) == 1 && t == 'A');
-
-       ok1(deq_pop(a, &t) == 0);
-       ok1(deq_shift(a, &t) == 0);
-
-       deq_free(a);
-       ok1(!a);
-
-       return exit_status();
-}
index 92502104f43dda17488a9088a8ed5baa31b9f36f..fba83f9a5b7d04f8e2a7354c3ddd283dd65187d3 100644 (file)
@@ -12,7 +12,7 @@ int main(void)
        struct quad { int w, x, y, z; } p, q, r, s, *save;
        assert(sizeof(struct quad) == sizeof(int) * 4);
 
        struct quad { int w, x, y, z; } p, q, r, s, *save;
        assert(sizeof(struct quad) == sizeof(int) * 4);
 
-       plan_tests(19);
+       plan_tests(20);
 
        typedef DEQ_WRAP(struct quad) qd_t;
        qd_t a_, *a = &a_;
 
        typedef DEQ_WRAP(struct quad) qd_t;
        qd_t a_, *a = &a_;
@@ -52,6 +52,9 @@ int main(void)
        deq_push(a, q);
        ok1(a->v != save && a->deq.head == 0 && a->deq.tail == 5 && a->deq.len == 5 && a->deq.cap == 8);
        ok1(malloc_sz == sizeof(struct quad) * 8);
        deq_push(a, q);
        ok1(a->v != save && a->deq.head == 0 && a->deq.tail == 5 && a->deq.len == 5 && a->deq.cap == 8);
        ok1(malloc_sz == sizeof(struct quad) * 8);
+       save = a->v;
+       deq_unshift(a, r);
+       ok1(a->v == save && a->deq.head == 7 && a->deq.tail == 5 && a->deq.len == 6 && a->deq.cap == 8);
 
        deq_reset(a);
 
 
        deq_reset(a);