From ed0f38748b9aa0505bbba820efbdfb81129cfd7d Mon Sep 17 00:00:00 2001 From: David Given Date: Sat, 15 May 2021 21:28:02 +0200 Subject: [PATCH] Add helper flags to fe-read and fe-write for setting common parameters. --- lib/flags.cc | 1 + lib/flags.h | 38 ++++++++++++++++------------ lib/imagereader/imagereader.cc | 27 ++++++++++++++++++++ lib/imagereader/imagereader.h | 1 + lib/imagewriter/imagewriter.cc | 45 ++++++++++++++++++++-------------- lib/imagewriter/imagewriter.h | 1 + src/fe-read.cc | 29 +++++++++++++++++++++- src/fe-write.cc | 29 +++++++++++++++++++++- 8 files changed, 136 insertions(+), 35 deletions(-) diff --git a/lib/flags.cc b/lib/flags.cc index 0f7a9062..f8613551 100644 --- a/lib/flags.cc +++ b/lib/flags.cc @@ -218,6 +218,7 @@ void BoolFlag::set(const std::string& value) _value = false; else Error() << "can't parse '" << value << "'; try 'true' or 'false'"; + _callback(_value); } const std::string HexIntFlag::defaultValueAsString() const diff --git a/lib/flags.h b/lib/flags.h index eed9ca1a..5bb8599e 100644 --- a/lib/flags.h +++ b/lib/flags.h @@ -92,10 +92,12 @@ class ValueFlag : public Flag { public: ValueFlag(const std::vector& names, const std::string helptext, - const T defaultValue): + const T defaultValue, + std::function callback = [](const T&) {}): Flag(names, helptext), _defaultValue(defaultValue), - _value(defaultValue) + _value(defaultValue), + _callback(callback) {} const T& get() const @@ -114,38 +116,42 @@ public: protected: T _defaultValue; T _value; + std::function _callback; }; class StringFlag : public ValueFlag { public: StringFlag(const std::vector& names, const std::string helptext, - const std::string defaultValue = ""): - ValueFlag(names, helptext, defaultValue) + const std::string defaultValue = "", + std::function callback = [](const std::string&) {}): + ValueFlag(names, helptext, defaultValue, callback) {} const std::string defaultValueAsString() const { return _defaultValue; } - void set(const std::string& value) { _value = value; } + void set(const std::string& value) { _value = value; _callback(_value); } }; class IntFlag : public ValueFlag { public: IntFlag(const std::vector& names, const std::string helptext, - int defaultValue = 0): - ValueFlag(names, helptext, defaultValue) + int defaultValue = 0, + std::function callback = [](const int&) {}): + ValueFlag(names, helptext, defaultValue, callback) {} const std::string defaultValueAsString() const { return std::to_string(_defaultValue); } - void set(const std::string& value) { _value = std::stoi(value); } + void set(const std::string& value) { _value = std::stoi(value); _callback(_value); } }; class HexIntFlag : public IntFlag { public: HexIntFlag(const std::vector& names, const std::string helptext, - int defaultValue = 0): - IntFlag(names, helptext, defaultValue) + int defaultValue = 0, + std::function callback = [](const int&) {}): + IntFlag(names, helptext, defaultValue, callback) {} const std::string defaultValueAsString() const; @@ -155,20 +161,22 @@ class DoubleFlag : public ValueFlag { public: DoubleFlag(const std::vector& names, const std::string helptext, - double defaultValue = 1.0): - ValueFlag(names, helptext, defaultValue) + double defaultValue = 1.0, + std::function callback = [](const double&) {}): + ValueFlag(names, helptext, defaultValue, callback) {} const std::string defaultValueAsString() const { return std::to_string(_defaultValue); } - void set(const std::string& value) { _value = std::stod(value); } + void set(const std::string& value) { _value = std::stod(value); _callback(_value); } }; class BoolFlag : public ValueFlag { public: BoolFlag(const std::vector& names, const std::string helptext, - bool defaultValue = false): - ValueFlag(names, helptext, defaultValue) + bool defaultValue = false, + std::function callback = [](const bool&) {}): + ValueFlag(names, helptext, defaultValue, callback) {} const std::string defaultValueAsString() const { return _defaultValue ? "true" : "false"; } diff --git a/lib/imagereader/imagereader.cc b/lib/imagereader/imagereader.cc index 2ea4a20a..1618712a 100644 --- a/lib/imagereader/imagereader.cc +++ b/lib/imagereader/imagereader.cc @@ -6,6 +6,7 @@ #include "imagereader/imagereader.h" #include "utils.h" #include "fmt/format.h" +#include "proto.h" #include "lib/config.pb.h" #include #include @@ -31,6 +32,32 @@ std::unique_ptr ImageReader::create(const InputFileProto& config) return std::unique_ptr(); } +void ImageReader::updateConfigForFilename(const std::string& filename) +{ + InputFileProto* f = config.mutable_input()->mutable_file(); + static const std::map> formats = + { + {".adf", [&]() { f->mutable_img(); }}, + {".jv3", [&]() { f->mutable_jv3(); }}, + {".d81", [&]() { f->mutable_img(); }}, + {".diskcopy", [&]() { f->mutable_diskcopy(); }}, + {".img", [&]() { f->mutable_img(); }}, + {".st", [&]() { f->mutable_img(); }}, + }; + + for (const auto& it : formats) + { + if (endsWith(filename, it.first)) + { + it.second(); + f->set_filename(filename); + return; + } + } + + Error() << fmt::format("unrecognised image filename '{}'", filename); +} + ImageReader::ImageReader(const InputFileProto& config): _config(config) {} diff --git a/lib/imagereader/imagereader.h b/lib/imagereader/imagereader.h index 73fa018d..98f27716 100644 --- a/lib/imagereader/imagereader.h +++ b/lib/imagereader/imagereader.h @@ -13,6 +13,7 @@ public: public: static std::unique_ptr create(const InputFileProto& config); + static void updateConfigForFilename(const std::string& filename); public: static std::unique_ptr createDiskCopyImageReader(const InputFileProto& config); diff --git a/lib/imagewriter/imagewriter.cc b/lib/imagewriter/imagewriter.cc index d418a087..c8cba5b4 100644 --- a/lib/imagewriter/imagewriter.cc +++ b/lib/imagewriter/imagewriter.cc @@ -6,23 +6,11 @@ #include "imagewriter/imagewriter.h" #include "utils.h" #include "lib/config.pb.h" +#include "proto.h" #include "fmt/format.h" #include #include -#if 0 -std::map ImageWriter::formats = -{ - {".adf", ImageWriter::createImgImageWriter}, - {".d64", ImageWriter::createD64ImageWriter}, - {".d81", ImageWriter::createImgImageWriter}, - {".diskcopy", ImageWriter::createDiskCopyImageWriter}, - {".img", ImageWriter::createImgImageWriter}, - {".ldbs", ImageWriter::createLDBSImageWriter}, - {".st", ImageWriter::createImgImageWriter}, -}; -#endif - std::unique_ptr ImageWriter::create(const OutputFileProto& config) { switch (config.format_case()) @@ -43,11 +31,32 @@ std::unique_ptr ImageWriter::create(const OutputFileProto& config) return std::unique_ptr(); } -//void ImageWriter::verifyImageSpec(const ImageSpec& spec) -//{ -// if (!findConstructor(spec)) -// Error() << "unrecognised output image filename extension"; -//} +void ImageWriter::updateConfigForFilename(const std::string& filename) +{ + OutputFileProto* f = config.mutable_output()->mutable_file(); + static const std::map> formats = + { + {".adf", [&]() { f->mutable_img(); }}, + {".d64", [&]() { f->mutable_d64(); }}, + {".d81", [&]() { f->mutable_img(); }}, + {".diskcopy", [&]() { f->mutable_diskcopy(); }}, + {".img", [&]() { f->mutable_img(); }}, + {".ldbs", [&]() { f->mutable_ldbs(); }}, + {".st", [&]() { f->mutable_img(); }}, + }; + + for (const auto& it : formats) + { + if (endsWith(filename, it.first)) + { + it.second(); + f->set_filename(filename); + return; + } + } + + Error() << fmt::format("unrecognised image filename '{}'", filename); +} ImageWriter::ImageWriter(const OutputFileProto& config): _config(config) diff --git a/lib/imagewriter/imagewriter.h b/lib/imagewriter/imagewriter.h index e0e78eca..40738457 100644 --- a/lib/imagewriter/imagewriter.h +++ b/lib/imagewriter/imagewriter.h @@ -12,6 +12,7 @@ public: public: static std::unique_ptr create(const OutputFileProto& config); + static void updateConfigForFilename(const std::string& filename); static std::unique_ptr createImgImageWriter( const OutputFileProto& config); diff --git a/src/fe-read.cc b/src/fe-read.cc index 7e90d7a7..890cc232 100644 --- a/src/fe-read.cc +++ b/src/fe-read.cc @@ -19,13 +19,40 @@ static FlagGroup flags; +static StringFlag sourceFlux( + { "-s", "--source" }, + "flux file to read from", + "", + [](const auto& value) + { + config.mutable_input()->mutable_disk()->set_fluxfile(value); + }); + +static IntFlag sourceDrive( + { "-D", "--drive" }, + "drive to write from", + 0, + [](const auto& value) + { + config.mutable_input()->mutable_disk()->mutable_drive()->set_drive(value); + }); + +static StringFlag destImage( + { "-o", "--output" }, + "destination image to write", + "", + [](const auto& value) + { + ImageWriter::updateConfigForFilename(value); + }); + extern const std::map readables; int mainRead(int argc, const char* argv[]) { flags.parseFlagsWithConfigFiles(argc, argv, readables); - if (!config.has_input() || !config.has_output()) + if (!config.input().has_disk() || !config.output().has_file()) Error() << "incomplete config (did you remember to specify the format?)"; std::unique_ptr fluxSource(FluxSource::create(config.input().disk())); diff --git a/src/fe-write.cc b/src/fe-write.cc index 049963eb..598ecc26 100644 --- a/src/fe-write.cc +++ b/src/fe-write.cc @@ -19,13 +19,40 @@ static FlagGroup flags; +static StringFlag sourceImage( + { "-i", "--input" }, + "source image to read from", + "", + [](const auto& value) + { + ImageReader::updateConfigForFilename(value); + }); + +static StringFlag destFlux( + { "-d", "--dest" }, + "flux file to write to", + "", + [](const auto& value) + { + config.mutable_output()->mutable_disk()->set_fluxfile(value); + }); + +static IntFlag destDrive( + { "-D", "--drive" }, + "drive to write to", + 0, + [](const auto& value) + { + config.mutable_output()->mutable_disk()->mutable_drive()->set_drive(value); + }); + extern const std::map writables; int mainWrite(int argc, const char* argv[]) { flags.parseFlagsWithConfigFiles(argc, argv, writables); - if (!config.has_input() || !config.has_output()) + if (!config.input().has_disk() || !config.output().has_file()) Error() << "incomplete config (did you remember to specify the format?)"; std::unique_ptr reader(ImageReader::create(config.input().file()));