From 7b3fcfdcb3b54e3ba05769575152764c2cedcfef Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Sun, 10 Aug 2008 19:38:31 +0200 Subject: [PATCH 01/24] Configitem brainstorm --- src/backend/configitem.h | 107 +++++++++++++++++++++++++++++++++++++++ src/backend/configline.h | 56 ++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 src/backend/configitem.h create mode 100644 src/backend/configline.h diff --git a/src/backend/configitem.h b/src/backend/configitem.h new file mode 100644 index 000000000..a84013060 --- /dev/null +++ b/src/backend/configitem.h @@ -0,0 +1,107 @@ +/* + configitem.h - generalized hierachy of configuration items + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_CONFIGITEM_H +#define LUMIERA_CONFIGITEM_H + +//TODO: Support library includes// + + +//TODO: Forward declarations// +typedef struct lumiera_configitem_struct lumiera_configitem; +typedef struct lumiera_configitem* LumieraConfigitem; + + +//TODO: Lumiera header includes// + + +//TODO: System includes// +#include + + +/** + * @file + * configitems build a 3 level hierachy: + * + * 1. file: + * contain sections + * + * 2. section: + * [prefix suffix] + * contain lines + * + * 3. lines are + * comment: + * empty line or line only containing spaces and tabs + * line starting with spaces and tabs followed by a # + * directive: + * '@include name' or '@readonly' + * directives are only valid at the toplevel section [] + * configurationentry: + * 'key = value' or 'key < redirect' + */ + +//TODO: declarations go here// +struct lumiera_configitem_struct +{ + llist link; // all lines on the same hierachy level are linked here (see childs) + LumieraConfigitem parent; // parent section + llist childs; // root node for all lines below this hierachy + + llist lookup; // all lines with the same key are stacked up on the loockup + + char* line; // raw line as read in allocated here trailing \n will be replaced with \0 + char* key; // pointer into line to start of key + size_t key_size; + char* delim; // delimiter, value starts at delim+1 +}; + +/* +brainstorm: + +identify the type of a configitem: + +file: + parent == NULL + line = filename (might be NULL for virtual files) + delim = NULL +section: + *delim == ' ' or ']' + *key != '@' +comment: + *key == NULL +directive: + *key == '@' + *delim == ' ' +configurationentry: + *delim == '=' + +*/ + + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/backend/configline.h b/src/backend/configline.h new file mode 100644 index 000000000..91ad5f764 --- /dev/null +++ b/src/backend/configline.h @@ -0,0 +1,56 @@ +/* + configline.h - single lines from configfiles + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_CONFIGLINE_H +#define LUMIERA_CONFIGLINE_H + +//TODO: Support library includes// + + +//TODO: Forward declarations// + + +//TODO: Lumiera header includes// +#include "backend/configitem.h" + +//TODO: System includes// +#include + + +/** + * @file + */ + +//TODO: declarations go here// +struct lumiera_configline_struct +{ + lumiera_configitem line; +} + + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ From f0cf49d7531311c0c762e77fa1c7c943cbd8b599 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 11 Aug 2008 09:20:49 +0200 Subject: [PATCH 02/24] WIP configitem brainstorming --- src/backend/{configline.h => configentry.h} | 27 ++++++++++--- src/backend/configitem.h | 44 +++++++++++++++++++++ 2 files changed, 65 insertions(+), 6 deletions(-) rename src/backend/{configline.h => configentry.h} (67%) diff --git a/src/backend/configline.h b/src/backend/configentry.h similarity index 67% rename from src/backend/configline.h rename to src/backend/configentry.h index 91ad5f764..9af84a025 100644 --- a/src/backend/configline.h +++ b/src/backend/configentry.h @@ -1,5 +1,5 @@ /* - configline.h - single lines from configfiles + configentry.h - single entries from configfiles Copyright (C) Lumiera.org 2008, Christian Thaeter @@ -19,13 +19,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifndef LUMIERA_CONFIGLINE_H -#define LUMIERA_CONFIGLINE_H +#ifndef LUMIERA_CONFIGENTRY_H +#define LUMIERA_CONFIGENTRY_H //TODO: Support library includes// //TODO: Forward declarations// +typedef struct lumiera_configentry_struct lumiera_configentry; +typedef lumiera_configentry* LumieraConfigentry; //TODO: Lumiera header includes// @@ -40,10 +42,23 @@ */ //TODO: declarations go here// -struct lumiera_configline_struct +struct lumiera_configentry_struct { - lumiera_configitem line; -} + lumiera_configitem entry; +}; + +LumieraConfigentry +lumiera_configentry_init (const char* entry); + +LumieraConfigentry +lumiera_configentry_destroy (LumieraConfigentry self); + + +LumieraConfigentry +lumiera_configentry_new (const char* data); + +void +lumiera_configentry_delete (); #endif diff --git a/src/backend/configitem.h b/src/backend/configitem.h index a84013060..db87680f5 100644 --- a/src/backend/configitem.h +++ b/src/backend/configitem.h @@ -59,7 +59,45 @@ typedef struct lumiera_configitem* LumieraConfigitem; * 'key = value' or 'key < redirect' */ + //TODO: declarations go here// + +enum lumiera_configitem_type + { + LUMIERA_CONFIGFILE, + LUMIERA_CONFISECTION, + LUMIERA_CONFIGCOMMENT, + LUMIERA_CONFIGDIRECTIVE, + LUMIERA_CONFIGENTRY, + LUMIERA_CONFIGERRONEOUS + }; + +/** + * @file + * configitems build a 3 level hierachy: + * + * 1. file: + * contain sections + * + * 2. section: + * [prefix suffix] + * contain lines + * + * 3. lines are + * comment: + * empty line or line only containing spaces and tabs + * line starting with spaces and tabs followed by a # + * directive: + * '@include name' or '@readonly' + * directives are only valid at the toplevel section [] + * configurationentry: + * 'key = value' or 'key < redirect' + * errorneous: + * any line which cant be parsed + */ + + + struct lumiera_configitem_struct { llist link; // all lines on the same hierachy level are linked here (see childs) @@ -74,6 +112,12 @@ struct lumiera_configitem_struct char* delim; // delimiter, value starts at delim+1 }; +struct lumiera_configitem_vtable +{ + +}; + + /* brainstorm: From ea97119fa675911e4e54058a1eb3eece14eb848a Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 11 Aug 2008 10:12:05 +0200 Subject: [PATCH 03/24] add a function to move llist nodes around --- src/lib/llist.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/lib/llist.h b/src/lib/llist.h index 128a3e826..3cb70f8ea 100644 --- a/src/lib/llist.h +++ b/src/lib/llist.h @@ -306,6 +306,18 @@ LLIST_FUNC (LList llist_relocate (LList self), return self->next->prev = self->prev->next = self; ); +/** + * Move a node from one memory location to another. + * @param self target of the move, must be uninitialized or empty before this move + * @param source source of the move, will be initialized to a empty list after this call + * @return self + */ +LLIST_FUNC (LList llist_move (LList self, LList source), + *self = *source; + llist_init (source); + return llist_relocate (self); +); + /** * Insert a node after another. * @param self node after which we want to insert From c7af270e4250ebb278a9d2e8ae538e161decc563 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 11 Aug 2008 12:17:03 +0200 Subject: [PATCH 04/24] config item bootstraping Mockup for review --- src/backend/configentry.h | 10 -- src/backend/configitem.c | 219 ++++++++++++++++++++++++++++++++++++++ src/backend/configitem.h | 56 +++++----- 3 files changed, 243 insertions(+), 42 deletions(-) create mode 100644 src/backend/configitem.c diff --git a/src/backend/configentry.h b/src/backend/configentry.h index 9af84a025..01d06dcb2 100644 --- a/src/backend/configentry.h +++ b/src/backend/configentry.h @@ -47,16 +47,6 @@ struct lumiera_configentry_struct lumiera_configitem entry; }; -LumieraConfigentry -lumiera_configentry_init (const char* entry); - -LumieraConfigentry -lumiera_configentry_destroy (LumieraConfigentry self); - - -LumieraConfigentry -lumiera_configentry_new (const char* data); - void lumiera_configentry_delete (); diff --git a/src/backend/configitem.c b/src/backend/configitem.c new file mode 100644 index 000000000..18e4f5a56 --- /dev/null +++ b/src/backend/configitem.c @@ -0,0 +1,219 @@ +/* + configitem.c - generalized hierachy of configuration items + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +//TODO: Support library includes// +#include "lib/llist.h" +#include "lib/safeclib.h" + + +//TODO: Lumiera header includes// +#include "backend/config.h" +#include "backend/configitem.h" +#include "backend/configentry.h" + +//TODO: internal/static forward declarations// + + +//TODO: System includes// + + +/** + * @file + * + */ + + +//code goes here// + +LumieraConfigitem +lumiera_configitem_init (LumieraConfigitem self) +{ + TRACE (config_item); + REQUIRE (self); + + llist_init (&self->link); + self->parent = NULL; + llist_init (&self->childs); + + llist_init (&self->lookup); + + self->line = NULL; + + self->key = NULL; + self->key_size = 0; + self->delim = NULL; + self->type = LUMIERA_CONFIGERRONEOUS; + + return self; +} + +LumieraConfigitem +lumiera_configitem_destroy (LumieraConfigitem self) +{ + TRACE (config_item); + REQUIRE (self); + +#if 0 + if (!llist_is_empty (&self->lookup)) + TODO ("remove from the lookup hash"); + + ENSURE (llist_is_empty (&self->childs), "TODO recursively remove childs (needs some kind of typed destructor)"); + llist_unlink (&self->link); + lumiera_free (self->line); +#endif + return self; +} + + +LumieraConfigitem +lumiera_configitem_new (const char* line) +{ + TRACE (config_item); + + /* MOCKUP */ + + // create a temporary configitem for parsing + + + lumiera_configitem tmp; + lumiera_configitem_init (&tmp); + + lumiera_configitem_parse (&tmp, line); + + FIXME ("MOCKUP only"); + + LumieraConfigitem self = NULL; + + switch (tmp.type) + { + case LUMIERA_CONFIGFILE: + + break; + + case LUMIERA_CONFIGSECTION: + break; + + case LUMIERA_CONFIGCOMMENT: + break; + + case LUMIERA_CONFIGDIRECTIVE: + break; + + case LUMIERA_CONFIGENTRY: + self = lumiera_malloc (sizeof (lumiera_configentry)); + + TODO ("call lumiera_configentry ctor"); + break; + + case LUMIERA_CONFIGERRONEOUS: + break; + } + + lumiera_configitem_move (self, &tmp); + + return self; +} + + +void +lumiera_configitem_delete (LumieraConfigitem self) +{ + TRACE (config_item); + + UNIMPLEMENTED (); +} + + + +LumieraConfigitem +lumiera_configitem_move (LumieraConfigitem self, LumieraConfigitem source) +{ + TRACE (config_item); + REQUIRE (self); + REQUIRE (source); + + llist_move (&self->link, &source->link); + + self->parent = source->parent; + + llist_move (&self->childs, &source->childs); + llist_move (&self->lookup, &source->lookup); + + self->line = source->line; + source->line = NULL; + + self->key = source->key; + self->key_size = source->key_size; + self->delim = source->delim; + self->type = source->type; + return self; +} + + +LumieraConfigitem +lumiera_configitem_parse (LumieraConfigitem self, const char* line) +{ + TRACE (config_item); + + FIXME ("MOCKUP only"); + + self->line = lumiera_strndup (line, SIZE_MAX); + TODO ("parsing here"); + + // MOCKUP pretrend this is an entry + self->type = LUMIERA_CONFIGENTRY; + + return self; +} + + +/* +brainstorm: + +identify the type of a configitem: + +file: + parent == NULL + line = filename (might be NULL for virtual files) + delim = NULL +section: + *delim == ' ' or ']' + *key != '@' +comment: + *key == NULL +directive: + *key == '@' + *delim == ' ' +configurationentry: + *delim == '=' + +*/ + + + + +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/backend/configitem.h b/src/backend/configitem.h index db87680f5..21842c22b 100644 --- a/src/backend/configitem.h +++ b/src/backend/configitem.h @@ -23,11 +23,12 @@ #define LUMIERA_CONFIGITEM_H //TODO: Support library includes// +#include "lib/llist.h" //TODO: Forward declarations// typedef struct lumiera_configitem_struct lumiera_configitem; -typedef struct lumiera_configitem* LumieraConfigitem; +typedef lumiera_configitem* LumieraConfigitem; //TODO: Lumiera header includes// @@ -65,7 +66,7 @@ typedef struct lumiera_configitem* LumieraConfigitem; enum lumiera_configitem_type { LUMIERA_CONFIGFILE, - LUMIERA_CONFISECTION, + LUMIERA_CONFIGSECTION, LUMIERA_CONFIGCOMMENT, LUMIERA_CONFIGDIRECTIVE, LUMIERA_CONFIGENTRY, @@ -100,46 +101,37 @@ enum lumiera_configitem_type struct lumiera_configitem_struct { - llist link; // all lines on the same hierachy level are linked here (see childs) - LumieraConfigitem parent; // parent section - llist childs; // root node for all lines below this hierachy + llist link; // all lines on the same hierachy level are linked here (see childs) + LumieraConfigitem parent; // parent section + llist childs; // root node for all lines below this hierachy - llist lookup; // all lines with the same key are stacked up on the loockup + llist lookup; // all lines with the same key are stacked up on the loockup - char* line; // raw line as read in allocated here trailing \n will be replaced with \0 - char* key; // pointer into line to start of key + char* line; // raw line as read in allocated here trailing \n will be replaced with \0 + char* key; // pointer into line to start of key size_t key_size; - char* delim; // delimiter, value starts at delim+1 -}; - -struct lumiera_configitem_vtable -{ - + char* delim; // delimiter, value starts at delim+1 + enum lumiera_configitem_type type; /* TODO tag by dtor instead enum */ }; -/* -brainstorm: +LumieraConfigitem +lumiera_configitem_init (LumieraConfigitem self); -identify the type of a configitem: +LumieraConfigitem +lumiera_configitem_destroy (LumieraConfigitem self); -file: - parent == NULL - line = filename (might be NULL for virtual files) - delim = NULL -section: - *delim == ' ' or ']' - *key != '@' -comment: - *key == NULL -directive: - *key == '@' - *delim == ' ' -configurationentry: - *delim == '=' +LumieraConfigitem +lumiera_configitem_new (const char* line); -*/ +void +lumiera_configitem_delete (LumieraConfigitem self); +LumieraConfigitem +lumiera_configitem_parse (LumieraConfigitem self, const char* line); + +LumieraConfigitem +lumiera_configitem_move (LumieraConfigitem self, LumieraConfigitem dest); #endif /* From c958aa29fbbd1dd061f5718f0d3bc69c49f6a73d Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 11 Aug 2008 17:22:15 +0200 Subject: [PATCH 05/24] more functional mockup of the configitem bootstrap includes some comments for simav about how to write parsers --- src/backend/configentry.c | 74 +++++++++++++++++++++ src/backend/configentry.h | 10 ++- src/backend/configitem.c | 131 ++++++++++++++++---------------------- src/backend/configitem.h | 35 ++++------ 4 files changed, 150 insertions(+), 100 deletions(-) create mode 100644 src/backend/configentry.c diff --git a/src/backend/configentry.c b/src/backend/configentry.c new file mode 100644 index 000000000..e2c846b12 --- /dev/null +++ b/src/backend/configentry.c @@ -0,0 +1,74 @@ +/* + configentry.c - single entries from configfiles + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +//TODO: Support library includes// +#include "lib/safeclib.h" + +//TODO: Lumiera header includes// +#include "backend/configentry.h" + +//TODO: internal/static forward declarations// + + +//TODO: System includes// + + +/** + * @file + * + */ + +//code goes here// +LumieraConfigitem +lumiera_configentry_new (LumieraConfigitem tmp) +{ + LumieraConfigentry self = lumiera_malloc (sizeof (*self)); + lumiera_configitem_move ((LumieraConfigitem)self, tmp); + + TODO ("initialize other stuff here (lookup, parent, ...)"); + + return (LumieraConfigitem)self; +} + + +LumieraConfigitem +lumiera_configentry_destroy (LumieraConfigitem self) +{ + TODO ("cleanup other stuff here (lookup, parent, ...)"); + + return self; +} + +struct lumiera_configitem_vtable lumiera_configentry_funcs = + { + .new = lumiera_configentry_new, + .destroy = lumiera_configentry_destroy + }; + + + +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/backend/configentry.h b/src/backend/configentry.h index 01d06dcb2..61f5f5f73 100644 --- a/src/backend/configentry.h +++ b/src/backend/configentry.h @@ -47,10 +47,16 @@ struct lumiera_configentry_struct lumiera_configitem entry; }; -void -lumiera_configentry_delete (); +extern struct lumiera_configitem_vtable lumiera_configentry_funcs; +LumieraConfigitem +lumiera_configentry_new (LumieraConfigitem tmp); + + +LumieraConfigitem +lumiera_configentry_destroy (LumieraConfigitem self); + #endif /* // Local Variables: diff --git a/src/backend/configitem.c b/src/backend/configitem.c index 18e4f5a56..70c397e82 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -60,7 +60,7 @@ lumiera_configitem_init (LumieraConfigitem self) self->key = NULL; self->key_size = 0; self->delim = NULL; - self->type = LUMIERA_CONFIGERRONEOUS; + self->vtable = NULL; return self; } @@ -69,16 +69,19 @@ LumieraConfigitem lumiera_configitem_destroy (LumieraConfigitem self) { TRACE (config_item); - REQUIRE (self); -#if 0 - if (!llist_is_empty (&self->lookup)) - TODO ("remove from the lookup hash"); + if (self) + { + if (self->vtable && self->vtable->destroy) + self->vtable->destroy (self); + + ENSURE (!llist_is_empty (&self->lookup), "destructor didn't cleaned lookup up"); + ENSURE (llist_is_empty (&self->childs), "destructor didn't remove childs"); + + llist_unlink (&self->link); + lumiera_free (self->line); + } - ENSURE (llist_is_empty (&self->childs), "TODO recursively remove childs (needs some kind of typed destructor)"); - llist_unlink (&self->link); - lumiera_free (self->line); -#endif return self; } @@ -88,46 +91,14 @@ lumiera_configitem_new (const char* line) { TRACE (config_item); - /* MOCKUP */ - - // create a temporary configitem for parsing - - lumiera_configitem tmp; lumiera_configitem_init (&tmp); lumiera_configitem_parse (&tmp, line); - FIXME ("MOCKUP only"); - - LumieraConfigitem self = NULL; - - switch (tmp.type) - { - case LUMIERA_CONFIGFILE: - - break; - - case LUMIERA_CONFIGSECTION: - break; - - case LUMIERA_CONFIGCOMMENT: - break; - - case LUMIERA_CONFIGDIRECTIVE: - break; - - case LUMIERA_CONFIGENTRY: - self = lumiera_malloc (sizeof (lumiera_configentry)); - - TODO ("call lumiera_configentry ctor"); - break; - - case LUMIERA_CONFIGERRONEOUS: - break; - } - - lumiera_configitem_move (self, &tmp); + LumieraConfigitem self = tmp.vtable && tmp.vtable->new + ? tmp.vtable->new (&tmp) + : lumiera_configitem_move (lumiera_malloc (sizeof (*self)), &tmp); return self; } @@ -137,8 +108,7 @@ void lumiera_configitem_delete (LumieraConfigitem self) { TRACE (config_item); - - UNIMPLEMENTED (); + lumiera_free (lumiera_configitem_destroy (self)); } @@ -163,7 +133,7 @@ lumiera_configitem_move (LumieraConfigitem self, LumieraConfigitem source) self->key = source->key; self->key_size = source->key_size; self->delim = source->delim; - self->type = source->type; + self->vtable = source->vtable; return self; } @@ -173,43 +143,50 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) { TRACE (config_item); - FIXME ("MOCKUP only"); - self->line = lumiera_strndup (line, SIZE_MAX); - TODO ("parsing here"); - // MOCKUP pretrend this is an entry - self->type = LUMIERA_CONFIGENTRY; + FIXME ("MOCKUP START"); + + TODO ("parsing here"); + /* + HOWTO parse (for simav) + in self->line liegt jetzt der 'rohe' string + + parsen setzt folgende werte in self: .key, .key_size, .delim und vtable. den rest macht dann die 'new' funktion aus der vtable + + es geht jetzt da drum rauszufinden ob diese zeile einses der folgenden sachen ist: + (ich zeig hier nur die grundsyntax, das parsen sollte auch entartete situationen behandeln, insbesondere leerzeichen/tabulatoren an allen moeglichen stellen) + auserdem sollt hier alles soweit wie moeglich validiert werden z.b. keys auf erlaubte zeichen gescheckt (siehe die _tr function) + + section: + '[prefix suffix]' + .key == prefix + .delim == das leerzeichen (oder tab) vor suffix oder aufs abschliessende ] wenn kein suffix + + kommentar: + leere zeile, zeile nur aus leerzeichen und tabulatoren, leerzeichen und tabulatoren gefolgt von # bis zum zeilenende + alles ausser vtable auf NULL + + direktive: + '@direktive argumente' + .key == @ + .delim == leerzeichen oder tab vor argumente, NULL wenn keine argumente + + configentry: + 'key = value' + .key == key begin + .delim == '=' + 'key < redirect' + .key == key begin + .delim == '=' + + */ + self->vtable = &lumiera_configentry_funcs; // MOCKUP pretend this is a configentry return self; } -/* -brainstorm: - -identify the type of a configitem: - -file: - parent == NULL - line = filename (might be NULL for virtual files) - delim = NULL -section: - *delim == ' ' or ']' - *key != '@' -comment: - *key == NULL -directive: - *key == '@' - *delim == ' ' -configurationentry: - *delim == '=' - -*/ - - - - /* // Local Variables: // mode: C diff --git a/src/backend/configitem.h b/src/backend/configitem.h index 21842c22b..c2b0bea92 100644 --- a/src/backend/configitem.h +++ b/src/backend/configitem.h @@ -30,6 +30,7 @@ typedef struct lumiera_configitem_struct lumiera_configitem; typedef lumiera_configitem* LumieraConfigitem; +struct lumiera_configitem_vtable; //TODO: Lumiera header includes// @@ -62,17 +63,6 @@ typedef lumiera_configitem* LumieraConfigitem; //TODO: declarations go here// - -enum lumiera_configitem_type - { - LUMIERA_CONFIGFILE, - LUMIERA_CONFIGSECTION, - LUMIERA_CONFIGCOMMENT, - LUMIERA_CONFIGDIRECTIVE, - LUMIERA_CONFIGENTRY, - LUMIERA_CONFIGERRONEOUS - }; - /** * @file * configitems build a 3 level hierachy: @@ -97,24 +87,27 @@ enum lumiera_configitem_type * any line which cant be parsed */ - +struct lumiera_configitem_vtable +{ + LumieraConfigitem (*new)(LumieraConfigitem); + LumieraConfigitem (*destroy)(LumieraConfigitem); +}; struct lumiera_configitem_struct { - llist link; // all lines on the same hierachy level are linked here (see childs) - LumieraConfigitem parent; // parent section - llist childs; // root node for all lines below this hierachy + llist link; // all lines on the same hierachy level are linked here (see childs) + LumieraConfigitem parent; // parent section + llist childs; // root node for all lines below this hierachy - llist lookup; // all lines with the same key are stacked up on the loockup + llist lookup; // all lines with the same key are stacked up on the loockup - char* line; // raw line as read in allocated here trailing \n will be replaced with \0 - char* key; // pointer into line to start of key + char* line; // raw line as read in allocated here trailing \n will be replaced with \0 + char* key; // pointer into line to start of key size_t key_size; - char* delim; // delimiter, value starts at delim+1 - enum lumiera_configitem_type type; /* TODO tag by dtor instead enum */ + char* delim; // delimiter, value starts at delim+1 + struct lumiera_configitem_vtable* vtable; // functiontable for subclassing }; - LumieraConfigitem lumiera_configitem_init (LumieraConfigitem self); From fd563a02848477f6b939723a14ff6ceea9655164 Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Mon, 11 Aug 2008 22:08:17 +0200 Subject: [PATCH 06/24] WIP: started low-level parser --- src/backend/configitem.c | 79 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index 70c397e82..0907c63e9 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -3,6 +3,7 @@ Copyright (C) Lumiera.org 2008, Christian Thaeter + Simeon Voelkel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -178,9 +179,85 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) .delim == '=' 'key < redirect' .key == key begin - .delim == '=' + .delim == '>' */ + /* + * What should be working (for cehteh) or not yet.. + * + * die Elemente sollten bereits richtig unterschieden werden, die {} sind noch zu füllen. + * + * TODO: include für verwendete Funkionen wie strlen und isspace + * + * */ + + int linelength = strlen(self->line); + int pos = 0; + + char* tmp1 = self->line; + + /*skip leading whitespaces*/ + while ( isspace(tmp1[0]) && pos < linelength ) + { + tmp1++; + pos++: + } + + /*decide what this line represents*/ + if ( tmp1[0] == '\0' || pos == linelenght ) + { + /*this was an empty line*/ + } + else + if ( tmp1[0] == '#' ) + { + /*this was a comment*/ + } + else + if ( tmp1[0] == '@' ) + { + /*this was a directive*/ + } + else + if ( tmp1[0] == '[' ) + { + /*this was a section*/ + } + else + { + /*this was a configentry*/ + + /*tmp1 points now to the first not-whitespace-character*/ + self->key = tmp1; + + /*now look for the end of the key and set the keysize*/ + self->keysize = 0; + + while ( ! isspace(tmp1[0]) && pos < linelength ) + { + tmp1++; + self->keysize++; + pos++; + } + + if ( tmp1[0] == '\0' || pos == linelength ) + { + /*error: line ended with end of the key*/ + } + else + { + /*skip the following whitespaces until we reach the delimeter*/ + while ( isspace(tmp1[0]) && pos < linelength ) + { + tmp1++; + pos++; + } + /*TODO: keep on parsing... ;^)*/ + } + + } + + self->vtable = &lumiera_configentry_funcs; // MOCKUP pretend this is a configentry return self; From 9c7cedbf75bd0f916d1abf4a5c095e03e7ce131d Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 07:13:45 +0200 Subject: [PATCH 07/24] fix to make parser mockup compileable, little simplified --- src/backend/configitem.c | 75 ++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 45 deletions(-) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index 0907c63e9..8462cfc4d 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -34,7 +34,7 @@ //TODO: System includes// - +#include /** * @file @@ -191,74 +191,59 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) * * */ - int linelength = strlen(self->line); - int pos = 0; - - char* tmp1 = self->line; + char* itr = self->line; /*skip leading whitespaces*/ - while ( isspace(tmp1[0]) && pos < linelength ) - { - tmp1++; - pos++: - } + while (*itr && isspace (*itr)) + itr++; /*decide what this line represents*/ - if ( tmp1[0] == '\0' || pos == linelenght ) + if (!*itr || *itr == '#' ) { - /*this was an empty line*/ + /*this is an empty line or a a comment*/ } - else - if ( tmp1[0] == '#' ) + else if (*itr == '@' ) { - /*this was a comment*/ + /*this is a directive*/ } - else - if ( tmp1[0] == '@' ) + else if (*itr == '[' ) { - /*this was a directive*/ - } - else - if ( tmp1[0] == '[' ) - { - /*this was a section*/ + /*this is a section*/ } else { - /*this was a configentry*/ - - /*tmp1 points now to the first not-whitespace-character*/ - self->key = tmp1; + /*this is a probably configentry*/ + + /*itr points now to the first not-whitespace-character*/ + self->key = itr; /*now look for the end of the key and set the keysize*/ - self->keysize = 0; + self->key_size = strspn (itr, "abcdefghijklmnopqrstuvwxyz0123456789_."); - while ( ! isspace(tmp1[0]) && pos < linelength ) - { - tmp1++; - self->keysize++; - pos++; - } + TODO ("if(self->keysize==0) then key_syntax_error"); - if ( tmp1[0] == '\0' || pos == linelength ) + /* skip blanks */ + itr += self->key_size; + while (*itr && isspace(*itr)) + itr++; + + if (*itr == '=') { - /*error: line ended with end of the key*/ + self->delim = itr; } - else + else if (*itr == '<') { - /*skip the following whitespaces until we reach the delimeter*/ - while ( isspace(tmp1[0]) && pos < linelength ) - { - tmp1++; - pos++; - } - /*TODO: keep on parsing... ;^)*/ + self->delim = itr; } + else + TODO ("syntax error"); + + /* TODO only if still everything ok */ + self->vtable = &lumiera_configentry_funcs; // MOCKUP pretend this is a configentry } - self->vtable = &lumiera_configentry_funcs; // MOCKUP pretend this is a configentry return self; } From 20d38b0b5ce909411566ac9372650f8907273c60 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 08:12:08 +0200 Subject: [PATCH 08/24] give the charsets for config keys some constants --- src/backend/config.c | 6 +++--- src/backend/config.h | 2 ++ src/backend/configitem.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backend/config.c b/src/backend/config.c index 1bf30b245..db8d929a7 100644 --- a/src/backend/config.c +++ b/src/backend/config.c @@ -127,11 +127,11 @@ lumiera_config_get (const char* key, const char** value) int ret = -1; - /* we translate the key for the env var override by making it uppercase and replace . and - with _, + /* we translate the key for the env var override by making it uppercase and replace . with _, as side effect, this also checks the key syntax */ char* tr_key = lumiera_tmpbuf_tr (key, - "abcdefghijklmnopqrstuvwxyz0123456789_.", - "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789__", + LUMIERA_CONFIG_KEY_CHARS, + LUMIERA_CONFIG_ENV_CHARS, NULL); if (!tr_key) { diff --git a/src/backend/config.h b/src/backend/config.h index 38ffce9e2..27d14980b 100644 --- a/src/backend/config.h +++ b/src/backend/config.h @@ -58,6 +58,8 @@ LUMIERA_ERROR_DECLARE (CONFIG_DEFAULT); * TODO documentation, http://www.pipapo.org/pipawiki/Lumiera/ConfigLoader */ +#define LUMIERA_CONFIG_KEY_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_." +#define LUMIERA_CONFIG_ENV_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789__" struct lumiera_config_struct { diff --git a/src/backend/configitem.c b/src/backend/configitem.c index 8462cfc4d..a715ca99b 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -218,7 +218,7 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) self->key = itr; /*now look for the end of the key and set the keysize*/ - self->key_size = strspn (itr, "abcdefghijklmnopqrstuvwxyz0123456789_."); + self->key_size = strspn (itr, LUMIERA_CONFIG_KEY_CHARS); TODO ("if(self->keysize==0) then key_syntax_error"); From 8e5b734f0392e1adec5b76692bb56160a41133da Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 08:13:15 +0200 Subject: [PATCH 09/24] add configitem and configentry to the build system --- src/backend/Makefile.am | 8 ++++++-- src/backend/config.c | 2 ++ src/backend/config.h | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index 34d48c9ed..afe7cc1f3 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -29,7 +29,9 @@ liblumibackend_a_SOURCES = \ $(liblumibackend_a_srcdir)/filedescriptor.c \ $(liblumibackend_a_srcdir)/filehandlecache.c \ $(liblumibackend_a_srcdir)/config.c \ - $(liblumibackend_a_srcdir)/config_typed.c + $(liblumibackend_a_srcdir)/config_typed.c \ + $(liblumibackend_a_srcdir)/configentry.c \ + $(liblumibackend_a_srcdir)/configitem.c noinst_HEADERS += \ @@ -39,5 +41,7 @@ noinst_HEADERS += \ $(liblumibackend_a_srcdir)/filehandle.h \ $(liblumibackend_a_srcdir)/filedescriptor.h \ $(liblumibackend_a_srcdir)/filehandlecache.h \ - $(liblumibackend_a_srcdir)/config.h + $(liblumibackend_a_srcdir)/config.h \ + $(liblumibackend_a_srcdir)/configentry.h \ + $(liblumibackend_a_srcdir)/configitem.h diff --git a/src/backend/config.c b/src/backend/config.c index db8d929a7..deec72697 100644 --- a/src/backend/config.c +++ b/src/backend/config.c @@ -42,6 +42,7 @@ NOBUG_DEFINE_FLAG_PARENT (config_all, backend); NOBUG_DEFINE_FLAG_PARENT (config, config_all); NOBUG_DEFINE_FLAG_PARENT (config_typed, config_all); NOBUG_DEFINE_FLAG_PARENT (config_file, config_all); +NOBUG_DEFINE_FLAG_PARENT (config_item, config_all); LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX, "syntax error in configfile"); LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX_KEY, "syntax error in key"); @@ -65,6 +66,7 @@ lumiera_config_init (const char* path) NOBUG_INIT_FLAG (config); NOBUG_INIT_FLAG (config_typed); NOBUG_INIT_FLAG (config_file); + NOBUG_INIT_FLAG (config_item); lumiera_global_config = lumiera_malloc (sizeof (*lumiera_global_config)); lumiera_global_config->path = lumiera_strndup (path, SIZE_MAX); diff --git a/src/backend/config.h b/src/backend/config.h index 27d14980b..1daf54087 100644 --- a/src/backend/config.h +++ b/src/backend/config.h @@ -38,6 +38,8 @@ NOBUG_DECLARE_FLAG (config); NOBUG_DECLARE_FLAG (config_typed); /* file operations */ NOBUG_DECLARE_FLAG (config_file); +/* single config items */ +NOBUG_DECLARE_FLAG (config_item); LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX); From 0f5c5e218a19d344e4ead842e3a68bf2668d7609 Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Tue, 12 Aug 2008 10:03:38 +0200 Subject: [PATCH 10/24] typo fix and redundant comment removal --- src/backend/config_typed.c | 2 +- src/backend/configitem.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backend/config_typed.c b/src/backend/config_typed.c index a8c18ad15..78f2e8cd7 100644 --- a/src/backend/config_typed.c +++ b/src/backend/config_typed.c @@ -157,7 +157,7 @@ scan_string (const char* in) if (end) { - ret = lumiera_tmpbuf_strndup (in, end-in); + ret = lumiera_tmpbuf_strndup (in, end - in); /* replace double quote chars with single one */ char* wpos; diff --git a/src/backend/configitem.c b/src/backend/configitem.c index a715ca99b..bf413e7e5 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -187,8 +187,6 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) * * die Elemente sollten bereits richtig unterschieden werden, die {} sind noch zu füllen. * - * TODO: include für verwendete Funkionen wie strlen und isspace - * * */ char* itr = self->line; @@ -212,7 +210,7 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) } else { - /*this is a probably configentry*/ + /*this is probably a configentry*/ /*itr points now to the first not-whitespace-character*/ self->key = itr; From ca58edf39cc8370c7df358d423813fa55688f913 Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Tue, 12 Aug 2008 10:29:05 +0200 Subject: [PATCH 11/24] added CONFIG_SYNTAX errors --- src/backend/configitem.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index bf413e7e5..075304c37 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -190,6 +190,7 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) * */ char* itr = self->line; + bool faultless = true; /*skip leading whitespaces*/ while (*itr && isspace (*itr)) @@ -199,6 +200,9 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) if (!*itr || *itr == '#' ) { /*this is an empty line or a a comment*/ + self->key = NULL; + self->keysize = 0; + self->delim = NULL; } else if (*itr == '@' ) { @@ -218,7 +222,17 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) /*now look for the end of the key and set the keysize*/ self->key_size = strspn (itr, LUMIERA_CONFIG_KEY_CHARS); - TODO ("if(self->keysize==0) then key_syntax_error"); + if ( self->keysize==0 ) + { + /*Obviously a malformed "key"; treat this line like a comment*/ + self->key = NULL; + self->keysize = 0; + self->delim = NULL; + + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + + faultless = false; + } /* skip blanks */ itr += self->key_size; @@ -234,10 +248,21 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) self->delim = itr; } else - TODO ("syntax error"); + { + /*this is not a valid configentry; treat this line like a comment*/ + self->key = NULL; + self->keysize = 0; + self->delim = NULL; - /* TODO only if still everything ok */ - self->vtable = &lumiera_configentry_funcs; // MOCKUP pretend this is a configentry + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + faultless = false; + } + + /*just set vtable if we are sure we had no syntax-error*/ + if (faultless) + { + self->vtable = &lumiera_configentry_funcs; // MOCKUP pretend this is a configentry + } } From e86ef0ba751283125e7080ced3cad0d2f2568ff3 Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Tue, 12 Aug 2008 10:57:46 +0200 Subject: [PATCH 12/24] parser improvements, compiles now --- src/backend/configitem.c | 34 ++++++++-------------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index 075304c37..1148b3486 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -35,6 +35,7 @@ //TODO: System includes// #include +#include /** * @file @@ -190,7 +191,6 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) * */ char* itr = self->line; - bool faultless = true; /*skip leading whitespaces*/ while (*itr && isspace (*itr)) @@ -200,9 +200,6 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) if (!*itr || *itr == '#' ) { /*this is an empty line or a a comment*/ - self->key = NULL; - self->keysize = 0; - self->delim = NULL; } else if (*itr == '@' ) { @@ -222,47 +219,32 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) /*now look for the end of the key and set the keysize*/ self->key_size = strspn (itr, LUMIERA_CONFIG_KEY_CHARS); - if ( self->keysize==0 ) - { - /*Obviously a malformed "key"; treat this line like a comment*/ - self->key = NULL; - self->keysize = 0; - self->delim = NULL; - - LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); - - faultless = false; - } - /* skip blanks */ itr += self->key_size; while (*itr && isspace(*itr)) itr++; - if (*itr == '=') + if (self->key_size && *itr == '=') { + /*this configentry assigns a value to a key*/ self->delim = itr; + self->vtable = &lumiera_configentry_funcs; } - else if (*itr == '<') + else if (self->key_size && *itr == '<') { + /*this configentry is a redirect*/ self->delim = itr; + self->vtable = &lumiera_configentry_funcs; } else { /*this is not a valid configentry; treat this line like a comment*/ self->key = NULL; - self->keysize = 0; - self->delim = NULL; + self->key_size = 0; LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); - faultless = false; } - /*just set vtable if we are sure we had no syntax-error*/ - if (faultless) - { - self->vtable = &lumiera_configentry_funcs; // MOCKUP pretend this is a configentry - } } From 19c2af0c6928b97a2b9f88958ff846e2a087cd84 Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Tue, 12 Aug 2008 12:39:48 +0200 Subject: [PATCH 13/24] added section part to parser --- src/backend/configitem.c | 64 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index 1148b3486..a64995aeb 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -208,6 +208,70 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) else if (*itr == '[' ) { /*this is a section*/ + + /*skip blanks before prefix*/ + while (*itr && isspace(*itr)) + itr++; + + /*itr points now to the begin of the key*/ + self->key = itr; + + /*now look for the end of the key and set the keysize*/ + self->key_size = strspn (itr, LUMIERA_CONFIG_KEY_CHARS); + + itr += self->key_size; + + /*if the line ends ends with prefix] delim points to ] + * and not the last (blank) character before the final square bracket*/ + if (self->key_size && *itr && *itr == ']') + { + self->delim = itr; + TODO("self->vtable = &lumiera_configsection_funcs;"); + } + else if (self->key_size && *itr && isspace(*itr)) + { + /* skip blanks until we reach the suffix or the final square bracket*/ + while (*itr && isspace(*itr)) + itr++; + + if (*itr && *itr == ']') + { + /*final square bracket reached, so place delim one char before the + * actual position which must be a whitespace: no extra check necessary*/ + self->delim = itr - 1; + TODO("self->vtable = &lumiera_configsection_funcs;"); + } + else if (*itr) + { + TODO("check wheter suffix is made of legal characters"); + + /*delim points to the last whitespace before the actual position; + * no extra check needed*/ + self->delim = itr - 1; + TODO("self->vtable = &lumiera_configsection_funcs;"); + } + else + { + /*malformed section line, treat this line like a comment*/ + self->key = NULL; + self->key_size = 0; + + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + + } + } + else + { + /*error: either *itr is false, points neither to a blank nor to a closed square + * bracket or the key_size is zero*/ + + /*treat this line like a comment*/ + self->key = NULL; + self->key_size = 0; + + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + + } } else { From b5dafbcd53465707b5e9d347dcf3ceb3907f21d7 Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Wed, 13 Aug 2008 08:33:49 +0200 Subject: [PATCH 14/24] Fix for section-parser --- src/backend/configitem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index a64995aeb..7e52f269e 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -210,6 +210,7 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) /*this is a section*/ /*skip blanks before prefix*/ + itr++; while (*itr && isspace(*itr)) itr++; From bd2cc4a026359b1999ef3e651e69ed7f9b81a4f0 Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Wed, 13 Aug 2008 08:34:44 +0200 Subject: [PATCH 15/24] Typo fix --- tests/library/test-llist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/library/test-llist.c b/tests/library/test-llist.c index 66bfa614d..c352edbf2 100644 --- a/tests/library/test-llist.c +++ b/tests/library/test-llist.c @@ -1,5 +1,5 @@ /* - test-llist.c - test the linked lis lib + test-llist.c - test the linked list lib Copyright (C) Lumiera.org 2008, Christian Thaeter From a8a186bb936c69d47e477ad2b41b6e4f05edd30b Mon Sep 17 00:00:00 2001 From: Simeon Voelkel Date: Wed, 13 Aug 2008 08:35:31 +0200 Subject: [PATCH 16/24] Added two very simple tests for configitem --- tests/20config.tests | 5 +++++ tests/backend/test-config.c | 24 +++++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/20config.tests b/tests/20config.tests index bbcd4debd..65dfb5404 100644 --- a/tests/20config.tests +++ b/tests/20config.tests @@ -135,3 +135,8 @@ END PLANNED "bool set" < + Simeon Voelkel This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -21,6 +22,7 @@ #include "lib/safeclib.h" #include "backend/config.h" +#include "backend/configitem.h" #include "tests/test.h" @@ -125,5 +127,25 @@ TEST ("word_get") lumiera_config_destroy (); } +TEST ("empty_line_configitem") +{ + LumieraConfigitem item; + + item = lumiera_configitem_new ( "" ); + + lumiera_configitem_delete(item); + item = NULL; +} + +TEST ("blank_line_configitem") +{ + LumieraConfigitem item; + + item = lumiera_configitem_new ( " " ); + + lumiera_configitem_delete(item); + item = NULL; +} + TESTS_END From 975150fe0afb481e5f991f32b45ecebe2d9cffff Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 11:38:56 +0200 Subject: [PATCH 17/24] Cuckoo hash update * add a destructor function for elements * rename cuckoo_free to cuckoo_delete to be consistent with the rest --- src/lib/cuckoo.c | 29 +++++++++++++++++++++++++---- src/lib/cuckoo.h | 18 +++++++++++++++--- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/lib/cuckoo.c b/src/lib/cuckoo.c index bbcb0e71a..04bf4a31c 100644 --- a/src/lib/cuckoo.c +++ b/src/lib/cuckoo.c @@ -52,6 +52,8 @@ struct cuckoo_struct enum compact_state autocompact; size_t elements; + + cuckoo_dtorfunc dtor; }; @@ -68,7 +70,8 @@ cuckoo_init (Cuckoo self, cuckoo_hashfunc h3, cuckoo_cmpfunc cmp, size_t itemsize, - unsigned startsize) + unsigned startsize, + cuckoo_dtorfunc dtor) { if (!self) return NULL; @@ -101,6 +104,8 @@ cuckoo_init (Cuckoo self, self->autocompact = COMPACTING_AUTO; self->elements = 0; + + self->dtor = dtor; return self; } @@ -110,10 +115,11 @@ cuckoo_new (cuckoo_hashfunc h1, cuckoo_hashfunc h3, cuckoo_cmpfunc cmp, size_t itemsize, - unsigned startsize) + unsigned startsize, + cuckoo_dtorfunc dtor) { Cuckoo self = malloc (sizeof (struct cuckoo_struct)); - if (!cuckoo_init (self, h1, h2, h3, cmp, itemsize, startsize)) + if (!cuckoo_init (self, h1, h2, h3, cmp, itemsize, startsize, dtor)) { free (self); return NULL; @@ -126,6 +132,18 @@ cuckoo_destroy (Cuckoo self) { if (self) { + + if (self->dtor) + { + void* elem; + for (elem = self->t1; elem < self->t1 + self->size * 4; elem += self->size) + self->dtor (elem); + for (elem = self->t2; elem < self->t1 + self->size * 2; elem += self->size) + self->dtor (elem); + for (elem = self->t3; elem < self->t1 + self->size; elem += self->size) + self->dtor (elem); + } + free (self->t1); free (self->t2); free (self->t3); @@ -135,7 +153,7 @@ cuckoo_destroy (Cuckoo self) void -cuckoo_free (Cuckoo self) +cuckoo_delete (Cuckoo self) { free (cuckoo_destroy (self)); } @@ -486,6 +504,9 @@ cuckoo_remove (Cuckoo self, void* item) { if (item) { + if (self->dtor) + self->dtor (item); + memset (item, 0, self->itemsize); --self->elements; diff --git a/src/lib/cuckoo.h b/src/lib/cuckoo.h index 323b5cc75..ed14f6cc8 100644 --- a/src/lib/cuckoo.h +++ b/src/lib/cuckoo.h @@ -54,6 +54,14 @@ typedef size_t (*cuckoo_hashfunc)(const void* item, const uint32_t r); */ typedef int (*cuckoo_cmpfunc)(const void* item1, const void* item2); +/** + * Item destructor function. + * User supplied destructor function. This function is called when items are removed + * from the hash or at hash detroy/delete time. Must be safe to be called on a zeroed element. + * @param item address of the item to be destroyed + */ +typedef void (*cuckoo_dtorfunc)(void* item); + /** * Initialize a cuckoo hash. * @param self pointer to a uninitialized cuckoo datastructure @@ -62,6 +70,7 @@ typedef int (*cuckoo_cmpfunc)(const void* item1, const void* item2); * @param h3 hash function for the third table * @param cmp function which compares two keys * @param startsize initial size of table t3, as 2's exponent + * @param dtor a function used to clean up hash entries, might be NULL if nothing required * @return The initialized hashtable or NULL at allocation failure */ Cuckoo @@ -71,7 +80,8 @@ cuckoo_init (Cuckoo self, cuckoo_hashfunc h3, cuckoo_cmpfunc cmp, size_t itemsize, - unsigned startsize); + unsigned startsize, + cuckoo_dtorfunc dtor); /** * Allocate a new cuckoo hash. @@ -80,6 +90,7 @@ cuckoo_init (Cuckoo self, * @param h3 hash function for the third table * @param cmp function which compares two keys * @param startsize initial size of table t3, as 2's exponent + * @param dtor a function used to clean up hash entries, might be NULL if nothing required * @return The initialized hashtable or NULL at allocation failure */ Cuckoo @@ -88,7 +99,8 @@ cuckoo_new (cuckoo_hashfunc h1, cuckoo_hashfunc h3, cuckoo_cmpfunc cmp, size_t itemsize, - unsigned startsize); + unsigned startsize, + cuckoo_dtorfunc dtor); /** * Destroy a cuckoo hash. @@ -104,7 +116,7 @@ cuckoo_destroy (Cuckoo self); * @param self handle of the hash table to be freed */ void -cuckoo_free (Cuckoo self); +cuckoo_delete (Cuckoo self); /** * Get the number of elements stored in a hash. From e78908bc7d276c5757b0dfb87d0a91631bb95abf Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 11:39:35 +0200 Subject: [PATCH 18/24] fixes after the cuckoo update in filedescriptor.c --- src/backend/filedescriptor.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index fee877dfd..a4165b58b 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -89,9 +89,7 @@ lumiera_filedescriptor_registry_init (void) TRACE (filedescriptor); REQUIRE (!registry); - registry = cuckoo_new (h1, h2, h3, cmp, - sizeof (LumieraFiledescriptor), - 3); + registry = cuckoo_new (h1, h2, h3, cmp, sizeof (LumieraFiledescriptor), 3, NULL); if (!registry) LUMIERA_DIE (NO_MEMORY); @@ -108,7 +106,7 @@ lumiera_filedescriptor_registry_destroy (void) RESOURCE_FORGET (filedescriptor, registry_mutex.rh); if (registry) - cuckoo_free (registry); + cuckoo_delete (registry); registry = NULL; } From 76a72a6b68043a409361b58afb286ae6bdaef7a0 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 20:57:08 +0200 Subject: [PATCH 19/24] add a custom copy function to the cuckoo hash --- src/lib/cuckoo.c | 95 ++++++++++++++++++++++++++---------------------- src/lib/cuckoo.h | 19 ++++++++-- 2 files changed, 67 insertions(+), 47 deletions(-) diff --git a/src/lib/cuckoo.c b/src/lib/cuckoo.c index 04bf4a31c..3b03ec0ef 100644 --- a/src/lib/cuckoo.c +++ b/src/lib/cuckoo.c @@ -23,6 +23,8 @@ #include +#define CUCKOO_GRANULARITY int + enum compact_state { COMPACTING_OFF, @@ -54,6 +56,7 @@ struct cuckoo_struct size_t elements; cuckoo_dtorfunc dtor; + cuckoo_cpyfunc cpy; }; @@ -63,6 +66,28 @@ static inline uint32_t cuckoo_fast_prng () return rnd = rnd<<1 ^ ((rnd>>30) & 1) ^ ((rnd>>2) & 1); } +static inline int +iszero (void* mem, size_t size) +{ + while (size && !*(CUCKOO_GRANULARITY*)mem) + { + size -= sizeof (CUCKOO_GRANULARITY); + mem += sizeof (CUCKOO_GRANULARITY); + } + return !size; +} + +static inline void +xmemcpy (void* dst, const void* src, size_t size) +{ + while (size) + { + size -= sizeof (CUCKOO_GRANULARITY); + *(CUCKOO_GRANULARITY*)(dst + size) = *(CUCKOO_GRANULARITY*)(src + size); + } +} + + Cuckoo cuckoo_init (Cuckoo self, cuckoo_hashfunc h1, @@ -71,13 +96,15 @@ cuckoo_init (Cuckoo self, cuckoo_cmpfunc cmp, size_t itemsize, unsigned startsize, - cuckoo_dtorfunc dtor) + cuckoo_dtorfunc dtor, + cuckoo_cpyfunc cpy) { if (!self) return NULL; self->size = 1<itemsize = itemsize; + self->itemsize = (itemsize * sizeof (CUCKOO_GRANULARITY) + + sizeof (CUCKOO_GRANULARITY) - 1) / sizeof (CUCKOO_GRANULARITY); /* round up to next CUCKOO_GRANULARITY boundary */ self->h1 = h1; self->r1 = cuckoo_fast_prng (); self->h2 = h2; @@ -106,6 +133,7 @@ cuckoo_init (Cuckoo self, self->elements = 0; self->dtor = dtor; + self->cpy = cpy ? cpy : xmemcpy; return self; } @@ -116,10 +144,11 @@ cuckoo_new (cuckoo_hashfunc h1, cuckoo_cmpfunc cmp, size_t itemsize, unsigned startsize, - cuckoo_dtorfunc dtor) + cuckoo_dtorfunc dtor, + cuckoo_cpyfunc cpy) { Cuckoo self = malloc (sizeof (struct cuckoo_struct)); - if (!cuckoo_init (self, h1, h2, h3, cmp, itemsize, startsize, dtor)) + if (!cuckoo_init (self, h1, h2, h3, cmp, itemsize, startsize, dtor, cpy)) { free (self); return NULL; @@ -159,28 +188,6 @@ cuckoo_delete (Cuckoo self) } -static inline int -iszero (void* mem, size_t size) -{ - while (size && !*(int*)mem) - { - size -= sizeof (int); - mem += sizeof (int); - } - return !size; -} - -static inline void -xmemcpy (void* dst, void* src, size_t size) -{ - while (size) - { - size -= sizeof (int); - *(int*)(dst + size) = *(int*)(src + size); - } -} - - static int cuckoo_insert_internal_ (Cuckoo self, void* item) { @@ -192,9 +199,9 @@ cuckoo_insert_internal_ (Cuckoo self, void* item) /* find nest */ pos = self->t1 + self->itemsize * (self->h1 (item, self->r1) % (4*self->size)); /* kick old egg out */ - xmemcpy (tmp, pos, self->itemsize); + self->cpy (tmp, pos, self->itemsize); /* lay egg */ - xmemcpy (pos, item, self->itemsize); + self->cpy (pos, item, self->itemsize); if (iszero (tmp, self->itemsize)) return 1; @@ -202,9 +209,9 @@ cuckoo_insert_internal_ (Cuckoo self, void* item) /* find nest */ pos = self->t2 + self->itemsize * (self->h2 (tmp, self->r2) % (2*self->size)); /* kick old egg out */ - xmemcpy (item, pos, self->itemsize); + self->cpy (item, pos, self->itemsize); /* lay egg */ - xmemcpy (pos, tmp, self->itemsize); + self->cpy (pos, tmp, self->itemsize); if (iszero (item, self->itemsize)) return 1; @@ -212,15 +219,15 @@ cuckoo_insert_internal_ (Cuckoo self, void* item) /* find nest */ pos = self->t3 + self->itemsize * (self->h3 (item, self->r3) % self->size); /* kick old egg out */ - xmemcpy (tmp, pos, self->itemsize); + self->cpy (tmp, pos, self->itemsize); /* lay egg */ - xmemcpy (pos, item, self->itemsize); + self->cpy (pos, item, self->itemsize); if (iszero (tmp, self->itemsize)) return 1; /* copy tmp to item, which will be reinserted on next interation / after rehashing */ - xmemcpy (item, tmp, self->itemsize); + self->cpy (item, tmp, self->itemsize); } return 0; } @@ -253,9 +260,9 @@ cuckoo_rehash (Cuckoo self) { char t[self->itemsize]; void* hpos = self->t1 + self->itemsize * hash; - xmemcpy (t, hpos, self->itemsize); - xmemcpy (hpos, pos, self->itemsize); - xmemcpy (pos, t, self->itemsize); + self->cpy (t, hpos, self->itemsize); + self->cpy (hpos, pos, self->itemsize); + self->cpy (pos, t, self->itemsize); if (iszero (t, self->itemsize)) break; } @@ -283,9 +290,9 @@ cuckoo_rehash (Cuckoo self) { char t[self->itemsize]; void* hpos = self->t2 + self->itemsize * hash; - xmemcpy (t, hpos, self->itemsize); - xmemcpy (hpos, pos, self->itemsize); - xmemcpy (pos, t, self->itemsize); + self->cpy (t, hpos, self->itemsize); + self->cpy (hpos, pos, self->itemsize); + self->cpy (pos, t, self->itemsize); if (iszero (t, self->itemsize)) break; } @@ -313,9 +320,9 @@ cuckoo_rehash (Cuckoo self) { char t[self->itemsize]; void* hpos = self->t3 + self->itemsize * hash; - xmemcpy (t, hpos, self->itemsize); - xmemcpy (hpos, pos, self->itemsize); - xmemcpy (pos, t, self->itemsize); + self->cpy (t, hpos, self->itemsize); + self->cpy (hpos, pos, self->itemsize); + self->cpy (pos, t, self->itemsize); if (iszero (t, self->itemsize)) break; } @@ -451,11 +458,11 @@ cuckoo_insert (Cuckoo self, void* item) void* found; if ((found = cuckoo_find (self, item))) { - xmemcpy (found, item, self->itemsize); + self->cpy (found, item, self->itemsize); return 1; } - xmemcpy (tmp, item, self->itemsize); + self->cpy (tmp, item, self->itemsize); for (unsigned n = 6; n; --n) /* rehash/grow loop */ { diff --git a/src/lib/cuckoo.h b/src/lib/cuckoo.h index ed14f6cc8..1576c8e41 100644 --- a/src/lib/cuckoo.h +++ b/src/lib/cuckoo.h @@ -62,6 +62,15 @@ typedef int (*cuckoo_cmpfunc)(const void* item1, const void* item2); */ typedef void (*cuckoo_dtorfunc)(void* item); +/** + * Copy function. + * User supplied item copy function + * @param dest target address for the copy operation + * @param src source for the copy operation + * @param size size of a item (requested size rounded up to the next CUCKOO_GRANULARITY) + */ +typedef void (*cuckoo_cpyfunc)(void* dest, const void* src, size_t size); + /** * Initialize a cuckoo hash. * @param self pointer to a uninitialized cuckoo datastructure @@ -70,7 +79,8 @@ typedef void (*cuckoo_dtorfunc)(void* item); * @param h3 hash function for the third table * @param cmp function which compares two keys * @param startsize initial size of table t3, as 2's exponent - * @param dtor a function used to clean up hash entries, might be NULL if nothing required + * @param dtor function used to clean up hash entries, might be NULL if nothing required + * @param cpy function used to copy hash entries, when NULL is given memcpy wil be used * @return The initialized hashtable or NULL at allocation failure */ Cuckoo @@ -81,7 +91,8 @@ cuckoo_init (Cuckoo self, cuckoo_cmpfunc cmp, size_t itemsize, unsigned startsize, - cuckoo_dtorfunc dtor); + cuckoo_dtorfunc dtor, + cuckoo_cpyfunc cpy); /** * Allocate a new cuckoo hash. @@ -100,7 +111,9 @@ cuckoo_new (cuckoo_hashfunc h1, cuckoo_cmpfunc cmp, size_t itemsize, unsigned startsize, - cuckoo_dtorfunc dtor); + cuckoo_dtorfunc dtor, + cuckoo_cpyfunc cpy); + /** * Destroy a cuckoo hash. From 0fe3d6a059e78822245fd3f84b0457b2cf8206d4 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 20:57:59 +0200 Subject: [PATCH 20/24] filedescriptor fixup for new copy func in cuckoo --- src/backend/filedescriptor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/filedescriptor.c b/src/backend/filedescriptor.c index a4165b58b..6c398dd6c 100644 --- a/src/backend/filedescriptor.c +++ b/src/backend/filedescriptor.c @@ -89,7 +89,7 @@ lumiera_filedescriptor_registry_init (void) TRACE (filedescriptor); REQUIRE (!registry); - registry = cuckoo_new (h1, h2, h3, cmp, sizeof (LumieraFiledescriptor), 3, NULL); + registry = cuckoo_new (h1, h2, h3, cmp, sizeof (LumieraFiledescriptor), 3, NULL, NULL); if (!registry) LUMIERA_DIE (NO_MEMORY); From 238218f7766995663cafcc7638e623b96b69d144 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 12 Aug 2008 21:24:41 +0200 Subject: [PATCH 21/24] WIP: add config_lookup skeleton --- src/backend/Makefile.am | 6 +- src/backend/config.c | 5 ++ src/backend/config.h | 7 +- src/backend/config_lookup.c | 151 ++++++++++++++++++++++++++++++++++++ src/backend/config_lookup.h | 102 ++++++++++++++++++++++++ 5 files changed, 267 insertions(+), 4 deletions(-) create mode 100644 src/backend/config_lookup.c create mode 100644 src/backend/config_lookup.h diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index afe7cc1f3..f9d19d5e1 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -31,7 +31,8 @@ liblumibackend_a_SOURCES = \ $(liblumibackend_a_srcdir)/config.c \ $(liblumibackend_a_srcdir)/config_typed.c \ $(liblumibackend_a_srcdir)/configentry.c \ - $(liblumibackend_a_srcdir)/configitem.c + $(liblumibackend_a_srcdir)/configitem.c \ + $(liblumibackend_a_srcdir)/config_lookup.c noinst_HEADERS += \ @@ -43,5 +44,6 @@ noinst_HEADERS += \ $(liblumibackend_a_srcdir)/filehandlecache.h \ $(liblumibackend_a_srcdir)/config.h \ $(liblumibackend_a_srcdir)/configentry.h \ - $(liblumibackend_a_srcdir)/configitem.h + $(liblumibackend_a_srcdir)/configitem.h \ + $(liblumibackend_a_srcdir)/config_lookup.h diff --git a/src/backend/config.c b/src/backend/config.c index deec72697..b68d30168 100644 --- a/src/backend/config.c +++ b/src/backend/config.c @@ -43,6 +43,7 @@ NOBUG_DEFINE_FLAG_PARENT (config, config_all); NOBUG_DEFINE_FLAG_PARENT (config_typed, config_all); NOBUG_DEFINE_FLAG_PARENT (config_file, config_all); NOBUG_DEFINE_FLAG_PARENT (config_item, config_all); +NOBUG_DEFINE_FLAG_PARENT (config_lookup, config_all); LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX, "syntax error in configfile"); LUMIERA_ERROR_DEFINE (CONFIG_SYNTAX_KEY, "syntax error in key"); @@ -67,9 +68,12 @@ lumiera_config_init (const char* path) NOBUG_INIT_FLAG (config_typed); NOBUG_INIT_FLAG (config_file); NOBUG_INIT_FLAG (config_item); + NOBUG_INIT_FLAG (config_lookup); lumiera_global_config = lumiera_malloc (sizeof (*lumiera_global_config)); lumiera_global_config->path = lumiera_strndup (path, SIZE_MAX); + lumiera_config_lookup_init (&lumiera_global_config->keys); + lumiera_rwlock_init (&lumiera_global_config->lock, "config rwlock", &NOBUG_FLAG (config)); return 0; @@ -83,6 +87,7 @@ lumiera_config_destroy () if (lumiera_global_config) { lumiera_rwlock_destroy (&lumiera_global_config->lock, &NOBUG_FLAG (config)); + lumiera_config_lookup_destroy (&lumiera_global_config->keys); lumiera_free (lumiera_global_config->path); lumiera_free (lumiera_global_config); lumiera_global_config = NULL; diff --git a/src/backend/config.h b/src/backend/config.h index 1daf54087..80a3f787f 100644 --- a/src/backend/config.h +++ b/src/backend/config.h @@ -40,6 +40,8 @@ NOBUG_DECLARE_FLAG (config_typed); NOBUG_DECLARE_FLAG (config_file); /* single config items */ NOBUG_DECLARE_FLAG (config_item); +/* lookup config keys */ +NOBUG_DECLARE_FLAG (config_lookup); LUMIERA_ERROR_DECLARE (CONFIG_SYNTAX); @@ -49,7 +51,7 @@ LUMIERA_ERROR_DECLARE (CONFIG_NO_ENTRY); LUMIERA_ERROR_DECLARE (CONFIG_DEFAULT); //TODO: Lumiera header includes// - +#include "backend/config_lookup.h" //TODO: System includes// #include @@ -65,7 +67,8 @@ LUMIERA_ERROR_DECLARE (CONFIG_DEFAULT); struct lumiera_config_struct { - // cuckoo hash + lumiera_config_lookup keys; + // configfile list char* path; /* diff --git a/src/backend/config_lookup.c b/src/backend/config_lookup.c new file mode 100644 index 000000000..b0b6caeaa --- /dev/null +++ b/src/backend/config_lookup.c @@ -0,0 +1,151 @@ +/* + config_lookup.c - Lookup functions for the config subsystem + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +//TODO: Support library includes// +#include "lib/safeclib.h" + + +//TODO: Lumiera header includes// +#include "backend/config_lookup.h" +#include "backend/config.h" + +//TODO: System includes// +//#include +//#include + +//TODO: internal/static forward declarations// +static size_t +h1 (const void* item, const uint32_t r); + +static size_t +h2 (const void* item, const uint32_t r); + +static size_t +h3 (const void* item, const uint32_t r); + +static int +cmp (const void* keya, const void* keyb); + +static int +cmp (const void* keya, const void* keyb); + +/** + * @file + * + */ + + +//code goes here// + + + +LumieraConfigLookup +lumiera_config_lookup_init (LumieraConfigLookup self) +{ + self->hash = cuckoo_new (h1, h2, h3, cmp, sizeof (lumiera_config_lookupentry), 3, NULL, NULL); // TODO copy func, dtor + return self; +} + + +LumieraConfigLookup +lumiera_config_lookup_destroy (LumieraConfigLookup self) +{ + cuckoo_delete (self->hash); + return self; +} + + + + + + +LumieraConfigLookupentry +lumiera_config_lookupentry_new (const char* prefix, const char* name, const char* suffix) +{ + char* tmpstr = lumiera_tmpbuf_snprintf (LUMIERA_CONFIG_KEY_MAX, "%s%s%s%s%s", + prefix?prefix:"", prefix?".":"", + name?name:"", + suffix?".":"", suffix?suffix:""); + + TRACE (config_lookup, "new key %s", tmpstr); + + LumieraConfigLookupentry self = lumiera_malloc (sizeof (*self)); + + self->full_key = lumiera_strndup (tmpstr, LUMIERA_CONFIG_KEY_MAX); + llist_init (&self->configitems); + + return self; +} + +void +lumiera_config_lookupentry_delete (LumieraConfigLookupentry self) +{ + TRACE (config_lookup); + + lumiera_free (self->full_key); + ENSURE (llist_is_empty (&self->configitems)); + lumiera_free (self); +} + + + + +/* + Support functions for the cuckoo hash +*/ + +static size_t +h1 (const void* item, const uint32_t r) +{ + (void) item; + return r; +} + +static size_t +h2 (const void* item, const uint32_t r) +{ + (void) item; + return r; +} + +static size_t +h3 (const void* item, const uint32_t r) +{ + (void) item; + return r; +} + +static int +cmp (const void* keya, const void* keyb) +{ + (void) keya; + (void) keyb; + + return 0; +} + +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ diff --git a/src/backend/config_lookup.h b/src/backend/config_lookup.h new file mode 100644 index 000000000..cb653dab8 --- /dev/null +++ b/src/backend/config_lookup.h @@ -0,0 +1,102 @@ +/* + config_lookup.h - Lookup functions for the config subsystem + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef LUMIERA_CONFIG_LOOKUP_H +#define LUMIERA_CONFIG_LOOKUP_H + +//TODO: Support library includes// +#include "lib/cuckoo.h" +#include "lib/llist.h" + + +//TODO: Forward declarations// + + +//TODO: Lumiera header includes// + + +//TODO: System includes// +#include + + +/** + * @file + * + */ + +#define LUMIERA_CONFIG_KEY_MAX 1023 + + + +//TODO: declarations go here// + +/* + Lookup uses a cuckoo hash for now +*/ + +struct lumiera_config_lookup_struct +{ + Cuckoo hash; +}; +typedef struct lumiera_config_lookup_struct lumiera_config_lookup; +typedef lumiera_config_lookup* LumieraConfigLookup; + +LumieraConfigLookup +lumiera_config_lookup_init (LumieraConfigLookup self); + +LumieraConfigLookup +lumiera_config_lookup_destroy (LumieraConfigLookup self); + + + +/* + Lookup hash entries for the cuckoo hash +*/ + +struct lumiera_config_lookupentry_struct +{ + /* + we store a copy of the full key here + configentry keys are complete as expected + section keys are the prefix stored with a trailing dot + */ + char* full_key; + /* stack of all configitems stored under this key */ + llist configitems; +}; +typedef struct lumiera_config_lookupentry_struct lumiera_config_lookupentry; +typedef lumiera_config_lookupentry* LumieraConfigLookupentry; + +LumieraConfigLookupentry +lumiera_config_lookupentry_init (const char* prefix, const char* name, const char* suffix); + +void +lumiera_config_lookupentry_destroy (LumieraConfigLookupentry self); + + +#endif +/* +// Local Variables: +// mode: C +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +*/ From 2f776858eeba6f3241b6cbc829d5a7ff916f4eb6 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 13 Aug 2008 09:20:08 +0200 Subject: [PATCH 22/24] FIX: Remove llist_move again and put a note to list_relocate, add test There was a fatal thinko, llist_relocate NUST NOT be called on a empty list, the pointers will just point to invaildated memory. This cant be handled by the llist code. The programmer is responsible to take proper actions. --- src/lib/llist.h | 14 +++----------- tests/15list.tests | 4 +++- tests/library/test-llist.c | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/lib/llist.h b/src/lib/llist.h index 3cb70f8ea..353fe4320 100644 --- a/src/lib/llist.h +++ b/src/lib/llist.h @@ -299,6 +299,9 @@ LLIST_FUNC (LList llist_unlink (LList self), /** * Fix a node which got relocated in memory. * It is supported to realloc/move list nodes in memory but one must call 'list_relocate' after doing so. + * IMPORTANT: it is not possible to relocate nodes which are empty this way, nor can this be determined + * after the relocation, so either llist_init them afterwards or insert a bogus node before moving the node + * and relocating it and remove it afterwards. * @param self node which got relocated * @return self */ @@ -306,17 +309,6 @@ LLIST_FUNC (LList llist_relocate (LList self), return self->next->prev = self->prev->next = self; ); -/** - * Move a node from one memory location to another. - * @param self target of the move, must be uninitialized or empty before this move - * @param source source of the move, will be initialized to a empty list after this call - * @return self - */ -LLIST_FUNC (LList llist_move (LList self, LList source), - *self = *source; - llist_init (source); - return llist_relocate (self); -); /** * Insert a node after another. diff --git a/tests/15list.tests b/tests/15list.tests index 88aef3c49..e04044f27 100644 --- a/tests/15list.tests +++ b/tests/15list.tests @@ -44,9 +44,11 @@ out: . out: . END +TEST "llist_relocate" relocate < Date: Wed, 13 Aug 2008 10:50:27 +0200 Subject: [PATCH 23/24] Fixed configitem_move, first parsing tests pass now --- src/backend/configitem.c | 12 ++++++++---- tests/20config.tests | 4 ++-- tests/backend/test-config.c | 20 +++++++------------- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index 7e52f269e..a49694280 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -77,7 +77,7 @@ lumiera_configitem_destroy (LumieraConfigitem self) if (self->vtable && self->vtable->destroy) self->vtable->destroy (self); - ENSURE (!llist_is_empty (&self->lookup), "destructor didn't cleaned lookup up"); + ENSURE (llist_is_empty (&self->lookup), "destructor didn't cleaned lookup up"); ENSURE (llist_is_empty (&self->childs), "destructor didn't remove childs"); llist_unlink (&self->link); @@ -122,12 +122,16 @@ lumiera_configitem_move (LumieraConfigitem self, LumieraConfigitem source) REQUIRE (self); REQUIRE (source); - llist_move (&self->link, &source->link); + llist_init (&self->link); + llist_insertlist_next (&self->link, &source->link); self->parent = source->parent; - llist_move (&self->childs, &source->childs); - llist_move (&self->lookup, &source->lookup); + llist_init (&self->childs); + llist_insertlist_next (&self->childs, &source->childs); + + llist_init (&self->lookup); + llist_insertlist_next (&self->lookup, &source->lookup); self->line = source->line; source->line = NULL; diff --git a/tests/20config.tests b/tests/20config.tests index 65dfb5404..7a4ea2517 100644 --- a/tests/20config.tests +++ b/tests/20config.tests @@ -135,8 +135,8 @@ END PLANNED "bool set" < Date: Wed, 27 Aug 2008 11:00:10 +0200 Subject: [PATCH 24/24] Added directive-parser and tests for a content-check of a parsed configitem --- src/backend/configitem.c | 54 +++++++++++++++++++++++++++++++++++ tests/20config.tests | 56 +++++++++++++++++++++++++++++++++++++ tests/backend/test-config.c | 31 ++++++++++++++++++++ 3 files changed, 141 insertions(+) diff --git a/src/backend/configitem.c b/src/backend/configitem.c index a49694280..9ce36328b 100644 --- a/src/backend/configitem.c +++ b/src/backend/configitem.c @@ -208,6 +208,60 @@ lumiera_configitem_parse (LumieraConfigitem self, const char* line) else if (*itr == '@' ) { /*this is a directive*/ + + /*itr points now to @*/ + self->key = itr; + + /*check whether there are illegal whitespaces after @*/ + itr++; + if (*itr && !isspace(*itr)) + { + /*now look for the end of the directive and set the keysize*/ + self->key_size = strspn (itr, LUMIERA_CONFIG_KEY_CHARS); + + itr += self->key_size; + + /*we need a key with a length greather than zero and + * either the end of the line + * or a whitespace after the key */ + + if ( self->key_size && ( !*itr || (*itr && isspace(*itr)) )) + { + /*look for given arguments*/ + + /*skip blanks*/ + while (*itr && isspace (*itr)) + itr++; + + if (*itr) + { + /*there are arguments given, thus set delim*/ + self->delim = itr - 1; + } + else + { + /*no arguments were given*/ + self->delim = NULL; + } + } + else + { + /*malformed lines shall be treated like if they were comments*/ + self->key = NULL; + self->key_size = 0; + + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + } + } + else + { + /*there occurred already an error right after the @!*/ + /*malformed lines shall be treated like if they were comments*/ + self->key = NULL; + self->key_size = 0; + + LUMIERA_ERROR_SET (config_item, CONFIG_SYNTAX); + } } else if (*itr == '[' ) { diff --git a/tests/20config.tests b/tests/20config.tests index 7a4ea2517..4f2ba9018 100644 --- a/tests/20config.tests +++ b/tests/20config.tests @@ -140,3 +140,59 @@ END TEST "create configitem with blank line" configitem_simple_ctor_dtor $' \t \t' <line = ' #comment bla' +END + +TEST "check content of configitem with section" configitem_simple_content_check $'[ key.foo suffix.bar ] ' << END +out: item->line = '[ key.foo suffix.bar ] ' +out: item->key_size = '7' +out: item->key = 'key.foo suffix.bar ] ' +out: item->delim = ' suffix.bar ] ' +END + +TEST "check content of configitem with directive (without argument)" configitem_simple_content_check $'\t @directive ' << END +out: item->line = ' @directive ' +out: item->key_size = '9' +out: item->key = '@directive ' +END + +TEST "check content of configitem with directive (with argument)" configitem_simple_content_check $'\t @directive \targument' << END +out: item->line = ' @directive argument' +out: item->key_size = '9' +out: item->key = '@directive argument' +out: item->delim = ' argument' +END + +TEST "check content of configitem with configentry" configitem_simple_content_check $' \t\t key.foo \t\t=\tbar' << END +out: item->line = ' key.foo = bar' +out: item->key_size = '7' +out: item->key = 'key.foo = bar' +out: item->delim = '= bar' +END + +TEST "check content of configitem with configentry (redirect)" configitem_simple_content_check $' \t\t key.foo \t\t<\tkey.bar' << END +out: item->line = ' key.foo < key.bar' +out: item->key_size = '7' +out: item->key = 'key.foo < key.bar' +out: item->delim = '< key.bar' +END diff --git a/tests/backend/test-config.c b/tests/backend/test-config.c index 1369aa8bc..eae982fc6 100644 --- a/tests/backend/test-config.c +++ b/tests/backend/test-config.c @@ -141,5 +141,36 @@ TEST ("configitem_simple_ctor_dtor") lumiera_config_destroy (); } +TEST ("configitem_simple_content_check") +{ + REQUIRE (argv[2]); + lumiera_config_init ("./"); + + LumieraConfigitem item; + + item = lumiera_configitem_new (argv[2]); + + if ( item->line ) + { + printf("item->line = \'%s\'\n", item->line); + } + if ( item->key_size ) + { + printf("item->key_size = \'%i\'\n", item->key_size); + } + if ( item->key ) + { + printf("item->key = \'%s\'\n", item->key); + } + if ( item->delim ) + { + printf("item->delim = \'%s\'\n", item->delim); + } + + lumiera_configitem_delete (item); + + lumiera_config_destroy (); +} + TESTS_END