aboutsummaryrefslogtreecommitdiff
path: root/src/grecs-gram.y
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-05-06 23:19:48 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-05-06 23:32:28 +0300
commit18d7db07b9f369901300bf664d07d4b39032ce64 (patch)
treea25c55b95491a507564b2f62a1c1abeebff636ad /src/grecs-gram.y
parent352b268186931579ae8dcc6a19aaaa89547555f5 (diff)
downloadgrecs-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.y61
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;
}
-
+

Return to:

Send suggestions and report system problems to the System administrator.