From e716ece6a93f1a92df75995a705e31f53ac39082 Mon Sep 17 00:00:00 2001 From: anon <anon@anon.anon> Date: Mon, 16 Sep 2024 16:53:48 +0200 Subject: [PATCH] fixed tests and memory management; added multi selector rule support --- Makefile | 3 +- source/main.c | 22 ++++------ source/rule.h | 28 +++++++++++++ source/tbsp.l | 3 +- source/tbsp.y | 78 ++++++++++++++++++++++-------------- test/CMDTEST_tbsp.rb | 48 +++++++++++++++++----- test/convert.tbsp | 50 ++++++++++------------- test/double_selector.tbsp | 36 +++++++++++++++++ test/file2str.h | 15 +++++++ test/function_collector.tbsp | 21 +++++----- 10 files changed, 206 insertions(+), 98 deletions(-) create mode 100644 source/rule.h create mode 100644 test/double_selector.tbsp create mode 100644 test/file2str.h diff --git a/Makefile b/Makefile index c48bf58..9324228 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ else endif CFLAGS += -std=c2x -Wall -Wpedantic -CPPFLAGS += -Iobject -Ilibrary +CPPFLAGS += -Isource -Iobject -Ilibrary # --- Rule Section --- ${OUT}: ${GENSOURCE} ${GENOBJECT} ${OBJECT} ${LIBS} @@ -60,3 +60,4 @@ clean: -rm ${GENSOURCE} -rm ${OBJECT} -rm ${OUT} + -rm test/*.tb.* diff --git a/source/main.c b/source/main.c index 2994d5f..6356666 100644 --- a/source/main.c +++ b/source/main.c @@ -23,10 +23,6 @@ extern int tbsp_yy_deinit(void); extern int tbsp_c_yy_init(void); extern int tbsp_c_yy_deinit(void); -char * language = NULL; -char * verbatim = NULL; -char * top = NULL; - void yyerror(const char * const fmt, ...) { extern int yylineno; va_list args; @@ -52,7 +48,7 @@ void dump_rule_table(const char * const name, rule_type_t type_mask) { sprint_r = asprintf(&sprint_buffer, TBSP_case, kv_A(rules, i).string, - kv_A(rules, i).target + kv_A(codes, kv_A(rules, i).code_index).number ); fputs(sprint_buffer, yyout); free(sprint_buffer); @@ -82,7 +78,7 @@ void dump_output(void) { dump_rule_table("leave_cases", LEAVE_RULE); fputs(TBSP_traverse_top, yyout); - for (int i = 0; i < kv_size(rules); i++) { + for (int i = 0; i < kv_size(codes); i++) { const char * const case_string = "\ case %d: {\n\ %s\n\ @@ -90,8 +86,8 @@ void dump_output(void) { "; sprint_r = asprintf(&sprint_buffer, case_string, - kv_A(rules, i).target, - kv_A(rules, i).code + kv_A(codes, i).number, + kv_A(codes, i).code ); fputs(sprint_buffer, yyout); free(sprint_buffer); @@ -111,17 +107,13 @@ void init(void) { static inline void deinit(void) { - for (int i = 0; i < kv_size(rules); i++) { - free(kv_A(rules, i).string); - free(kv_A(rules, i).code); - } + fclose(yyin); + fclose(yyout); + tbsp_tab_deinit(); tbsp_yy_deinit(); tbsp_c_yy_deinit(); free(output_file_name); free(input_file_name); - free(verbatim); - free(language); - free(top); } signed main(const int argc, const char * const * const argv) { diff --git a/source/rule.h b/source/rule.h new file mode 100644 index 0000000..59e2e53 --- /dev/null +++ b/source/rule.h @@ -0,0 +1,28 @@ +#ifndef RULE_H +#define RULE_H + +#include <kvec.h> + +typedef enum { + ENTER_RULE = 0b0001, + LEAVE_RULE = 0b0010, +} rule_type_t; + +typedef struct { + int number; + char * code; +} code_t; + +typedef struct { + rule_type_t type; + char * string; + int code_index; +} rule_t; + +typedef kvec_t(rule_t) rule_vector_t; +extern rule_vector_t rules; + +typedef kvec_t(code_t) code_vector_t; +extern code_vector_t codes; + +#endif diff --git a/source/tbsp.l b/source/tbsp.l index 7b87d34..220d41a 100644 --- a/source/tbsp.l +++ b/source/tbsp.l @@ -40,7 +40,7 @@ identifier [a-zA-z][-a-zA-z0-9_]* return SEPARATOR; } . { - yyerror("unknown shit"); + yyerror("unknown expression in rule section"); } } @@ -86,7 +86,6 @@ leave[[:space:]] { return LEAVE; } } --code_nesting; - ; } .|\n { buffer = sdscat(buffer, yytext); } } diff --git a/source/tbsp.y b/source/tbsp.y index 23534c3..f8a7874 100644 --- a/source/tbsp.y +++ b/source/tbsp.y @@ -1,36 +1,30 @@ %{ #include "tbsp.yy.h" - - extern char * language; - extern char * top; - extern char * verbatim; + #include <kvec.h> int target_counter = 1; + kvec_t(char *) rule_selectors; + + char * language = NULL; + char * verbatim = NULL; + char * top = NULL; + #define COMA , %} %code requires { - typedef enum { - ENTER_RULE = 0b0001, - LEAVE_RULE = 0b0010, - } rule_type_t; - - typedef struct { - rule_type_t type; - int target; - char * string; - char * code; - } rule_t; - - #include <kvec.h> - typedef kvec_t(rule_t) rule_vector_t; - extern rule_vector_t rules; - + #include "rule.h" extern void yyerror(const char * const s, ...); } %code provides { void tbsp_tab_init(void); void tbsp_tab_deinit(void); + + extern rule_vector_t rules; + + extern char * language; + extern char * top; + extern char * verbatim; } %union{ char * strval; @@ -41,7 +35,6 @@ %token ENTER LEAVE %token<strval> IDENTIFIER CODE_BLOB %type<ruleval> rule_type -%type<strval> rule_selector %% document : %empty @@ -91,16 +84,22 @@ rule char * code_blob_expanded = strdup(tbsp_c_expland_code($3)); - kv_push(rule_t, rules, (rule_t) { - .type = $1 COMA - .target = target_counter COMA - .string = $2 COMA - .code = code_blob_expanded COMA + kv_push(code_t, codes, (code_t) { + .number = target_counter++ COMA + .code = code_blob_expanded COMA }); - ++target_counter; + for (int i = 0; i < kv_size(rule_selectors); i++) { + kv_push(rule_t, rules, (rule_t) { + .type = $1 COMA + .string = kv_A(rule_selectors, i) COMA + .code_index = codes.n-1 COMA + }); + } + rule_selectors.n = 0; tbsp_c_yy_reset(); + free($3); } ; @@ -111,7 +110,12 @@ rule_type ; rule_selector - : IDENTIFIER { $$ = $1; } + : IDENTIFIER { + kv_push(char *, rule_selectors, $1); + } + | IDENTIFIER rule_selector { + kv_push(char *, rule_selectors, $1); + } ; @@ -123,16 +127,32 @@ code_section %% rule_vector_t rules; +code_vector_t codes; void tbsp_tab_init(void) { kv_init(rules); + kv_init(codes); + kv_init(rule_selectors); } void tbsp_tab_deinit(void) { + for (int i = 0; i < kv_size(rule_selectors); i++) { + free(kv_A(rule_selectors, i)); + } + + for (int i = 0; i < kv_size(codes); i++) { + free(kv_A(codes, i).code); + } + for (int i = 0; i < kv_size(rules); i++) { free(kv_A(rules, i).string); - free(kv_A(rules, i).code); } kv_destroy(rules); + kv_destroy(codes); + kv_destroy(rule_selectors); + + free(verbatim); + free(language); + free(top); } diff --git a/test/CMDTEST_tbsp.rb b/test/CMDTEST_tbsp.rb index bce3190..192b32b 100644 --- a/test/CMDTEST_tbsp.rb +++ b/test/CMDTEST_tbsp.rb @@ -1,25 +1,53 @@ class CMDTEST_master_batch < Cmdtest::Testcase + def setup + import_file "test/file2str.h", "./" + end + def test_converter - import_file "test/convert.tbsp", "./" + source = "convert" + + import_file "test/#{source}.tbsp", "./" import_file "test/input.md", "./" - cmd "tbsp -o convert.tb.c convert.tbsp" do - created_files ["convert.tb.c"] + cmd "tbsp -o #{source}.tb.c #{source}.tbsp" do + created_files ["#{source}.tb.c"] end - shell "bake convert.tb.c" - cmd "./convert.tb.out input.md" do + cmd "gcc -w -o #{source}.out #{source}.tb.c $(pkg-config --cflags --libs tree-sitter) -ltree-sitter-markdown" do + created_files ["#{source}.out"] + end + cmd "./#{source}.out input.md" do stdout_equal /.+/ end end def test_function_collector - import_file "test/function_collector.tbsp", "./" + source = "function_collector" - cmd "tbsp -o function_collector.tb.cpp function_collector.tbsp" do - created_files ["function_collector.tb.cpp"] + import_file "test/#{source}.tbsp", "./" + + cmd "tbsp -o #{source}.tb.cpp #{source}.tbsp" do + created_files ["#{source}.tb.cpp"] end - shell "bake function_collector.tb.cpp" - cmd "./function_collector.tb.out function_collector.tb.cpp" do + cmd "g++ -w -o #{source}.out #{source}.tb.cpp $(pkg-config --cflags --libs tree-sitter tree-sitter-cpp)" do + created_files ["#{source}.out"] + end + cmd "./#{source}.out #{source}.tb.cpp" do + stdout_equal /.+/ + end + end + + def test_double_selector + source = "double_selector" + + import_file "test/#{source}.tbsp", "./" + + cmd "tbsp #{source}.tbsp" do + created_files ["#{source}.tb.c"] + end + cmd "g++ -w -o #{source}.out #{source}.tb.c $(pkg-config --cflags --libs tree-sitter tree-sitter-c)" do + created_files ["#{source}.out"] + end + cmd "./#{source}.out #{source}.tb.c" do stdout_equal /.+/ end end diff --git a/test/convert.tbsp b/test/convert.tbsp index 8697b69..b0706af 100644 --- a/test/convert.tbsp +++ b/test/convert.tbsp @@ -14,6 +14,7 @@ leave section { } enter atx_heading { + puts("AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); printf("<h%d>\n", depth); } leave atx_heading { @@ -21,66 +22,57 @@ leave atx_heading { } enter paragraph { - printf("<p>"); + puts("<p>"); } leave paragraph { - printf("</p>\n"); + puts("</p>"); } enter list { - printf("<ol>"); + puts("<ol>"); } leave list { - printf("</ol>\n"); + puts("</ol>"); } enter list_item { - printf("<li>"); + puts("<li>"); } leave list_item { - printf("</li>\n"); + puts("</li>"); } enter fenced_code_block { - printf("<pre>"); + puts("<pre>"); } leave fenced_code_block { - printf("</pre>\n"); + puts("</pre>"); } enter inline { char * text = tbget_text; - printf(text); + puts(text); free(text); } enter code_fence_content { char * text = tbget_text; - printf(text); + puts(text); free(text); } %% -// @BAKE g++ -o $*.out $@ $(pkg-config --cflags --libs tree-sitter) -ltree-sitter-markdown -ggdb +/* @BAKE + tbsp $@ + gcc -o $*.out $*.tb.c $(pkg-config --cflags --libs tree-sitter) -ltree-sitter-markdown -ggdb + ./$*.out input.md + @STOP +*/ + +#include "file2str.h" signed main(int argc, char * * argv) { - if (argc < 2) { - return 1; - } - - FILE* f = fopen(argv[1], "r"); - - if (!f) { - return 2; - } - - fseek(f, 0, SEEK_END); - int flen = ftell(f); - rewind(f); - char fstr[flen+1]; - fstr[flen] = '\00'; - fread(fstr, flen, sizeof(char), f); - - fclose(f); + if (argc < 2) { return 1; } + FILE2STR(fstr, argv[1]); printf("-- meta: %d chars\n", flen); diff --git a/test/double_selector.tbsp b/test/double_selector.tbsp new file mode 100644 index 0000000..9509ba7 --- /dev/null +++ b/test/double_selector.tbsp @@ -0,0 +1,36 @@ +%language c +%% + +enter function_definition declaration { + TSNode declarator = $$->"declarator"; + TSNode next_declarator = declarator; + while (next_declarator = tbnode_child_by_field_name(next_declarator, "declarator"), + !ts_node_is_null(next_declarator)) { + declarator = next_declarator; + } + + char * s = tbget_node_text(declarator); + puts(s); + free(s); +} + +%% +/* @BAKE + tbsp $@ + gcc -o $*.out $*.tb.c $(pkg-config --cflags --libs tree-sitter tree-sitter-c) -ggdb + ./$*.out $.tb.c + @STOP +*/ + +#include "file2str.h" + +signed main(int argc, char * * argv) { + if (argc < 2) { return 1; } + FILE2STR(fstr, argv[1]); + + puts(fstr); + + tbtraverse(fstr); + + return 0; +} diff --git a/test/file2str.h b/test/file2str.h new file mode 100644 index 0000000..4d2ebd1 --- /dev/null +++ b/test/file2str.h @@ -0,0 +1,15 @@ +#ifndef FILE2STR_H +#define FILE2STR_H + +#define FILE2STR(dest, filename) \ + FILE* f = fopen(filename, "r"); \ + if (!f) { return 1; } \ + fseek(f, 0, SEEK_END); \ + int flen = ftell(f); \ + rewind(f); \ + char fstr[flen+1]; \ + dest[flen] = '\00'; \ + fread(dest, flen, sizeof(char), f); \ + fclose(f); + +#endif diff --git a/test/function_collector.tbsp b/test/function_collector.tbsp index e661979..a8ea814 100644 --- a/test/function_collector.tbsp +++ b/test/function_collector.tbsp @@ -19,22 +19,19 @@ enter function_definition { } %% +/* @BAKE + tbsp -o $*.tb.cpp $@ + g++ -o $*.out $*.tb.cpp $(pkg-config --cflags --libs tree-sitter tree-sitter-cpp) -ggdb + ./$*.out $@ + @STOP +*/ -// @BAKE g++ $@ -o $*.out $(pkg-config --cflags --libs tree-sitter tree-sitter-cpp) +#include "file2str.h" signed main(int argc, char * * argv) { - if (argc < 2) { - return 1; - } + if (argc < 2) { return 1; } - FILE* f = fopen(argv[1], "r"); - fseek(f, 0, SEEK_END); - int flen = ftell(f); - rewind(f); - char fstr[flen+1]; - fstr[flen] = '\00'; - fread(fstr, flen, sizeof(char), f); - fclose(f); + FILE2STR(fstr, argv[1]); tbtraverse(fstr);