From: Arjen Baart Date: Sun, 9 Feb 2020 10:02:12 +0000 (+0100) Subject: Add class configuration X-Git-Tag: V0.3~1 X-Git-Url: http://www.andromeda.nl/gitweb/?a=commitdiff_plain;h=450cb07e7aac0e38fe461580f222034c219d3214;p=libacl.git Add class configuration --- diff --git a/ChangeLog b/ChangeLog index 169770f..fb8153d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ - Add parameter bool localtime to now() and today() - String: Boundary checking on index and subtring operators - Ported class Integer from the Gnu libg++ library. + - Added date::Weekday() + - Added class configration Oct 31, 2019 - Release 0.2 ============================ diff --git a/TODO b/TODO index 42de7cc..ce2e1d5 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,7 @@ Things to do: - String: format operator % like in python - String: split and join - String: assign fstream objects to read and write a file +- regex: throw an exception when contructing a regex returns an error - date: test parser for invalid dates and syntax errors - date: Parser for stream input diff --git a/config.h.in b/config.h.in index 3ab1027..31bc546 100644 --- a/config.h.in +++ b/config.h.in @@ -24,6 +24,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LIBINTL_H +/* Define to 1 if you have the `xml2' library (-lxml2). */ +#undef HAVE_LIBXML2 + /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC diff --git a/configure.ac b/configure.ac index 1d282cb..19c4c15 100644 --- a/configure.ac +++ b/configure.ac @@ -17,10 +17,24 @@ AM_PROG_AR # Checks for libraries. +AC_PATH_PROG(XML_CONFIG,xml2-config,no) + +if test $XML_CONFIG = "no" +then + echo "XML library not found (see http://xmlsoft.org/)." + exit 1; +fi + +XML_CFLAGS=`$XML_CONFIG --cflags` +XML_LFLAGS=`$XML_CONFIG --libs` +AC_CHECK_LIB(xml2, xmlParseFile) + # Checks for header files. AC_FUNC_ALLOCA AC_CHECK_HEADERS([libintl.h malloc.h stddef.h stdlib.h string.h]) +CXXFLAGS="$CXXFLAGS $X_CFLAGS $XML_CFLAGS -Wall" +LDFLAGS="$LDFLAGS $XML_LFLAGS" # Checks for typedefs, structures, and compiler characteristics. AC_CHECK_HEADER_STDBOOL AC_TYPE_SIZE_T diff --git a/src/Integer.cpp b/src/Integer.cpp index 57de7d2..e116478 100644 --- a/src/Integer.cpp +++ b/src/Integer.cpp @@ -2257,7 +2257,6 @@ char* cvtItoa(const IntRep* x, char* fmt, int& fmtlen, int base, int showbase, else { char* p = fmt; - int gap = s - p; for (char* t = s; *t != 0; ++t, ++p) *p = *t; while (w++ < width) *p++ = fillchar; *p = 0; diff --git a/src/Makefile.am b/src/Makefile.am index fc7abab..a52770b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,8 +2,9 @@ lib_LTLIBRARIES = libACL.la libACL_la_SOURCES = string.cpp regex.cpp date.cpp parsedate.c dateyacc.y datelex.c \ hour.cpp utc.cpp \ - Integer.cpp + Integer.cpp \ + configuration.cpp libACL_la_LDFLAGS = -version-info 2:2:0 -include_HEADERS = String.h date.h Integer.h +include_HEADERS = String.h date.h Integer.h configuration.h diff --git a/src/configuration.cpp b/src/configuration.cpp new file mode 100644 index 0000000..cbd2745 --- /dev/null +++ b/src/configuration.cpp @@ -0,0 +1,252 @@ + +/************************************************************************** +** (c) Copyright 2002, Andromeda Technology & Automation +*************************************************************************** +** MODULE INFORMATION * +*********************** +** FILE NAME : configuration.cpp +** SYSTEM NAME : AXE - Andromeda X-windows Encapsulation +** VERSION NUMBER : $Revision: 1.6 $ +** +** DESCRIPTION : Implementation of configuration class +** +** EXPORTED OBJECTS : +** LOCAL OBJECTS : +** MODULES USED : +*************************************************************************** +** ADMINISTRATIVE INFORMATION * +******************************** +** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl +** CREATION DATE : Jul 23, 2002 +** LAST UPDATE : Apr 13, 2007 +** MODIFICATIONS : +**************************************************************************/ + +/***************************** + $Log: configuration.cpp,v $ + Revision 1.6 2007-05-04 14:01:22 arjen + Added new arguments to configuration::find_parameter() to allow for a list of + sections and a list of parameters in sections. + The new arguments are section index and parameter index (default = 0). + + Revision 1.5 2003/03/29 07:19:37 arjen + Bugfix: Do not read the config file in the home + directory if the HOME environment variable doesn't exist + + Revision 1.4 2002/11/23 12:48:18 arjen + Check if a configuration file exists before feeding it to the XML parser. + + Revision 1.3 2002/11/02 14:35:15 arjen + Uses the XML2 library + BugFix: segfault when finding a parameters that is not in the user-sepcific + config tree. + + Revision 1.2 2002/09/28 06:48:46 arjen + Bugfix: In configuration::find_parameter(), check if the parameter node exists + before retrieving its contents. + + Revision 1.1 2002/07/25 08:01:26 arjen + First checkin, AXE release 0.2 + +*****************************/ + +#include +#include +#include "configuration.h" + + +/*========================================================================= +** NAME : configuration::read +** SYNOPSIS : +** PARAMETERS : +** RETURN VALUE : true if any config files were found +** +** DESCRIPTION : +** +** VARS USED : +** VARS CHANGED : +** FUNCTIONS USED : +** SEE ALSO : +** LAST MODIFIED : Nov 22, 2002 +**========================================================================= +*/ + +bool configuration::read(const String name) +{ + String filename; + + app_name = name; + + // Try to read the config files. + // Two configuarions are read. The system and the user config. + // First system config in /etc and if it does not exist, in /usr/local/etc + + filename = "/etc/" + name + ".conf"; + // Check if we can read the file. + + int fd = open(filename, O_RDONLY); + if (fd < 0) + { + filename = "/usr/local/etc/" + name + ".conf"; + fd = open(filename, O_RDONLY); + } + + if (fd > 0) + { + close(fd); + system = xmlParseFile(filename); + } + + // The user config is read from the current directory. + // If that does not exist, try the home directory. + + filename = name + ".conf"; + fd = open(filename, O_RDONLY); + if (fd < 0) + { + if (getenv("HOME") != NULL) + { + filename = getenv("HOME"); + filename += "/."; + filename += name + ".conf"; + fd = open(filename, O_RDONLY); + } + } + if (fd > 0) + { + close(fd); + user = xmlParseFile(filename); + } + + // Check the root element, which must be the application name + + xmlNodePtr root; + + if (system != NULL) + { + root = xmlDocGetRootElement(system); + if (app_name != (const char *)root->name) + { + std::cerr << "Wrong config file.\n"; + xmlFreeDoc(system); + system = NULL; + } + } + + if (user != NULL) + { + root = xmlDocGetRootElement(user); + if (app_name != (const char *)root->name) + { + std::cerr << "Wrong config file.\n"; + xmlFreeDoc(user); + user = NULL; + } + } + + return system != NULL || user != NULL; +} + +/*========================================================================= +** NAME : configuration::xmlFindTag +** SYNOPSIS : +** PARAMETERS : +** RETURN VALUE : Pointer to the XML element or NULL +** +** DESCRIPTION : +** +** VARS USED : +** VARS CHANGED : +** FUNCTIONS USED : +** SEE ALSO : +** LAST MODIFIED : Apr 13, 2007 +**========================================================================= +*/ + +xmlNodePtr configuration::xmlFindTag(xmlNodePtr node, const String tag, int n) +{ + xmlNodePtr element = NULL; + + while (element == NULL && node != NULL) + { + if (node->type == XML_ELEMENT_NODE && tag == (char *)node->name) + { + if (n == 0) + { + element = node; + } + n--; + } + node = node->next; + } + + return element; +} + +/*========================================================================= +** NAME : configuration::find_parameter +** SYNOPSIS : +** PARAMETERS : +** RETURN VALUE : The content of the parameter or an empty string +** +** DESCRIPTION : +** +** VARS USED : +** VARS CHANGED : +** FUNCTIONS USED : +** SEE ALSO : +** LAST MODIFIED : Apr 13, 2007 +**========================================================================= +*/ + +String configuration::find_parameter(const String section, const String parameter, int sec_n, int param_n) +{ + xmlNodePtr root_node; + xmlNodePtr section_node; + xmlNodePtr param_node; + + String param_value(""); + + // First, we try to find the parameter in the system-wide config + + if (system) + { + root_node = xmlDocGetRootElement(system); + section_node = xmlFindTag(root_node->children, section, sec_n); + if (section_node != NULL) + { + param_node = xmlFindTag(section_node->children, parameter, param_n); + if (param_node != NULL) + { + param_node = param_node->children; + } + if (param_node != NULL) + { + param_value = (char *)param_node->content; + } + } + } + + // If the parameter is also defined in the user config, it will override + // the system-wide value. + + if (user) + { + root_node = xmlDocGetRootElement(user); + section_node = xmlFindTag(root_node->children, section, sec_n); + if (section_node != NULL) + { + param_node = xmlFindTag(section_node->children, parameter, param_n); + if (param_node != NULL) + { + param_node = param_node->children; + } + if (param_node != NULL) + { + param_value = (char *)param_node->content; + } + } + } + + return param_value; +} diff --git a/src/configuration.h b/src/configuration.h new file mode 100644 index 0000000..c894a43 --- /dev/null +++ b/src/configuration.h @@ -0,0 +1,107 @@ +/************************************************************************** +** (c) Copyright 2002, Andromeda Technology & Automation +*************************************************************************** +** MODULE INFORMATION * +*********************** +** FILE NAME : configuration.h +** SYSTEM NAME : AXE - Andromeda X-windows Encapsulation +** VERSION NUMBER : $Revision: 1.4 $ +** +** DESCRIPTION : Definition of configuration class +** +** EXPORTED OBJECTS : class configuration +** LOCAL OBJECTS : +** MODULES USED : String +*************************************************************************** +** ADMINISTRATIVE INFORMATION * +******************************** +** ORIGINAL AUTHOR : Arjen Baart - arjen@andromeda.nl +** CREATION DATE : Nov 02, 2002 +** LAST UPDATE : +** MODIFICATIONS : +**************************************************************************/ + +/***************************** + $Log: configuration.h,v $ + Revision 1.4 2007-05-04 14:01:22 arjen + Added new arguments to configuration::find_parameter() to allow for a list of + sections and a list of parameters in sections. + The new arguments are section index and parameter index (default = 0). + + Revision 1.3 2002/11/02 14:35:15 arjen + Uses the XML2 library + BugFix: segfault when finding a parameters that is not in the user-sepcific + config tree. + + Revision 1.2 2002/09/02 06:18:20 arjen + Fixed some date and time conversion functions + + Revision 1.1 2002/07/25 08:01:26 arjen + First checkin, AXE release 0.2 + +*****************************/ + +/* static const char *RCSID = "$Id: configuration.h,v 1.4 2007-05-04 14:01:22 arjen Exp $"; */ + +#ifndef CONFIGURATION_H +#define CONFIGURATION_H + +#include // usually in /usr/include/libxml2, see xml2-config + +#include "String.h" + +/* +/////////////////////////////////////////////////////////////////////////// +// NAME : configuration +// BASECLASS : +// MEMBERS : +// OPERATORS : +// METHODS : read +// find_parameter +// +// DESCRIPTION : Handle configurational parameters for the application. +// Many applications need some permanently stored configurational +// data. The information is usually stored in two places: A system- +// wide configuration file and a configuration file per user. +// The content of the configuration file is in XML format. +// The configuration base class takes care of finding the configuration +// files, e.g. in /etc/app.conf or in /usr/local/etc/app.conf, along +// with the configuration file in the user's home directory. +// The config files are parsed with the gnome XML parser and a +// framework is provided to find configurational items. +// +// RELATIONS : +// SEE ALSO : +// LAST MODIFIED : Apr 13, 2007 +/////////////////////////////////////////////////////////////////////////// +*/ + +class configuration +{ + + xmlDocPtr system; // The system-wide config tree + xmlDocPtr user; // User-specific config tree + String app_name; // Name of the application and XML root element + + xmlNodePtr xmlFindTag(xmlNodePtr, const String, int n = 0); + +public: + + configuration() + { + system = NULL; + user = NULL; + app_name = "ACL"; + } + + // Find the config files and parse the XML + + bool read(const String name); + + // Return the value of a config parameter + + String find_parameter(const String section, const String parameter, int sec_n = 0, int param_n = 0); + +}; + +#endif // CONFIGURATION_H diff --git a/src/date.cpp b/src/date.cpp index f9dd5ac..d988778 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -41,8 +41,6 @@ *****************************/ -static const char *RCSID = "$Id: date.cpp,v 1.3 2002-09-28 06:58:45 arjen Exp $"; - #include #include #include "date.h" diff --git a/src/hour.cpp b/src/hour.cpp index 7c762b5..eb1741e 100644 --- a/src/hour.cpp +++ b/src/hour.cpp @@ -41,8 +41,6 @@ *****************************/ -static const char *RCSID = "$Id: hour.cpp,v 1.3 2002-09-28 06:58:45 arjen Exp $"; - #include #include "date.h" diff --git a/src/regex.cpp b/src/regex.cpp index 2ec3132..ae4de84 100644 --- a/src/regex.cpp +++ b/src/regex.cpp @@ -35,8 +35,6 @@ *****************************/ -static const char RCSID[] = "$Id: regex.cpp,v 1.3 2007/05/04 13:56:05 arjen Exp $"; - #include #include #include "String.h" @@ -47,18 +45,24 @@ regex::regex(const String ®) { original = reg; int error = regcomp (&expression, reg.p->s, REG_EXTENDED); + + //TODO: Handle error } regex::regex(const char *reg) { original = reg; int error = regcomp (&expression, reg, REG_EXTENDED); + + //TODO: Handle error } regex::regex(const regex & reg) { original = reg.original; int error = regcomp (&expression, reg.original, REG_EXTENDED); + + //TODO: Handle error } regex::~regex() diff --git a/test/ACL.conf b/test/ACL.conf new file mode 100644 index 0000000..d2a3aa8 --- /dev/null +++ b/test/ACL.conf @@ -0,0 +1,7 @@ + + +
+ Test1 +
+
+ diff --git a/test/ACL_wrong.conf b/test/ACL_wrong.conf new file mode 100644 index 0000000..d2a3aa8 --- /dev/null +++ b/test/ACL_wrong.conf @@ -0,0 +1,7 @@ + + +
+ Test1 +
+
+ diff --git a/test/Makefile.am b/test/Makefile.am index 7a33525..cb977a1 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -6,7 +6,8 @@ check_PROGRAMS = string_assign string_basics string_compare string_cat string_su date_assign date_parse date_compare date_arithmetic date_attributes date_check_today \ hour_assign hour_parse hour_compare hour_arithmetic hour_check_now \ utc_assign utc_compare utc_arithmetic \ - integer_assign integer_factorial integer_fibonacci integer_pow64 integer_modulo + integer_assign integer_factorial integer_fibonacci integer_pow64 integer_modulo \ + configuration_read configuration_find string_assign_SOURCES = string_assign.cpp string_basics_SOURCES = string_basics.cpp @@ -41,3 +42,6 @@ integer_factorial_SOURCES = integer_factorial.cpp tInteger.cpp integer_fibonacci_SOURCES = integer_fibonacci.cpp tInteger.cpp integer_pow64_SOURCES = integer_pow64.cpp tInteger.cpp integer_modulo_SOURCES = integer_modulo.cpp tInteger.cpp + +configuration_read_SOURCES = configuration_read.cpp +configuration_find_SOURCES = configuration_find.cpp diff --git a/test/configuration_find.cpp b/test/configuration_find.cpp new file mode 100644 index 0000000..beb1647 --- /dev/null +++ b/test/configuration_find.cpp @@ -0,0 +1,34 @@ +/******************************************************* + * Unit test for the configuration class + * + * test finding configuration parameters + ****************************************************** + * + */ + +#include "configuration.h" +#include + +int main() +{ + configuration config1; + bool result; + String value; + + result = config1.read("ACL"); + assert(result == true); + + value = config1.find_parameter("section", "parameter"); + assert(value == "Test1"); + + // Wrong parameter + value = config1.find_parameter("section", "not_exist"); + assert(value == ""); + + // Wrong section + value = config1.find_parameter("not_exist", "parameter"); + assert(value == ""); + + return 0; +} + diff --git a/test/configuration_read.cpp b/test/configuration_read.cpp new file mode 100644 index 0000000..974a804 --- /dev/null +++ b/test/configuration_read.cpp @@ -0,0 +1,28 @@ +/******************************************************* + * Unit test for the configuration class + * + * test reading the configuration file + ****************************************************** + * + */ + +#include "configuration.h" +#include + +int main() +{ + configuration config1; + bool result; + + result = config1.read("ACL_not_exist"); + assert(result == false); + + result = config1.read("ACL"); + assert(result == true); + + result = config1.read("ACL_wrong"); + assert(result == false); + + return 0; +} + diff --git a/test/configuration_read.exp b/test/configuration_read.exp new file mode 100644 index 0000000..2320687 --- /dev/null +++ b/test/configuration_read.exp @@ -0,0 +1,2 @@ +Wrong config file. +PASS configuration_read (exit status: 0)