From eacf29f8342a4d759fa70b4d7217e86aa2fb4a15 Mon Sep 17 00:00:00 2001 From: sanine Date: Tue, 31 Jan 2023 14:24:55 -0600 Subject: fix all memory leaks --- yy/bad.xml | 2 +- yy/kalmia.y | 50 ++++++++++++++++++++++++++++++++++++++------------ yy/main.c | 15 +++++++++++---- 3 files changed, 50 insertions(+), 17 deletions(-) (limited to 'yy') diff --git a/yy/bad.xml b/yy/bad.xml index 873797b..4078a14 100644 --- a/yy/bad.xml +++ b/yy/bad.xml @@ -36,7 +36,7 @@ 1.0 - + diff --git a/yy/kalmia.y b/yy/kalmia.y index 56b15ac..ec806f7 100644 --- a/yy/kalmia.y +++ b/yy/kalmia.y @@ -8,14 +8,11 @@ #include #include #include + #include } %code requires { typedef void* yyscan_t; - struct kalmia_t { - struct kai_tag_t *tag; - }; - struct kai_attr_t { char *key; char *value; @@ -31,11 +28,21 @@ struct kai_tag_t *next; }; + + void kai_tag_destroy(struct kai_tag_t *tag); } -%parse-param { struct kalmia_t *result } +%parse-param { struct kai_tag_t **document } %code { int yylex(YYSTYPE *yylvalp, YYLTYPE *yyllocp, yyscan_t scanner); - int yyerror(YYLTYPE *yyllocp, yyscan_t unused, struct kalmia_t *unused2, const char *msg); + int yyerror(YYLTYPE *yyllocp, yyscan_t unused, struct kai_tag_t **unused2, const char *msg); + + #define TAG_MISMATCH(a, b) \ + do { \ + char buf[1024]; \ + snprintf(buf, 1024, "Tag name mismatch: \"%s\" != \"%s\"", a, b); \ + yyerror(&yylloc, NULL, NULL, (const char*) buf); \ + YYABORT; \ + } while (0) struct kai_attr_t * kai_attr_new(char *key, char *value); struct kai_attr_t * kai_attr_last(struct kai_attr_t *head); @@ -60,6 +67,7 @@ %token CONTENT %type start_tag +%type end_tag %type empty_tag %type tag %type tags @@ -71,7 +79,7 @@ %% -document: PROLOG tag { result->tag = $2; } +document: PROLOG tag { *document = $2; } tags: @@ -81,9 +89,26 @@ tags: tag: - start_tag end_tag { $$ = $1; } - | start_tag CONTENT end_tag { $$ = $1; $$->content = $2; } - | start_tag tags end_tag { $$ = $1; $$->children = $2; } + start_tag end_tag + { + $$ = $1; + if (strcmp($$->type, $2) != 0) TAG_MISMATCH($$->type, $2); + free($2); + } + | start_tag CONTENT end_tag + { + $$ = $1; + $$->content = $2; + if (strcmp($$->type, $3) != 0) TAG_MISMATCH($$->type, $3); + free($3); + } + | start_tag tags end_tag + { + $$ = $1; + $$->children = $2; + if (strcmp($$->type, $3) != 0) TAG_MISMATCH($$->type, $3); + free($3); + } | empty_tag { $$ = $1; } ; @@ -116,7 +141,7 @@ empty_tag: end_tag: - E_TAG_OPEN NAME TAG_CLOSE + E_TAG_OPEN NAME TAG_CLOSE { $$ = $2; } ; @@ -140,7 +165,7 @@ attribute: int yyerror( YYLTYPE *yyllocp, yyscan_t unused, - struct kalmia_t *unused2, + struct kai_tag_t **unused2, const char *msg) { fprintf( @@ -220,4 +245,5 @@ void kai_tag_destroy(struct kai_tag_t *tag) kai_tag_destroy(tag->children); free(tag->content); kai_tag_destroy(tag->next); + free(tag); } diff --git a/yy/main.c b/yy/main.c index 823db5a..5bc5508 100644 --- a/yy/main.c +++ b/yy/main.c @@ -56,16 +56,23 @@ int main(int argc, char **argv) return -1; } - struct kalmia_t result; + struct kai_tag_t *document; yyscan_t scanner; kalmialex_init(&scanner); kalmiaset_in(in, scanner); - kalmiaparse(scanner, &result); + int result = kalmiaparse(scanner, &document); kalmialex_destroy(scanner); + fclose(in); - print_tag("", result.tag); - print_level(1, result.tag->children); + if (result != 0) { + return result; + } + + print_tag("", document); + print_level(1, document->children); + + kai_tag_destroy(document); return 0; } -- cgit v1.2.1