- UTC: Convert to and from struct tm
-- xml: Add access to attributes
- xml: Xinclude processing
+
+- configuraion: Handle environment variables to override parameters
--- /dev/null
+<chapter>
+<heading>configuration - Class for configuration parameters</heading>
+
+<pre>
+#include <configuration.h>
+
+configuration config;
+</pre>
+
+<para>
+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.
+
+</para>
+
+<section>
+<heading>Class configuration</heading>
+<para>
+Hold the configuration data for an application.
+Both the system-wide configuration and a user-specific configuration are stores in a configuration object.
+
+<description>
+<item tag="configuration()">
+The default constructor creates an empty configuration.
+</item>
+<item tag="read(String name)">
+Find the config files and parse the XML.
+Both the filename and the root element of the XML files must match the name.
+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.
+The user config is read from the current directory.
+If that does not exist, try the home directory.
+</item>
+</description>
+</para>
+
+<description>
+<item tag="find_parameter(String section, String parameter, int sec_nr = 0, int param_n = 0)">
+Return the value of a config parameter.
+The parameter is obtained from the system-wide config.
+If the parameter is also defined in the user config, this will override the value in the system config.
+</item>
+</description>
+
+</section>
+
+
+</chapter>
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="xml.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="configuration.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
</book>
</doc>
<item tag="UTC(String s)">
Parse the date and time from String s.
</item>
+<item tag="UTC(time_t clock)">
+Convert the UNIX time_t, defined as the number of seconds since the Epoch to a UTC object.
+</item>
</description>
</para>
<para>
String()
</para>
+<para>
+time_t() - Convert to the UNIX time_t.
+</para>
</section>
<description>
<item tag="UTC operator+(UTC &t1, UTC &t2)"></item>
-<item tag="UTC operator-(UTC &t1, UTC &t2)"></item>
+<item tag="long operator-(UTC &t1, UTC &t2)">
+Calculate the number of seconds from t2 to t1;
+</item>
<item tag="UTC &operator+=(UTC &t)"></item>
<item tag="UTC &operator-=(UTC &t)"></item>
<item tag="UTC &operator++()">
<item tag="std::vector<xml_element> operator[](String tagname);">
Find the child elements with the specified tagname.
</item>
+<item tag="String attribute(String name);">
+Find the value of an attribute.
+Return an empty string is the attribute does not exist.
+</item>
+<item tag="std::map<String, String> attributes(void);">
+Find all attributes of the element in a map.
+</item>
</description>
</section>
** MODULE INFORMATION *
***********************
** FILE NAME : configuration.cpp
-** SYSTEM NAME : AXE - Andromeda X-windows Encapsulation
+** SYSTEM NAME : ACL - Andromeda Class Library
** VERSION NUMBER : $Revision: 1.6 $
**
** DESCRIPTION : Implementation of configuration class
** 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"
** MODULE INFORMATION *
***********************
** FILE NAME : configuration.h
-** SYSTEM NAME : AXE - Andromeda X-windows Encapsulation
+** SYSTEM NAME : ACL - Andromeda class Library
** VERSION NUMBER : $Revision: 1.4 $
**
** DESCRIPTION : Definition of configuration class
**
** EXPORTED OBJECTS : class configuration
** LOCAL OBJECTS :
-** MODULES USED : String
+** MODULES USED : String, XML
***************************************************************************
** ADMINISTRATIVE INFORMATION *
********************************
** 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
if (_ss.size() != 0)
{
joined = _ss[0];
- for (int i = 1; i < _ss.size(); i++)
+ for (unsigned i = 1; i < _ss.size(); i++)
{
joined += separator + _ss[i];
}
#include "xml.h"
+/*
+ * class xml
+ */
+
void xml::ParseFile(const char * filename)
{
ctxt = xmlNewParserCtxt();
- //document = xmlParseFile(filename);
document = xmlCtxtReadFile(ctxt, filename, NULL, XML_PARSE_NOWARNING|XML_PARSE_NOERROR);
}
return root_name;
}
+/*
+ * class xml_node
+ */
+
xml_node xml::RootNode(void)
{
xmlNodePtr root;
return xml_node(root);
}
-//xml_node::xml_node(xml doc)
-//{
-// *this = doc.RootNode();
-//}
-
// Find the nth child element by name (non-recursive)
xml_node xml_node::operator[](int i)
{
}
+/*
+ * class xml_element
+ */
+
std::vector<xml_element> xml_element::operator[](String tagname)
{
std::vector<xml_element> elements_found;
return elements_found;
}
+
+String xml_element::attribute(String name)
+{
+ String value;
+
+ struct _xmlAttr *prop_list;
+ prop_list = n->properties;
+
+ while (prop_list != NULL)
+ {
+ if (name == (const char *)prop_list->name)
+ {
+ value = (const char *)prop_list->children->content;
+ }
+ prop_list = prop_list->next;
+ }
+
+ return value;
+}
+
+std::map<String, String> xml_element::attributes(void)
+{
+ std::map<String, String> attrs;
+ struct _xmlAttr *prop_list;
+
+ prop_list = n->properties;
+
+ while (prop_list != NULL)
+ {
+ String name, value;
+
+ name = String((const char *)prop_list->name);
+ value = String((const char *)prop_list->children->content);
+
+ attrs[name] = value;
+
+ prop_list = prop_list->next;
+ }
+
+ return attrs;
+}
#include <libxml/parser.h> // usually in /usr/include/libxml2, see xml2-config
#include <vector>
+#include <map>
#include "String.h"
std::vector<xml_element> operator[](String tagname);
+ String attribute(String name);
+ std::map<String, String> attributes(void);
+
};
hour_assign hour_parse hour_compare hour_arithmetic hour_check_now \
utc_assign utc_parse utc_compare utc_arithmetic utc_convert \
integer_assign integer_factorial integer_fibonacci integer_pow64 integer_modulo \
- xml_file xml_find xml_node xml_elem \
+ xml_file xml_find xml_node xml_elem xml_elem_attr \
configuration_read configuration_find
string_assign_SOURCES = string_assign.cpp
xml_find_SOURCES = xml_find.cpp
xml_node_SOURCES = xml_node.cpp
xml_elem_SOURCES = xml_elem.cpp
+xml_elem_attr_SOURCES = xml_elem_attr.cpp
configuration_read_SOURCES = configuration_read.cpp
configuration_find_SOURCES = configuration_find.cpp
--- /dev/null
+/*******************************************************
+ * Unit test for the xml_element class
+ *
+ * test xml attributes access
+ ******************************************************
+ *
+ */
+
+#include "xml.h"
+#include <assert.h>
+
+int main()
+{
+ xml doc;
+
+ const char xml_file[] = "xml_test01.xml";
+
+ std::cout << "Reading XML file " << xml_file << "\n";
+
+ doc.ParseFile("xml_test01.xml");
+
+ xml_element root_node(doc);
+
+ std::cout << "Root element is " << root_node.name() << "\n";
+ std::cout << "Root node type is " << root_node.type() << "\n";
+ assert(root_node.name() == "doc");
+
+ //std::vector<xml_element> book;
+ xml_element book;
+ std::map<String, String> book_attrs;
+
+ book = root_node["book"][0];
+ book_attrs = book.attributes();
+
+ std::cout << book_attrs.size() << " attributes in element book.\n";
+ std::cout << "Attribute id = " << book_attrs["id"] << "\n";
+ assert(book_attrs["id"] == "toplevel");
+
+ std::cout << "Attribute layout = " << book.attribute("layout") << "\n";
+ assert(book.attribute("layout") == "A4");
+
+ return 0;
+}
+
--- /dev/null
+Reading XML file xml_test01.xml
+Root element is doc
+Root node type is 1
+3 attributes in element book.
+Attribute id = toplevel
+Attribute layout = A4
+PASS xml_elem_attr (exit status: 0)
<?xml version="1.0"?>
<doc style="main.css">
- <book attr="value">
+ <book id="toplevel" layout="A4" attr="value">
<titlepage>
<title>Andromeda Class Library</title>
</titlepage>
<toc/>
- <chapter>
+ <chapter id="ch1">
<heading>Chapter 1</heading>
</chapter>
<chapter>