commit cbf9612aaec6926e5e953b2c308d6c9b75bd7a55
parent c244d030f12caa09b01fc6e4aaeb378f4ce4e597
Author: hhvn <dev@hhvn.uk>
Date: Sun, 27 Nov 2022 20:29:20 +0000
bdbget() works on arrays rather than allocating them
Diffstat:
M | src/bdb.c | | | 43 | ++++++++++++++++++++----------------------- |
A | tests/bdb.test | | | 94 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 114 insertions(+), 23 deletions(-)
diff --git a/src/bdb.c b/src/bdb.c
@@ -11,14 +11,14 @@
* Set: 'T', key, val[], n
*
* Get: 't', key, &val
- * Get: 'T', key, &val[], &n
+ * Get: 'T', key, val[], n
*
* Where 't'/'T' is:
- * 's' - string
+ * 's' - string (will allocate memory on get)
* 'i' - int
* 'f' - float
* 'v' - vector
- * 'S' - array of strings
+ * 'S' - array of strings (will allocate memory for elements on get)
* 'I' - array of ints
* 'F' - array of floats
*
@@ -121,11 +121,11 @@ _bdbget(char *dir, char *group, ...) {
int *i;
float *f;
Vector *v;
- char ***S;
- int **I;
- float **F;
+ char **S;
+ int *I;
+ float *F;
} v;
- int i;
+ int i, n;
va_start(ap, group);
@@ -142,7 +142,7 @@ _bdbget(char *dir, char *group, ...) {
switch (type) {
case 's':
v.s = va_arg(ap, char **);
- dbgetf(dir, group, key, "%s", v.s);
+ *v.s = nstrdup(dbget(dir, group, key));
break;
case 'i':
v.i = va_arg(ap, int *);
@@ -158,25 +158,22 @@ _bdbget(char *dir, char *group, ...) {
&(*v.v).x, &(*v.v).y);
break;
case 'S':
- v.S = va_arg(ap, char ***);
- *v.S = emalloc(len * sizeof(char *));
- for (i = 0; i < len; i++)
- (*v.S)[i] = nstrdup(list[i]);
- *va_arg(ap, int *) = len;
+ v.S = va_arg(ap, char **);
+ n = va_arg(ap, int);
+ for (i = 0; i < n; i++)
+ v.S[i] = i < len ? nstrdup(list[i]) : NULL;
break;
case 'I':
- v.I = va_arg(ap, int **);
- *v.I = emalloc(len * sizeof(int));
- for (i = 0; i < len; i++)
- (*v.I)[i] = atoi(list[i]);
- *va_arg(ap, int *) = len;
+ v.I = va_arg(ap, int *);
+ n = va_arg(ap, int);
+ for (i = 0; i < n; i++)
+ v.I[i] = i < len ? atoi(list[i]) : 0;
break;
case 'F':
- v.F = va_arg(ap, float **);
- *v.F = emalloc(len * sizeof(float));
- for (i = 0; i < len; i++)
- (*v.F)[i] = strtol(list[i], NULL, 10);
- *va_arg(ap, int *) = len;
+ v.F = va_arg(ap, float *);
+ n = va_arg(ap, int);
+ for (i = 0; i < n; i++)
+ v.F[i] = i < len ? strtof(list[i], NULL) : 0;
break;
default:
error(1, "invalid bdb type: '%c'\n", type);
diff --git a/tests/bdb.test b/tests/bdb.test
@@ -0,0 +1,94 @@
+/* vim: set filetype=c : */
+#include <stdio.h>
+#include "../src/main.h"
+
+/* Generated using xxd -i on the outputted group, plus an extra 0x00 on the end in order to check for excess data */
+static unsigned char output[] = {
+ 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x09, 0x6f, 0x6e, 0x65, 0x0a, 0x69,
+ 0x6e, 0x74, 0x09, 0x32, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x09, 0x33,
+ 0x2e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x76, 0x65, 0x63, 0x74,
+ 0x6f, 0x72, 0x09, 0x34, 0x2e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x09,
+ 0x35, 0x2e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x41, 0x73, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0x09, 0x73, 0x69, 0x78, 0x09, 0x73, 0x65, 0x76,
+ 0x65, 0x6e, 0x0a, 0x41, 0x69, 0x6e, 0x74, 0x09, 0x38, 0x09, 0x39, 0x09,
+ 0x31, 0x30, 0x0a, 0x41, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x09, 0x31, 0x31,
+ 0x2e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x09, 0x31, 0x32, 0x2e, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x09, 0x30, 0x2e, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x0a, 0x00
+};
+
+%{
+ FILE *fp;
+ char *dir = ".";
+ char *group = "test";
+ unsigned char buf[sizeof(output)] = {0};
+ int cnt;
+
+ char *s = "one";
+ int i = 2;
+ float f = 3;
+ Vector v = {4, 5};
+ char *S[3] = {"six", "seven", NULL};
+ int I[3] = {8, 9, 10};
+ float F[4] = {11, 12, 0, 0};
+
+ dbdeclare(dir);
+
+ bdbset(dir, group,
+ 's', "string", s,
+ 'i', "int", i,
+ 'f', "float", f,
+ 'v', "vector", v,
+ 'S', "Astring", S, 2,
+ 'I', "Aint", I, 3,
+ 'F', "Afloat", F, 3);
+
+ dbwritegroup(dir, group);
+
+ fp = fopen(group, "r");
+ fread(buf, sizeof(unsigned char), sizeof(buf), fp);
+ fclose(fp);
+
+#define A(x) ck_assert(x);
+ for (cnt = 0; i < sizeof(buf); i++)
+ A(buf[cnt] == output[cnt]);
+
+#define SET(var) memset(&var, 57, sizeof(var));
+ SET(s);
+ SET(i);
+ SET(f);
+ SET(v);
+#undef SET
+#define SET(var) memset(var, 57, sizeof(var));
+ SET(S);
+ SET(I);
+ SET(F);
+
+ bdbget(dir, group,
+ 's', "string", &s,
+ 'i', "int", &i,
+ 'f', "float", &f,
+ 'v', "vector", &v,
+ 'S', "Astring", S, 3,
+ 'I', "Aint", I, 3,
+ 'F', "Afloat", F, 4);
+
+ A(streq(s, "one"));
+ A(i == 2);
+ A(f == 3);
+ A(v.x == 4);
+ A(v.y == 5);
+ A(streq(S[0], "six"));
+ A(streq(S[1], "seven"));
+ A(S[2] == NULL);
+ A(I[0] == 8);
+ A(I[1] == 9);
+ A(I[2] == 10);
+
+#undef A
+#define A(x, y) ck_assert_float_eq_tol(x, y, 0.1)
+ A(F[0], 11.0);
+ A(F[1], 12.0);
+ A(F[2], 0.0);
+ A(F[3], 0.0);
+}