From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Dumitrescu, Cristian" Subject: Re: [PATCH v3 3/6] cfgfile: add support for configurable comment character Date: Wed, 29 Mar 2017 09:22:38 +0000 Message-ID: <3EB4FA525960D640B5BDFFD6A3D89126527813FE@IRSMSX108.ger.corp.intel.com> References: <1489065060-98370-1-git-send-email-allain.legacy@windriver.com> <20170329004737.44249-1-allain.legacy@windriver.com> <20170329004737.44249-4-allain.legacy@windriver.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Cc: "dev@dpdk.org" , "yuanhan.liu@linux.intel.com" , "thomas.monjalon@6wind.com" To: "Legacy, Allain (Wind River)" , "Richardson, Bruce" Return-path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id BAB67D1F7 for ; Wed, 29 Mar 2017 11:22:42 +0200 (CEST) In-Reply-To: <20170329004737.44249-4-allain.legacy@windriver.com> Content-Language: en-US List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > -----Original Message----- > From: Allain Legacy [mailto:allain.legacy@windriver.com] > Sent: Wednesday, March 29, 2017 1:48 AM > To: Dumitrescu, Cristian ; Richardson, Bru= ce > > Cc: dev@dpdk.org; yuanhan.liu@linux.intel.com; > thomas.monjalon@6wind.com > Subject: [PATCH v3 3/6] cfgfile: add support for configurable comment > character >=20 > The current cfgfile comment character is hardcoded to ';'. This commit a > new API to allow the user to specify which comment character to use while > parsing the file. >=20 > This is to ease adoption by applications that have an existing > configuration file which may use a different comment character. For > instance, an application may already have a configuration file that uses > the '#' as the comment character. >=20 > The approach of using a new API with an extensible parameters structure > was > used rather than simply adding a new argument to the existing API to allo= w > for additional arguments to be introduced in the future. >=20 > Signed-off-by: Allain Legacy > --- > lib/librte_cfgfile/rte_cfgfile.c | 61 > ++++++++++++++++++++++++++++++++- > lib/librte_cfgfile/rte_cfgfile.h | 29 ++++++++++++++++ > test/test/test_cfgfile.c | 47 +++++++++++++++++++++++++ > test/test/test_cfgfiles/etc/sample2.ini | 12 +++++++ > 4 files changed, 148 insertions(+), 1 deletion(-) > create mode 100644 test/test/test_cfgfiles/etc/sample2.ini >=20 > diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cf= gfile.c > index 832fea829..63e34bbb0 100644 > --- a/lib/librte_cfgfile/rte_cfgfile.c > +++ b/lib/librte_cfgfile/rte_cfgfile.c > @@ -35,6 +35,7 @@ > #include > #include > #include > +#include > #include >=20 > #include "rte_cfgfile.h" > @@ -58,6 +59,25 @@ struct rte_cfgfile { > * for new entries do we add in */ > #define CFG_ALLOC_ENTRY_BATCH 16 >=20 > +/** > + * Default cfgfile load parameters. > + */ > +static const struct rte_cfgfile_parameters default_cfgfile_params =3D { > + .comment_character =3D CFG_DEFAULT_COMMENT_CHARACTER, > +}; > + > +/** > + * Defines the list of acceptable comment characters supported by this > + * library. > + */ > +static const char valid_comment_chars[] =3D { > + '!', > + '#', > + '%', > + ';', > + '@' > +}; > + > static unsigned > _strip(char *str, unsigned len) > { > @@ -85,9 +105,45 @@ _strip(char *str, unsigned len) > return newlen; > } >=20 > +static int > +rte_cfgfile_check_params(const struct rte_cfgfile_parameters *params) > +{ > + unsigned int valid_comment; > + unsigned int i; > + > + if (!params) { > + printf("Error - missing cfgfile parameters\n"); > + return -EINVAL; > + } > + > + valid_comment =3D 0; > + for (i =3D 0; i < RTE_DIM(valid_comment_chars); i++) { > + if (params->comment_character =3D=3D valid_comment_chars[i]) > { > + valid_comment =3D 1; > + break; > + } > + } > + > + if (valid_comment =3D=3D 0) { > + printf("Error - invalid comment characters %c\n", > + params->comment_character); > + return -ENOTSUP; > + } > + > + return 0; > +} > + > struct rte_cfgfile * > rte_cfgfile_load(const char *filename, int flags) > { > + return rte_cfgfile_load_with_params(filename, flags, > + &default_cfgfile_params); > +} > + > +struct rte_cfgfile * > +rte_cfgfile_load_with_params(const char *filename, int flags, > + const struct rte_cfgfile_parameters *params) > +{ > int allocated_sections =3D CFG_ALLOC_SECTION_BATCH; > int allocated_entries =3D 0; > int curr_section =3D -1; > @@ -96,6 +152,9 @@ rte_cfgfile_load(const char *filename, int flags) > int lineno =3D 0; > struct rte_cfgfile *cfg =3D NULL; >=20 > + if (rte_cfgfile_check_params(params)) > + return NULL; > + > FILE *f =3D fopen(filename, "r"); > if (f =3D=3D NULL) > return NULL; > @@ -132,7 +191,7 @@ rte_cfgfile_load(const char *filename, int flags) > "Check if line too long\n", lineno); > goto error1; > } > - pos =3D memchr(buffer, ';', sizeof(buffer)); > + pos =3D memchr(buffer, params->comment_character, > sizeof(buffer)); > if (pos !=3D NULL) { > *pos =3D '\0'; > len =3D pos - buffer; > diff --git a/lib/librte_cfgfile/rte_cfgfile.h b/lib/librte_cfgfile/rte_cf= gfile.h > index 0e805c268..a7cd3944e 100644 > --- a/lib/librte_cfgfile/rte_cfgfile.h > +++ b/lib/librte_cfgfile/rte_cfgfile.h > @@ -66,6 +66,12 @@ struct rte_cfgfile_entry { > char value[CFG_VALUE_LEN]; /**< Value */ > }; >=20 > +/** Configuration file operation optional arguments */ > +struct rte_cfgfile_parameters { > + char comment_character; > + /**< Config file comment character; one of '!', '#', '%', ';', '@' */ I think this comment should be placed above the structure field definition = (preferable) or on the same line, but not below. > +}; > + > /**@{ cfgfile load operation flags */ > /** > * Indicates that the file supports key value entries before the first d= efined > @@ -74,6 +80,9 @@ struct rte_cfgfile_entry { > #define CFG_FLAG_GLOBAL_SECTION (1 << 0) > /**@} */ >=20 > +/** Defines the default comment character used for parsing config files.= */ > +#define CFG_DEFAULT_COMMENT_CHARACTER ';' > + > /** > * Open config file > * > @@ -87,6 +96,26 @@ struct rte_cfgfile_entry { > struct rte_cfgfile *rte_cfgfile_load(const char *filename, int flags); >=20 > /** > + * Open config file with specified optional parameters. Use @see > + * rte_cfgfile_init_parameters to setup the default parameters. > + * Please update this comment, as there is no rte_cfgfile_init() function anym= ore. > + * @param filename > + * Config file name > + * @param flags > + * Config file flags > + * @param params > + * Additional configuration attributes. Must be configured with defau= lt > + * values prior to invoking this API. Same here. > + * @return > + * Handle to configuration file on success, NULL otherwise > + * @param > + * > + */ > +struct rte_cfgfile *rte_cfgfile_load_with_params(const char *filename, > + int flags, const struct rte_cfgfile_parameters *params); > + > + > +/** > * Get number of sections in config file > * > * @param cfg > diff --git a/test/test/test_cfgfile.c b/test/test/test_cfgfile.c > index ad293cc89..0478de59e 100644 > --- a/test/test/test_cfgfile.c > +++ b/test/test/test_cfgfile.c > @@ -130,6 +130,30 @@ test_cfgfile_sample1(void) > } >=20 > static int > +test_cfgfile_sample2(void) > +{ > + struct rte_cfgfile_parameters params; > + struct rte_cfgfile *cfgfile; > + int ret; > + > + /* override comment character */ > + memset(¶ms, 0, sizeof(params)); > + params.comment_character =3D '#'; > + > + cfgfile =3D rte_cfgfile_load_with_params(CFG_FILES_ETC > "/sample2.ini", 0, > + ¶ms); > + TEST_ASSERT_NOT_NULL(cfgfile, "Failed to parse sample2.ini"); > + > + ret =3D _test_cfgfile_sample(cfgfile); > + TEST_ASSERT_SUCCESS(ret, "Failed to validate sample file: %d", ret); > + > + ret =3D rte_cfgfile_close(cfgfile); > + TEST_ASSERT_SUCCESS(ret, "Failed to close cfgfile"); > + > + return 0; > +} > + > +static int > test_cfgfile_invalid_section_header(void) > { > struct rte_cfgfile *cfgfile; > @@ -141,6 +165,23 @@ test_cfgfile_invalid_section_header(void) > } >=20 > static int > +test_cfgfile_invalid_comment(void) > +{ > + struct rte_cfgfile_parameters params; > + struct rte_cfgfile *cfgfile; > + > + /* override comment character with an invalid one */ > + memset(¶ms, 0, sizeof(params)); > + params.comment_character =3D '$'; > + > + cfgfile =3D rte_cfgfile_load_with_params(CFG_FILES_ETC > "/sample2.ini", 0, > + ¶ms); > + TEST_ASSERT_NULL(cfgfile, "Expected failured did not occur"); > + > + return 0; > +} > + > +static int > test_cfgfile_invalid_key_value_pair(void) > { > struct rte_cfgfile *cfgfile; > @@ -219,9 +260,15 @@ test_cfgfile(void) > if (test_cfgfile_sample1()) > return -1; >=20 > + if (test_cfgfile_sample2()) > + return -1; > + > if (test_cfgfile_invalid_section_header()) > return -1; >=20 > + if (test_cfgfile_invalid_comment()) > + return -1; > + > if (test_cfgfile_invalid_key_value_pair()) > return -1; >=20 > diff --git a/test/test/test_cfgfiles/etc/sample2.ini > b/test/test/test_cfgfiles/etc/sample2.ini > new file mode 100644 > index 000000000..21075e976 > --- /dev/null > +++ b/test/test/test_cfgfiles/etc/sample2.ini > @@ -0,0 +1,12 @@ > +# this is a global comment > + > +[section1] > +# this is section 1 > +key1=3Dvalue1 > + > +[section2] > +# this is section 2 > +#key1=3Dvalue1 > +key2=3Dvalue2 > +key3=3Dvalue3 # this is key3 > +ignore-missing-separator > -- > 2.12.1