diff options
Diffstat (limited to '')
-rw-r--r-- | src/pattern.c | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/src/pattern.c b/src/pattern.c index 52dda5e..f07223f 100644 --- a/src/pattern.c +++ b/src/pattern.c @@ -1547,6 +1547,10 @@ struct pat_ref *pat_ref_lookup(const char *reference) { struct pat_ref *ref; + /* Skip file@ prefix, it is the default case. Can be mixed with ref omitting the prefix */ + if (strlen(reference) > 5 && strncmp(reference, "file@", 5) == 0) + reference += 5; + list_for_each_entry(ref, &pattern_reference, list) if (ref->reference && strcmp(reference, ref->reference) == 0) return ref; @@ -1834,6 +1838,22 @@ struct pat_ref *pat_ref_new(const char *reference, const char *display, unsigned } } + + if (strlen(reference) > 5 && strncmp(reference, "virt@", 5) == 0) + flags |= PAT_REF_ID; + else if (strlen(reference) > 4 && strncmp(reference, "opt@", 4) == 0) { + flags |= (PAT_REF_ID|PAT_REF_FILE); // Will be decided later + reference += 4; + } + else { + /* A file by default */ + flags |= PAT_REF_FILE; + /* Skip file@ prefix to be mixed with ref omitting the prefix */ + if (strlen(reference) > 5 && strncmp(reference, "file@", 5) == 0) + reference += 5; + } + + ref->reference = strdup(reference); if (!ref->reference) { free(ref->display); @@ -2239,7 +2259,7 @@ struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref * * Return non-zero in case of success, otherwise 0. */ -int pat_ref_read_from_file_smp(struct pat_ref *ref, const char *filename, char **err) +int pat_ref_read_from_file_smp(struct pat_ref *ref, char **err) { FILE *file; char *c; @@ -2250,11 +2270,17 @@ int pat_ref_read_from_file_smp(struct pat_ref *ref, const char *filename, char * char *value_beg; char *value_end; - file = fopen(filename, "r"); + file = fopen(ref->reference, "r"); if (!file) { - memprintf(err, "failed to open pattern file <%s>", filename); + if (ref->flags & PAT_REF_ID) { + /* file not found for an optional file, switch it to a virtual list of patterns */ + ref->flags &= ~PAT_REF_FILE; + return 1; + } + memprintf(err, "failed to open pattern file <%s>", ref->reference); return 0; } + ref->flags |= PAT_REF_FILE; /* now parse all patterns. The file may contain only one pattern * followed by one value per line. The start spaces, separator spaces @@ -2310,7 +2336,7 @@ int pat_ref_read_from_file_smp(struct pat_ref *ref, const char *filename, char * if (ferror(file)) { memprintf(err, "error encountered while reading <%s> : %s", - filename, strerror(errno)); + ref->reference, strerror(errno)); goto out_close; } /* success */ @@ -2324,7 +2350,7 @@ int pat_ref_read_from_file_smp(struct pat_ref *ref, const char *filename, char * /* Reads patterns from a file. If <err_msg> is non-NULL, an error message will * be returned there on errors and the caller will have to free it. */ -int pat_ref_read_from_file(struct pat_ref *ref, const char *filename, char **err) +int pat_ref_read_from_file(struct pat_ref *ref, char **err) { FILE *file; char *c; @@ -2332,9 +2358,14 @@ int pat_ref_read_from_file(struct pat_ref *ref, const char *filename, char **err int ret = 0; int line = 0; - file = fopen(filename, "r"); + file = fopen(ref->reference, "r"); if (!file) { - memprintf(err, "failed to open pattern file <%s>", filename); + if (ref->flags & PAT_REF_ID) { + /* file not found for an optional file, switch it to a virtual list of patterns */ + ref->flags &= ~PAT_REF_FILE; + return 1; + } + memprintf(err, "failed to open pattern file <%s>", ref->reference); return 0; } @@ -2365,14 +2396,14 @@ int pat_ref_read_from_file(struct pat_ref *ref, const char *filename, char **err continue; if (!pat_ref_append(ref, arg, NULL, line)) { - memprintf(err, "out of memory when loading patterns from file <%s>", filename); + memprintf(err, "out of memory when loading patterns from file <%s>", ref->reference); goto out_close; } } if (ferror(file)) { memprintf(err, "error encountered while reading <%s> : %s", - filename, strerror(errno)); + ref->reference, strerror(errno)); goto out_close; } ret = 1; /* success */ @@ -2406,14 +2437,16 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, return 0; } - if (load_smp) { - ref->flags |= PAT_REF_SMP; - if (!pat_ref_read_from_file_smp(ref, filename, err)) - return 0; - } - else { - if (!pat_ref_read_from_file(ref, filename, err)) - return 0; + if (ref->flags & PAT_REF_FILE) { + if (load_smp) { + ref->flags |= PAT_REF_SMP; + if (!pat_ref_read_from_file_smp(ref, err)) + return 0; + } + else { + if (!pat_ref_read_from_file(ref, err)) + return 0; + } } } else { @@ -2479,7 +2512,10 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, /* Load reference content in the pattern expression. * We need to load elements in the same order they were seen in the - * file as list-based matching types may rely on it. + * file. Indeed, some list-based matching types may rely on it as the + * list is positional, and for tree-based matching, even if the tree is + * content-based in case of duplicated keys we only want the first key + * in the file to be considered. */ list_for_each_entry(elt, &ref->head, list) { if (!pat_ref_push(elt, expr, patflags, err)) { |