]> git.ipfire.org Git - pakfire.git/commitdiff
parser: Correct pass down the parent parser
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 3 May 2021 21:43:34 +0000 (21:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 3 May 2021 21:43:34 +0000 (21:43 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/parser.c
src/libpakfire/parser/grammar.y

index e33769bb8422a421b8013b679f73252afd8c9b58..83e216312b4d61bf8ecb1bd4b09f135e907d1bca 100644 (file)
@@ -177,9 +177,6 @@ static void pakfire_parser_free(PakfireParser parser) {
 }
 
 PAKFIRE_EXPORT PakfireParser pakfire_parser_unref(PakfireParser parser) {
-       if (!parser)
-               return NULL;
-
        if (--parser->nrefs > 0)
                return parser;
 
@@ -622,6 +619,11 @@ PAKFIRE_EXPORT int pakfire_parser_merge(PakfireParser parser1, PakfireParser par
        DEBUG(parser1->pakfire, "Merging parsers %p and %p\n", parser1, parser2);
        char namespace[NAME_MAX*2+1];
 
+       if (!parser2) {
+               errno = EINVAL;
+               return 1;
+       }
+
        // Do not try to merge a parser with itself
        if (parser1 == parser2)
                return EINVAL;
index 8b45d5b486787cdffd12f5d5da6ec1eecae178ef..d17d3e918ca8b9a72003b894f1b384aa5e048421 100644 (file)
@@ -22,8 +22,9 @@
 
 %parse-param
        {yyscan_t* scanner}
-       {PakfireParser* parser}
        {Pakfire pakfire}
+       {PakfireParser* parser}
+       {PakfireParser parent}
        {struct pakfire_parser_error** error}
 
 // Make the parser reentrant
@@ -73,8 +74,8 @@ enum operator {
        OP_EQUALS = 0,
 };
 
-static void yyerror(yyscan_t* scanner, PakfireParser* parser, Pakfire pakfire,
-               struct pakfire_parser_error** error, const char* s) {
+static void yyerror(yyscan_t* scanner, Pakfire pakfire, PakfireParser* parser,
+               PakfireParser parent, struct pakfire_parser_error** error, const char* s) {
        ERROR(pakfire, "Error (line %d): %s\n", num_lines, s);
 
        // Create a new error object
@@ -86,7 +87,7 @@ static void yyerror(yyscan_t* scanner, PakfireParser* parser, Pakfire pakfire,
        }
 }
 
-static PakfireParser make_if_stmt(Pakfire pakfire, PakfireParser* parser, const enum operator op,
+static PakfireParser make_if_stmt(Pakfire pakfire, PakfireParser parser, const enum operator op,
                const char* val1, const char* val2, PakfireParser if_block, PakfireParser else_block);
 
 static int pakfire_parser_new_declaration(
@@ -172,12 +173,16 @@ static void pakfire_parser_free_declaration(struct pakfire_parser_declaration* d
 
 grammar                                                : %empty
                                                        {
-                                                               $$ = pakfire_parser_create(pakfire, NULL, NULL, 0);
+                                                               $$ = pakfire_parser_create(pakfire, parent, NULL, 0);
                                                                if (!$$)
                                                                        ABORT;
 
+                                                               // Make this the root
                                                                if (!*parser)
                                                                        *parser = pakfire_parser_ref($$);
+
+                                                               // This is now the new parent parser
+                                                               parent = $$;
                                                        }
                                                        | grammar declaration
                                                        {
@@ -194,10 +199,12 @@ grammar                                           : %empty
                                                                $$ = $1;
 
                                                                int r = pakfire_parser_merge($1, $2);
+                                                               pakfire_parser_unref($2);
                                                                if (r)
                                                                        ABORT;
 
-                                                               pakfire_parser_unref($2);
+                                                               // Go back to the parent parser
+                                                               parent = $$;
                                                        }
                                                        | grammar if_stmt
                                                        {
@@ -209,6 +216,9 @@ grammar                                             : %empty
                                                                        if (r)
                                                                                ABORT;
                                                                }
+
+                                                               // Go back to the parent parser
+                                                               parent = $$;
                                                        }
                                                        | grammar empty
                                                        {
@@ -219,6 +229,9 @@ grammar                                             : %empty
 subgrammar                                     : T_INDENT grammar T_OUTDENT
                                                        {
                                                                $$ = $2;
+
+                                                               // Go back to the parent parser
+                                                               parent = $$;
                                                        }
                                                        ;
 
@@ -302,7 +315,7 @@ subparser                                   : subparser_name T_EOL subgrammar T_END T_EOL
                                                                char* value;
 
                                                                // Create a new parser
-                                                               $$ = pakfire_parser_create(pakfire, NULL, NULL, 0);
+                                                               $$ = pakfire_parser_create(pakfire, parent, NULL, 0);
                                                                if (!$$)
                                                                        ABORT;
 
@@ -330,10 +343,7 @@ subparser_name                             : T_SUBPARSER
 
 if_stmt                                                : T_IF T_STRING T_EQUALS T_STRING T_EOL subgrammar else_stmt T_END T_EOL
                                                        {
-                                                               $$ = make_if_stmt(pakfire, parser, OP_EQUALS, $2, $4, $6, $7);
-
-                                                               pakfire_parser_unref($6);
-                                                               pakfire_parser_unref($7);
+                                                               $$ = make_if_stmt(pakfire, parent, OP_EQUALS, $2, $4, $6, $7);
                                                        }
                                                        ;
 
@@ -371,18 +381,20 @@ int pakfire_parser_parse_data(PakfireParser parent, const char* data, size_t len
        num_lines = 1;
 
        YY_BUFFER_STATE buffer = yy_scan_bytes(data, len, scanner);
-       int r = yyparse(scanner, &parser, pakfire, error);
+       int r = yyparse(scanner, pakfire, &parser, parent, error);
        yy_delete_buffer(buffer, scanner);
 
        // If everything was parsed successfully, we merge the sub-parser into
        // the parent parser. That way, it will be untouched if something could
        // not be successfully parsed.
        if (r == 0) {
-               pakfire_parser_merge(parent, parser);
+               if (parser)
+                       pakfire_parser_merge(parent, parser);
        }
 
        // Destroy the parser
-       pakfire_parser_unref(parser);
+       if (parser)
+               pakfire_parser_unref(parser);
 
 #ifdef ENABLE_DEBUG
        // Save end time
@@ -406,7 +418,7 @@ int pakfire_parser_parse_data(PakfireParser parent, const char* data, size_t len
        return r;
 }
 
-static PakfireParser make_if_stmt(Pakfire pakfire, PakfireParser* parser, const enum operator op,
+static PakfireParser make_if_stmt(Pakfire pakfire, PakfireParser parser, const enum operator op,
                const char* val1, const char* val2, PakfireParser if_block, PakfireParser else_block) {
        switch (op) {
                case OP_EQUALS:
@@ -414,11 +426,11 @@ static PakfireParser make_if_stmt(Pakfire pakfire, PakfireParser* parser, const
                        break;
        }
 
-       DEBUG(pakfire, "  parser = %p, if = %p, else = %p\n", *parser, if_block, else_block);
+       DEBUG(pakfire, "  parent = %p, if = %p, else = %p\n", parser, if_block, else_block);
 
        // Expand values
-       char* v1 = pakfire_parser_expand(*parser, NULL, val1);
-       char* v2 = pakfire_parser_expand(*parser, NULL, val2);
+       char* v1 = pakfire_parser_expand(parser, NULL, val1);
+       char* v2 = pakfire_parser_expand(parser, NULL, val2);
 
        PakfireParser result = NULL;