From: Eduardo Ramos Testillano Date: Tue, 25 Jun 2013 01:12:45 +0000 (+0200) Subject: New Environment core class X-Git-Tag: REFACTORING_TESTING_LIBRARY~274 X-Git-Url: https://git.teslayout.com/public/public/public/?a=commitdiff_plain;h=bebea4009ed5a273fbf9ed3644a2140a8f477f99;p=anna.git New Environment core class --- diff --git a/SConstruct b/SConstruct index 1cff096..d811f34 100644 --- a/SConstruct +++ b/SConstruct @@ -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/ 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): diff --git a/include/anna/app/Application.hpp b/include/anna/app/Application.hpp index fe40542..c34c46a 100644 --- a/include/anna/app/Application.hpp +++ b/include/anna/app/Application.hpp @@ -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 index 584ba5f..0000000 --- a/include/anna/core/Configuration.hpp +++ /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 - -#include -#include -#include - -#include -#include -#include - -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 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 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 (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 index 0000000..7385301 --- /dev/null +++ b/include/anna/core/util/Configuration.hpp @@ -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 + +#include +#include +#include + +#include +#include +#include + +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 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 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 (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 index 0000000..fa7fb09 --- /dev/null +++ b/include/anna/core/util/Environment.hpp @@ -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 +#include + +#include +#include + + +namespace anna { + +/** + Environment variables reader +*/ +class Environment : public Singleton { +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 a_managedVars; + + Environment() { initialize();} + + friend class Singleton ; +}; + +} + +#endif + diff --git a/include/anna/core/util/defines.hpp b/include/anna/core/util/defines.hpp index 3acb459..fbe7bc9 100644 --- a/include/anna/core/util/defines.hpp +++ b/include/anna/core/util/defines.hpp @@ -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; diff --git a/source/core/util/Configuration.cpp b/source/core/util/Configuration.cpp index 60bf5d0..10d5087 100644 --- a/source/core/util/Configuration.cpp +++ b/source/core/util/Configuration.cpp @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include #include diff --git a/source/core/util/Environment.cpp b/source/core/util/Environment.cpp new file mode 100644 index 0000000..7b51fa1 --- /dev/null +++ b/source/core/util/Environment.cpp @@ -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 + +#include +#include +#include + +#include +#include + + +#include + + + +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::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(); + 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::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; +} + diff --git a/test/core/SConscript b/test/core/SConscript index 3b28786..4216c09 100644 --- a/test/core/SConscript +++ b/test/core/SConscript @@ -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 index 0000000..ed3fa84 --- /dev/null +++ b/test/core/example.cnf @@ -0,0 +1,7 @@ +[ property ] +thing = tshirt +size = 1 +color = blue +[ owner ] +name = edu +address = madrid diff --git a/test/core/main.cpp b/test/core/main.cpp index 9208755..d804ab0 100644 --- a/test/core/main.cpp +++ b/test/core/main.cpp @@ -44,6 +44,8 @@ #include #include +#include +#include #include 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("")); +} + diff --git a/test/time/main.cpp b/test/time/main.cpp index ab78bc6..77d0af3 100644 --- a/test/time/main.cpp +++ b/test/time/main.cpp @@ -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;