aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
+ };