From: Michael Tremer Date: Wed, 2 Jun 2021 15:09:17 +0000 (+0000) Subject: parser: Fix lookup order X-Git-Tag: 0.9.28~1285^2~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3f6e35a7d0dcf9df1862eb615104d29a900f0e65;p=pakfire.git parser: Fix lookup order This fixes that variables were sometimes not expanded correctly Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/parser.c b/src/libpakfire/parser.c index bd7304b6c..74c93a45e 100644 --- a/src/libpakfire/parser.c +++ b/src/libpakfire/parser.c @@ -197,10 +197,10 @@ static struct pakfire_parser_declaration* pakfire_parser_get_declaration( if (!namespace) namespace = ""; - if (namespace) - DEBUG(parser->pakfire, "Looking up %s.%s\n", namespace, name); + if (*namespace) + DEBUG(parser->pakfire, "%p: Looking up %s.%s\n", parser, namespace, name); else - DEBUG(parser->pakfire, "Looking up %s\n", name); + DEBUG(parser->pakfire, "%p: Looking up %s\n", parser, name); struct pakfire_parser_declaration* d; for (unsigned i = 0; i < parser->num_declarations; i++) { @@ -209,10 +209,64 @@ static struct pakfire_parser_declaration* pakfire_parser_get_declaration( break; // Return if namespace and name match - if ((strcmp(d->namespace, namespace) == 0) && (strcmp(d->name, name) == 0)) + if ((strcmp(d->namespace, namespace) == 0) && (strcmp(d->name, name) == 0)) { + DEBUG(parser->pakfire, "%p: Found result = %s\n", parser, d->value); + return d; + } } + DEBUG(parser->pakfire, "%p: Nothing found\n", parser); + + return NULL; +} + +static struct pakfire_parser_declaration* pakfire_parser_get_declaration_recursive( + PakfireParser parser, const char* namespace, const char* name) { + struct pakfire_parser_declaration* d = pakfire_parser_get_declaration( + parser, namespace, name); + if (d) + return d; + + // Continue searching in parent parser + if (parser->parent) + return pakfire_parser_get_declaration_recursive(parser->parent, namespace, name); + + return NULL; +} + +static void pakfire_parser_strip_namespace(char** s) { + char* pos = strrchr(*s, '.'); + + if (pos) + (*s)[pos - *s] = '\0'; + else + (*s)[0] = '\0'; +} + +static struct pakfire_parser_declaration* pakfire_parser_find_declaration( + PakfireParser parser, const char* namespace, const char* name) { + struct pakfire_parser_declaration* d; + char* n = NULL; + + // Create a working copy of namespace + if (namespace) + n = strdupa(namespace); + + while (1) { + d = pakfire_parser_get_declaration_recursive(parser, n, name); + if (d && d->value) + return d; + + // End if we have exhausted the namespace + if (!n || !*n) + break; + + // Strip namespace + pakfire_parser_strip_namespace(&n); + } + + // Nothing found return NULL; } @@ -289,62 +343,34 @@ static const char* pakfire_parser_find_template(PakfireParser parser, return template; } -static void pakfire_parser_strip_namespace(char** s) { - char* pos = strrchr(*s, '.'); - - if (pos) - (*s)[pos - *s] = '\0'; - else - (*s)[0] = '\0'; -} - static const char* pakfire_parser_get_raw(PakfireParser parser, const char* namespace, const char* name) { struct pakfire_parser_declaration* d = NULL; // First, perform a simple lookup - d = pakfire_parser_get_declaration(parser, namespace, name); + d = pakfire_parser_get_declaration_recursive(parser, namespace, name); // Return a match when it actually contains a string if (d && d->value) return d->value; - // We are done, if the namespace is empty - if (!namespace || !*namespace) - return NULL; - char template[NAME_MAX] = ""; // If we couldn't find anything, we check if there is a template, and if that // has our value... - if (pakfire_string_startswith(namespace, "packages.package:")) { + if (namespace && pakfire_string_startswith(namespace, "packages.package:")) { pakfire_parser_find_template(parser, template, sizeof(template) - 1, namespace); if (*template) { - d = pakfire_parser_get_declaration(parser, template, name); + d = pakfire_parser_find_declaration(parser, template, name); if (d && d->value) return d->value; } } - // Create a working copy of namespace - char* n = strdupa(namespace); - - while (n) { - // Strip namespace - pakfire_parser_strip_namespace(&n); - - d = pakfire_parser_get_declaration(parser, n, name); - if (d && d->value) - return d->value; - - // End if we have exhausted the namespace - if (!*n) - break; - } - - // Search in parent parser if available - if (parser->parent) - return pakfire_parser_get_raw(parser->parent, namespace, name); + // Otherwise we walk up the namespace to find a match + d = pakfire_parser_find_declaration(parser, namespace, name); + if (d && d->value) + return d->value; return NULL; } @@ -356,6 +382,9 @@ PAKFIRE_EXPORT int pakfire_parser_append(PakfireParser parser, // Fetch the value of the current declaration const char* old_value = pakfire_parser_get_raw(parser, namespace, name); + DEBUG(parser->pakfire, "%p: Old value for %s.%s = %s\n", + parser, namespace, name, old_value); + // Set the new value when there is no old one if (!old_value) return pakfire_parser_set(parser, namespace, name, value); diff --git a/src/libpakfire/parser/grammar.y b/src/libpakfire/parser/grammar.y index b94b11b0d..07486fa5b 100644 --- a/src/libpakfire/parser/grammar.y +++ b/src/libpakfire/parser/grammar.y @@ -165,7 +165,6 @@ static void pakfire_parser_free_declaration(struct pakfire_parser_declaration* d } %initial-action { - //*parser = pakfire_parser_ref(parent); *parser = pakfire_parser_create(pakfire, parent, NULL, 0); };