]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: pattern/map/acl: Centralization of the file parsers
authorThierry FOURNIER <tfournier@exceliance.fr>
Wed, 29 Jan 2014 12:29:45 +0000 (13:29 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 17 Mar 2014 17:06:08 +0000 (18:06 +0100)
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.

include/proto/pattern.h
src/acl.c
src/map.c
src/pattern.c

index c04daebb7cf8023d264978ef8dfc429d4b273d6a..450a8dbaca9153a18695e8d5851072fe91c3bb96 100644 (file)
@@ -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.
index b4bb5360478bde54f5d5bc48234b01967a3d1407..55761873690561fd30c2ccf654f6968b5934f77e 100644 (file)
--- a/src/acl.c
+++ b/src/acl.c
@@ -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++;
index f5cbee48bb9c506f3b0ae92d6abb6d63f6f27c2c..ea671512baa81a19200fe90375414f1697261f9c 100644 (file)
--- a/src/map.c
+++ b/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 */
index 806ad3f91ac865cd55526d30039fe6090e7e047a..7cab38930df06927906c68cd2b8469e5225e7b0b 100644 (file)
@@ -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;
 }