diff options
author | JSDurand <mmemmew@gmail.com> | 2023-07-08 12:30:21 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2023-07-08 12:31:13 +0800 |
commit | 9a317e56f8a6126583f7d0c431bf878d9b1fe7b1 (patch) | |
tree | 7bb6004196b38446a5ab0cb3a0ab642d35f113e9 /src/test.c | |
parent | 691f969eb104fa3d4c2a1667693fd0382eb9d6b5 (diff) |
Finished the Emacs binding.
Now the binding part is finished.
What remains is a bug encountered when planting a fragment to the
forest which intersects a packed node, which would lead to invalid
forests. This will also cause problem when planting a packed
fragment, but until now my testing grammars do not produce packed
fragments, so this problem is not encountered yet.
I am still figuring out efficient ways to solve this problem.
Diffstat (limited to 'src/test.c')
-rw-r--r-- | src/test.c | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..d309fb7 --- /dev/null +++ b/src/test.c @@ -0,0 +1,224 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <limits.h> +#include <string.h> +#include <emacs-module.h> + +#include "big_endian.h" +#include "helper.h" + +int +main(int argc, char **argv) +{ + unsigned char error_vec_len[8] = { 0 }; + unsigned char error_vec_cap[8] = { 0 }; + + struct SignedVec error_vec = { 0 }; + + error_vec.len = error_vec_len; + error_vec.capacity = error_vec_cap; + + struct parser *parser = new_parser("start = \"a\"\"b\"\n", &error_vec); + + uint64_t error_length = from_big_endian(error_vec.len); + + if (error_length) { + printf("error: "); + + char *error_str = error_vec.data; + + for (int i = 0; i < error_length; i++) { + printf("%c", *(error_str+i)); + } + + printf("\n"); + + clean_signed(&error_vec, 4); + + return 1; + } + + unsigned char *input = malloc (sizeof(unsigned char) * 16); + + for (int i = 0; i < 16; i++) *(input+i) = 0; + + *(input+15) = 1; + + unsigned char input_len[8] = { 0 }; + input_len[7] = 16; + + struct UnsignedVec input_vec = (struct UnsignedVec) { input_len, NULL, input }; + + int result = parser_recognize + (parser, + &input_vec, + &error_vec, + (unsigned char) 0); + + error_length = from_big_endian(error_vec.len); + + if (error_length) { + clean_parser((void *) parser); + free(input); + + printf("error: "); + + char *error_str = error_vec.data; + + for (uint64_t i = 0; i < error_length; i++) { + printf("%c", *(error_str + (unsigned long) i)); + } + + printf("\n"); + + clean_signed(&error_vec, 4); + + return 1; + } + + if (result) + printf("result = true\n"); + else + printf("result = false\n"); + + for (int i = 0; i < 8; i++) { + error_vec.len[i] = 0; + error_vec.capacity[i] = 0; + } + + struct UnsignedVec *forest_ptr = parser_parse + (parser, + &input_vec, + &error_vec, + (unsigned char) 1); + + error_length = from_big_endian(error_vec.len); + + if (error_length) { + clean_parser((void *) parser); + free(input); + + printf("error: "); + + char *error_str = error_vec.data; + + for (uint64_t i = 0; i < error_length; i++) { + printf("%c", *(error_str + (unsigned long) i)); + } + + printf("\n"); + + clean_signed(&error_vec, 4); + + return 1; + } + + free(input); + clean_parser((void *) parser); + + if (forest_ptr) { + uint64_t forest_len = from_big_endian(forest_ptr->len); + + /* forest_len++; */ + + printf("a non-empty forest of length %llu\n", forest_len); + + unsigned char *forest = forest_ptr->data; + + uint64_t forest_real_len = from_big_endian(forest); + + if (forest_real_len != forest_len) { + fprintf(stderr, "wrong length: %llu\n", forest_real_len); + + clean_unsigned(forest_ptr, 15); + + return 1; + } + + if (forest_len < 27) { + fprintf(stderr, "length too small: %llu\n", forest_len); + + clean_unsigned(forest_ptr, 15); + + return 1; + } + + printf("the lengths match\n"); + + if (*(forest+8) != 114 || *(forest+9) != 101 || *(forest+10) != 112) { + fprintf(stderr, "the forest does not begin with the special mark\n"); + + fprintf(stderr, "the first bytes are: "); + fprintf(stderr, "%c", *(forest+8)); + fprintf(stderr, "%c", *(forest+9)); + fprintf(stderr, "%c\n", *(forest+10)); + + clean_unsigned(forest_ptr, 15); + + return 1; + } + + printf("the special mark is correct.\n"); + + uint64_t nodes_len = from_big_endian(forest+11); + + printf("forest has %llu nodes\n", nodes_len); + + uint64_t labels_offset = from_big_endian(forest+19); + + printf("the offset of labels is %llu\n", labels_offset); + + if (forest_len < labels_offset || + forest_len < (27 + 16 * nodes_len)) { + fprintf(stderr, "length too small: %llu\n", forest_len); + + clean_unsigned(forest_ptr, 15); + + return 1; + } + + uint64_t total_degree = 0; + + for (uint64_t i = 0; i < nodes_len; i++) { + uint64_t offset = 27 + 16 * i; + + uint64_t degree = from_big_endian(forest+offset); + uint64_t node_offset = from_big_endian(forest+offset+8); + + total_degree += degree; + + printf("the %llu-th node has degree %llu and offset %llu\n", + i, degree, node_offset); + + printf("label: "); + print_label(read_label(forest + labels_offset + 34 * i)); + + for (uint64_t j = 0; j < degree; j++) { + uint64_t child = from_big_endian(forest+node_offset+8*j); + + printf("the %llu-th child is %llu\n", j, child); + } + + printf("\n"); + } + + uint64_t correct = 27 + 50 * nodes_len + 8 * total_degree; + + if (forest_len != correct) { + fprintf(stderr, "length does not conform to the format: %llu\n", correct); + + clean_unsigned(forest_ptr, 15); + + return 1; + } + + printf("the forest has the correct length according to the format\n"); + + clean_unsigned(forest_ptr, 15); + } else { + printf("no forest\n"); + } + + return 0; +} |