diff options
Diffstat (limited to 'src/mds-kbdc')
-rw-r--r-- | src/mds-kbdc/process-includes.c | 1 | ||||
-rw-r--r-- | src/mds-kbdc/raw-data.c | 17 | ||||
-rw-r--r-- | src/mds-kbdc/raw-data.h | 14 | ||||
-rw-r--r-- | src/mds-kbdc/tree.c | 41 | ||||
-rw-r--r-- | src/mds-kbdc/tree.h | 9 | ||||
-rw-r--r-- | src/mds-kbdc/validate-tree.c | 32 |
6 files changed, 97 insertions, 17 deletions
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): @@ -258,6 +259,15 @@ void mds_kbdc_tree_free(mds_kbdc_tree_t* restrict this) /** + * 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 * * @param LOWERCASE:identifer The name of 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 <stddef.h> #include <stdio.h> #include <unistd.h> @@ -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 @@ -77,6 +77,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 */ static mds_kbdc_tree_include_t** restrict includes = NULL; @@ -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; |