From cdf4d858664012a8639a52850493beb6c8728343 Mon Sep 17 00:00:00 2001 From: Keyvan Kambakhsh Date: Thu, 28 Nov 2024 17:50:37 +0330 Subject: [PATCH] test: Enable inp_include.c test + feat: ifndef, fixes #60 --- examples/inp_preprocess.c | 26 ++++------------- preprocess/macro_ifndef.c | 60 +++++++++++++++++++++++++++++++++++++++ preprocess/macro_ifndef.h | 15 ++++++++++ preprocess/preprocess.c | 35 +++++++++++++++++++++++ scripts/test.py | 4 +-- 5 files changed, 117 insertions(+), 23 deletions(-) create mode 100644 preprocess/macro_ifndef.c create mode 100644 preprocess/macro_ifndef.h diff --git a/examples/inp_preprocess.c b/examples/inp_preprocess.c index c9dae9a..2457e9c 100644 --- a/examples/inp_preprocess.c +++ b/examples/inp_preprocess.c @@ -1,27 +1,11 @@ void printf(char *, ...); -#define DEBUG 1 +#define DEBUG -#ifdef DEBUG -int function() { - return 69; -} -#endif - -#ifdef RELEASE -int function() { - return 13; -} +int main() +{ +#ifndef DEBUG + printf("Debug disabled!\n"); #endif - -#ifndef RELEASE -int function2() { - return 99; -} -#endif - -int main() { - printf("function(): %d\n", function()); - printf("function2(): %d\n", function2()); return 0; } diff --git a/preprocess/macro_ifndef.c b/preprocess/macro_ifndef.c new file mode 100644 index 0000000..891f2b6 --- /dev/null +++ b/preprocess/macro_ifndef.c @@ -0,0 +1,60 @@ +#include +#include +#include "macro_ifndef.h" +#include "preprocess.h" +#include + +seg_ifndef *parse_ifndef(prep_ctx *ctx, typed_token **tkns_ptr) +{ + typed_token *tkn = *tkns_ptr; + if (tkn->type_id == TKN_DIRECTIVE) + { + typed_token *inner_tkn = (typed_token *)tkn->data; + tkn = tkn->next; + if (inner_tkn->type_id == TKN_ID) + { + if (strcmp((char *)inner_tkn->data, "ifndef") == 0) + { + inner_tkn = inner_tkn->next; + if (inner_tkn->type_id == TKN_ID) + { + char *def = (char *)inner_tkn->data; + inner_tkn = inner_tkn->next; + + if (inner_tkn->type_id == TKN_EOF) + { + *tkns_ptr = tkn; + seg_ifndef *ret = malloc(sizeof(seg_ifndef)); + ret->def = def; + return ret; + } + else + { + return NULL; + } + } + } + } + } + return NULL; +} + +int is_endif(typed_token *tkn) +{ + if (tkn->type_id == TKN_DIRECTIVE) + { + typed_token *inner_tkn = (typed_token *)tkn->data; + if (inner_tkn->type_id == TKN_ID) + { + if (strcmp((char *)inner_tkn->data, "endif") == 0) + { + inner_tkn = inner_tkn->next; + if (inner_tkn->type_id == TKN_EOF) + { + return 1; + } + } + } + } + return 0; +} \ No newline at end of file diff --git a/preprocess/macro_ifndef.h b/preprocess/macro_ifndef.h new file mode 100644 index 0000000..668c3b6 --- /dev/null +++ b/preprocess/macro_ifndef.h @@ -0,0 +1,15 @@ +#ifndef MACRO_IFNDEF_H +#define MACRO_IFNDEF_H + +#include "../linked_list.h" +#include "preprocess.h" + +typedef struct +{ + char *def; +} seg_ifndef; + +seg_ifndef *parse_ifndef(prep_ctx *ctx, typed_token **tkns_ptr); +int is_endif(typed_token *tkn); + +#endif \ No newline at end of file diff --git a/preprocess/preprocess.c b/preprocess/preprocess.c index 3c006e6..1dae2d6 100644 --- a/preprocess/preprocess.c +++ b/preprocess/preprocess.c @@ -9,6 +9,7 @@ #include "macro_define.h" #include "macro_call.h" #include "macro_include.h" +#include "macro_ifndef.h" #include "token.h" typed_token *chain_tokens(linked_list *tkns) @@ -37,6 +38,40 @@ typed_token *preprocess(prep_ctx *ctx, char *path) while (tkn->type_id != TKN_EOF) { + if (is_endif(tkn)) + { + tkn = tkn->next; + continue; + } + + seg_ifndef *ifndef = parse_ifndef(ctx, &tkn); + if (ifndef) + { + if (find_define(ctx, ifndef->def)) + { + int endif_found = 0; + while (tkn->type_id != TKN_EOF) + { + if (is_endif(tkn)) + { + tkn = tkn->next; + endif_found = 1; + break; + } + tkn = tkn->next; + } + if (!endif_found) + { + fprintf(stderr, "Couldn't find #endif!\n"); + exit(1); + } + else + { + continue; + } + } + } + seg *s = NULL; if (!s) s = parse_token(ctx, &tkn); diff --git a/scripts/test.py b/scripts/test.py index 63c25ad..78cee3f 100755 --- a/scripts/test.py +++ b/scripts/test.py @@ -15,11 +15,11 @@ "./examples/inp_linked_list.c": [], "./examples/inp_unary_op.c": [], "./examples/lib_usage.c": [], - #"./examples/inp_include.c": [], + "./examples/inp_include.c": [], "./examples/inp_func_ptrs.c": [], "./examples/inp_goto.c": [], "./examples/inp_break.c": [], - #"./examples/inp_preprocess.c": [], + "./examples/inp_preprocess.c": [], "./examples/inp_pointer.c": [], "./examples/switch.c": [], "./examples/inp_loop.c": [],