From: Dan Good Date: Tue, 5 Jan 2016 01:07:19 +0000 (+0000) Subject: deque: check HAVE_STATEMENT_EXPR, tweaks from feedback X-Git-Url: https://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=3022d16de40870c66c891a4aa75280e194ddf89f;ds=inline deque: check HAVE_STATEMENT_EXPR, tweaks from feedback 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 --- diff --git a/ccan/deque/_info b/ccan/deque/_info index b1a47bbb..63687b74 100644 --- a/ccan/deque/_info +++ b/ccan/deque/_info @@ -16,7 +16,7 @@ * 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 * #include * #include @@ -122,6 +122,12 @@ * * License: APACHE-2 * Author: Dan Good + * + * 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[]) { diff --git a/ccan/deque/deque.c b/ccan/deque/deque.c index cb628d37..548b4efa 100644 --- a/ccan/deque/deque.c +++ b/ccan/deque/deque.c @@ -1,3 +1,5 @@ +/* Licensed under Apache License v2.0 - see LICENSE file for details */ +#include "config.h" #include #include #include diff --git a/ccan/deque/deque.h b/ccan/deque/deque.h index 1e5b4e8e..ffd6c2a5 100644 --- a/ccan/deque/deque.h +++ b/ccan/deque/deque.h @@ -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 +#include +#include /** * struct deq - deque metadata @@ -87,7 +93,7 @@ int deq_resize_(struct deq *q, unsigned n); * //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)); \ diff --git a/ccan/deque/test/api1.c b/ccan/deque/test/api1.c new file mode 100644 index 00000000..faa87248 --- /dev/null +++ b/ccan/deque/test/api1.c @@ -0,0 +1,138 @@ +#include +#include + +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 index 8d953ea4..00000000 --- a/ccan/deque/test/run1.c +++ /dev/null @@ -1,140 +0,0 @@ -#include -/* Include the C files directly. */ -#include -#include - -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/run2.c b/ccan/deque/test/run2.c index 92502104..fba83f9a 100644 --- a/ccan/deque/test/run2.c +++ b/ccan/deque/test/run2.c @@ -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); - plan_tests(19); + plan_tests(20); 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); + 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);