aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2006-08-09 08:27:03 +0000
committerlloyd <[email protected]>2006-08-09 08:27:03 +0000
commit53414fe78b29b1957ab8b29fde05a90e179092d7 (patch)
treed057b1c41ea435489ea2268b8e856a55c8a6ff5f
parentd9fda681dd79dca09b9955960eaf27fda200f928 (diff)
Add a simple option parser to the check utility; it makes for much saner
code in check.cpp, and now the order of options on the command line should not change what heppens. The options taken have changed slightly. All options that take values are now --arg=value instead of "--arg value", and the various --bench-(blah) options have been turned into a new option --bench-type that takes an argument specifying the type of algorithm to benchmark.
-rw-r--r--checks/check.cpp126
-rw-r--r--checks/getopt.cpp79
-rw-r--r--checks/getopt.h38
3 files changed, 171 insertions, 72 deletions
diff --git a/checks/check.cpp b/checks/check.cpp
index 81bb92220..c67dbd953 100644
--- a/checks/check.cpp
+++ b/checks/check.cpp
@@ -15,11 +15,10 @@
#include <botan/botan.h>
#include <botan/mp_types.h>
-/* Flag to use engine(s) for PK operations, if available */
-#define USE_ENGINES 0
-
using namespace Botan_types;
+#include "getopt.h"
+
/* Not on by default as many compilers (including egcs and gcc 2.95.x)
* do not have the C++ <limits> header.
*
@@ -43,88 +42,72 @@ void benchmark(const std::string&, bool html, double seconds);
void bench_pk(const std::string&, bool html, double seconds);
u32bit bench_algo(const std::string&);
int validate();
-void print_help(double);
+void print_help();
int main(int argc, char* argv[])
{
- try {
+ try
+ {
+ if(argc <= 1)
+ { print_help(); return 1; }
-#if 0
- // Make sure we can repeatedly init/shutdown without problems
- for(u32bit j = 0; j != 3; j++)
- {
- Botan::Init::initialize();
- Botan::Init::deinitialize();
- }
-#endif
+ OptionParser opts("help|html|init=|validate|"
+ "benchmark|bench-type=|bench-algo=|seconds=");
+ opts.parse(argv);
- std::string init_flags = "";
- if(USE_ENGINES)
- init_flags += " use_engines";
+ if(opts.is_set("help"))
+ { print_help(); return 1; }
- Botan::LibraryInitializer init(init_flags);
- bool html = false; // default to text output
- double seconds = 1.5;
+ std::string init_flags = (opts.is_set("init") ? opts.value("init") : "");
- std::vector<std::string> args;
- for(int j = 1; j != argc; j++)
- args.push_back(argv[j]);
+ Botan::InitializerOptions init_options(init_flags);
+ Botan::LibraryInitializer init(init_options);
- if(!args.size()) { print_help(seconds); return 2; }
+ if(opts.is_set("validate"))
+ return validate();
- for(u32bit j = 0; j != args.size(); j++)
+ double seconds = 1.5;
+
+ if(opts.is_set("seconds"))
{
- if(args[j] == "--help") { print_help(seconds); return 1; }
- if(args[j] == "--html") html = true;
- if(args[j] == "--bench-algo")
- {
- if(j != args.size() - 1)
- {
- u32bit found = bench_algo(args[j+1]);
- if(!found) // maybe it's a PK algorithm
- bench_pk(args[j+1], false, seconds);
- }
- else
- {
- std::cout << "Option --bench-algo needs an argument\n";
- return 2;
- }
- }
- if(args[j] == "--seconds")
+ seconds = std::atof(opts.value("seconds").c_str());
+ if((seconds < 0.1 || seconds > 30) && seconds != 0)
{
- if(j != args.size() - 1) // another arg remains
- {
- seconds = std::atof(args[j+1].c_str());
- // sanity check; we allow zero for testing porpoises
- if((seconds < 0.1 || seconds > 30) && seconds != 0)
- {
- std::cout << "Invalid argument to --seconds\n";
- return 2;
- }
- }
- else
- {
- std::cout << "Option --seconds needs an argument\n";
- return 2;
- }
+ std::cout << "Invalid argument to --seconds\n";
+ return 2;
}
}
- for(u32bit j = 0; j != args.size(); j++)
+ if(opts.is_set("bench-algo"))
+ {
+ const std::string alg = opts.value("bench-algo");
+ u32bit found = bench_algo(alg);
+ if(!found) // maybe it's a PK algorithm
+ bench_pk(alg, false, seconds);
+ }
+
+ const bool html = opts.is_set("html");
+
+ if(opts.is_set("benchmark"))
+ benchmark("All", html, seconds);
+ else if(opts.is_set("bench-type"))
{
- if(args[j] == "--validate") return validate();
- if(args[j] == "--benchmark") benchmark("All", html, seconds);
- if(args[j] == "--bench-all") benchmark("All", html, seconds);
- if(args[j] == "--bench-block")
+ const std::string type = opts.value("bench-type");
+
+ if(type == "all")
+ benchmark("All", html, seconds);
+ else if(type == "block")
benchmark("Block Cipher", html, seconds);
- if(args[j] == "--bench-mode")
- benchmark("Cipher Mode", html, seconds);
- if(args[j] == "--bench-stream")
+ else if(type == "stream")
benchmark("Stream Cipher", html, seconds);
- if(args[j] == "--bench-hash") benchmark("Hash", html, seconds);
- if(args[j] == "--bench-mac") benchmark("MAC", html, seconds);
- if(args[j] == "--bench-rng") benchmark("RNG", html, seconds);
- if(args[j] == "--bench-pk") bench_pk("All", html, seconds);
+ else if(type == "hash")
+ benchmark("Hash", html, seconds);
+ else if(type == "mac")
+ benchmark("MAC", html, seconds);
+ else if(type == "rng")
+ benchmark("RNG", html, seconds);
+ else if(type == "pk")
+ bench_pk("All", html, seconds);
}
}
catch(Botan::Exception& e)
@@ -147,17 +130,16 @@ int main(int argc, char* argv[])
return 0;
}
-void print_help(double seconds)
+void print_help()
{
std::cout << Botan::version_string() << " test driver" << std::endl
<< "Usage:\n"
<< " --validate: Check test vectors\n"
<< " --benchmark: Benchmark everything\n"
- << " --bench-{block,mode,stream,hash,mac,rng,pk}:\n"
+ << " --bench-type={block,mode,stream,hash,mac,rng,pk}:\n"
<< " Benchmark only algorithms of a particular type\n"
<< " --html: Produce HTML output for benchmarks\n"
- << " --seconds n: Benchmark for n seconds (default is "
- << seconds << ")\n"
+ << " --seconds=n: Benchmark for n seconds\n"
<< " --help: Print this message\n";
}
diff --git a/checks/getopt.cpp b/checks/getopt.cpp
new file mode 100644
index 000000000..a30134ff9
--- /dev/null
+++ b/checks/getopt.cpp
@@ -0,0 +1,79 @@
+
+#include "getopt.h"
+
+#include <botan/parsing.h>
+#include <botan/exceptn.h>
+
+OptionParser::OptionParser(const std::string& opt_string)
+ {
+ std::vector<std::string> opts = Botan::split_on(opt_string, '|');
+
+ for(size_t j = 0; j != opts.size(); j++)
+ flags.push_back(OptionFlag(opts[j]));
+ }
+
+OptionParser::OptionFlag OptionParser::find_option(const std::string& name) const
+ {
+ for(size_t j = 0; j != flags.size(); j++)
+ if(flags[j].name() == name)
+ return flags[j];
+ throw Botan::Exception("Unknown option " + name);
+ }
+
+bool OptionParser::is_set(const std::string& key) const
+ {
+ return (options.find(key) != options.end());
+ }
+
+std::string OptionParser::value(const std::string& key) const
+ {
+ std::map<std::string, std::string>::const_iterator i = options.find(key);
+ if(i == options.end())
+ throw Botan::Exception("Option " + key + " not found");
+ return i->second;
+ }
+
+void OptionParser::parse(char* argv[])
+ {
+ std::vector<std::string> args;
+ for(int j = 1; argv[j]; j++)
+ args.push_back(argv[j]);
+
+ for(size_t j = 0; j != args.size(); j++)
+ {
+ std::string arg = args[j];
+
+ if(arg.size() > 2 && arg[0] == '-' && arg[1] == '-')
+ {
+ const std::string opt_name = arg.substr(0, arg.find('='));
+
+ arg = arg.substr(2);
+
+ std::string::size_type mark = arg.find('=');
+
+ OptionFlag opt = find_option(arg.substr(0, mark));
+
+ if(opt.takes_arg())
+ {
+ if(mark == std::string::npos)
+ throw Botan::Exception("Option " + opt_name +
+ " requires an argument");
+
+ std::string name = arg.substr(0, mark);
+ std::string value = arg.substr(mark+1);
+
+ options[name] = value;
+ }
+ else
+ {
+ if(mark != std::string::npos)
+ throw Botan::Exception("Option " + opt_name +
+ " does not take an argument");
+
+ options[arg] = "";
+ }
+ }
+ else
+ leftover.push_back(arg);
+ }
+ }
diff --git a/checks/getopt.h b/checks/getopt.h
new file mode 100644
index 000000000..5796f7ae7
--- /dev/null
+++ b/checks/getopt.h
@@ -0,0 +1,38 @@
+
+#include <string>
+#include <vector>
+#include <map>
+
+class OptionParser
+ {
+ public:
+ std::vector<std::string> leftovers() const { return leftover; }
+ bool is_set(const std::string&) const;
+ std::string value(const std::string&) const;
+
+ void parse(char*[]);
+ OptionParser(const std::string&);
+ private:
+ class OptionFlag
+ {
+ public:
+ std::string name() const { return opt_name; }
+ bool takes_arg() const { return opt_takes_arg; }
+
+ OptionFlag(const std::string& opt_string)
+ {
+ std::string::size_type mark = opt_string.find('=');
+ opt_name = opt_string.substr(0, mark);
+ opt_takes_arg = (mark != std::string::npos);
+ }
+ private:
+ std::string opt_name;
+ bool opt_takes_arg;
+ };
+
+ OptionFlag find_option(const std::string&) const;
+
+ std::vector<OptionFlag> flags;
+ std::map<std::string, std::string> options;
+ std::vector<std::string> leftover;
+ };