aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-12-01 13:27:13 +0100
committerMattias Andrée <maandree@operamail.com>2014-12-01 13:27:13 +0100
commit2d0181e9e07236ea28fb638c4a9eafb5896635b6 (patch)
tree2cd560e7bd8fa5960a06e4fade81fd57b6dc581f
parentm (diff)
downloadmds-2d0181e9e07236ea28fb638c4a9eafb5896635b6.tar.gz
mds-2d0181e9e07236ea28fb638c4a9eafb5896635b6.tar.bz2
mds-2d0181e9e07236ea28fb638c4a9eafb5896635b6.tar.xz
mds-kbdc: add some test cases + fix issued with inclusion
Signed-off-by: Mattias Andrée <maandree@operamail.com>
-rw-r--r--src/mds-kbdc/process-includes.c1
-rw-r--r--src/mds-kbdc/raw-data.c17
-rw-r--r--src/mds-kbdc/raw-data.h14
-rw-r--r--src/mds-kbdc/tree.c41
-rw-r--r--src/mds-kbdc/tree.h9
-rw-r--r--src/mds-kbdc/validate-tree.c32
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/function-assumption19
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/function-function19
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/function-information19
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/function-macro19
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/include_information-information26
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/information-assumption19
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/information-function19
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/information-information19
-rw-r--r--test-files/mds-kbdc/validate-tree/invalid/information-macro19
15 files changed, 275 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;
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
+# ^^^^^^^^^^^
+