aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile3
-rw-r--r--src/mds-kbdc/eliminate-dead-code.c114
-rw-r--r--src/mds-kbdc/include-stack.c170
-rw-r--r--src/mds-kbdc/include-stack.h118
-rw-r--r--src/mds-kbdc/validate-tree.c114
5 files changed, 314 insertions, 205 deletions
diff --git a/Makefile b/Makefile
index 35e9591..27d92e8 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,8 @@ OBJ_mds-registry_ = mds-registry util globals reexec registry signals \
OBJ_mds-kbdc_ = mds-kbdc globals raw-data functions string tree \
make-tree parse-error simplify-tree parsed \
- process-includes validate-tree eliminate-dead-code
+ process-includes validate-tree eliminate-dead-code \
+ include-stack
OBJ_mds-server = $(foreach O,$(OBJ_mds-server_),obj/mds-server/$(O).o)
OBJ_mds-registry = $(foreach O,$(OBJ_mds-registry_),obj/mds-registry/$(O).o)
diff --git a/src/mds-kbdc/eliminate-dead-code.c b/src/mds-kbdc/eliminate-dead-code.c
index cedf576..0881b20 100644
--- a/src/mds-kbdc/eliminate-dead-code.c
+++ b/src/mds-kbdc/eliminate-dead-code.c
@@ -17,6 +17,8 @@
*/
#include "eliminate-dead-code.h"
+#include "include-stack.h"
+
#include <stdlib.h>
#include <errno.h>
@@ -28,26 +30,6 @@
#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
/**
- * Add an error to the error list
- *
- * @param NODE:const mds_kbdc_tree_t* The node the triggered the error
- * @param SEVERITY:identifier * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
- * @param ...:const char*, ... Error description format string and arguments
- * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
- */
-#define NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, ...) \
- NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line, \
- (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
-
-/**
- * Add “included from here”-notes
- *
- * @param PTR:size_t The number of “included from here”-notes
- */
-#define DUMP_INCLUDE_STACK(PTR) \
- fail_if (dump_include_stack(PTR))
-
-/**
* Add an error with “included from here”-notes to the error list
*
* @param NODE:const mds_kbdc_tree_t* The node the triggered the error
@@ -57,12 +39,7 @@
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
#define NEW_ERROR(NODE, PTR, SEVERITY, ...) \
- do \
- { \
- NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, __VA_ARGS__); \
- DUMP_INCLUDE_STACK(PTR); \
- } \
- while (0)
+ NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, __VA_ARGS__)
@@ -77,31 +54,6 @@ 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;
-
-/**
- * The number elements allocated for `includes`
- */
-static size_t includes_size = 0;
-
-/**
- * The number elements stored in `includes`
- */
-static size_t includes_ptr = 0;
-
-/**
* 2: Eliminating because of a return-statement
* 1: Eliminating because of a break- or continue-statement
* 0: Not eliminating
@@ -121,32 +73,6 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree);
/**
- * Add “included from here”-notes
- *
- * @param ptr The number of “included from here”-notes
- * @return Zero on success, -1 on error
- */
-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--)
- {
- result->pathname = ptr ? includes[ptr - 1]->filename : original_pathname;
- result->source_code = ptr ? includes[ptr - 1]->source_code : original_source_code;
- NEW_ERROR_WITHOUT_INCLUDES(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;
-}
-
-
-/**
* Eliminate dead code in an include-statement
*
* @param tree The tree to reduce
@@ -154,20 +80,13 @@ static int dump_include_stack(size_t ptr)
*/
static int eliminate_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;
+ void* data;
+ int r;
+ if (mds_kbdc_include_stack_push(tree, &data))
+ return -1;
r = eliminate_subtree(tree->inner);
- result->pathname = pathname;
- result->source_code = source_code;
- return includes_ptr--, r;
+ mds_kbdc_include_stack_pop(data);
+ return r;
}
@@ -252,23 +171,14 @@ static int eliminate_subtree(mds_kbdc_tree_t* restrict tree)
*/
int eliminate_dead_code(mds_kbdc_parsed_t* restrict result_)
{
- int r, saved_errno;
- result = result_;
- original_pathname = result_->pathname;
- original_source_code = result_->source_code;
+ int r;
+ mds_kbdc_include_stack_begin(result = result_);
r = eliminate_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;
- return errno = saved_errno, r;
+ return mds_kbdc_include_stack_end(), r;
}
#undef NEW_ERROR
-#undef DUMP_INCLUDE_STACK
-#undef NEW_ERROR_WITHOUT_INCLUDES
#undef C
diff --git a/src/mds-kbdc/include-stack.c b/src/mds-kbdc/include-stack.c
new file mode 100644
index 0000000..e3aff48
--- /dev/null
+++ b/src/mds-kbdc/include-stack.c
@@ -0,0 +1,170 @@
+/**
+ * mds — A micro-display server
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "include-stack.h"
+
+#include <alloca.h>
+#include <stdlib.h>
+#include <errno.h>
+
+
+
+/**
+ * Variable whether the latest created error is stored
+ */
+static mds_kbdc_parse_error_t* error;
+
+/**
+ * The `result` parameter of root procedure that requires the include stack
+ */
+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;
+
+/**
+ * The number elements allocated for `includes`
+ */
+static size_t includes_size = 0;
+
+/**
+ * The number elements stored in `includes`
+ */
+size_t includes_ptr = 0;
+
+
+
+/**
+ * Add “included from here”-notes
+ *
+ * @param ptr The number of “included from here”-notes
+ * @return Zero on success, -1 on error
+ */
+int mds_kbdc_include_stack_dump(size_t ptr)
+{
+ char* old_pathname = result->pathname;
+ mds_kbdc_source_code_t* old_source_code = result->source_code;
+ while (ptr--)
+ {
+ result->pathname = ptr ? includes[ptr - 1]->filename : original_pathname;
+ result->source_code = ptr ? includes[ptr - 1]->source_code : original_source_code;
+ NEW_ERROR_WITHOUT_INCLUDES(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;
+}
+
+
+/**
+ * Mark the root of the tree as included
+ *
+ * @param result_ The `result` parameter of root procedure that requires the include stack
+ */
+void mds_kbdc_include_stack_begin(mds_kbdc_parsed_t* restrict result_)
+{
+ result = result_;
+ original_pathname = result_->pathname;
+ original_source_code = result_->source_code;
+}
+
+
+/**
+ * Mark the root of the tree as no longer being visited,
+ * and release clean up after the use of this module
+ *
+ * This function is guaranteed not to modify `errno`
+ */
+void mds_kbdc_include_stack_end(void)
+{
+ int saved_errno = errno;
+ result->pathname = original_pathname;
+ result->source_code = original_source_code;
+ free(includes), includes = NULL;
+ includes_size = includes_ptr = 0;
+ errno = saved_errno;
+}
+
+
+/**
+ * Mark an include-statement as visited
+ *
+ * @param tree The visisted include-statement
+ * @param data Output parameter with stack information that should be passed to
+ * the corresponding call to `mds_kbdc_include_stack_pop`, `*data`
+ * is undefined on error
+ * @return Zero on success, -1 on error
+ */
+int mds_kbdc_include_stack_push(mds_kbdc_tree_include_t* restrict tree, void** data)
+{
+ mds_kbdc_tree_include_t** old = NULL;
+ int saved_errno;
+
+ if (includes_ptr == includes_size)
+ fail_if (xxrealloc(old, includes, includes_size += 4, mds_kbdc_tree_include_t*));
+
+ fail_if (xmalloc(*data, 2, void*));
+
+ includes[includes_ptr++] = tree;
+
+ ((char**)(*data))[0] = result->pathname;
+ ((mds_kbdc_source_code_t**)(*data))[1] = result->source_code;
+
+ result->pathname = tree->filename;
+ result->source_code = tree->source_code;
+
+ return 0;
+ pfail:
+ saved_errno = errno;
+ free(old);
+ return errno = saved_errno, -1;
+}
+
+
+/**
+ * Undo the lasted not-undone call to `mds_kbdc_include_stack_push`
+ *
+ * This function is guaranteed not to modify `errno`
+ *
+ * @param data `*data` from `mds_kbdc_include_stack_push`
+ */
+void mds_kbdc_include_stack_pop(void* data)
+{
+ int saved_errno = errno;
+ result->pathname = ((char**)data)[0];
+ result->source_code = ((mds_kbdc_source_code_t**)data)[1];
+ includes_ptr--;
+ free(data);
+ errno = saved_errno;
+}
+
diff --git a/src/mds-kbdc/include-stack.h b/src/mds-kbdc/include-stack.h
new file mode 100644
index 0000000..2c9fce8
--- /dev/null
+++ b/src/mds-kbdc/include-stack.h
@@ -0,0 +1,118 @@
+/**
+ * mds — A micro-display server
+ * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef MDS_MDS_KBDC_INCLUDE_STACK_H
+#define MDS_MDS_KBDC_INCLUDE_STACK_H
+
+
+#include "parsed.h"
+
+
+
+/**
+ * Add an error to the error list
+ *
+ * @param NODE:const mds_kbdc_tree_t* The node the triggered the error
+ * @param SEVERITY:identifier * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
+ * @param ...:const char*, ... Error description format string and arguments
+ * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
+ */
+#define NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, ...) \
+ NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line, \
+ (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
+
+/**
+ * Add “included from here”-notes
+ *
+ * @param PTR:size_t The number of “included from here”-notes
+ */
+#define DUMP_INCLUDE_STACK(PTR) \
+ fail_if (mds_kbdc_include_stack_dump(PTR))
+
+/**
+ * Add an error with “included from here”-notes to the error list
+ *
+ * @param NODE:const mds_kbdc_tree_t* The node the triggered the error
+ * @param PTR:size_t The number of “included from here”-notes
+ * @param SEVERITY:identifier * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
+ * @param ...:const char*, ... Error description format string and arguments
+ * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
+ */
+#define NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, ...) \
+ do \
+ { \
+ NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, __VA_ARGS__); \
+ DUMP_INCLUDE_STACK(PTR); \
+ } \
+ while (0)
+
+
+
+/**
+ * The number elements stored by `mds_kbdc_include_stack_push`
+ * but not removed by `mds_kbdc_include_stack_pop`
+ */
+extern size_t includes_ptr;
+
+
+
+/**
+ * Add “included from here”-notes
+ *
+ * @param ptr The number of “included from here”-notes
+ * @return Zero on success, -1 on error
+ */
+int mds_kbdc_include_stack_dump(size_t ptr);
+
+/**
+ * Mark the root of the tree as included
+ *
+ * @param result The `result` parameter of root procedure that requires the include stack
+ */
+void mds_kbdc_include_stack_begin(mds_kbdc_parsed_t* restrict result);
+
+/**
+ * Mark the root of the tree as no longer being visited,
+ * and release clean up after the use of this module
+ *
+ * This function is guaranteed not to modify `errno`
+ */
+void mds_kbdc_include_stack_end(void);
+
+/**
+ * Mark an include-statement as visited
+ *
+ * @param tree The visisted include-statement
+ * @param data Output parameter with stack information that should be passed to
+ * the corresponding call to `mds_kbdc_include_stack_pop`, `*data`
+ * is undefined on error
+ * @return Zero on success, -1 on error
+ */
+int mds_kbdc_include_stack_push(mds_kbdc_tree_include_t* restrict tree, void** data);
+
+/**
+ * Undo the lasted not-undone call to `mds_kbdc_include_stack_push`
+ *
+ * This function is guaranteed not to modify `errno`
+ *
+ * @param data `*data` from `mds_kbdc_include_stack_push`
+ */
+void mds_kbdc_include_stack_pop(void* data);
+
+
+#endif
+
diff --git a/src/mds-kbdc/validate-tree.c b/src/mds-kbdc/validate-tree.c
index 1bfbc9e..ed96343 100644
--- a/src/mds-kbdc/validate-tree.c
+++ b/src/mds-kbdc/validate-tree.c
@@ -17,6 +17,8 @@
*/
#include "validate-tree.h"
+#include "include-stack.h"
+
#include <stdlib.h>
#include <errno.h>
@@ -28,26 +30,6 @@
#define C(TYPE) MDS_KBDC_TREE_TYPE_##TYPE
/**
- * Add an error to the error list
- *
- * @param NODE:const mds_kbdc_tree_t* The node the triggered the error
- * @param SEVERITY:identifier * in `MDS_KBDC_PARSE_ERROR_*` to indicate severity
- * @param ...:const char*, ... Error description format string and arguments
- * @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
- */
-#define NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, ...) \
- NEW_ERROR_(result, SEVERITY, 1, (NODE)->loc_line, \
- (NODE)->loc_start, (NODE)->loc_end, 1, __VA_ARGS__)
-
-/**
- * Add “included from here”-notes
- *
- * @param PTR:size_t The number of “included from here”-notes
- */
-#define DUMP_INCLUDE_STACK(PTR) \
- fail_if (dump_include_stack(PTR))
-
-/**
* Add an error with “included from here”-notes to the error list
*
* @param NODE:const mds_kbdc_tree_t* The node the triggered the error
@@ -57,12 +39,7 @@
* @scope error:mds_kbdc_parse_error_t* Variable where the new error will be stored
*/
#define NEW_ERROR(NODE, PTR, SEVERITY, ...) \
- do \
- { \
- NEW_ERROR_WITHOUT_INCLUDES(NODE, SEVERITY, __VA_ARGS__); \
- DUMP_INCLUDE_STACK(PTR); \
- } \
- while (0)
+ NEW_ERROR_WITH_INCLUDES(NODE, PTR, SEVERITY, __VA_ARGS__)
@@ -77,31 +54,6 @@ 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;
-
-/**
- * The number elements allocated for `includes`
- */
-static size_t includes_size = 0;
-
-/**
- * The number elements stored in `includes`
- */
-static size_t includes_ptr = 0;
-
-/**
* The number visited for-statements
*/
static size_t fors = 0;
@@ -145,32 +97,6 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree);
/**
- * Add “included from here”-notes
- *
- * @param ptr The number of “included from here”-notes
- * @return Zero on success, -1 on error
- */
-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--)
- {
- result->pathname = ptr ? includes[ptr - 1]->filename : original_pathname;
- result->source_code = ptr ? includes[ptr - 1]->source_code : original_source_code;
- NEW_ERROR_WITHOUT_INCLUDES(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;
-}
-
-
-/**
* Validate an include-statement
*
* @param tree The tree to validate
@@ -178,20 +104,13 @@ 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;
+ void* data;
+ int r;
+ if (mds_kbdc_include_stack_push(tree, &data))
+ return -1;
r = validate_subtree(tree->inner);
- result->pathname = pathname;
- result->source_code = source_code;
- return includes_ptr--, r;
+ mds_kbdc_include_stack_pop(data);
+ return r;
}
@@ -579,24 +498,15 @@ static int validate_subtree(mds_kbdc_tree_t* restrict tree)
*/
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;
+ int r;
+ mds_kbdc_include_stack_begin(result = result_);
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;
fors = 0;
- return errno = saved_errno, r;
+ return mds_kbdc_include_stack_end(), r;
}
#undef NEW_ERROR
-#undef DUMP_INCLUDE_STACK
-#undef NEW_ERROR_WITHOUT_INCLUDES
#undef C