commit b3e0725c444b6685150b2928598fc70167cd03ee
parent e8ada1f3d439b09de6f31ecfb60e73fe7c0d48f9
Author: Samdal <samdal@protonmail.com>
Date: Mon, 14 Nov 2022 00:19:30 +0100
more testing and some small updates
Diffstat:
M | nisse.h | | | 53 | ++++++++++++++++++++++++++++++++++++++--------------- |
M | test.c | | | 70 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
M | test.nisse | | | 13 | +++++++------ |
M | test2.nisse | | | 11 | ++++++----- |
4 files changed, 105 insertions(+), 42 deletions(-)
diff --git a/nisse.h b/nisse.h
@@ -11,6 +11,12 @@
** Basically you only have "raw" strings
*/
+/*
+** TODO:
+** Perhaps some better error messages with line indication and so on.
+** Better programatic error handling.
+*/
+
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
@@ -64,7 +70,7 @@ typedef struct nisse_data_entry_s {
#define nisse_tndea(__name, __count, ...) nisse_andea(__count + 1, nisse_andes(__name), __VA_ARGS__)
#define nisse_tndeanl(__name, __count, ...) nisse_andeanl(__count + 1, nisse_andes(__name), __VA_ARGS__)
-extern int nisse_nde_fits_format(nde_t* nde, nde_t fmt);
+extern int nisse_nde_fits_format(nde_t* nde, nde_t* fmt);
// shallow comapre, does not support anonymous string arrays
// if nde is array:
// > will check if named structs are present in fmt
@@ -75,8 +81,9 @@ extern int nisse_nde_fits_format(nde_t* nde, nde_t fmt);
// else:
// > check if type is the same
-extern nde_t* nisse_nde_get_tagged(const nde_t* nde, const char* tag);
-extern nde_t* nisse_nde_get_index(const nde_t* nde, int index); // has bounds checking
+extern nde_t* nisse_nde_get_value(nde_t* nde, int* len); // returns nde->nde + 1 if nde is string
+extern nde_t* nisse_nde_get_tagged(nde_t* nde, const char* tag);
+extern nde_t* nisse_nde_get_index(nde_t* nde, int index); // has bounds checking
extern int nisse_write_to_file(char* filename, const nde_t nde);
@@ -109,19 +116,16 @@ nisse_eprintf(const char* fmt, ...)
#endif // NISSE_NO_ERROR
int
-nisse_nde_fits_format(nde_t* nde, nde_t fmt)
+nisse_nde_fits_format(nde_t* nde, nde_t* fmt)
{
if (!nde) return 0;
if (nde->type == NISSE_TYPE_ARRAY) {
for (int i = nde->nde_len && nde->nde->type == NISSE_TYPE_STRING; i < nde->nde_len; i++) {
if (nde->nde[i].type == NISSE_TYPE_ARRAY && nde->nde[i].nde_len && nde->nde[i].nde->type == NISSE_TYPE_STRING) {
- // tagged array
- nde_t* res = nisse_nde_get_tagged(&fmt, nde->nde[i].nde->str);
- if (!res) return 0;
+ if (!nisse_nde_get_tagged(fmt, nde->nde[i].nde->str)) return 0;
} else {
- // untagged
- nde_t* res = nisse_nde_get_index(&fmt, i);
+ nde_t* res = nisse_nde_get_index(fmt, i);
if (!res) return 0;
if (nde->nde[i].type != NISSE_TYPE_ARRAY && res->type == NISSE_TYPE_ARRAY && res->nde_len == 2) {
if (res->nde[1].type != nde->nde[i].type)
@@ -133,25 +137,38 @@ nisse_nde_fits_format(nde_t* nde, nde_t fmt)
}
return 1;
}
- return nde->type == fmt.type;
+ return nde->type == fmt->type;
}
nde_t*
-nisse_nde_get_tagged(const nde_t* nde, const char* tag)
+nisse_nde_get_value(nde_t* nde, int* len)
{
- if (!nde || nde->type != NISSE_TYPE_ARRAY) return NULL;
+ if (!nde) return NULL;
+ if (len) *len = 1;
+ if (nde->type != NISSE_TYPE_ARRAY) return nde;
+
+ if (!nde->nde || nde->nde_len < 2 || nde->nde->type != NISSE_TYPE_STRING) return nde->nde;
+ if (len) *len = nde->nde_len - 1;
+ return nde->nde + 1;
+}
+
+nde_t*
+nisse_nde_get_tagged(nde_t* nde, const char* tag)
+{
+ if (!nde || nde->type != NISSE_TYPE_ARRAY || !nde->nde) return NULL;
for (int i = 0; i < nde->nde_len; i++)
- if (nde->nde[i].type == NISSE_TYPE_ARRAY && nde->nde[i].nde_len && nde->nde[i].nde->type == NISSE_TYPE_STRING)
+ if (nde->nde[i].type == NISSE_TYPE_ARRAY && nde->nde[i].nde_len && nde->nde[i].nde->type == NISSE_TYPE_STRING) {
if (strcmp(tag, nde->nde[i].nde->str) == 0)
return nde->nde + i;
+ }
return NULL;
}
nde_t*
-nisse_nde_get_index(const nde_t* nde, int index)
+nisse_nde_get_index(nde_t* nde, int index)
{
- if (!nde || nde->type != NISSE_TYPE_ARRAY || index < 0 || index >= nde->nde_len)
+ if (!nde || nde->type != NISSE_TYPE_ARRAY || !nde->nde || index < 0 || index >= nde->nde_len)
return NULL;
return nde->nde + index;
}
@@ -188,6 +205,10 @@ void nisse_write_nde(FILE* fd, const nde_t* nde, int root, int indents, int new_
} else if (nde->type == NISSE_TYPE_STRING) {
int res = 0;
for (int i = 0; i < strlen(nde->str); i++) {
+ if (i == 0 && memchr("1234567890.-", nde->str[i], sizeof("1234567890.-"))) {
+ res = 1;
+ break;
+ }
if (memchr("\n '\t\v()\r", nde->str[i], sizeof("\n '\t\v()\r"))) {
res = 1;
break;
@@ -396,10 +417,12 @@ nisse_dup_nde(nde_t* nde)
{
if (nde->type == NISSE_TYPE_STRING) {
nde->str = strdup(nde->str);
+ nde->is_str_allocated = 1;
} else if (nde->type == NISSE_TYPE_ARRAY) {
for (int i = 0; i < nde->nde_len; i++) nisse_free_nde(nde->nde + i);
nde_t* n = malloc(nde->nde_len * sizeof(*n));
memcpy(n, nde->nde, nde->nde_len * sizeof(*n));
+ nde->is_nde_allocated = 1;
}
}
diff --git a/test.c b/test.c
@@ -7,14 +7,18 @@
*/
nde_t fmt_v3 = nisse_andea(3, nisse_andef(0), nisse_andef(0), nisse_andef(0));
+nde_t fmt_item = nisse_andea(1, nisse_tndea("type", 0,));
+nde_t fmt_ranged = nisse_andea(2, nisse_andea(1, nisse_andes("damage")),
+ nisse_andea(1, nisse_andes("range")));
+nde_t fmt_weapon = nisse_andea(1, nisse_tndea("damage", 0,));
-nde_t ndes[] = {
+nde_t nde_arr[] = {
{
.type = NISSE_TYPE_ARRAY,
.new_line_at_end_of_subsequent_elements = 1,
.nde = (nde_t[]){
nisse_andes("player"),
- nisse_andei(-100),
+ nisse_andei(-100), // just here for example purposes
nisse_tndef("hp", 2.0f),
{
.type = NISSE_TYPE_ARRAY,
@@ -26,14 +30,17 @@ nde_t ndes[] = {
nisse_tndes("type", "weapon"),
nisse_tndei("damage", 10)
),
- nisse_tndea("knife", 1, nisse_tndei("damage", 4)),
+ nisse_tndea("knife", 2,
+ nisse_tndes("type", "weapon"),
+ nisse_tndei("damage", 4)
+ ),
nisse_tndea("bow", 3,
- nisse_tndes("type", "weapon"),
+ nisse_tndes("type", "ranged"),
nisse_tndei("damage", 10),
nisse_tndei("range", 15)
),
nisse_tndeanl("crossbow", 4,
- nisse_tndes("type", "ranged weapon"),
+ nisse_tndes("type", "ranged"),
nisse_tndei("damage", 16),
nisse_tndei("range", 25),
nisse_tndea("properties", 2,
@@ -41,7 +48,8 @@ nde_t ndes[] = {
nisse_andes("fire")
),
),
- nisse_tndea("sling", 2,
+ nisse_tndea("sling", 3,
+ nisse_tndes("type", "ranged"),
nisse_tndei("damage", 4),
nisse_tndei("range", 3)
),
@@ -55,18 +63,14 @@ nde_t ndes[] = {
.type = NISSE_TYPE_ARRAY,
.new_line_at_end_of_subsequent_elements = 1,
.nde = (nde_t[]){
- nisse_andes("items"),
+ nisse_andes("test-array"),
nisse_andea(1, nisse_andes("test")),
nisse_andea(0, ),
nisse_andea(1, nisse_andea(0, )),
nisse_tndea("sword", 1, nisse_tndei("damage", 10)),
- nisse_tndea("knife", 1, nisse_tndei("damage", 4)),
- nisse_tndea("bow", 2,
- nisse_tndei("damage", 10),
- nisse_tndei("range", 15)
- ),
+ nisse_andea(3, nisse_andes("test 1"), nisse_andes("2 test"), nisse_andes("test3")),
},
- .nde_len = 5,
+ .nde_len = 6,
},
nisse_tndeanl("v3 array", 4,
nisse_andea(3,
@@ -96,16 +100,50 @@ nde_t ndes[] = {
int main()
{
- nde_t test = {.type = NISSE_TYPE_ARRAY, .nde_len = ARR_SZ(ndes), .nde = ndes};
+ nde_t test = {.type = NISSE_TYPE_ARRAY, .nde_len = ARR_SZ(nde_arr), .nde = nde_arr};
+#if 1
nisse_write_to_file("./test.nisse", test);
+#endif
nde_t nde = nisse_parse_file("./test.nisse");
- printf("does test fit? %s.\n", nisse_nde_fits_format(nisse_nde_get_index(&nde, 0), *nisse_nde_get_index(&test, 0)) ? "yes" : "no");
+#if 1
+ nde_t* player_true = nisse_nde_get_index(&test, 0);
+ nde_t* player_parsed = nisse_nde_get_index(&nde, 0);
+ assert(player_true);
+ assert(player_parsed);
+
+ printf("test->player has some of player? %s.\n", nisse_nde_fits_format(player_parsed, player_true) ? "yes" : "no");
+ printf("test->player has at least all of player? %s.\n", nisse_nde_fits_format(player_true, player_parsed) ? "yes" : "no");
+
+ // check if items are correct
+
+ nde_t* items_parsed = nisse_nde_get_tagged(player_parsed, "items");
+ assert(items_parsed && items_parsed->type == NISSE_TYPE_ARRAY);
+
+ for (int i = 1; i < items_parsed->nde_len; i++) {
+ if (!nisse_nde_fits_format(&fmt_item, items_parsed->nde + i)) {
+ printf("item does not define a type %s:%d\n", items_parsed->nde[i].nde->type == NISSE_TYPE_STRING ? items_parsed->nde[i].nde->str : NULL, i);
+ continue;
+ }
+
+ nde_t* type_parsed = nisse_nde_get_tagged(items_parsed->nde + i, "type");
+ if (!type_parsed || type_parsed->type != NISSE_TYPE_ARRAY || type_parsed->nde_len != 2 || type_parsed->nde[1].type != NISSE_TYPE_STRING) {
+ printf("invalid item, wrong type value %s:%d\n", items_parsed->nde[i].nde->type == NISSE_TYPE_STRING ? items_parsed->nde[i].nde->str : NULL, i);
+ } else {
+ const char* item_type = nisse_nde_get_value(type_parsed, NULL)->str;
+ if (strcmp(item_type, "weapon") == 0 && !nisse_nde_fits_format(&fmt_weapon, items_parsed->nde + i))
+ printf("invalid weapon %s:%d\n", items_parsed->nde[i].nde->type == NISSE_TYPE_STRING ? items_parsed->nde[i].nde->str : NULL, i);
+ else if (strcmp(item_type, "ranged") == 0 && !nisse_nde_fits_format(&fmt_ranged, items_parsed->nde + i))
+ printf("invalid ranged %s:%d\n", items_parsed->nde[i].nde->type == NISSE_TYPE_STRING ? items_parsed->nde[i].nde->str : NULL, i);
+ }
+ }
+#endif
+
nde_t* v3a = nisse_nde_get_tagged(&nde, "v3 array");
assert(v3a);
for (int i = 1; i < v3a->nde_len; i++)
- if (!nisse_nde_fits_format(v3a->nde+ i, fmt_v3))
+ if (!nisse_nde_fits_format(v3a->nde+ i, &fmt_v3))
printf("infalid v3 array %d!\n", i);
nisse_write_to_file("./test2.nisse", nde);
diff --git a/test.nisse b/test.nisse
@@ -3,24 +3,25 @@
(hp 2.000000)
(items
(sword (type weapon) (damage 10))
- (knife (damage 4))
- (bow (type weapon) (damage 10) (range 15))
+ (knife (type weapon) (damage 4))
+ (bow (type ranged) (damage 10) (range 15))
(crossbow
- (type ´ranged weapon´)
+ (type ranged)
(damage 16)
(range 25)
(properties poison fire)
)
- (sling (damage 4) (range 3))
+ (sling (type ranged) (damage 4) (range 3))
)
)
-(items
+(test-array
(test)
()
(())
(sword (damage 10))
+ (`test 1` `2 test` test3)
)
-(´v3 array´
+(`v3 array`
(1.000000 2.000000 3.000000)
(4.000000 5.000000 6.000000)
(7.000000 8.000000 9.000000)
diff --git a/test2.nisse b/test2.nisse
@@ -3,22 +3,23 @@
(hp 2.000000)
(items
(sword (type weapon) (damage 10))
- (knife (damage 4))
- (bow (type weapon) (damage 10) (range 15))
+ (knife (type weapon) (damage 4))
+ (bow (type ranged) (damage 10) (range 15))
(crossbow
- (type `ranged weapon`)
+ (type ranged)
(damage 16)
(range 25)
(properties poison fire)
)
- (sling (damage 4) (range 3))
+ (sling (type ranged) (damage 4) (range 3))
)
)
-(items
+(test-array
(test)
()
(())
(sword (damage 10))
+ (`test 1` `2 test` test3)
)
(`v3 array`
(1.000000 2.000000 3.000000)