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:
--- a/src/value.h	Sun Aug 25 10:06:54 2019 +0200
+++ b/src/value.h	Sun Aug 25 14:26:17 2019 +0200
@@ -75,7 +75,6 @@
  */
 void yref_destroy(yref_t* ref);
 
-
 /**
  * @brief A value with a name, stored in the global value table to be referenced
  * by name or ID. To be used as pointer (not value).