diff options
Diffstat (limited to 'src/mds-kbdc')
-rw-r--r-- | src/mds-kbdc/call-stack.c | 112 | ||||
-rw-r--r-- | src/mds-kbdc/call-stack.h | 17 |
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 |