int pakfire_string_startswith(const char* s, const char* prefix);
int pakfire_string_endswith(const char* s, const char* suffix);
+int pakfire_string_matches(const char* s, const char* pattern);
char* pakfire_unquote_in_place(char* s);
int pakfire_string_partition(const char* s, const char* delim, char** s1, char** s2);
char* pakfire_string_replace(const char* s, const char* pattern, const char* repl);
if (!namespace)
namespace = "";
+ if (namespace)
+ DEBUG(parser->pakfire, "Looking up %s.%s\n", namespace, name);
+ else
+ DEBUG(parser->pakfire, "Looking up %s\n", name);
+
struct pakfire_parser_declaration* d;
for (unsigned i = 0; i < parser->num_declarations; i++) {
d = parser->declarations[i];
d = pakfire_parser_get_declaration(parser, namespace, name);
// Return a match when it actually contains a string
- if (d)
+ if (d && d->value)
return d->value;
// We are done, if the namespace is empty
if (*template) {
d = pakfire_parser_get_declaration(parser, template, name);
- if (d)
+ if (d && d->value)
return d->value;
}
}
pakfire_parser_strip_namespace(&n);
d = pakfire_parser_get_declaration(parser, n, name);
- if (d)
+ if (d && d->value)
return d->value;
// End if we have exhausted the namespace
break;
}
+ // Find the entire matched pattern
+ r = pcre2_substring_get_bynumber(match, 0, &pattern, &pattern_length);
+ if (r)
+ goto ERROR;
+
// Find the variable name
r = pcre2_substring_get_bynumber(match, 1, &variable, &variable_length);
if (r)
// Search for a declaration of this variable
const char* repl = pakfire_parser_get_raw(parser, namespace, (const char*)variable);
+ // Is this a recursive pattern?
+ if (repl && pakfire_string_matches(repl, (const char*)pattern)) {
+ DEBUG(parser->pakfire, "Recursion detected in %s\n", pattern);
+
+ // Move up one step and lookup there
+ if (namespace && *namespace) {
+ char* parent_namespace = strdupa(namespace);
+ pakfire_parser_strip_namespace(&parent_namespace);
+
+ repl = pakfire_parser_get_raw(parser, parent_namespace, (const char*)variable);
+
+ // If we have already reached the top namespace, we replace with an empty string
+ } else {
+ repl = NULL;
+ }
+ }
+
// What is its value?
if (repl) {
DEBUG(parser->pakfire, "Replacing %%{%s} with '%s'\n", variable, repl);
DEBUG(parser->pakfire, "Replacing %%{%s} with an empty string\n", variable);
}
- // Find the entire matched pattern
- r = pcre2_substring_get_bynumber(match, 0, &pattern, &pattern_length);
- if (r)
- goto ERROR;
-
// Replace all occurrences
char* tmp = pakfire_string_replace(*buffer, (const char*)pattern, (repl) ? repl : "");
if (!tmp)
int r = pakfire_string_partition($1, ":", &key, &value);
if (r == 0) {
if (strcmp("package", key) == 0) {
- char* name = pakfire_parser_expand($$, NULL, value);
- if (name) {
- pakfire_parser_set($$, NULL, "name", name);
- free(name);
- }
+ pakfire_parser_set($$, NULL, "name", value);
}
if (key)