MINOR: pattern/map/acl: Centralization of the file parsers
The acl and map function do the same work with the file parsing. This patch merge these code in only one. Note that the function map_read_entries_from_file() in the file "map.c" is moved to the the function pat_ref_read_from_file_smp() in the file "pattern.c". The code of this function is not modified, only the the name and the arguments order has changed.
This commit is contained in:
parent
9356c68727
commit
39bef456fb
|
@ -186,7 +186,7 @@ int pat_ref_load(struct pat_ref *ref, struct pattern_expr *expr, int patflags, i
|
|||
*/
|
||||
void pattern_init_head(struct pattern_head *head);
|
||||
void pattern_prune(struct pattern_head *head);
|
||||
int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, const char *filename, int patflags, char **err, const char *display);
|
||||
int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, const char *filename, int patflags, int load_smp, char **err, const char *display);
|
||||
|
||||
/*
|
||||
* pattern_expr manipulation.
|
||||
|
|
|
@ -451,7 +451,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list *
|
|||
snprintf(trash.str, trash.size, "acl(s) loaded from file '%s'", args[1]);
|
||||
trash.str[trash.size - 1] = '\0';
|
||||
|
||||
if (!pattern_read_from_file(&expr->pat, PAT_REF_ACL, args[1], patflags | PAT_F_FROM_FILE, err, trash.str))
|
||||
if (!pattern_read_from_file(&expr->pat, PAT_REF_ACL, args[1], patflags | PAT_F_FROM_FILE, 0, err, trash.str))
|
||||
goto out_free_expr;
|
||||
is_loaded = 1;
|
||||
args++;
|
||||
|
|
134
src/map.c
134
src/map.c
|
@ -108,107 +108,6 @@ static struct map_descriptor *map_create_descriptor(struct sample_conv *conv)
|
|||
return desc;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* The file contains one key + value per line. Lines which start with '#' are
|
||||
* ignored, just like empty lines. Leading tabs/spaces are stripped. The key is
|
||||
* then the first "word" (series of non-space/tabs characters), and the value is
|
||||
* what follows this series of space/tab till the end of the line excluding
|
||||
* trailing spaces/tabs.
|
||||
*
|
||||
* Example :
|
||||
*
|
||||
* # this is a comment and is ignored
|
||||
* 62.212.114.60 1wt.eu \n
|
||||
* <-><-----------><---><----><---->
|
||||
* | | | | `--- trailing spaces ignored
|
||||
* | | | `-------- value
|
||||
* | | `--------------- middle spaces ignored
|
||||
* | `------------------------ key
|
||||
* `-------------------------------- leading spaces ignored
|
||||
*
|
||||
* Return non-zero in case of succes, otherwise 0.
|
||||
*/
|
||||
static int map_read_entries_from_file(const char *filename,
|
||||
struct pat_ref *ref,
|
||||
char **err)
|
||||
{
|
||||
FILE *file;
|
||||
char *c;
|
||||
int ret = 0;
|
||||
int line = 0;
|
||||
char *key_beg;
|
||||
char *key_end;
|
||||
char *value_beg;
|
||||
char *value_end;
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
memprintf(err, "failed to open pattern file <%s>", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* now parse all patterns. The file may contain only one pattern
|
||||
* followed by one value per line. The start spaces, separator spaces
|
||||
* and and spaces are stripped. Each can contain comment started by '#'
|
||||
*/
|
||||
while (fgets(trash.str, trash.size, file) != NULL) {
|
||||
line++;
|
||||
c = trash.str;
|
||||
|
||||
/* ignore lines beginning with a dash */
|
||||
if (*c == '#')
|
||||
continue;
|
||||
|
||||
/* strip leading spaces and tabs */
|
||||
while (*c == ' ' || *c == '\t')
|
||||
c++;
|
||||
|
||||
/* empty lines are ignored too */
|
||||
if (*c == '\0' || *c == '\r' || *c == '\n')
|
||||
continue;
|
||||
|
||||
/* look for the end of the key */
|
||||
key_beg = c;
|
||||
while (*c && *c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
|
||||
c++;
|
||||
|
||||
key_end = c;
|
||||
|
||||
/* strip middle spaces and tabs */
|
||||
while (*c == ' ' || *c == '\t')
|
||||
c++;
|
||||
|
||||
/* look for the end of the value, it is the end of the line */
|
||||
value_beg = c;
|
||||
while (*c && *c != '\n' && *c != '\r')
|
||||
c++;
|
||||
value_end = c;
|
||||
|
||||
/* trim possibly trailing spaces and tabs */
|
||||
while (value_end > value_beg && (value_end[-1] == ' ' || value_end[-1] == '\t'))
|
||||
value_end--;
|
||||
|
||||
/* set final \0 and check entries */
|
||||
*key_end = '\0';
|
||||
*value_end = '\0';
|
||||
|
||||
/* insert values */
|
||||
if (!pat_ref_append(ref, key_beg, value_beg, line)) {
|
||||
memprintf(err, "out of memory");
|
||||
goto out_close;
|
||||
}
|
||||
}
|
||||
|
||||
/* succes */
|
||||
ret = 1;
|
||||
|
||||
out_close:
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function load the map file according with data type declared into
|
||||
* the "struct sample_conv".
|
||||
*
|
||||
|
@ -217,28 +116,7 @@ static int map_read_entries_from_file(const char *filename,
|
|||
*/
|
||||
static int sample_load_map(struct arg *arg, struct sample_conv *conv, char **err)
|
||||
{
|
||||
struct pat_ref *ref;
|
||||
struct map_descriptor *desc;
|
||||
struct pattern_expr *expr;
|
||||
|
||||
/* look for existing map reference. The reference is the
|
||||
* file encountered in the first argument. arg[0] with string
|
||||
* type is guaranteed by the parser.
|
||||
*
|
||||
* If the reference dosn't exists, create it and load file.
|
||||
*/
|
||||
ref = pat_ref_lookup(arg[0].data.str.str);
|
||||
if (!ref) {
|
||||
snprintf(trash.str, trash.size, "map(s) loaded from file '%s'", arg[0].data.str.str);
|
||||
trash.str[trash.size - 1] = '\0';
|
||||
ref = pat_ref_new(arg[0].data.str.str, trash.str, PAT_REF_MAP);
|
||||
if (!ref) {
|
||||
memprintf(err, "out of memory");
|
||||
return 0;
|
||||
}
|
||||
if (!map_read_entries_from_file(arg[0].data.str.str, ref, err))
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create new map descriptor */
|
||||
desc = map_create_descriptor(conv);
|
||||
|
@ -273,13 +151,13 @@ static int sample_load_map(struct arg *arg, struct sample_conv *conv, char **err
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Create new pattern expression for this reference. */
|
||||
expr = pattern_new_expr(&desc->pat, ref, err);
|
||||
if (!expr)
|
||||
return 0;
|
||||
/* Build displayed message. */
|
||||
snprintf(trash.str, trash.size, "map(s) loaded from file '%s'", arg[0].data.str.str);
|
||||
trash.str[trash.size - 1] = '\0';
|
||||
|
||||
/* Load the reference content in the pattern expression. */
|
||||
if (!pat_ref_load(ref, expr, 0, 1, err))
|
||||
/* Load map. */
|
||||
if (!pattern_read_from_file(&desc->pat, PAT_REF_MAP, arg[0].data.str.str, 0,
|
||||
1, err, trash.str))
|
||||
return 0;
|
||||
|
||||
/* The second argument is the default value */
|
||||
|
|
149
src/pattern.c
149
src/pattern.c
|
@ -1696,27 +1696,6 @@ void pat_ref_prune(struct pat_ref *ref)
|
|||
expr->pat_head->prune(expr);
|
||||
}
|
||||
|
||||
/* This function browse <ref> and try to index each entries in the <expr>.
|
||||
* If the flag <soe> (stop on error) is set, this function stop on the first
|
||||
* error, <err> is filled and return 0. If is not set, the function try to
|
||||
* load each entries and 1 is always returned.
|
||||
*/
|
||||
int pat_ref_load(struct pat_ref *ref, struct pattern_expr *expr,
|
||||
int patflags, int soe, char **err)
|
||||
{
|
||||
struct pat_ref_elt *elt;
|
||||
|
||||
list_for_each_entry(elt, &ref->head, list) {
|
||||
if (soe && !pat_ref_push(elt, expr, patflags, err)) {
|
||||
if (elt->line > 0)
|
||||
memprintf(err, "%s at line %d of file '%s'",
|
||||
*err, elt->line, ref->reference);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This function lookup for existing reference <ref> in pattern_head <head>. */
|
||||
struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_ref *ref)
|
||||
{
|
||||
|
@ -1802,6 +1781,105 @@ struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref
|
|||
return expr;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* The file contains one key + value per line. Lines which start with '#' are
|
||||
* ignored, just like empty lines. Leading tabs/spaces are stripped. The key is
|
||||
* then the first "word" (series of non-space/tabs characters), and the value is
|
||||
* what follows this series of space/tab till the end of the line excluding
|
||||
* trailing spaces/tabs.
|
||||
*
|
||||
* Example :
|
||||
*
|
||||
* # this is a comment and is ignored
|
||||
* 62.212.114.60 1wt.eu \n
|
||||
* <-><-----------><---><----><---->
|
||||
* | | | | `--- trailing spaces ignored
|
||||
* | | | `-------- value
|
||||
* | | `--------------- middle spaces ignored
|
||||
* | `------------------------ key
|
||||
* `-------------------------------- leading spaces ignored
|
||||
*
|
||||
* Return non-zero in case of succes, otherwise 0.
|
||||
*/
|
||||
int pat_ref_read_from_file_smp(struct pat_ref *ref, const char *filename, char **err)
|
||||
{
|
||||
FILE *file;
|
||||
char *c;
|
||||
int ret = 0;
|
||||
int line = 0;
|
||||
char *key_beg;
|
||||
char *key_end;
|
||||
char *value_beg;
|
||||
char *value_end;
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
memprintf(err, "failed to open pattern file <%s>", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* now parse all patterns. The file may contain only one pattern
|
||||
* followed by one value per line. The start spaces, separator spaces
|
||||
* and and spaces are stripped. Each can contain comment started by '#'
|
||||
*/
|
||||
while (fgets(trash.str, trash.size, file) != NULL) {
|
||||
line++;
|
||||
c = trash.str;
|
||||
|
||||
/* ignore lines beginning with a dash */
|
||||
if (*c == '#')
|
||||
continue;
|
||||
|
||||
/* strip leading spaces and tabs */
|
||||
while (*c == ' ' || *c == '\t')
|
||||
c++;
|
||||
|
||||
/* empty lines are ignored too */
|
||||
if (*c == '\0' || *c == '\r' || *c == '\n')
|
||||
continue;
|
||||
|
||||
/* look for the end of the key */
|
||||
key_beg = c;
|
||||
while (*c && *c != ' ' && *c != '\t' && *c != '\n' && *c != '\r')
|
||||
c++;
|
||||
|
||||
key_end = c;
|
||||
|
||||
/* strip middle spaces and tabs */
|
||||
while (*c == ' ' || *c == '\t')
|
||||
c++;
|
||||
|
||||
/* look for the end of the value, it is the end of the line */
|
||||
value_beg = c;
|
||||
while (*c && *c != '\n' && *c != '\r')
|
||||
c++;
|
||||
value_end = c;
|
||||
|
||||
/* trim possibly trailing spaces and tabs */
|
||||
while (value_end > value_beg && (value_end[-1] == ' ' || value_end[-1] == '\t'))
|
||||
value_end--;
|
||||
|
||||
/* set final \0 and check entries */
|
||||
*key_end = '\0';
|
||||
*value_end = '\0';
|
||||
|
||||
/* insert values */
|
||||
if (!pat_ref_append(ref, key_beg, value_beg, line)) {
|
||||
memprintf(err, "out of memory");
|
||||
goto out_close;
|
||||
}
|
||||
}
|
||||
|
||||
/* succes */
|
||||
ret = 1;
|
||||
|
||||
out_close:
|
||||
fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
|
@ -1859,11 +1937,12 @@ int pat_ref_read_from_file(struct pat_ref *ref, const char *filename, char **err
|
|||
}
|
||||
|
||||
int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
|
||||
const char *filename, int patflags,
|
||||
const char *filename, int patflags, int load_smp,
|
||||
char **err, const char *display)
|
||||
{
|
||||
struct pat_ref *ref;
|
||||
struct pattern_expr *expr;
|
||||
struct pat_ref_elt *elt;
|
||||
|
||||
/* Lookup for the existing reference. */
|
||||
ref = pat_ref_lookup(filename);
|
||||
|
@ -1876,8 +1955,18 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!pat_ref_read_from_file(ref, filename, err))
|
||||
return 0;
|
||||
if (load_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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* The reference already exists, Merge flags. */
|
||||
ref->flags |= refflags;
|
||||
}
|
||||
|
||||
/* Now, we can loading patterns from the reference. */
|
||||
|
@ -1892,9 +1981,15 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Load reference content in expression. */
|
||||
if (!pat_ref_load(ref, expr, patflags, 1, err))
|
||||
return 0;
|
||||
/* Load reference content in the pattern expression. */
|
||||
list_for_each_entry(elt, &ref->head, list) {
|
||||
if (!pat_ref_push(elt, expr, patflags, err)) {
|
||||
if (elt->line > 0)
|
||||
memprintf(err, "%s at line %d of file '%s'",
|
||||
*err, elt->line, filename);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue