diff --git a/Makefile b/Makefile index 9a44789..b1a6229 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ OBJECTS=$(subst .cc,.o,$(SOURCE)) TOP_DIR:=$(PWD) CPPFLAGS=-Wall -g -I$(TOP_DIR) #CPPFLAGS=-Wall -std=c++0x -g -I$(TOP_DIR) -LIBS=-lstdc++ +LIBS=-lstdc++ -lboost_program_options .PHONEY: test-programs diff --git a/metadata.h b/metadata.h index 732fbcb..aa5b6e8 100644 --- a/metadata.h +++ b/metadata.h @@ -3,6 +3,7 @@ #include "block.h" #include "btree.h" +#include "emitter.h" #include "endian_utils.h" #include "error_set.h" #include "metadata_disk_structures.h" @@ -173,7 +174,7 @@ namespace thin_provisioning { boost::optional check(); // Dumping metadata - void dump(); + void dump(emitter::ptr e); private: friend class thin; diff --git a/metadata_dump.cc b/metadata_dump.cc index fe20823..373585d 100644 --- a/metadata_dump.cc +++ b/metadata_dump.cc @@ -1,8 +1,5 @@ #include "metadata.h" -#include "human_readable_format.h" -#include "xml_format.h" - using namespace persistent_data; using namespace thin_provisioning; @@ -124,10 +121,8 @@ namespace { } void -metadata::dump() +metadata::dump(emitter::ptr e) { - emitter::ptr e = create_xml_emitter(cout); - details_extractor::ptr de(new details_extractor); details_.visit(de); diff --git a/thin_dump.cc b/thin_dump.cc index 52929dd..788fe2c 100644 --- a/thin_dump.cc +++ b/thin_dump.cc @@ -1,33 +1,70 @@ #include +#include "human_readable_format.h" #include "metadata.h" +#include "xml_format.h" + +#include using namespace persistent_data; using namespace std; using namespace thin_provisioning; +namespace po = boost::program_options; + //---------------------------------------------------------------- namespace { - void dump(string const &path) { + void dump(string const &path, string const &format) { metadata md(path); - //human_readable::ptr emitter(new human_readable); - md.dump(); + emitter::ptr e; + + if (format == "xml") + e = create_xml_emitter(cout); + else if (format == "human_readable") + e = create_human_readable_emitter(cout); + else { + cerr << "unknown format '" << format << "'" << endl; + exit(1); + } + + md.dump(e); } - void usage(string const &cmd) { - cerr << "Usage: " << cmd << " " << endl; + void usage(po::options_description const &desc) { + cerr << "Usage: thin_dump [options] " << endl << endl; + cerr << desc; } } int main(int argc, char **argv) { - if (argc != 2) { - usage(argv[0]); - exit(1); + po::options_description desc("Options"); + desc.add_options() + ("help", "Produce help message") + ("format,f", po::value()->default_value("xml"), "Select format (human_readable|xml)") + ("input,i", po::value(), "Input file") + ; + + po::positional_options_description p; + p.add("input", -1); + + po::variables_map vm; + po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); + po::notify(vm); + + if (vm.count("help")) { + usage(desc); + return 0; } - dump(argv[1]); + if (vm.count("input") != 1) { + cerr << "No input file provided." << endl; + usage(desc); + return 1; + } + + dump(vm["input"].as(), vm["format"].as()); return 0; } diff --git a/xml_format.cc b/xml_format.cc index 1b8624a..92d712e 100644 --- a/xml_format.cc +++ b/xml_format.cc @@ -6,6 +6,8 @@ using namespace std; using namespace thin_provisioning; +namespace tp = thin_provisioning; + //---------------------------------------------------------------- namespace { @@ -101,8 +103,8 @@ namespace { //---------------------------------------------------------------- -thin_provisioning::emitter::ptr -thin_provisioning::create_xml_emitter(ostream &out) +tp::emitter::ptr +tp::create_xml_emitter(ostream &out) { return emitter::ptr(new xml_emitter(out)); }