aboutsummaryrefslogtreecommitdiffstats
path: root/src/mds-kbdc
diff options
context:
space:
mode:
Diffstat (limited to 'src/mds-kbdc')
-rw-r--r--src/mds-kbdc/call-stack.c112
-rw-r--r--src/mds-kbdc/call-stack.h17
2 files changed, 128 insertions, 1 deletions
diff --git a/src/mds-kbdc/call-stack.c b/src/mds-kbdc/call-stack.c
index c8b4e2c..cd77b15 100644
--- a/src/mds-kbdc/call-stack.c
+++ b/src/mds-kbdc/call-stack.c
@@ -17,6 +17,40 @@
*/
#include "call-stack.h"
+#include <stdlib.h>
+
+
+
+/**
+ * An entry in the call-stack
+ */
+typedef struct mds_kbdc_call
+{
+ /**
+ * The tree node where the call was made
+ */
+ const mds_kbdc_tree_t* tree;
+
+ /**
+ * The position of the line of the tree node
+ * where the call begins
+ */
+ size_t start;
+
+ /**
+ * The position of the line of the tree node
+ * where the call end
+ */
+ size_t end;
+
+ /**
+ * A snapshot of the include-stack as it
+ * looked when the call was being made
+ */
+ mds_kbdc_include_stack_t* include_stack;
+
+} mds_kbdc_call_t;
+
/**
@@ -29,16 +63,43 @@ static mds_kbdc_parse_error_t* error;
*/
static mds_kbdc_parsed_t* 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 function- and macro-calls
+ */
+static mds_kbdc_call_t* restrict calls = NULL;
+
+/**
+ * The number elements allocated for `calls`
+ */
+static size_t calls_size = 0;
+
+/**
+ * The number elements stored in `calls`
+ */
+static size_t calls_ptr = 0;
+
/**
* Prepare for usage of call-stacks
*
- * @param result_ The `result` parameter of root procedure that requires the call-stack
+xo * @param result_ The `result` parameter of root procedure that requires the call-stack
*/
void mds_kbdc_call_stack_begin(mds_kbdc_parsed_t* restrict result_)
{
result = result_;
+ original_pathname = result_->pathname;
+ original_source_code = result_->source_code;
}
@@ -47,5 +108,54 @@ void mds_kbdc_call_stack_begin(mds_kbdc_parsed_t* restrict result_)
*/
void mds_kbdc_call_stack_end(void)
{
+ result->pathname = original_pathname;
+ result->source_code = original_source_code;
+ free(calls), calls = NULL;
+ calls_size = calls_ptr = 0;
+}
+
+
+/**
+ * Mark an function- or macro-call
+ *
+ * @param tree The tree node where the call was made
+ * @param start The position of the line of the tree node where the call begins
+ * @param end The position of the line of the tree node where the call end
+ * @return Zero on success, -1 on error
+ */
+int mds_kbdc_call_stack_push(const mds_kbdc_tree_t* restrict tree, size_t start, size_t end)
+{
+ mds_kbdc_call_t* tmp;
+ mds_kbdc_call_t* call;
+
+ if (calls_ptr == calls_size)
+ {
+ fail_if (yrealloc(tmp, calls, calls_size + 4, mds_kbdc_call_t));
+ calls_size += 4;
+ }
+
+ call = calls + calls_ptr++;
+ call->tree = tree;
+ call->start = start;
+ call->end = end;
+ call->include_stack = mds_kbdc_include_stack_save();
+ fail_if (call->include_stack == NULL);
+
+ return 0;
+ fail:
+ return -1;
+}
+
+
+/**
+ * Undo the lasted not-undone call to `mds_kbdc_call_stack_push`
+ *
+ * This function is guaranteed not to modify `errno`
+ */
+void mds_kbdc_call_stack_pop(void)
+{
+ int saved_errno = errno;
+ mds_kbdc_include_stack_free(calls[--calls_ptr].include_stack);
+ errno = saved_errno;
}
diff --git a/src/mds-kbdc/call-stack.h b/src/mds-kbdc/call-stack.h
index fffedf1..aa206b3 100644
--- a/src/mds-kbdc/call-stack.h
+++ b/src/mds-kbdc/call-stack.h
@@ -36,6 +36,23 @@ void mds_kbdc_call_stack_begin(mds_kbdc_parsed_t* restrict result);
*/
void mds_kbdc_call_stack_end(void);
+/**
+ * Mark an function- or macro-call
+ *
+ * @param tree The tree node where the call was made
+ * @param start The position of the line of the tree node where the call begins
+ * @param end The position of the line of the tree node where the call end
+ * @return Zero on success, -1 on error
+ */
+int mds_kbdc_call_stack_push(const mds_kbdc_tree_t* restrict tree, size_t start, size_t end);
+
+/**
+ * Undo the lasted not-undone call to `mds_kbdc_call_stack_push`
+ *
+ * This function is guaranteed not to modify `errno`
+ */
+void mds_kbdc_call_stack_pop(void);
+
#endif