diff --git a/.gitattributes b/.gitattributes index 8e3a2f1186d635b20f1b4f61299c44fab7e09799..e8d047488a1ce8d482ba8d2ed428562205647f4a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -23,11 +23,13 @@ src/main.cpp -text src/memory_space.cpp -text src/plugin_man.cpp -text src/zipr.cpp -text +src/zipr_new_options.cpp -text src/zipr_options.cpp -text src/zipr_stats.cpp -text test/MemorySpace.cpp -text test/SConscript -text test/SConstruct -text +test/ZiprOptions.cpp -text test/dylib/Makefile -text test/dylib/dylib.c -text test/dylib/dylib.h -text diff --git a/src/zipr_new_options.cpp b/src/zipr_new_options.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e5e76da5e4cfe33690ae74ec26a6e21efbdfd01f --- /dev/null +++ b/src/zipr_new_options.cpp @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <zipr_sdk.h> +#include <unistd.h> +#include <iostream> +#include <cstddef> + +#ifndef IMPLEMENTATION_DEBUG +#define IMPLEMENTATION_DEBUG 0 +#endif + +using namespace Zipr_SDK; +using namespace std; + +void ZiprOptionsNamespace_t::PrintNamespace() { + ZiprOptionsNamespace_t::const_iterator it = begin(); + ZiprOptionsNamespace_t::const_iterator it_end = end(); + for (it; it != it_end; it++) { + cout << (*it)->Key() << ": " << (*it)->StringValue() << endl; + } +} + +bool ZiprOptionsNamespace_t::RequirementsMet() { + ZiprOptionsNamespace_t::const_iterator it = begin(); + ZiprOptionsNamespace_t::const_iterator it_end = end(); + for (it; it != it_end; it++) { + if (!(*it)->RequirementMet()) + return false; + } + return true; +} + +void ZiprOptionsNamespace_t::AddOption(ZiprUntypedOption_t *option) { + insert(option); +} + +ZiprUntypedOption_t *ZiprOptionsNamespace_t::OptionByKey(string key) { + ZiprOptionsNamespace_t::const_iterator it = begin(); + ZiprOptionsNamespace_t::const_iterator it_end = end(); + for (it; it != it_end; it++) { + if ((*it)->Key() == key) + return *it; + } + return NULL; +} + +void ZiprOptionsNamespace_t::PrintUsage(int tabs, ostream &out) { + ZiprOptionsNamespace_t::const_iterator it = begin(); + ZiprOptionsNamespace_t::const_iterator it_end = end(); + for (it; it != it_end; it++) { + string description = (*it)->Description(); + { int t = 0; for (; t<tabs; t++) cout << "\t"; } + out << Namespace() << ":" << description << endl; + } +} + +void ZiprNewOptions_t::PrintUsage(ostream &out) { + set<ZiprOptionsNamespace_t*>::const_iterator it = m_namespaces.begin(); + set<ZiprOptionsNamespace_t*>::const_iterator it_end = m_namespaces.end(); + for (it; it != it_end; it++) + (*it)->PrintUsage(1, out); +} + +bool ZiprNewOptions_t::RequirementsMet() { + set<ZiprOptionsNamespace_t*>::const_iterator it = m_namespaces.begin(); + set<ZiprOptionsNamespace_t*>::const_iterator it_end = m_namespaces.end(); + for (it; it != it_end; it++) + if (!(*it)->RequirementsMet()) + return false; + return true; +} + +ZiprNewOptions_t::ZiprNewOptions_t(int argc, char **argv) { + int i = 0; + for (i = 0; i<argc; i++) { + m_arguments.push_back(string(argv[i])); + } +} + +bool ZiprNewOptions_t::Parse(ostream &warn) { + vector<string>::const_iterator it = m_arguments.begin(); + vector<string>::const_iterator it_end = m_arguments.end(); + + for (it; it != it_end; it++) { + string ns, key, argument = *it; + string::size_type location = 0; + ZiprOptionsNamespace_t *option_ns; + ZiprUntypedOption_t *option_option; + + if (0 != (location = argument.find_first_of("--"))) { + warn << "Warning: " << argument << " does not start with --" << endl; + continue; + } +#if IMPLEMENTATION_DEBUG + cout << "location: " << location << endl; +#endif + argument = argument.substr(location+2, string::npos); + if (string::npos == (location = argument.find_first_of(":"))) { + warn << "Warning: " << argument << " going in global namespace." << endl; + ns = "global"; + location = -1; + } else { + ns = argument.substr(0, location); + } +#if IMPLEMENTATION_DEBUG + cout << "argument: " << argument << endl; +#endif + key = argument.substr(location+1, string::npos); +#if IMPLEMENTATION_DEBUG + cout << "ns: " << ns << endl; + cout << "key: " << key << endl; +#endif + if (!(option_ns = Namespace(ns))) { + warn << "Invalid namespace: " << ns << endl; + continue; + } + if (!(option_option = option_ns->OptionByKey(key))) { + warn << ns << " does not accept key " << key << endl; + continue; + } + /* + * By default, options need and take values. Some, though, + * take values but don't need them. Finally, some neither + * take nor need values. + */ + if (option_option->NeedsValue()) { + if ((it + 1) == it_end) + { + warn << ns << ":" << key << " is missing value." << endl; + continue; + } + option_option->SetValue(*(++it)); + } else if (option_option->TakesValue()) { + /* + * Check to see if the next argument starts with --. + * If it does, we consider it the next option + * and not the value to the previous option. + */ + if (((it+1) != it_end) && + (0 != (location = (*(it+1)).find_first_of("--")))) { + option_option->SetValue(*(++it)); + } else { + option_option->Set(); + } + } else { + option_option->Set(); + } + } + return true; +} + +ZiprOptionsNamespace_t *ZiprNewOptions_t::Namespace(string ns) { + set<ZiprOptionsNamespace_t*>::const_iterator it = m_namespaces.begin(); + set<ZiprOptionsNamespace_t*>::const_iterator it_end = m_namespaces.end(); + for (it; it != it_end; it++) { + if ((*it)->Namespace() == ns) + return *it; + } + return NULL; +} + +void ZiprNewOptions_t::AddNamespace(ZiprOptionsNamespace_t *ns) { + m_namespaces.insert(ns); +} + +void ZiprNewOptions_t::PrintNamespaces() { + set<ZiprOptionsNamespace_t*>::const_iterator it = m_namespaces.begin(); + set<ZiprOptionsNamespace_t*>::const_iterator it_end = m_namespaces.end(); + + for (it; it != it_end; it++) { + cout << (*it)->Namespace() << endl; + (*it)->PrintNamespace(); + } +} diff --git a/test/SConscript b/test/SConscript index 3b65e67d5fb040ab967b18300d1f05509d1fbd3a..7d21bbdab5fdfd1d68a3bce01ea5956753d45c9c 100644 --- a/test/SConscript +++ b/test/SConscript @@ -8,12 +8,17 @@ myenv.Replace(ZIPR_SDK=os.environ['ZIPR_SDK']) myenv.Replace(ZIPR_INSTALL=os.environ['ZIPR_INSTALL']) -files= ''' +MemorySpaceFiles= ''' MemorySpace.cpp ../src/memory_space.cpp ../src/zipr_options.cpp ''' +OptionFiles= ''' + ZiprOptions.cpp + ../src/zipr_new_options.cpp + ''' + # ELFIO needs to be first so we get the zipr version instead of the sectrans version. the zipr version is modified to include get_offset. cpppath=''' . @@ -44,6 +49,7 @@ libpath=''' ''' myenv.Append(CCFLAGS=" -Wall ") +myenv.Append(CXXFLAGS=" -g -O0 -std=c++11 ") myenv.Append(LINKFLAGS=" -Wl,-E ") # export all symbols @@ -52,6 +58,7 @@ myenv=myenv.Clone(CPPPATH=Split(cpppath), LIBS=Split(libs), LIBPATH=Split(libpat #print 'myenv=' #print myenv.Dump() -MemorySpace=myenv.Program("MemorySpace.exe", Split(files)) -Default(MemorySpace) +MemorySpace=myenv.Program("MemorySpace.exe", Split(MemorySpaceFiles)) +Options=myenv.Program("Options.exe", Split(OptionFiles)) +Default([MemorySpace, Options]) diff --git a/test/ZiprOptions.cpp b/test/ZiprOptions.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c906e5d56528a2159b020fb9abaca7b31446dd95 --- /dev/null +++ b/test/ZiprOptions.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2014 - Zephyr Software LLC + * + * This file may be used and modified for non-commercial purposes as long as + * all copyright, permission, and nonwarranty notices are preserved. + * Redistribution is prohibited without prior written consent from Zephyr + * Software. + * + * Please contact the authors for restrictions applying to commercial use. + * + * THIS SOURCE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Author: Zephyr Software + * e-mail: jwd@zephyr-software.com + * URL : http://www.zephyr-software.com/ + * + */ + +#include <zipr_all.h> +#include <zipr_sdk.h> + +using namespace zipr; +using namespace std; + +#define INVOKE(a) \ +bool __ ## a ## _result = false; \ +__ ## a ## _result = a(); \ +printf(#a ":"); \ +if (__ ## a ## _result) \ +{ \ +printf(" pass\n"); \ +} \ +else \ +{ \ +printf(" fail\n"); \ +} + +int main(int argc, char *argv[]) +{ + ZiprNewOptions_t options(argc-1, argv+1); + + ZiprOptionsNamespace_t global_ns("global"); + ZiprOptionsNamespace_t local_ns("local"); + + ZiprStringOption_t global_a_option("a"); + ZiprBooleanOption_t local_b_option("b"); + ZiprBooleanOption_t local_c_option("c", false); + ZiprIntegerOption_t local_d_option("d", "55"); + + local_b_option.SetRequired(true); + local_b_option.SetDescription("Set the B option."); + local_d_option.SetRequired(true); + + global_ns.AddOption(&global_a_option); + local_ns.AddOption(&local_b_option); + local_ns.AddOption(&local_c_option); + local_ns.AddOption(&local_d_option); + + options.AddNamespace(&global_ns); + options.AddNamespace(&local_ns); + + options.Parse(cout); + + if (!options.RequirementsMet()) + { + cout << "Usage: " << endl; + options.PrintUsage(cout); + } + + options.PrintNamespaces(); + if (global_a_option == "avl") { + cout << "global_a_option is avl." << endl; + } else { + cout << "global_a_option is NOT avl." << endl; + } + + if (local_b_option == true) { + cout << "local_b_option is true." << endl; + } else { + cout << "local_b_option is false." << endl; + } + if (local_c_option == false) { + cout << "local_c_option is false." << endl; + } else { + cout << "local_c_option is true." << endl; + } + if (local_d_option == 55) { + cout << "local_d_option is " << local_d_option.Value() << endl; + } +}