From c958aa29fbbd1dd061f5718f0d3bc69c49f6a73d Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Mon, 11 Aug 2008 17:22:15 +0200 Subject: [PATCH] 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);