New Environment core class
authorEduardo Ramos Testillano <eduardo.ramos.testillano@gmail.com>
Tue, 25 Jun 2013 01:12:45 +0000 (03:12 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@gmail.com>
Tue, 25 Jun 2013 01:12:45 +0000 (03:12 +0200)
12 files changed:
SConstruct
include/anna/app/Application.hpp
include/anna/core/Configuration.hpp [deleted file]
include/anna/core/util/Configuration.hpp [new file with mode: 0644]
include/anna/core/util/Environment.hpp [new file with mode: 0644]
include/anna/core/util/defines.hpp
source/core/util/Configuration.cpp
source/core/util/Environment.cpp [new file with mode: 0644]
test/core/SConscript
test/core/example.cnf [new file with mode: 0644]
test/core/main.cpp
test/time/main.cpp

index 1cff096..d811f34 100644 (file)
@@ -22,6 +22,7 @@ source_include = os.path.join (current_directory, "include")
 usr_include = [
   "/usr/include/oracle/11.2/client",
   "/usr/include/libxml2",
+  #"/usr/include/boost",
   #"/usr/include/mysql", 
   #"/usr/include/openssl", 
 ]
@@ -34,6 +35,9 @@ env = Environment ()
 # CPPPATH will be relative to src/<target>
 env.Append (CPPPATH = [source_include, usr_local_include, usr_include ])
 env.Append (CCFLAGS = '-std=c++0x')
+# C++11 support:
+env.Append (CXXFLAGS = '-std=c++11')
+
 env.Append (LIBS = [''])
 # scons -Q release=1
 if int(release):
index fe40542..c34c46a 100644 (file)
@@ -43,8 +43,6 @@
 
 namespace anna {
 
-class Configuration;
-
 namespace xml {
 class Node;
 }
diff --git a/include/anna/core/Configuration.hpp b/include/anna/core/Configuration.hpp
deleted file mode 100644 (file)
index 584ba5f..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-// ANNA - Anna is Not 'N' Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// https://bitbucket.org/testillano/anna
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: eduardo.ramos.testillano@gmail.com
-//          cisco.tierra@gmail.com
-
-
-#ifndef anna_core_Configuration_hpp
-#define anna_core_Configuration_hpp
-
-#include <stdlib.h>
-
-#include <vector>
-#include <map>
-#include <string>
-
-#include <anna/core/functions.hpp>
-#include <anna/core/util/Variable.hpp>
-#include <anna/core/RuntimeException.hpp>
-
-namespace anna {
-
-/**
-   Clase para recoger parametros de un determinado archivo de configuracion.
-*/
-class Configuration {
-public:
-  static const char* defaultSection;
-
-  /**
-     Constructor.
-     \param className Nombre de la clase usado para registrar en la lista de componentes.
-  */
-  Configuration(const char* className) {;}
-
-  /**
-     Constructor.
-  */
-  Configuration() {;}
-
-  /**
-  * Destructor.
-  */
-  ~Configuration() { removeAll(); }
-
-  /**
-     Carga en memoria el archivo indicado como argumento.
-
-     @param configFile Ruta completa con el nombre del archivo de configuracion a cargar.
-     Cualquier otro archivo procesado anteriormente con esta instancia se perdera.
-  */
-  void load(const char* configFile) throw(RuntimeException);
-
-  /**
-    Establece el valor por defecto para una determinada variable, es decir, en caso de que
-    la variable no exista en el fichero de configuracion cargado (ver #load) devolvera
-    el valor establecido mediante este metodo.
-
-    @param sectionName Nombre de la seccion a la que pertenece la variable.
-    @param variableName Nombre de la variable de configuracion.
-    @param defaultValue Valor por defecto de la variable. Éste valor solo sera devuelto en caso
-    de que la variable indicada por la seccion y el nombre de variable no este contenido en
-    el archivo de configuracion cargado.
-  */
-  void setDefaultValue(const char* sectionName, const char* variableName, const char* defaultValue)
-  throw(RuntimeException);
-
-  /**
-     Devuelve el valor asociada a la variable indicada.
-
-    @param sectionName Nombre de la seccion a la que pertenece la variable.
-    @param variableName Nombre de la variable de configuracion.
-    @param strict Si es true indica que debe devolver el valor estricto de la variable, de forma,
-    que si esta variable no esta contenida en el archivo de configuracion devolvera NULL, en otro
-    caso, devolvera el posible valor por defecto que tenga asociado esta variable (ver #setDefaultValue).
-
-    @return El valor asociado a la variable. Puede ser NULL.
-  */
-  const char* getValue(const char* sectionName, const char* variableName, const bool strict = false) const
-  throw(RuntimeException);
-
-  /**
-     Devuelve el valor asociada a la variable indicada.
-    @param sectionName Nombre de la seccion a la que pertenece la variable.
-    @param variableName Nombre de la variable de configuracion.
-    @param strict Si es true indica que debe devolver el valor estricto de la variable, de forma,
-    que si esta variable no esta contenida en el archivo de configuracion devolvera NULL, en otro
-    caso, devolvera el posible valor por defecto que tenga asociado esta variable (ver #setDefaultValue).
-
-    @return El valor asociado a la variable.
-  */
-  int getIntegerValue(const char* sectionName, const char* variableName, const bool strict = false) const
-  throw(RuntimeException);
-
-  /**
-     Devuelve el estado de existencia o no de la variable indicada.
-    @param sectionName Nombre de la seccion a la que pertenece la variable.
-    @param variableName Nombre de la variable de configuracion.
-
-    @return true si la variable existe, y false en otro caso. Solo deberia invocarse despues de
-    invocar al metodo #load.
-  */
-  bool exists(const char* sectionName, const char* variableName) const throw();
-
-  /**
-     Devuelve la cadena por la que podemos buscar el componente.
-     \return La cadena por la que podemos buscar el componente.
-     \see Application::find
-  */
-  static const char* getClassName() { return "anna::Configuration"; }
-
-private:
-  class VariableEx : public Variable {
-  public:
-    typedef std::vector <VariableEx*> Vector;
-
-    VariableEx(const char* variableName) :
-      Variable(variableName, Variable::Type::String),
-      a_defaultValue(NULL) {}
-
-    void setDefaultValue(const char* defaultValue) { a_defaultValue = defaultValue; }
-
-    const char* getDefaultValue() const { return a_defaultValue; }
-
-  private:
-    const char* a_defaultValue;
-  };
-
-  std::map <std::string, VariableEx::Vector*> a_sections;
-
-  Configuration(const Configuration& other);  // No implementado
-
-  void initialize() throw(RuntimeException) {;}
-  void stop() throw() {;}
-
-  void removeAll() throw();
-  bool processSection(const int nline, char* buffer, std::string& currentSection);
-  void processVariable(const int nline, char* buffer, const std::string& currentSection) throw(RuntimeException);
-  VariableEx* createVariable(const std::string& section, const char* variableName) throw();
-  VariableEx* find(const std::string& section, const char* variableName) throw();
-  const VariableEx* find(const std::string& section, const char* variableName) const
-  throw() {
-    return const_cast <Configuration*>(this)->find(section, variableName);
-  }
-
-  static char* strip(char* buffer);
-};
-
-}
-
-#endif
-
diff --git a/include/anna/core/util/Configuration.hpp b/include/anna/core/util/Configuration.hpp
new file mode 100644 (file)
index 0000000..7385301
--- /dev/null
@@ -0,0 +1,181 @@
+// ANNA - Anna is Not 'N' Anymore
+//
+// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
+//
+// https://bitbucket.org/testillano/anna
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: eduardo.ramos.testillano@gmail.com
+//          cisco.tierra@gmail.com
+
+
+#ifndef anna_core_Configuration_hpp
+#define anna_core_Configuration_hpp
+
+#include <stdlib.h>
+
+#include <vector>
+#include <map>
+#include <string>
+
+#include <anna/core/functions.hpp>
+#include <anna/core/util/Variable.hpp>
+#include <anna/core/RuntimeException.hpp>
+
+namespace anna {
+
+/**
+   Clase para recoger parametros de un determinado archivo de configuracion.
+*/
+class Configuration {
+public:
+  static const char* defaultSection;
+
+  /**
+     Constructor.
+     \param className Nombre de la clase usado para registrar en la lista de componentes.
+  */
+  Configuration(const char* className) {;}
+
+  /**
+     Constructor.
+  */
+  Configuration() {;}
+
+  /**
+  * Destructor.
+  */
+  ~Configuration() { removeAll(); }
+
+  /**
+     Carga en memoria el archivo indicado como argumento.
+
+     @param configFile Ruta completa con el nombre del archivo de configuracion a cargar.
+     Cualquier otro archivo procesado anteriormente con esta instancia se perdera.
+  */
+  void load(const char* configFile) throw(RuntimeException);
+
+  /**
+    Establece el valor por defecto para una determinada variable, es decir, en caso de que
+    la variable no exista en el fichero de configuracion cargado (ver #load) devolvera
+    el valor establecido mediante este metodo.
+
+    @param sectionName Nombre de la seccion a la que pertenece la variable.
+    @param variableName Nombre de la variable de configuracion.
+    @param defaultValue Valor por defecto de la variable. Éste valor solo sera devuelto en caso
+    de que la variable indicada por la seccion y el nombre de variable no este contenido en
+    el archivo de configuracion cargado.
+  */
+  void setDefaultValue(const char* sectionName, const char* variableName, const char* defaultValue)
+  throw(RuntimeException);
+
+  /**
+     Devuelve el valor asociada a la variable indicada.
+
+    @param sectionName Nombre de la seccion a la que pertenece la variable.
+    @param variableName Nombre de la variable de configuracion.
+    @param strict Si es true indica que debe devolver el valor estricto de la variable, de forma,
+    que si esta variable no esta contenida en el archivo de configuracion aun habiendo asociado
+    un valor por defecto (ver #setDefaultValue) devolvera NULL.
+
+    @return El valor asociado a la variable. Puede ser NULL.
+  */
+  const char* getValue(const char* sectionName, const char* variableName, const bool strict = false) const
+  throw(RuntimeException);
+
+  /**
+     Devuelve el valor asociada a la variable indicada.
+    @param sectionName Nombre de la seccion a la que pertenece la variable.
+    @param variableName Nombre de la variable de configuracion.
+    @param strict Si es true indica que debe devolver el valor estricto de la variable, de forma,
+    que si esta variable no esta contenida en el archivo de configuracion aun habiendo asociado
+    un valor por defecto (ver #setDefaultValue) devolvera NULL.
+
+    @return El valor asociado a la variable.
+  */
+  int getIntegerValue(const char* sectionName, const char* variableName, const bool strict = false) const
+  throw(RuntimeException);
+
+  /**
+     Devuelve el estado de existencia o no de la variable indicada.
+    @param sectionName Nombre de la seccion a la que pertenece la variable.
+    @param variableName Nombre de la variable de configuracion.
+
+    @return true si la variable existe, y false en otro caso. Solo deberia invocarse despues de
+    invocar al metodo #load.
+  */
+  bool exists(const char* sectionName, const char* variableName) const throw();
+
+  /**
+     Devuelve la cadena por la que podemos buscar el componente.
+     \return La cadena por la que podemos buscar el componente.
+     \see Application::find
+  */
+  static const char* getClassName() { return "anna::Configuration"; }
+
+private:
+  class VariableEx : public Variable {
+  public:
+    typedef std::vector <VariableEx*> Vector;
+
+    VariableEx(const char* variableName) :
+      Variable(variableName, Variable::Type::String),
+      a_defaultValue(NULL) {}
+
+    void setDefaultValue(const char* defaultValue) { a_defaultValue = defaultValue; }
+
+    const char* getDefaultValue() const { return a_defaultValue; }
+
+  private:
+    const char* a_defaultValue;
+  };
+
+  std::map <std::string, VariableEx::Vector*> a_sections;
+
+  Configuration(const Configuration& other);  // No implementado
+
+  void initialize() throw(RuntimeException) {;}
+  void stop() throw() {;}
+
+  void removeAll() throw();
+  bool processSection(const int nline, char* buffer, std::string& currentSection);
+  void processVariable(const int nline, char* buffer, const std::string& currentSection) throw(RuntimeException);
+  VariableEx* createVariable(const std::string& section, const char* variableName) throw();
+  VariableEx* find(const std::string& section, const char* variableName) throw();
+  const VariableEx* find(const std::string& section, const char* variableName) const
+  throw() {
+    return const_cast <Configuration*>(this)->find(section, variableName);
+  }
+
+  static char* strip(char* buffer);
+};
+
+}
+
+#endif
+
diff --git a/include/anna/core/util/Environment.hpp b/include/anna/core/util/Environment.hpp
new file mode 100644 (file)
index 0000000..fa7fb09
--- /dev/null
@@ -0,0 +1,87 @@
+// ANNA - Anna is Not 'N' Anymore
+//
+// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
+//
+// https://bitbucket.org/testillano/anna
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: eduardo.ramos.testillano@gmail.com
+//          cisco.tierra@gmail.com
+
+
+#ifndef anna_core_Environment_hpp
+#define anna_core_Environment_hpp
+
+#include <string>
+#include <map>
+
+#include <anna/core/RuntimeException.hpp>
+#include <anna/core/Singleton.hpp>
+
+
+namespace anna {
+
+/**
+  Environment variables reader
+*/
+class Environment : public Singleton <Environment> {
+public:
+
+  /**
+  * Destructor.
+  */
+  ~Environment() {;}
+
+  /**
+    Parses the current environment data (all variables available)
+  */
+  void initialize() throw();
+
+  /**
+    Return associated value (could be empty).
+
+    @param variableName Environment variable name.
+    @param exceptionIfMissing When enabled, an exception is launched for missing variables. Empty string in other case (default behaviour).
+
+    @return Environment value.
+  */
+  std::string getValue(const char* variableName, bool exceptionIfMissing = false) const throw(RuntimeException);
+
+private:
+
+  std::map<std::string /* variable name */, std::string /* variable value */> a_managedVars;
+
+  Environment() { initialize();}
+
+  friend class Singleton <Environment>;
+};
+
+}
+
+#endif
+
index 3acb459..fbe7bc9 100644 (file)
@@ -403,69 +403,71 @@ typedef struct {
 
 
 /**
-   Struct for IANA Addresses
+* IANA Address Family Numbers
+* @see http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml
 */
 typedef struct {
+  enum _v {
+    //Number    Description                                          Reference
+    //------    ---------------------------------------------------- ---------
+    //     0    Reserved
+    IPv4 = 1, //IP (IP version 4)
+    IPv6 = 2, //IP6 (IP version 6)
+    //     3    NSAP
+    //     4    HDLC (8-bit multidrop)
+    //     5    BBN 1822
+    //     6    802 (includes all 802 media plus Ethernet "canonical format")
+    //     7    E.163
+    E164 = 8  //E.164 (SMDS, Frame Relay, ATM)
+    //     9    F.69 (Telex)
+    //    10    X.121 (X.25, Frame Relay)
+    //    11    IPX
+    //    12    Appletalk
+    //    13    Decnet IV
+    //    14    Banyan Vines
+    //    15    E.164 with NSAP format subaddress           [UNI-3.1] [Andy_Malis]
+    //    16    DNS (Domain Name System)
+    //    17    Distinguished Name                                    [Charles_Lynn]
+    //    18    AS Number                                             [Charles_Lynn]
+    //    19    XTP over IP version 4                                 [Mike_Saul]
+    //    20    XTP over IP version 6                                 [Mike_Saul]
+    //    21    XTP native mode XTP                                   [Mike_Saul]
+    //    22    Fibre Channel World-Wide Port Name                   [Mark_Bakke]
+    //    23    Fibre Channel World-Wide Node Name                   [Mark_Bakke]
+    //    24    GWID                                                 [Subra_Hegde]
+    //    25    AFI for L2VPN information [RFC4761][RFC6074]
+    //    26-16383 Unassigned
+    //    16384 EIGRP Common Service Family [Donnie_Savage] 2008-05-13
+    //    16385 EIGRP IPv4 Service Family [Donnie_Savage] 2008-05-13
+    //    16386 EIGRP IPv6 Service Family [Donnie_Savage] 2008-05-13
+    //    16387 LISP Canonical Address Format (LCAF) [David_Meyer] 2009-11-12
+    //    16388-32767 Unassigned
+    //    32768-65534 Unassigned
+    //    65535 Reserved
+  };
 
   /**
-  * IANA Address Family Numbers
-  * @see http://www.iana.org/assignments/address-family-numbers/address-family-numbers.xml
+  * Version description
+  * @param v Version type
+  * @return Version description
   */
-  struct version {
-    enum _v {
-      //Number    Description                                          Reference
-      //------    ---------------------------------------------------- ---------
-      //     0    Reserved
-      IPv4 = 1, //IP (IP version 4)
-      IPv6 = 2, //IP6 (IP version 6)
-      //     3    NSAP
-      //     4    HDLC (8-bit multidrop)
-      //     5    BBN 1822
-      //     6    802 (includes all 802 media plus Ethernet "canonical format")
-      //     7    E.163
-      E164 = 8  //E.164 (SMDS, Frame Relay, ATM)
-      //     9    F.69 (Telex)
-      //    10    X.121 (X.25, Frame Relay)
-      //    11    IPX
-      //    12    Appletalk
-      //    13    Decnet IV
-      //    14    Banyan Vines
-      //    15    E.164 with NSAP format subaddress           [UNI-3.1] [Andy_Malis]
-      //    16    DNS (Domain Name System)
-      //    17    Distinguished Name                                    [Charles_Lynn]
-      //    18    AS Number                                             [Charles_Lynn]
-      //    19    XTP over IP version 4                                 [Mike_Saul]
-      //    20    XTP over IP version 6                                 [Mike_Saul]
-      //    21    XTP native mode XTP                                   [Mike_Saul]
-      //    22    Fibre Channel World-Wide Port Name                   [Mark_Bakke]
-      //    23    Fibre Channel World-Wide Node Name                   [Mark_Bakke]
-      //    24    GWID                                                 [Subra_Hegde]
-      //    25    AFI for L2VPN information [RFC4761][RFC6074]
-      //    26-16383 Unassigned
-      //    16384 EIGRP Common Service Family [Donnie_Savage] 2008-05-13
-      //    16385 EIGRP IPv4 Service Family [Donnie_Savage] 2008-05-13
-      //    16386 EIGRP IPv6 Service Family [Donnie_Savage] 2008-05-13
-      //    16387 LISP Canonical Address Format (LCAF) [David_Meyer] 2009-11-12
-      //    16388-32767 Unassigned
-      //    32768-65534 Unassigned
-      //    65535 Reserved
-    };
-
-    /**
-    * Version description
-    * @param v Version type
-    * @return Version description
-    */
-    static const char* asText(const version::_v v) throw() { // anna_declare_enum is not safe, because labels don't have to match a sequence
-      if(v == version::IPv4) return "IPv4";
-
-      if(v == version::IPv6) return "IPv6";
-
-      if(v == version::E164) return "E164";
-
-      return NULL;
-    }
-  };
+  static const char* asText(const _v v) throw() { // anna_declare_enum is not safe, because labels don't have to match a sequence
+    if(v == IPv4) return "IPv4";
+
+    if(v == IPv6) return "IPv6";
+
+    if(v == E164) return "E164";
+
+    return NULL;
+  }
+
+} iana_address_version_t;
+
+
+/**
+   Struct for IANA Addresses
+*/
+typedef struct {
 
   /** address version */
   U16 Version;
@@ -484,20 +486,20 @@ typedef struct {
   // Helpers
 
   /** Return true when is an IPv4 address */
-  bool isIPv4() const throw() { return ((version::_v)Version == version::IPv4); }
+  bool isIPv4() const throw() { return ((iana_address_version_t::_v)Version == iana_address_version_t::IPv4); }
   /** Return true when is an IPv6 address */
-  bool isIPv6() const throw() { return ((version::_v)Version == version::IPv6); }
+  bool isIPv6() const throw() { return ((iana_address_version_t::_v)Version == iana_address_version_t::IPv6); }
   /** Return true when is an E164 (SMDS, Frame Relay, ATM) address */
-  bool isE164() const throw() { return ((version::_v)Version == version::E164); }
+  bool isE164() const throw() { return ((iana_address_version_t::_v)Version == iana_address_version_t::E164); }
 
   /** Sets version for IPv4 address and address itself. Checking is not performed (could assign IPv6 instead ...) */
-  void setIPv4(const char *value) throw() { Version = version::IPv4; Value = value ? value : ""; }
+  void setIPv4(const char *value) throw() { Version = iana_address_version_t::IPv4; Value = value ? value : ""; }
 
   /** Sets version for IPv6 address and address itself. Checking is not performed (could assign IPv4 instead ...) */
-  void setIPv6(const char *value) throw() { Version = version::IPv6; Value = value ? value : ""; }
+  void setIPv6(const char *value) throw() { Version = iana_address_version_t::IPv6; Value = value ? value : ""; }
 
   /** Sets version for E164 address and address itself. Checking is not performed ... */
-  void setE164(const char *value) throw() { Version = version::E164; Value = value ? value : ""; }
+  void setE164(const char *value) throw() { Version = iana_address_version_t::E164; Value = value ? value : ""; }
 
 
   /**
@@ -509,7 +511,7 @@ typedef struct {
     std::string result;
     result += Value.c_str(); // assume that all IANA addresses have a printable representation
     result += " (";
-    const char *versionAsText = version::asText((version::_v)Version);
+    const char *versionAsText = iana_address_version_t::asText((iana_address_version_t::_v)Version);
 
     if(versionAsText) {
       result += versionAsText;
index 60bf5d0..10d5087 100644 (file)
@@ -40,7 +40,7 @@
 #include <algorithm>
 
 #include <anna/core/functions.hpp>
-#include <anna/core/Configuration.hpp>
+#include <anna/core/util/Configuration.hpp>
 #include <anna/core/RuntimeException.hpp>
 #include <anna/core/tracing/Logger.hpp>
 #include <anna/core/tracing/TraceMethod.hpp>
diff --git a/source/core/util/Environment.cpp b/source/core/util/Environment.cpp
new file mode 100644 (file)
index 0000000..7b51fa1
--- /dev/null
@@ -0,0 +1,129 @@
+// ANNA - Anna is Not 'N' Anymore
+//
+// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
+//
+// https://bitbucket.org/testillano/anna
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: eduardo.ramos.testillano@gmail.com
+//          cisco.tierra@gmail.com
+
+
+#include <anna/core/util/Environment.hpp>
+
+#include <anna/config/defines.hpp>
+#include <anna/core/tracing/Logger.hpp>
+#include <anna/core/tracing/TraceMethod.hpp>
+
+#include <boost/program_options.hpp>
+#include <boost/algorithm/string.hpp>
+
+
+#include <stdlib.h>
+
+
+
+using namespace std;
+using namespace anna;
+
+
+
+void Environment::initialize() throw() {
+  LOGMETHOD(TraceMethod tm("Environment", "initialize", ANNA_FILE_LOCATION));
+
+  // clear data
+  a_managedVars.clear();
+
+  // Register:
+  namespace po = boost::program_options;
+  po::options_description desc("Options");
+
+  FILE *fp;
+  char c_var[256];
+  std::string var;
+
+  /* Open the command for reading. */
+  fp = popen("env | cut -d'=' -f1", "r");
+  if (fp == NULL) {
+    Logger::error("Failed to get environment variables list", ANNA_FILE_LOCATION);
+    return;
+  }
+
+  /* Read the output a line at a time - output it. */
+  while (fgets(c_var, sizeof(c_var)-1, fp) != NULL) {
+    var = c_var;
+    boost::trim(var);
+    desc.add_options()(var.c_str(), var.c_str());
+    a_managedVars[var] = ""; // temporary
+  }
+
+  /* close */
+  pclose(fp);
+
+  // Parsing:
+  po::variables_map vm;
+  try {
+    po::store(po::parse_environment(desc, [](const std::string& variable) { return variable; }), vm); // can throw
+
+    std::map<std::string, std::string>::const_iterator it;
+    std::string var, val;
+    for (it = a_managedVars.begin(); it != a_managedVars.end(); it++) {
+      var = (*it).first;
+      if (vm.count(var.c_str())) { // protection
+        val = vm[var.c_str()].as<std::string>();
+        a_managedVars[var] = val;
+      }
+    }
+
+    po::notify(vm);
+
+  } catch (po::error& e) {
+    Logger::error(e.what(), ANNA_FILE_LOCATION);
+  }
+}
+
+std::string Environment::getValue (const char* variableName, bool exceptionIfMissing) const throw(RuntimeException) {
+  std::string result = "";
+
+  if (!variableName)
+    throw RuntimeException("Invalid NULL variable name!", ANNA_FILE_LOCATION);
+
+  std::map<std::string, std::string>::const_iterator it = a_managedVars.find(variableName);
+  if (it == a_managedVars.end()) {
+    std::string msg = "The variable '";
+    msg += variableName;
+    msg += "' is not defined in the environment.";
+    LOGDEBUG(Logger::debug(msg, ANNA_FILE_LOCATION));
+    if (exceptionIfMissing)
+      throw RuntimeException(msg, ANNA_FILE_LOCATION);
+    return "";
+  }
+
+  return it->second;
+}
+
index 3b28786..4216c09 100644 (file)
@@ -8,6 +8,9 @@ env.MergeFlags (boost_library)
 anna_library = { 'LIBS' : 'anna_core' }
 env.MergeFlags (anna_library)
 
+system_library = { 'LIBS' : 'boost_program_options' }
+env.MergeFlags (system_library)
+
 pwd = Dir ('.').abspath;
 current_directory = str (pwd);
 
@@ -17,3 +20,7 @@ env.Append (LIBPATH = [libpath])
 result = env.Program ('anna_test_core', Glob ('*.cpp'))
 
 Return ('result')
+
+
+
+
diff --git a/test/core/example.cnf b/test/core/example.cnf
new file mode 100644 (file)
index 0000000..ed3fa84
--- /dev/null
@@ -0,0 +1,7 @@
+[ property ]
+thing = tshirt
+size = 1
+color = blue
+[ owner ]
+name = edu
+address = madrid
index 9208755..d804ab0 100644 (file)
@@ -44,6 +44,8 @@
 #include <limits.h>
 
 #include <anna/core/util/Tokenizer.hpp>
+#include <anna/core/util/Configuration.hpp>
+#include <anna/core/util/Environment.hpp>
 #include <anna/core/functions.hpp>
 
 using namespace std;
@@ -111,3 +113,46 @@ BOOST_AUTO_TEST_CASE(functions_asString) {
   BOOST_REQUIRE_EQUAL(anna::functions::asString(d, "%4.2f"), cad_aux);
 }
 
+BOOST_AUTO_TEST_CASE(configuration) {
+
+  anna::Configuration conf;
+
+  BOOST_CHECK_THROW(conf.load("missing_file.cnf"), anna::RuntimeException);
+  BOOST_CHECK_NO_THROW(conf.load("test/core/example.cnf"));
+  
+  //[ property ]
+  //thing = tshirt
+  //size = 1
+  //color = blue
+  //[ owner ]
+  //name = edu
+  //address = madrid
+  
+  BOOST_CHECK_THROW(conf.getValue("property", "WRONG_VAR"), anna::RuntimeException);
+  BOOST_CHECK_THROW(conf.getValue("WRONG_SECTION", "thing"), anna::RuntimeException);
+
+  std::string value;
+
+  BOOST_REQUIRE_EQUAL(value = conf.getValue("property", "thing"), "tshirt");
+  BOOST_REQUIRE_EQUAL(conf.getIntegerValue("property", "size"), 1);
+  BOOST_REQUIRE_EQUAL(std::string(conf.getValue("property", "color")), "blue");
+  BOOST_REQUIRE_EQUAL(std::string(conf.getValue("owner", "name")), "edu");
+  BOOST_REQUIRE_EQUAL(std::string(conf.getValue("owner", "address")), "madrid");
+
+  conf.setDefaultValue("owner", "phone", "555 55 55");
+  BOOST_REQUIRE_EQUAL(std::string(conf.getValue("owner", "phone")), "555 55 55");
+  BOOST_REQUIRE(!conf.getValue("owner", "phone", true) /* query value is NULL: 'true = strict' even with default value assigned */);
+  BOOST_REQUIRE(!conf.exists("owner", "phone"));
+  BOOST_REQUIRE(conf.exists("owner", "name"));
+}
+
+BOOST_AUTO_TEST_CASE(environment) {
+
+  anna::Environment &env = anna::Environment::instantiate();
+
+  BOOST_CHECK_THROW(env.getValue("WRONG_ENV_VAR", true /* exception if missing */), anna::RuntimeException);
+  BOOST_CHECK_THROW(env.getValue(NULL), anna::RuntimeException);
+  BOOST_REQUIRE_EQUAL(env.getValue("HOME"), std::string("/home/eramos"));
+  BOOST_REQUIRE_EQUAL(env.getValue("MISSING_ENV_VAR"), std::string(""));
+}
+
index ab78bc6..77d0af3 100644 (file)
@@ -50,7 +50,7 @@ using namespace anna;
 // see http://www.boost.org/doc/libs/1_44_0/libs/test/doc/html/utf/testing-tools.html
 //     http://www.boost.org/doc/libs/1_44_0/libs/test/doc/html/utf/testing-tools/reference.html
 
-BOOST_AUTO_TEST_CASE(Date) {
+BOOST_AUTO_TEST_CASE(date) {
   const char * tzarg = NULL;
   anna::time::functions::initialize();
   anna::time::Date current, current2;