Mercurial > lbo > hg > ylisp
changeset 67:b2401225b53f
gen, parse: Fix memory leaks in parser, some refactoring
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 25 Aug 2019 14:26:17 +0200 |
parents | 1b061b1fecdf |
children | d7a3916c0e17 |
files | gen/debug_parser.c gen/y.yy src/base/str.c src/base/vec.h src/expr.c src/parse.c src/parse_test.c src/value.c src/value.h |
diffstat | 9 files changed, 31 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/gen/debug_parser.c Sun Aug 25 10:06:54 2019 +0200 +++ b/gen/debug_parser.c Sun Aug 25 14:26:17 2019 +0200 @@ -6,13 +6,13 @@ bool YENABLE_DEBUG_PRINT; -int parse(FILE* in, yvec_t* out, ystr_t* ystr_error); +int y_bison_parse(FILE* in, yvec_t* out, ystr_t* ystr_error); int main(int argc, char** argv) { YENABLE_DEBUG_PRINT = true; yvec_t expr; ystr_t err; - if (0 < parse(stdin, &expr, &err)) { + if (0 < y_bison_parse(stdin, &expr, &err)) { fprintf(stderr, ">>> error: %s\n", ystr_str(&err)); return 1; }
--- a/gen/y.yy Sun Aug 25 10:06:54 2019 +0200 +++ b/gen/y.yy Sun Aug 25 14:26:17 2019 +0200 @@ -64,9 +64,9 @@ // A number literal (todo: floats) long long number; // A string literal. -const char* string; +char* string; // An atom. -const char* atom; +char* atom; } %{ // Type of yylval. @@ -91,7 +91,8 @@ prog: many_sexpr { // Assign overall result (list of yexpr_t) to parser's output // argument. - *output_yexprs = $1; + yvec_append(output_yexprs, &$1); + yvec_destroy(&$1); ydbg_print("finished\n"); } @@ -127,7 +128,7 @@ } | %empty { ydbg_print("finished quoted sexpr\n"); - yexpr_t e; + yexpr_t e = yexpr_new(); yexpr_init(&e); yvec_t v; YVEC_INIT(&v, 0, yexpr_t); @@ -145,7 +146,7 @@ } | %empty { ydbg_print("finished sexpr\n"); - yexpr_t e; + yexpr_t e = yexpr_new(); yexpr_init(&e); yvec_t v; YVEC_INIT(&v, 0, yexpr_t); @@ -159,8 +160,10 @@ } | TOK_ATOM { ydbg_print("found ID %s\n", $1); - yref_t ref = yref_new_c($1); - yexpr_t expr; + ystr_t sym = ystr_new(NULL); + ystr_set_owned(&sym, $1); + yref_t ref = yref_new_str(&sym); + yexpr_t expr = yexpr_new(); yexpr_set_ref(&expr, ref); $$ = expr; } @@ -168,28 +171,30 @@ quoted_value: TOK_ATOM { ydbg_print("found atom %s\n", $1); - yexpr_t expr; + yexpr_t expr = yexpr_new(); yexpr_set_atom_name(&expr, $1); + free($1); $$ = expr; } | literal; literal: TOK_NUMBER_LITERAL { ydbg_print("found number %d\n", $1); - yexpr_t expr; + yexpr_t expr = yexpr_new(); yexpr_set_number(&expr, $1); $$ = expr; } | TOK_STRING_LITERAL { ydbg_print("found string %s\n", $1); - yexpr_t expr; - ystr_t str = ystr_new($1); + yexpr_t expr = yexpr_new(); + ystr_t str = ystr_new(NULL); + ystr_set_owned(&str, $1); yexpr_set_str(&expr, str); $$ = expr; }; %% -int parse(FILE* in, yvec_t* out_exprs, ystr_t* ystr_error) { +int y_bison_parse(FILE* in, yvec_t* out_exprs, ystr_t* ystr_error) { void* scanner; int r; if (0 != (r = yylex_init(&scanner))) { @@ -209,7 +214,9 @@ int ret = yyparse(scanner, out_exprs, ystr_error); +#ifndef DEBUG fclose(out); +#endif assert(0 == yylex_destroy(scanner)); return ret; }
--- a/src/base/str.c Sun Aug 25 10:06:54 2019 +0200 +++ b/src/base/str.c Sun Aug 25 14:26:17 2019 +0200 @@ -15,6 +15,7 @@ void ystr_init(ystr_t *s, const char *src) { memset(s, 0, sizeof(ystr_t)); + if (src == NULL) return; ystr_set(s, src); }
--- a/src/base/vec.h Sun Aug 25 10:06:54 2019 +0200 +++ b/src/base/vec.h Sun Aug 25 14:26:17 2019 +0200 @@ -50,7 +50,7 @@ * elements of each `size` bytes. Use `YVEC_NEW()` to directly specify the type * of the array. */ -yvec_t yvec_new(void* src, size_t size, size_t len); +yvec_t yvec_new(void *src, size_t size, size_t len); /** * @brief Initialize a vector with `n` elements of `size` bytes each. See also
--- a/src/expr.c Sun Aug 25 10:06:54 2019 +0200 +++ b/src/expr.c Sun Aug 25 14:26:17 2019 +0200 @@ -1,7 +1,7 @@ #include "expr.h" +#include <src/built-ins.h> #include <src/value.h> -#include <src/built-ins.h> #include <src/base/str.h> #include <src/base/vec.h>
--- a/src/parse.c Sun Aug 25 10:06:54 2019 +0200 +++ b/src/parse.c Sun Aug 25 14:26:17 2019 +0200 @@ -1,17 +1,17 @@ #include "parse.h" // From y.yy -int parse(FILE* input, yvec_t* out, ystr_t* err); +int y_bison_parse(FILE* input, yvec_t* out, ystr_t* err); bool yparse(FILE* input, yexpr_t* result, ystr_t* error) { - yvec_t exprs; + yvec_t exprs = YVEC_NEW(0, 0, yexpr_t); ystr_init(error, NULL); - int ret = parse(input, &exprs, error); + int ret = y_bison_parse(input, &exprs, error); if (ret > 0) { return false; } - yexpr_set_list(result, exprs); // don't destroy exprs! + yexpr_set_list(result, exprs); // don't destroy exprs! return true; }
--- a/src/parse_test.c Sun Aug 25 10:06:54 2019 +0200 +++ b/src/parse_test.c Sun Aug 25 14:26:17 2019 +0200 @@ -11,7 +11,7 @@ "r"); // const-cast is ok, we open only for reading. yexpr_t result = yexpr_new(); - ystr_t error; + ystr_t error = ystr_new(NULL); bool ret = yparse(input_f, &result, &error); if (!ret) { fputs(ystr_str(&error), stderr); @@ -20,6 +20,7 @@ assert(result.typ == YEXPR_LIST); ystr_destroy(&error); + yexpr_destroy(&result); } int main(int argc, char** argv) {
--- a/src/value.c Sun Aug 25 10:06:54 2019 +0200 +++ b/src/value.c Sun Aug 25 14:26:17 2019 +0200 @@ -59,7 +59,7 @@ yvalue_id_t yvalue_create(void); yref_t yref_new(void) { - yref_t ref = {.ref.id = yvalue_create() }; + yref_t ref = {.ref.id = yvalue_create()}; return ref; } @@ -98,7 +98,6 @@ if (yref_type(ref) == YREF_SYM) ystr_destroy(&ref->ref.sym); } - void yvalue_destroy(yvalue_t* val) { switch (val->typ) { case YVALUE_EXPR: