]> git.ipfire.org Git - pakfire.git/commitdiff
parser: Fix lookup order
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 2 Jun 2021 15:09:17 +0000 (15:09 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 2 Jun 2021 15:09:17 +0000 (15:09 +0000)
This fixes that variables were sometimes not expanded correctly

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/parser.c
src/libpakfire/parser/grammar.y

index bd7304b6cbf08efefa09dba17a3f3b665fbede30..74c93a45e9aef64940a6e6ec2b27a3c0f7982b79 100644 (file)
@@ -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);
index b94b11b0d426beb117ad0622c39c996f6397b290..07486fa5b3144e96d2d9089078a684e14dec8cdb 100644 (file)
@@ -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);
 };