Re: [libvirt] [PATCH 08/14] Add a virKeyfilePtr object for parsing '.ini' files
On 03/23/2012 08:16 PM, Daniel P. Berrange wrote: On Thu, Mar 22, 2012 at 05:34:54PM +0800, Osier Yang wrote: On 2012年03月21日 01:33, Daniel P. Berrange wrote: From: "Daniel P. Berrange" +static int virKeyFileParseValue(virKeyFileParserCtxtPtr ctxt) +{ +int ret = -1; +const char *keystart; +const char *valuestart; +char *key = NULL; +char *value = NULL; +size_t len; + +if (!ctxt->groupname || !ctxt->group) { +virKeyFileError(ctxt, VIR_ERR_CONF_SYNTAX, "value found before first group"); +return -1; +} + +keystart = ctxt->cur; +while (!IS_EOF&& c_isalnum(CUR)&& CUR != '=') +ctxt->cur++; +if (CUR != '=') { +virKeyFileError(ctxt, VIR_ERR_CONF_SYNTAX, "expected end of value name, expected '='"); +return -1; +} + +if (!(key = strndup(keystart, ctxt->cur - keystart))) { +virReportOOMError(); +return -1; +} + +NEXT; +valuestart = ctxt->cur; +while (!IS_EOF&& !IS_EOL(CUR)) +ctxt->cur++; +if (!(IS_EOF || IS_EOL(CUR))) { +virKeyFileError(ctxt, VIR_ERR_CONF_SYNTAX, "unexpected end of value"); +goto cleanup; +} +len = ctxt->cur - valuestart; +if (IS_EOF&& !IS_EOL(CUR)) +len++; +if (!(value = strndup(valuestart, len))) { +virReportOOMError(); +goto cleanup; +} + +if (virHashAddEntry(ctxt->group, key, value)< 0) +goto cleanup; I meant here. Perhaps I commented at wrong place. + +NEXT; + +ret = 0; + +cleanup: +VIR_FREE(key); Do we need to VIR_FREE(value) too? No, the value is owned by the hash table now How about virHashAddEntry fails? :-) Osier -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 08/14] Add a virKeyfilePtr object for parsing '.ini' files
On Thu, Mar 22, 2012 at 05:34:54PM +0800, Osier Yang wrote: > On 2012年03月21日 01:33, Daniel P. Berrange wrote: > >From: "Daniel P. Berrange" > >+static int virKeyFileParseValue(virKeyFileParserCtxtPtr ctxt) > >+{ > >+int ret = -1; > >+const char *keystart; > >+const char *valuestart; > >+char *key = NULL; > >+char *value = NULL; > >+size_t len; > >+ > >+if (!ctxt->groupname || !ctxt->group) { > >+virKeyFileError(ctxt, VIR_ERR_CONF_SYNTAX, "value found before > >first group"); > >+return -1; > >+} > >+ > >+keystart = ctxt->cur; > >+while (!IS_EOF&& c_isalnum(CUR)&& CUR != '=') > >+ctxt->cur++; > >+if (CUR != '=') { > >+virKeyFileError(ctxt, VIR_ERR_CONF_SYNTAX, "expected end of value > >name, expected '='"); > >+return -1; > >+} > >+ > >+if (!(key = strndup(keystart, ctxt->cur - keystart))) { > >+virReportOOMError(); > >+return -1; > >+} > >+ > >+NEXT; > >+valuestart = ctxt->cur; > >+while (!IS_EOF&& !IS_EOL(CUR)) > >+ctxt->cur++; > >+if (!(IS_EOF || IS_EOL(CUR))) { > >+virKeyFileError(ctxt, VIR_ERR_CONF_SYNTAX, "unexpected end of > >value"); > >+goto cleanup; > >+} > >+len = ctxt->cur - valuestart; > >+if (IS_EOF&& !IS_EOL(CUR)) > >+len++; > >+if (!(value = strndup(valuestart, len))) { > >+virReportOOMError(); > >+goto cleanup; > >+} > >+ > >+if (virHashAddEntry(ctxt->group, key, value)< 0) > >+goto cleanup; > >+ > >+NEXT; > >+ > >+ret = 0; > >+ > >+cleanup: > >+VIR_FREE(key); > > Do we need to VIR_FREE(value) too? No, the value is owned by the hash table now Daniel -- |: http://berrange.com -o-http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
Re: [libvirt] [PATCH 08/14] Add a virKeyfilePtr object for parsing '.ini' files
On 2012年03月21日 01:33, Daniel P. Berrange wrote: From: "Daniel P. Berrange" The '.ini' file format is a useful alternative to the existing config file style, when you need to have config files which are hashes of hashes. The 'virKeyFilePtr' object provides a way to parse these file types. * src/Makefile.am, src/util/virkeyfile.c, src/util/virkeyfile.h: Add .ini file parser * tests/Makefile.am, tests/virkeyfiletest.c: Test basic parsing capabilities --- po/POTFILES.in |1 + src/Makefile.am |1 + src/libvirt_private.syms | 10 ++ src/util/virkeyfile.c| 367 ++ src/util/virkeyfile.h| 64 tests/Makefile.am|8 +- tests/virkeyfiletest.c | 123 7 files changed, 573 insertions(+), 1 deletions(-) create mode 100644 src/util/virkeyfile.c create mode 100644 src/util/virkeyfile.h create mode 100644 tests/virkeyfiletest.c diff --git a/po/POTFILES.in b/po/POTFILES.in index 16a3f9e..8354c09 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -127,6 +127,7 @@ src/util/util.c src/util/viraudit.c src/util/virfile.c src/util/virhash.c +src/util/virkeyfile.c src/util/virnetdev.c src/util/virnetdevbridge.c src/util/virnetdevmacvlan.c diff --git a/src/Makefile.am b/src/Makefile.am index 39076cc..07d7faa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,6 +90,7 @@ UTIL_SOURCES = \ util/virhash.c util/virhash.h \ util/virhashcode.c util/virhashcode.h \ util/virkeycode.c util/virkeycode.h \ + util/virkeyfile.c util/virkeyfile.h \ util/virkeymaps.h \ util/virmacaddr.h util/virmacaddr.c \ util/virnetdev.h util/virnetdev.c \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8a14838..3f69ec1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1198,6 +1198,16 @@ virKeycodeValueFromString; virKeycodeValueTranslate; +# virkeyfile.h +virKeyFileNew; +virKeyFileLoadFile; +virKeyFileLoadData; +virKeyFileFree; +virKeyFileHasValue; +virKeyFileHasGroup; +virKeyFileGetValueString; Again, the sorting, per all the strings are sorted now. :-) + + # virmacaddr.h virMacAddrCompare; virMacAddrFormat; diff --git a/src/util/virkeyfile.c b/src/util/virkeyfile.c new file mode 100644 index 000..3dd4960 --- /dev/null +++ b/src/util/virkeyfile.c @@ -0,0 +1,367 @@ +/* + * virkeyfile.c: "ini"-style configuration file handling + * + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Daniel P. Berrange + */ + +#include + +#include + +#include "c-ctype.h" +#include "logging.h" +#include "memory.h" +#include "util.h" +#include "virhash.h" +#include "virkeyfile.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_CONF + +typedef struct _virKeyFileGroup virKeyFileGroup; +typedef virKeyFileGroup *virKeyFileGroupPtr; + +typedef struct _virKeyFileParserCtxt virKeyFileParserCtxt; +typedef virKeyFileParserCtxt *virKeyFileParserCtxtPtr; + +struct _virKeyFile { +virHashTablePtr groups; +}; + +struct _virKeyFileParserCtxt { +virKeyFilePtr conf; + +const char *filename; + +const char *base; +const char *cur; +const char *end; +size_t line; + +char *groupname; +virHashTablePtr group; +}; + +/* + * The grammar for the keyfile + * + * KEYFILE = (GROUP | COMMENT | BLANK )* + * + * COMMENT = ('#' | ';') [^\n]* '\n' + * BLANK = (' ' | '\t' )* '\n' + * + * GROUP = '[' GROUPNAME ']' '\n' (ENTRY ) * + * GROUPNAME = [^[]\n]+ + * + * ENTRY = KEYNAME '=' VALUE + * VALUE = [^\n]* '\n' + * KEYNAME = [-a-zA-Z0-9]+ + */ + +#define IS_EOF (ctxt->cur>= ctxt->end) +#define IS_EOL(c) (((c) == '\n') || ((c) == '\r')) +#define CUR (*ctxt->cur) +#define NEXT if (!IS_EOF) ctxt->cur++; + + +#define virKeyFileError(ctxt, error, info) \ +virKeyFileErrorHelper(__FILE__, __FUNCTION__, __LINE__, ctxt, error, info) +static void +virKeyFileErrorHelper(const char *file, const char *func, size_t line, +
[libvirt] [PATCH 08/14] Add a virKeyfilePtr object for parsing '.ini' files
From: "Daniel P. Berrange" The '.ini' file format is a useful alternative to the existing config file style, when you need to have config files which are hashes of hashes. The 'virKeyFilePtr' object provides a way to parse these file types. * src/Makefile.am, src/util/virkeyfile.c, src/util/virkeyfile.h: Add .ini file parser * tests/Makefile.am, tests/virkeyfiletest.c: Test basic parsing capabilities --- po/POTFILES.in |1 + src/Makefile.am |1 + src/libvirt_private.syms | 10 ++ src/util/virkeyfile.c| 367 ++ src/util/virkeyfile.h| 64 tests/Makefile.am|8 +- tests/virkeyfiletest.c | 123 7 files changed, 573 insertions(+), 1 deletions(-) create mode 100644 src/util/virkeyfile.c create mode 100644 src/util/virkeyfile.h create mode 100644 tests/virkeyfiletest.c diff --git a/po/POTFILES.in b/po/POTFILES.in index 16a3f9e..8354c09 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -127,6 +127,7 @@ src/util/util.c src/util/viraudit.c src/util/virfile.c src/util/virhash.c +src/util/virkeyfile.c src/util/virnetdev.c src/util/virnetdevbridge.c src/util/virnetdevmacvlan.c diff --git a/src/Makefile.am b/src/Makefile.am index 39076cc..07d7faa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -90,6 +90,7 @@ UTIL_SOURCES = \ util/virhash.c util/virhash.h \ util/virhashcode.c util/virhashcode.h \ util/virkeycode.c util/virkeycode.h \ + util/virkeyfile.c util/virkeyfile.h \ util/virkeymaps.h \ util/virmacaddr.h util/virmacaddr.c \ util/virnetdev.h util/virnetdev.c \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8a14838..3f69ec1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1198,6 +1198,16 @@ virKeycodeValueFromString; virKeycodeValueTranslate; +# virkeyfile.h +virKeyFileNew; +virKeyFileLoadFile; +virKeyFileLoadData; +virKeyFileFree; +virKeyFileHasValue; +virKeyFileHasGroup; +virKeyFileGetValueString; + + # virmacaddr.h virMacAddrCompare; virMacAddrFormat; diff --git a/src/util/virkeyfile.c b/src/util/virkeyfile.c new file mode 100644 index 000..3dd4960 --- /dev/null +++ b/src/util/virkeyfile.c @@ -0,0 +1,367 @@ +/* + * virkeyfile.c: "ini"-style configuration file handling + * + * Copyright (C) 2012 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: + * Daniel P. Berrange + */ + +#include + +#include + +#include "c-ctype.h" +#include "logging.h" +#include "memory.h" +#include "util.h" +#include "virhash.h" +#include "virkeyfile.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_CONF + +typedef struct _virKeyFileGroup virKeyFileGroup; +typedef virKeyFileGroup *virKeyFileGroupPtr; + +typedef struct _virKeyFileParserCtxt virKeyFileParserCtxt; +typedef virKeyFileParserCtxt *virKeyFileParserCtxtPtr; + +struct _virKeyFile { +virHashTablePtr groups; +}; + +struct _virKeyFileParserCtxt { +virKeyFilePtr conf; + +const char *filename; + +const char *base; +const char *cur; +const char *end; +size_t line; + +char *groupname; +virHashTablePtr group; +}; + +/* + * The grammar for the keyfile + * + * KEYFILE = (GROUP | COMMENT | BLANK )* + * + * COMMENT = ('#' | ';') [^\n]* '\n' + * BLANK = (' ' | '\t' )* '\n' + * + * GROUP = '[' GROUPNAME ']' '\n' (ENTRY ) * + * GROUPNAME = [^[]\n]+ + * + * ENTRY = KEYNAME '=' VALUE + * VALUE = [^\n]* '\n' + * KEYNAME = [-a-zA-Z0-9]+ + */ + +#define IS_EOF (ctxt->cur >= ctxt->end) +#define IS_EOL(c) (((c) == '\n') || ((c) == '\r')) +#define CUR (*ctxt->cur) +#define NEXT if (!IS_EOF) ctxt->cur++; + + +#define virKeyFileError(ctxt, error, info) \ +virKeyFileErrorHelper(__FILE__, __FUNCTION__, __LINE__, ctxt, error, info) +static void +virKeyFileErrorHelper(const char *file, const char *func, size_t line, + virKeyFileParserCtxtPtr ctxt, + virErrorNumber error, const char *info) +{ +/* Construct the