summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2014-08-18 15:39:17 +0200
committerYorhel <git@yorhel.nl>2014-08-18 15:39:17 +0200
commita19e8244dd57b161858c3a793b255a0d72035ebc (patch)
treed0d3c281cc4bce4c8815084c16b12e7d8d68ebb2
parent8d5116d0480148d5cb7ca136c60da06347628782 (diff)
Add test for ypc_val/ypc_get functions + fix two bugs found with it
-rw-r--r--Makefile.am4
-rw-r--r--lib/util/byteswap.h2
-rw-r--r--lib/val/ypc_add_int.c8
-rw-r--r--lib/ypc.h4
-rw-r--r--test/hex.c5
-rw-r--r--test/val.c119
6 files changed, 134 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am
index 1d2f745..369aa70 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -51,7 +51,7 @@ EXTRA_DIST=\
include_HEADERS=lib/ypc.h
-TESTS=test/str2sockaddr test/hex test/val_parse
+TESTS=test/str2sockaddr test/hex test/val_parse test/val
check_PROGRAMS=$(TESTS)
test_str2sockaddr_SOURCES=test/str2sockaddr.c lib/util/str2sockaddr.c lib/util/str2sockaddr_ip.c lib/util/str2sockaddr_port.c
test_str2sockaddr_CFLAGS=$(AM_CFLAGS)
@@ -59,6 +59,8 @@ test_hex_SOURCES=test/hex.c lib/util/hex2bin.c lib/util/bin2hex.c
test_hex_CFLAGS=$(AM_CFLAGS)
test_val_parse_SOURCES=test/val_parse.c
test_val_parse_LDADD=libypc.la
+test_val_SOURCES=test/val.c
+test_val_LDADD=libypc.la
MOSTLYCLEANFILES=ypc.dll ypc.lib ypc.exp ypc.pdb ypc.ilk *.obj
ACLOCAL_AMFLAGS=-I ac
diff --git a/lib/util/byteswap.h b/lib/util/byteswap.h
index 99981a6..13fbc23 100644
--- a/lib/util/byteswap.h
+++ b/lib/util/byteswap.h
@@ -31,7 +31,7 @@ static inline uint32_t ypc__swap32(uint32_t v) {
}
-static inline uint32_t ypc__swap64(uint64_t v) {
+static inline uint64_t ypc__swap64(uint64_t v) {
#if defined(_MSC_VER)
return _byteswap_uint64(v);
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
diff --git a/lib/val/ypc_add_int.c b/lib/val/ypc_add_int.c
index bb31983..68095fe 100644
--- a/lib/val/ypc_add_int.c
+++ b/lib/val/ypc_add_int.c
@@ -5,20 +5,20 @@ YPC_EXPORT int ypc_add_int(ypc_val *v, int64_t i) {
if(v->size < v->len + 9 && ypc_val_resize(v, v->len+9) != 0)
return -1;
if(i >= INT8_MIN && i <= INT8_MAX) {
- v->buf[v->len++] = 3;
+ v->buf[v->len++] = YPCT_INT8;
v->buf[v->len++] = i;
} else if(i >= INT16_MIN && i <= INT16_MAX) {
- v->buf[v->len++] = 4;
+ v->buf[v->len++] = YPCT_INT16;
uint16_t n = ypc__hn16(i);
memcpy(v->buf+v->len, &n, 2);
v->len += 2;
} else if(i >= INT32_MIN && i <= INT32_MAX) {
- v->buf[v->len++] = 5;
+ v->buf[v->len++] = YPCT_INT32;
uint32_t n = ypc__hn32(i);
memcpy(v->buf+v->len, &n, 4);
v->len += 4;
} else {
- v->buf[v->len++] = 6;
+ v->buf[v->len++] = YPCT_INT64;
uint64_t n = ypc__hn64(i);
memcpy(v->buf+v->len, &n, 8);
v->len += 8;
diff --git a/lib/ypc.h b/lib/ypc.h
index ee71df5..2885ab4 100644
--- a/lib/ypc.h
+++ b/lib/ypc.h
@@ -145,8 +145,8 @@ static inline ypc_get ypc_iter_next(ypc_iter *i) { ypc_get g = {i->buf};
* *v->buf == 9, which is much cheaper than a function call. A similar
* optimization is possible when using ypc_get_type() in a switch statement.
*/
-static inline ypc_type ypc_get_type(ypc_get *v) {
- switch(*v->buf) {
+static inline ypc_type ypc_get_type(ypc_get v) {
+ switch(*v.buf) {
case 0:
return YPC_NULL;
case 1:
diff --git a/test/hex.c b/test/hex.c
index df3ec9f..9531948 100644
--- a/test/hex.c
+++ b/test/hex.c
@@ -1,5 +1,10 @@
#include "../lib/internal.h"
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
int main(int argc, char **argv) {
#define E(str, len) do {\
uint8_t buf[len];\
diff --git a/test/val.c b/test/val.c
new file mode 100644
index 0000000..743a977
--- /dev/null
+++ b/test/val.c
@@ -0,0 +1,119 @@
+#include "../lib/ypc.h"
+#include "../lib/util/bin2hex.c"
+#include <math.h>
+#include <stdio.h>
+
+#ifdef NDEBUG
+#undef NDEBUG
+#endif
+#include <assert.h>
+
+
+#define T_MSG\
+ C("\x0a", ypc_add_array(v))\
+ C("\x00", ypc_add_null(v))\
+ C("\x02", ypc_add_bool(v, true))\
+ C("\x01", ypc_add_bool(v, false))\
+ C("\x03\x01", ypc_add_int(v, 1))\
+ C("\x03\xff", ypc_add_int(v, -1))\
+ C("\x04\x01\xf4", ypc_add_int(v, 500))\
+ C("\x04\xfe\x0c", ypc_add_int(v, -500))\
+ C("\x05\x00\x07\xa1\x20", ypc_add_int(v, 500000))\
+ C("\x05\xff\xf8\x5e\xe0", ypc_add_int(v, -500000))\
+ C("\x06\x7f\xff\xff\xff\xff\xff\xff\xff", ypc_add_int(v, INT64_MAX))\
+ C("\x06\x80\x00\x00\x00\x00\x00\x00\x00", ypc_add_int(v, INT64_MIN))\
+ C("\x07\x00\x00\x00\x00\x00\x00\x00\x00", ypc_add_float(v, 0.0))\
+ C("\x07\x40\x09\x21\xfb\x54\x44\x2d\x18", ypc_add_float(v, M_PI))\
+ C("\x07\x7f\xf0\x00\x00\x00\x00\x00\x00", ypc_add_float(v, HUGE_VAL))\
+ C("\x0b", ypc_add_map(v))\
+ C("\x0c", ypc_add_close(v))\
+ C("\x0b", ypc_add_map(v))\
+ C("\x09""abc\0", ypc_add_text(v, "abc"))\
+ C("\x09""foob\0", ypc_add_textn(v, "foobar", 4))\
+ C("\x08\0\0\5\0\1\2\3\xff", ypc_add_bin(v, (const uint8_t *)"\0\1\2\3\xff", 5))\
+ C("\x08\0\0\0", ypc_add_bin(v, (const uint8_t *)"", 0))\
+ C("\x0c", ypc_add_close(v))\
+ C("\x0c", ypc_add_close(v))
+
+#define C(s, x) s
+static const char msg[] = T_MSG;
+#undef C
+
+#define STR(x) #x
+
+static void t_create(ypc_val *v) {
+ assert(ypc_val_init(v, 32) == 0);
+#define C(s, x) do {\
+ size_t l = v->len;\
+ if(x != 0) {\
+ fputs(STR(x)" failed\n", stderr);\
+ exit(1);\
+ }\
+ l = v->len - l;\
+ if(l != sizeof s - 1 || memcmp(v->buf + v->len - l, s, l) != 0) {\
+ char exp[2*sizeof s];\
+ ypc__bin2hex(exp, (const uint8_t *)s, sizeof s - 1);\
+ char got[2*l+1];\
+ ypc__bin2hex(got, v->buf + v->len - l, l);\
+ fprintf(stderr, "%s produced wrong output\n Got: %s\n Expected: %s\n", STR(x), got, exp);\
+ exit(1);\
+ }\
+ } while(0);
+ T_MSG
+#undef C
+
+ assert(v->len == sizeof msg - 1);
+ assert(memcmp(v->buf, msg, v->len) == 0);
+}
+
+
+static void t_read(ypc_get g) {
+ assert(ypc_get_type(g) == YPC_ARRAY);
+ assert(ypc_get_size(g) == sizeof msg - 1);
+ ypc_iter i = ypc_get_iter(g);
+ ypc_iter m;
+
+#define V(i, t, x) do {\
+ assert(!ypc_iter_end(i));\
+ g = ypc_iter_next(&i);\
+ assert(ypc_get_type(g) == t);\
+ assert(x);\
+ } while(0)
+
+ V(i, YPC_NULL, 1);
+ V(i, YPC_BOOL, ypc_get_bool(g) == true);
+ V(i, YPC_BOOL, ypc_get_bool(g) == false);
+ V(i, YPC_INT, ypc_get_int(g) == 1);
+ V(i, YPC_INT, ypc_get_int(g) == -1);
+ V(i, YPC_INT, ypc_get_int(g) == 500);
+ V(i, YPC_INT, ypc_get_int(g) == -500);
+ V(i, YPC_INT, ypc_get_int(g) == 500000);
+ V(i, YPC_INT, ypc_get_int(g) == -500000);
+ V(i, YPC_INT, ypc_get_int(g) == INT64_MAX);
+ V(i, YPC_INT, ypc_get_int(g) == INT64_MIN);
+ V(i, YPC_FLOAT, ypc_get_float(g) == 0.0);
+ V(i, YPC_FLOAT, ypc_get_float(g) == M_PI);
+ V(i, YPC_FLOAT, ypc_get_float(g) == HUGE_VAL);
+
+ V(i, YPC_MAP, ypc_iter_end(ypc_get_iter(g)));
+
+ V(i, YPC_MAP, 1);
+ m = ypc_get_iter(g);
+ V(m, YPC_TEXT, strcmp(ypc_get_text(g), "abc") == 0);
+ V(m, YPC_TEXT, strcmp(ypc_get_text(g), "foob") == 0);
+ V(m, YPC_BIN, ypc_get_bin_len(g) == 5 && memcmp(ypc_get_bin(g), "\0\1\2\3\xff", 5) == 0);
+ V(m, YPC_BIN, ypc_get_bin_len(g) == 0);
+ assert(ypc_iter_end(m));
+#undef V
+
+ assert(ypc_iter_end(i));
+}
+
+
+int main(int argc, char **argv) {
+ ypc_val v;
+ t_create(&v);
+ t_read(ypc_val_get(&v));
+ ypc_val_free(&v);
+ return 0;
+}