diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-06 23:19:48 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-05-06 23:32:28 +0300 |
commit | 18d7db07b9f369901300bf664d07d4b39032ce64 (patch) | |
tree | a25c55b95491a507564b2f62a1c1abeebff636ad /src/grecs-gram.y | |
parent | 352b268186931579ae8dcc6a19aaaa89547555f5 (diff) | |
download | grecs-18d7db07b9f369901300bf664d07d4b39032ce64.tar.gz grecs-18d7db07b9f369901300bf664d07d4b39032ce64.tar.bz2 |
Redo memory management (1).
* src/grecs-lex.l (grecs_lex_end): Free both lists.
Additional argument specifies if string data should be
freed as well (on error).
(grecs_value_dup): Don't append to string_list.
* src/grecs.h (grecs_value) <v.string>: Remove const qualifier.
<v.arg.v>: Array of struct grecs_value pointers.
(grecs_node)<value>: Move to the union v.
<v.texttab>: Text storage table (for grecs_node_root).
(grecs_lex_end): Fix prototype.
(grecs_value_list_create): New prototype.
(grecs_value_free: New prototype.
(grecs_value_dup): Rename to grecs_value_ptr_from_static.
* src/text.c (grecs_text_table): New function.
* src/tree.c (grecs_value_free): New function.
(grecs_node_free): Reimplement.
(grecs_tree_free): Rewrite using grecs_tree_recurse.
(grecs_string_convert): strdup string values.
(grecs_value_list_create): New function.
* tests/gcffmt.c: Call grecs_tree_free.
* tests/gcfpeek.c: Likewise.
* tests/gcfset.c: Likewise.
Diffstat (limited to 'src/grecs-gram.y')
-rw-r--r-- | src/grecs-gram.y | 61 |
1 files changed, 26 insertions, 35 deletions
diff --git a/src/grecs-gram.y b/src/grecs-gram.y index f31305e..3d4cb2f 100644 --- a/src/grecs-gram.y +++ b/src/grecs-gram.y @@ -34,7 +34,7 @@ int grecs_default_port = 0; %union { char *string; - grecs_value_t value; + grecs_value_t svalue, *pvalue; struct grecs_list *list; struct grecs_node *node; struct { struct grecs_node *head, *tail; } node_list; @@ -43,7 +43,8 @@ int grecs_default_port = 0; %token <string> IDENT STRING QSTRING MSTRING %type <string> string slist %type <list> slist0 -%type <value> value tag vallist +%type <svalue> value tag +%type <pvalue> vallist %type <list> values list vlist %type <node> stmt simple block %type <node_list> stmtlist @@ -54,6 +55,7 @@ input : stmtlist { parse_tree = grecs_node_create(grecs_node_root, &grecs_current_locus); + parse_tree->v.texttab = grecs_text_table(); grecs_node_bind(parse_tree, $1.head, 1); } ; @@ -77,7 +79,7 @@ simple : IDENT vallist ';' $$ = grecs_node_create(grecs_node_stmt, &grecs_current_locus); $$->ident = $1; - $$->value = $2; + $$->v.value = $2; } ; @@ -86,7 +88,7 @@ block : IDENT tag '{' stmtlist '}' opt_sc $$ = grecs_node_create(grecs_node_block, &grecs_current_locus); $$->ident = $1; - $$->value = $2; + $$->v.value = grecs_value_ptr_from_static(&$2); grecs_node_bind($$, $4.head, 1); } ; @@ -104,30 +106,32 @@ vallist : vlist size_t n; if ((n = grecs_list_size($1)) == 1) { - $$ = *(grecs_value_t *)grecs_list_index($1, 0); + $$ = grecs_list_index($1, 0); } else { size_t i; struct grecs_list_entry *ep; - $$.type = GRECS_TYPE_ARRAY; - $$.v.arg.c = n; - $$.v.arg.v = grecs_malloc(n * - sizeof($$.v.arg.v[0])); + $$ = grecs_malloc(sizeof($$[0])); + $$->type = GRECS_TYPE_ARRAY; + $$->v.arg.c = n; + $$->v.arg.v = grecs_calloc(n, + sizeof($$->v.arg.v[0])); for (i = 0, ep = $1->head; ep; i++, ep = ep->next) - $$.v.arg.v[i] = *(grecs_value_t *)ep->data; + $$->v.arg.v[i] = ep->data; } + $1->free_entry = NULL; grecs_list_free($1); } ; vlist : value { - $$ = _grecs_simple_list_create(0); - grecs_list_append($$, grecs_value_dup(&$1)); + $$ = grecs_value_list_create(); + grecs_list_append($$, grecs_value_ptr_from_static(&$1)); } | vlist value { - grecs_list_append($1, grecs_value_dup(&$2)); + grecs_list_append($1, grecs_value_ptr_from_static(&$2)); } ; @@ -167,7 +171,7 @@ slist : slist0 slist0 : QSTRING { - $$ = _grecs_simple_list_create(0); + $$ = grecs_list_create(); grecs_list_append($$, $1); } | slist0 QSTRING @@ -193,12 +197,12 @@ list : '(' ')' values : value { - $$ = _grecs_simple_list_create(0); - grecs_list_append($$, grecs_value_dup(&$1)); + $$ = grecs_value_list_create(); + grecs_list_append($$, grecs_value_ptr_from_static(&$1)); } | values ',' value { - grecs_list_append($1, grecs_value_dup(&$3)); + grecs_list_append($1, grecs_value_ptr_from_static(&$3)); $$ = $1; } ; @@ -216,21 +220,6 @@ yyerror(char *s) return 0; } -static void -listel_dispose(void *el) -{ - free(el); -} - -struct grecs_list * -_grecs_simple_list_create(int dispose) -{ - struct grecs_list *lp = grecs_list_create(); - if (dispose) - lp->free_entry = listel_dispose; - return lp; -} - int grecs_vasprintf(char **pbuf, size_t *psize, const char *fmt, va_list ap) { @@ -301,8 +290,10 @@ grecs_parse(const char *name) return NULL; parse_tree = NULL; rc = yyparse(); - grecs_lex_end(); - if (grecs_error_count) { + if (grecs_error_count) + rc = 1; + grecs_lex_end(rc); + if (rc) { grecs_tree_free(parse_tree); parse_tree = NULL; } @@ -315,7 +306,7 @@ grecs_gram_trace(int n) yydebug = n; } - + |