- 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
============================
- 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
/* Define to 1 if you have the <libintl.h> 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
# 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
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;
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
--- /dev/null
+
+/**************************************************************************
+** (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 <fcntl.h>
+#include <unistd.h>
+#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;
+}
--- /dev/null
+/**************************************************************************
+** (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 <libxml/parser.h> // 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
*****************************/
-static const char *RCSID = "$Id: date.cpp,v 1.3 2002-09-28 06:58:45 arjen Exp $";
-
#include <iostream>
#include <time.h>
#include "date.h"
*****************************/
-static const char *RCSID = "$Id: hour.cpp,v 1.3 2002-09-28 06:58:45 arjen Exp $";
-
#include <time.h>
#include "date.h"
*****************************/
-static const char RCSID[] = "$Id: regex.cpp,v 1.3 2007/05/04 13:56:05 arjen Exp $";
-
#include <stdio.h>
#include <ctype.h>
#include "String.h"
{
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()
--- /dev/null
+<?xml version='1.0'?>
+<ACL version='0.2.0'>
+ <section>
+ <parameter>Test1</parameter>
+ </section>
+</ACL>
+
--- /dev/null
+<?xml version='1.0'?>
+<ACL version='0.2.0'>
+ <section>
+ <parameter>Test1</parameter>
+ </section>
+</ACL>
+
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
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
--- /dev/null
+/*******************************************************
+ * Unit test for the configuration class
+ *
+ * test finding configuration parameters
+ ******************************************************
+ *
+ */
+
+#include "configuration.h"
+#include <assert.h>
+
+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;
+}
+
--- /dev/null
+/*******************************************************
+ * Unit test for the configuration class
+ *
+ * test reading the configuration file
+ ******************************************************
+ *
+ */
+
+#include "configuration.h"
+#include <assert.h>
+
+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;
+}
+
--- /dev/null
+Wrong config file.
+PASS configuration_read (exit status: 0)