From 2d0181e9e07236ea28fb638c4a9eafb5896635b6 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Mon, 1 Dec 2014 13:27:13 +0100 Subject: mds-kbdc: add some test cases + fix issued with inclusion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- src/mds-kbdc/process-includes.c | 1 + src/mds-kbdc/raw-data.c | 17 +++++++++ src/mds-kbdc/raw-data.h | 14 ++++++++ src/mds-kbdc/tree.c | 41 ++++++++++++++-------- src/mds-kbdc/tree.h | 9 ++++- src/mds-kbdc/validate-tree.c | 32 ++++++++++++++++- .../validate-tree/invalid/function-assumption | 19 ++++++++++ .../validate-tree/invalid/function-function | 19 ++++++++++ .../validate-tree/invalid/function-information | 19 ++++++++++ .../mds-kbdc/validate-tree/invalid/function-macro | 19 ++++++++++ .../invalid/include_information-information | 26 ++++++++++++++ .../validate-tree/invalid/information-assumption | 19 ++++++++++ .../validate-tree/invalid/information-function | 19 ++++++++++ .../validate-tree/invalid/information-information | 19 ++++++++++ .../validate-tree/invalid/information-macro | 19 ++++++++++ 15 files changed, 275 insertions(+), 17 deletions(-) create mode 100644 test-files/mds-kbdc/validate-tree/invalid/function-assumption create mode 100644 test-files/mds-kbdc/validate-tree/invalid/function-function create mode 100644 test-files/mds-kbdc/validate-tree/invalid/function-information create mode 100644 test-files/mds-kbdc/validate-tree/invalid/function-macro create mode 100644 test-files/mds-kbdc/validate-tree/invalid/include_information-information create mode 100644 test-files/mds-kbdc/validate-tree/invalid/information-assumption create mode 100644 test-files/mds-kbdc/validate-tree/invalid/information-function create mode 100644 test-files/mds-kbdc/validate-tree/invalid/information-information create mode 100644 test-files/mds-kbdc/validate-tree/invalid/information-macro diff --git a/src/mds-kbdc/process-includes.c b/src/mds-kbdc/process-includes.c index 28d1652..18d995f 100644 --- a/src/mds-kbdc/process-includes.c +++ b/src/mds-kbdc/process-includes.c @@ -211,6 +211,7 @@ static int process_include(mds_kbdc_tree_include_t* restrict tree) /* Move over data to our result. */ free(tree->filename); tree->filename = subresult.pathname, subresult.pathname = NULL; + tree->source_code = subresult.source_code, subresult.source_code = NULL; tree->inner = subresult.tree, subresult.tree = NULL; if (result->severest_error_level < subresult.severest_error_level) result->severest_error_level = subresult.severest_error_level; diff --git a/src/mds-kbdc/raw-data.c b/src/mds-kbdc/raw-data.c index 3e97c9f..9f56210 100644 --- a/src/mds-kbdc/raw-data.c +++ b/src/mds-kbdc/raw-data.c @@ -46,6 +46,7 @@ void mds_kbdc_source_code_initialise(mds_kbdc_source_code_t* restrict this) this->content = NULL; this->real_content = NULL; this->line_count = 0; + this->duplicates = 0; } @@ -58,6 +59,8 @@ void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t* restrict this) { if (this == NULL) return; + if (this->duplicates--) + return; free(this->lines), this->lines = NULL; free(this->real_lines), this->real_lines = NULL; free(this->content), this->content = NULL; @@ -74,6 +77,8 @@ void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this) { if (this == NULL) return; + if (this->duplicates--) + return; free(this->lines); free(this->real_lines); free(this->content); @@ -81,6 +86,18 @@ void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this) free(this); } +/** + * Create a duplicate of a `mds_kbdc_source_code_t*` + * + * @param this The `mds_kbdc_source_code_t*` + * @return `this` is returned + */ +mds_kbdc_source_code_t* mds_kbdc_source_code_dup(mds_kbdc_source_code_t* restrict this) +{ + this->duplicates++; + return this; +} + /** diff --git a/src/mds-kbdc/raw-data.h b/src/mds-kbdc/raw-data.h index a2f1edc..95163db 100644 --- a/src/mds-kbdc/raw-data.h +++ b/src/mds-kbdc/raw-data.h @@ -55,6 +55,12 @@ typedef struct mds_kbdc_source_code */ size_t line_count; + /** + * The number of duplicates there are of this + * structure that shared the memory + */ + size_t duplicates; + } mds_kbdc_source_code_t; @@ -79,6 +85,14 @@ void mds_kbdc_source_code_destroy(mds_kbdc_source_code_t* restrict this); */ void mds_kbdc_source_code_free(mds_kbdc_source_code_t* restrict this); +/** + * Create a duplicate of a `mds_kbdc_source_code_t*` + * + * @param this The `mds_kbdc_source_code_t*` + * @return `this` is returned + */ +mds_kbdc_source_code_t* mds_kbdc_source_code_dup(mds_kbdc_source_code_t* restrict this); + /** * Find the end of a function call diff --git a/src/mds-kbdc/tree.c b/src/mds-kbdc/tree.c index 695a8a7..27265d3 100644 --- a/src/mds-kbdc/tree.c +++ b/src/mds-kbdc/tree.c @@ -112,6 +112,7 @@ static void mds_kbdc_tree_destroy_(mds_kbdc_tree_t* restrict this, int recursive case C(INCLUDE): xfree(mds_kbdc_tree_include_t*, filename); xdestroy(mds_kbdc_tree_include_t*, inner); + mds_kbdc_source_code_free(this->include.source_code); break; case C(ASSUMPTION_HAVE): @@ -257,6 +258,15 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) fail_if (t->member && (n->member = strdup(t->member), n->member == NULL)) +/** + * Duplicate a source code structure and goto `fail` on failure + * + * @param member:identifer The member in the tree to copied + */ +#define R(member) \ + fail_if (t->member && (n->member = mds_kbdc_source_code_dup(t->member), n->member == NULL)) + + /** * Cast the trees to a specialised subtype * @@ -294,24 +304,24 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(mds_kbdc_tree_t* restrict this) case C(ASSUMPTION): case C(ALTERNATION): case C(UNORDERED): - case C(ORDERED): { NODE(nesting); T(inner); } break; + case C(ORDERED): { NODE(nesting); T(inner); } break; case C(FUNCTION): - case C(MACRO): { NODE(callable); S(name);T(inner); } break; - case C(ASSUMPTION_HAVE): { NODE(assumption_have); T(data); } break; - case C(ARRAY): { NODE(array); T(elements); } break; - case C(LET): { NODE(let); S(variable);T(value); } break; - case C(MACRO_CALL): { NODE(macro_call); S(name);T(arguments); } break; + case C(MACRO): { NODE(callable); S(name);T(inner); } break; + case C(ASSUMPTION_HAVE): { NODE(assumption_have); T(data); } break; + case C(ARRAY): { NODE(array); T(elements); } break; + case C(LET): { NODE(let); S(variable);T(value); } break; + case C(MACRO_CALL): { NODE(macro_call); S(name);T(arguments); } break; case C(INFORMATION_LANGUAGE): case C(INFORMATION_COUNTRY): - case C(INFORMATION_VARIANT): { NODE(information_data); S(data); } break; - case C(INCLUDE): { NODE(include); S(filename);T(inner); } break; - case C(ASSUMPTION_HAVE_CHARS): { NODE(assumption_have_chars); S(chars); } break; - case C(KEYS): { NODE(keys); S(keys); } break; - case C(STRING): { NODE(string); S(string); } break; - case C(ASSUMPTION_HAVE_RANGE): { NODE(assumption_have_range); S(first);S(last); } break; - case C(FOR): { NODE(for); S(first);S(last);S(variable);T(inner); } break; - case C(IF): { NODE(if); S(condition);T(inner);T(otherwise); } break; - case C(MAP): { NODE(map); T(sequence);T(result); } break; + case C(INFORMATION_VARIANT): { NODE(information_data); S(data); } break; + case C(INCLUDE): { NODE(include); S(filename);T(inner);R(source_code); } break; + case C(ASSUMPTION_HAVE_CHARS): { NODE(assumption_have_chars); S(chars); } break; + case C(KEYS): { NODE(keys); S(keys); } break; + case C(STRING): { NODE(string); S(string); } break; + case C(ASSUMPTION_HAVE_RANGE): { NODE(assumption_have_range); S(first);S(last); } break; + case C(FOR): { NODE(for); S(first);S(last);S(variable);T(inner); } break; + case C(IF): { NODE(if); S(condition);T(inner);T(otherwise); } break; + case C(MAP): { NODE(map); T(sequence);T(result); } break; default: break; } @@ -325,6 +335,7 @@ mds_kbdc_tree_t* mds_kbdc_tree_dup(mds_kbdc_tree_t* restrict this) #undef NODE +#undef R #undef S #undef T diff --git a/src/mds-kbdc/tree.h b/src/mds-kbdc/tree.h index 64a703d..fe67faf 100644 --- a/src/mds-kbdc/tree.h +++ b/src/mds-kbdc/tree.h @@ -19,6 +19,8 @@ #define MDS_MDS_KBDC_TREE_H +#include "raw-data.h" + #include #include #include @@ -290,7 +292,12 @@ typedef struct mds_kbdc_tree_include */ mds_kbdc_tree_t* inner; - MDS_KBDC_TREE_PADDING(2); + /** + * The source code of the file included by this statement + */ + mds_kbdc_source_code_t* source_code; + + MDS_KBDC_TREE_PADDING(3); } mds_kbdc_tree_include_t; diff --git a/src/mds-kbdc/validate-tree.c b/src/mds-kbdc/validate-tree.c index 73ec07e..e1369e0 100644 --- a/src/mds-kbdc/validate-tree.c +++ b/src/mds-kbdc/validate-tree.c @@ -76,6 +76,16 @@ static mds_kbdc_parse_error_t* error; */ static mds_kbdc_parsed_t* restrict result; +/** + * The original value of `result->pathname` + */ +static char* original_pathname; + +/** + * The original value of `result->source_code` + */ +static mds_kbdc_source_code_t* original_source_code; + /** * Stack of visited include-statements */ @@ -152,10 +162,20 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree); */ static int dump_include_stack(size_t ptr) { + char* old_pathname = result->pathname; + mds_kbdc_source_code_t* old_source_code = result->source_code; while (ptr--) - NEW_ERROR(includes[ptr], NOTE, "included from here"); + { + result->pathname = ptr ? includes[ptr - 1]->filename : original_pathname; + result->source_code = ptr ? includes[ptr - 1]->source_code : original_source_code; + NEW_ERROR(includes[ptr], NOTE, "included from here"); + } + result->pathname = old_pathname; + result->source_code = old_source_code; return 0; pfail: + result->pathname = old_pathname; + result->source_code = old_source_code; return -1; } @@ -169,12 +189,18 @@ static int dump_include_stack(size_t ptr) static int validate_include(mds_kbdc_tree_include_t* restrict tree) { mds_kbdc_tree_include_t** old; + char* pathname = result->pathname; + mds_kbdc_source_code_t* source_code = result->source_code; int r, saved_errno; if (includes_ptr == includes_size) if (xxrealloc(old, includes, includes_size += 4, mds_kbdc_tree_include_t*)) return saved_errno = errno, free(old), errno = saved_errno, -1; includes[includes_ptr++] = tree; + result->pathname = tree->filename; + result->source_code = tree->source_code; r = validate_subtree(tree->inner); + result->pathname = pathname; + result->source_code = source_code; return includes_ptr--, r; } @@ -569,8 +595,12 @@ int validate_tree(mds_kbdc_parsed_t* restrict result_) { int r, saved_errno; result = result_; + original_pathname = result_->pathname; + original_source_code = result_->source_code; r = validate_subtree(result_->tree); saved_errno = errno; + result_->pathname = original_pathname; + result_->source_code = original_source_code; free(includes), includes = NULL, includes_size = includes_ptr = 0; free(fors), fors = NULL, fors_size = fors_ptr = 0; return errno = saved_errno, r; diff --git a/test-files/mds-kbdc/validate-tree/invalid/function-assumption b/test-files/mds-kbdc/validate-tree/invalid/function-assumption new file mode 100644 index 0000000..3ebe83e --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/function-assumption @@ -0,0 +1,19 @@ +function f/0 + assumption + end assumption +end function + +# (function (@ 1 0-8) ‘f/0’ +# (.inner +# (assumption (@ 2 2-12) +# (.inner nil) +# ) +# ) +# ) +# :2:2–12: error: assumption clause inside function definition +# assumption +# ^^^^^^^^^^ +# :1:0–8: note: outer function definition defined here +# function f/0 +# ^^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/function-function b/test-files/mds-kbdc/validate-tree/invalid/function-function new file mode 100644 index 0000000..4793bbc --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/function-function @@ -0,0 +1,19 @@ +function f/0 + function g/0 + end function +end function + +# (function (@ 1 0-8) ‘f/0’ +# (.inner +# (function (@ 2 2-10) ‘g/0’ +# (.inner nil) +# ) +# ) +# ) +# :2:2–10: error: nested function definition +# function g/0 +# ^^^^^^^^ +# :1:0–8: note: outer function defined here +# function f/0 +# ^^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/function-information b/test-files/mds-kbdc/validate-tree/invalid/function-information new file mode 100644 index 0000000..d6cda45 --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/function-information @@ -0,0 +1,19 @@ +function f/0 + information + end information +end function + +# (function (@ 1 0-8) ‘f/0’ +# (.inner +# (information (@ 2 2-13) +# (.inner nil) +# ) +# ) +# ) +# :2:2–13: error: information clause inside function definition +# information +# ^^^^^^^^^^^ +# :1:0–8: note: outer function definition defined here +# function f/0 +# ^^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/function-macro b/test-files/mds-kbdc/validate-tree/invalid/function-macro new file mode 100644 index 0000000..e8f48cd --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/function-macro @@ -0,0 +1,19 @@ +function f/0 + macro m/0 + end macro +end function + +# (function (@ 1 0-8) ‘f/0’ +# (.inner +# (macro (@ 2 2-7) ‘m/0’ +# (.inner nil) +# ) +# ) +# ) +# :2:2–7: error: macro definition inside function definition +# macro m/0 +# ^^^^^ +# :1:0–8: note: outer function definition defined here +# function f/0 +# ^^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/include_information-information b/test-files/mds-kbdc/validate-tree/invalid/include_information-information new file mode 100644 index 0000000..25a23ed --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/include_information-information @@ -0,0 +1,26 @@ +include "information-information" + +# (include (@ 1 0-7) ‘.../test-files/mds-kbdc/validate-tree/invalid/information-information’ +# (.inner +# (information (@ 1 0-11) +# (.inner +# (information (@ 2 2-13) +# (.inner nil) +# ) +# ) +# ) +# ) +# ) +# .../test-files/mds-kbdc/validate-tree/invalid/information-information:2:2–13: error: nested information clause +# information +# ^^^^^^^^^^^ +# .../test-files/mds-kbdc/validate-tree/invalid/include_information-information:1:0–7: note: included from here +# include "information-information" +# ^^^^^^^ +# .../test-files/mds-kbdc/validate-tree/invalid/information-information:1:0–11: note: outer information clause defined here +# information +# ^^^^^^^^^^^ +# .../test-files/mds-kbdc/validate-tree/invalid/include_information-information:1:0–7: note: included from here +# include "information-information" +# ^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/information-assumption b/test-files/mds-kbdc/validate-tree/invalid/information-assumption new file mode 100644 index 0000000..662542f --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/information-assumption @@ -0,0 +1,19 @@ +information + assumption + end assumption +end information + +# (information (@ 1 0-11) +# (.inner +# (assumption (@ 2 2-12) +# (.inner nil) +# ) +# ) +# ) +# :2:2–12: error: assumption clause inside information clause +# assumption +# ^^^^^^^^^^ +# :1:0–11: note: outer information clause defined here +# information +# ^^^^^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/information-function b/test-files/mds-kbdc/validate-tree/invalid/information-function new file mode 100644 index 0000000..06613f6 --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/information-function @@ -0,0 +1,19 @@ +information + function f/0 + end function +end information + +# (information (@ 1 0-11) +# (.inner +# (function (@ 2 2-10) ‘f/0’ +# (.inner nil) +# ) +# ) +# ) +# :2:2–10: error: function definition inside information clause +# function f/0 +# ^^^^^^^^ +# :1:0–11: note: outer information clause defined here +# information +# ^^^^^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/information-information b/test-files/mds-kbdc/validate-tree/invalid/information-information new file mode 100644 index 0000000..caa3003 --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/information-information @@ -0,0 +1,19 @@ +information + information + end information +end information + +# (information (@ 1 0-11) +# (.inner +# (information (@ 2 2-13) +# (.inner nil) +# ) +# ) +# ) +# :2:2–13: error: nested information clause +# information +# ^^^^^^^^^^^ +# :1:0–11: note: outer information clause defined here +# information +# ^^^^^^^^^^^ + diff --git a/test-files/mds-kbdc/validate-tree/invalid/information-macro b/test-files/mds-kbdc/validate-tree/invalid/information-macro new file mode 100644 index 0000000..51991de --- /dev/null +++ b/test-files/mds-kbdc/validate-tree/invalid/information-macro @@ -0,0 +1,19 @@ +information + macro m/0 + end macro +end information + +# (information (@ 1 0-11) +# (.inner +# (macro (@ 2 2-7) ‘m/0’ +# (.inner nil) +# ) +# ) +# ) +# :2:2–7: error: macro definition inside information clause +# macro m/0 +# ^^^^^ +# :1:0–11: note: outer information clause defined here +# information +# ^^^^^^^^^^^ + -- cgit v1.2.3-70-g09d2