// Enable to get more debugging output
//#define PAKFIRE_DEBUG_PARSER
+// Regular expressions
+static struct pakfire_parser_regexes {
+ pcre2_code* variable;
+ pcre2_code* command;
+} regexes = {};
+
struct pakfire_parser {
struct pakfire_ctx* ctx;
struct pakfire* pakfire;
struct pakfire_parser_declaration** declarations;
size_t num_declarations;
-
- // Regular expressions
- pcre2_code* regex_command;
- pcre2_code* regex_variable;
};
-static int pakfire_parser_compile_regexes(struct pakfire_parser* parser) {
- int r;
-
- // Commands
- if (!parser->regex_command && (parser->flags & PAKFIRE_PARSER_FLAGS_EXPAND_COMMANDS)) {
- r = pakfire_compile_regex(parser->ctx, &parser->regex_command,
- "%(\\(((?>[^()]|(?1))*)\\))");
- if (r)
- return r;
- }
-
- // Variables
- if (!parser->regex_variable) {
- r = pakfire_compile_regex(parser->ctx, &parser->regex_variable,
- "%\\{([A-Za-z0-9_\\-]+)\\}");
- if (r)
- return r;
- }
-
- return 0;
-}
-
static void pakfire_parser_free_declaration(struct pakfire_parser_declaration* d) {
if (d->value)
free(d->value);
}
static void pakfire_parser_free(struct pakfire_parser* parser) {
- // Release regular expressions
- if (parser->regex_variable)
- pcre2_code_free(parser->regex_variable);
- if (parser->regex_command)
- pcre2_code_free(parser->regex_command);
-
pakfire_parser_free_declarations(parser);
if (parser->namespace)
}
static int pakfire_parser_expand_commands(struct pakfire_parser* parser, char** buffer) {
- int r = 0;
+ pcre2_match_data* match = NULL;
PCRE2_UCHAR* command = NULL;
PCRE2_SIZE command_length;
PCRE2_UCHAR* pattern = NULL;
PCRE2_SIZE pattern_length;
+ int r = 0;
DEBUG(parser->ctx, "Searching for commands in:\n%s\n", *buffer);
+ // Compile the regular expression
+ if (!regexes.command) {
+ r = pakfire_compile_regex(parser->ctx, ®exes.command, "%(\\(((?>[^()]|(?1))*)\\))");
+ if (r < 0) {
+ ERROR(parser->ctx, "Failed to compile the command regex: %s\n", strerror(-r));
+ goto ERROR;
+ }
+ }
+
// Allocate memory for results
- pcre2_match_data* match = pcre2_match_data_create_from_pattern(
- parser->regex_command, NULL);
+ match = pcre2_match_data_create_from_pattern(regexes.command, NULL);
// Arguments passed to pakfire_execute
const char* argv[4] = {
"/bin/sh", "-c", NULL /* will be replaced by command later */, NULL,
};
- while (1) {
+ for (;;) {
// Perform matching
- r = pcre2_jit_match(parser->regex_command,
+ r = pcre2_jit_match(regexes.command,
(PCRE2_UCHAR*)*buffer, strlen(*buffer), 0, 0, match, NULL);
// End loop when we have expanded all variables
}
ERROR:
- pcre2_match_data_free(match);
-
+ if (match)
+ pcre2_match_data_free(match);
if (command)
pcre2_substring_free(command);
if (pattern)
static int pakfire_parser_expand_variables(struct pakfire_parser* parser,
const char* namespace, char** buffer) {
+ pcre2_match_data* match = NULL;
PCRE2_UCHAR* variable = NULL;
PCRE2_SIZE variable_length = 0;
PCRE2_UCHAR* pattern = NULL;
else if (!*buffer)
return 0;
+ // Compile the regular expression
+ if (!regexes.variable) {
+ r = pakfire_compile_regex(parser->ctx, ®exes.variable, "%\\{([A-Za-z0-9_\\-]+)\\}");
+ if (r < 0) {
+ ERROR(parser->ctx, "Failed to compile the variable regex: %s\n", strerror(-r));
+ goto ERROR;
+ }
+ }
+
// Allocate memory for results
- pcre2_match_data* match = pcre2_match_data_create_from_pattern(
- parser->regex_variable, NULL);
+ match = pcre2_match_data_create_from_pattern(regexes.variable, NULL);
// Search for any variables
- while (1) {
+ for (;;) {
// Perform matching
- r = pcre2_jit_match(parser->regex_variable,
+ r = pcre2_jit_match(regexes.variable,
(PCRE2_UCHAR*)*buffer, strlen(*buffer), 0, 0, match, NULL);
// End loop when we have expanded all variables
char* pakfire_parser_expand(struct pakfire_parser* parser,
const char* namespace, const char* value) {
+ int r;
+
// Return NULL when the value is NULL
if (!value)
return NULL;
if (!pos)
return buffer;
- // Compile all regular expressions
- int r = pakfire_parser_compile_regexes(parser);
- if (r) {
- DEBUG(parser->ctx, "Could not compile regular expressions: %m\n");
- goto ERROR;
- }
-
// Expand all variables
r = pakfire_parser_expand_variables(parser, namespace, &buffer);
if (r) {