Combine enums for flux source/sink types. config.cc now knows whether they're

read-only, write-only, and read-write.
This commit is contained in:
David Given
2023-07-24 00:50:54 +02:00
parent 315889faf6
commit 9867f8c302
16 changed files with 175 additions and 163 deletions

View File

@@ -19,4 +19,19 @@ enum IndexMode {
INDEXMODE_360 = 2;
}
enum FluxSourceSinkType {
NOT_SET = 0;
A2R = 1;
AU = 2;
CWF = 3;
DRIVE = 4;
ERASE = 5;
FLUX = 6;
FLX = 7;
KRYOFLUX = 8;
SCP = 9;
TEST_PATTERN = 10;
VCD = 11;
}

View File

@@ -15,6 +15,114 @@
static Config config;
struct FluxConstructor
{
std::regex pattern;
std::function<void(const std::string& filename, FluxSourceProto*)> source;
std::function<void(const std::string& filename, FluxSinkProto*)> sink;
};
static const std::vector<FluxConstructor> fluxConstructors = {
{.pattern = std::regex("^(.*\\.flux)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::FLUX);
proto->mutable_fl2()->set_filename(s);
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::FLUX);
proto->mutable_fl2()->set_filename(s);
}},
{
.pattern = std::regex("^(.*\\.scp)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::SCP);
proto->mutable_scp()->set_filename(s);
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::SCP);
proto->mutable_scp()->set_filename(s);
}, },
{.pattern = std::regex("^(.*\\.a2r)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::A2R);
proto->mutable_a2r()->set_filename(s);
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::A2R);
proto->mutable_a2r()->set_filename(s);
}},
{.pattern = std::regex("^(.*\\.cwf)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::CWF);
proto->mutable_cwf()->set_filename(s);
}},
{.pattern = std::regex("^erase:$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::ERASE);
}},
{.pattern = std::regex("^kryoflux:(.*)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::KRYOFLUX);
proto->mutable_kryoflux()->set_directory(s);
}},
{.pattern = std::regex("^testpattern:(.*)"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::TEST_PATTERN);
}},
{.pattern = std::regex("^drive:(.*)"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}},
{.pattern = std::regex("^flx:(.*)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::FLX);
proto->mutable_flx()->set_directory(s);
}},
{.pattern = std::regex("^vcd:(.*)$"),
.sink =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::VCD);
proto->mutable_vcd()->set_directory(s);
}},
{.pattern = std::regex("^au:(.*)$"),
.sink =
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceSinkType::AU);
proto->mutable_au()->set_directory(s);
}},
};
Config& globalConfig()
{
return config;
@@ -336,70 +444,14 @@ void Config::clearOptions()
static void setFluxSourceImpl(std::string filename, FluxSourceProto* proto)
{
static const std::vector<std::pair<std::regex,
std::function<void(const std::string&, FluxSourceProto*)>>>
formats = {
{std::regex("^(.*\\.flux)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::FLUX);
proto->mutable_fl2()->set_filename(s);
}},
{std::regex("^(.*\\.scp)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::SCP);
proto->mutable_scp()->set_filename(s);
}},
{std::regex("^(.*\\.a2r)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::A2R);
proto->mutable_a2r()->set_filename(s);
}},
{std::regex("^(.*\\.cwf)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::CWF);
proto->mutable_cwf()->set_filename(s);
}},
{std::regex("^erase:$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::ERASE);
}},
{std::regex("^kryoflux:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::KRYOFLUX);
proto->mutable_kryoflux()->set_directory(s);
}},
{std::regex("^testpattern:(.*)"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::TEST_PATTERN);
}},
{std::regex("^drive:(.*)"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}},
{std::regex("^flx:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::FLX);
proto->mutable_flx()->set_directory(s);
}},
};
for (const auto& it : formats)
for (const auto& it : fluxConstructors)
{
std::smatch match;
if (std::regex_match(filename, match, it.first))
if (std::regex_match(filename, match, it.pattern))
{
it.second(match[1], proto);
if (!it.source)
throw new InapplicableValueException();
it.source(match[1], proto);
return;
}
}
@@ -414,54 +466,14 @@ void Config::setFluxSource(std::string filename)
static void setFluxSinkImpl(std::string filename, FluxSinkProto* proto)
{
static const std::vector<std::pair<std::regex,
std::function<void(const std::string&, FluxSinkProto*)>>>
formats = {
{std::regex("^(.*\\.a2r)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::A2R);
proto->mutable_a2r()->set_filename(s);
}},
{std::regex("^(.*\\.flux)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::FLUX);
proto->mutable_fl2()->set_filename(s);
}},
{std::regex("^(.*\\.scp)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::SCP);
proto->mutable_scp()->set_filename(s);
}},
{std::regex("^vcd:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::VCD);
proto->mutable_vcd()->set_directory(s);
}},
{std::regex("^au:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::AU);
proto->mutable_au()->set_directory(s);
}},
{std::regex("^drive:(.*)"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}},
};
for (const auto& it : formats)
for (const auto& it : fluxConstructors)
{
std::smatch match;
if (std::regex_match(filename, match, it.first))
if (std::regex_match(filename, match, it.pattern))
{
it.second(match[1], proto);
if (!it.sink)
throw new InapplicableValueException();
it.sink(match[1], proto);
return;
}
}
@@ -560,7 +572,7 @@ void Config::setImageWriter(std::string filename)
bool Config::hasFluxSource()
{
return (*this)->flux_source().type() != FluxSourceProto::NOT_SET;
return (*this)->flux_source().type() != FluxSourceSinkType::NOT_SET;
}
std::shared_ptr<FluxSource>& Config::getFluxSource()
@@ -578,7 +590,7 @@ std::shared_ptr<FluxSource>& Config::getFluxSource()
bool Config::hasVerificationFluxSource() const
{
return _verificationFluxSourceProto.type() != FluxSourceProto::NOT_SET;
return _verificationFluxSourceProto.type() != FluxSourceSinkType::NOT_SET;
}
std::shared_ptr<FluxSource>& Config::getVerificationFluxSource()
@@ -614,7 +626,7 @@ std::shared_ptr<ImageReader>& Config::getImageReader()
bool Config::hasFluxSink()
{
return (*this)->flux_sink().type() != FluxSinkProto::NOT_SET;
return (*this)->flux_sink().type() != FluxSourceSinkType::NOT_SET;
}
std::unique_ptr<FluxSink> Config::getFluxSink()

View File

@@ -4,6 +4,7 @@
#include <google/protobuf/message.h>
#include "lib/config.pb.h"
#include "lib/common.pb.h"
class ConfigProto;
class OptionProto;
@@ -46,6 +47,14 @@ public:
}
};
class InapplicableValueException : public ErrorException
{
public:
InapplicableValueException():
ErrorException("selected format cannot be used here")
{}
};
class Config
{
public:

View File

@@ -10,26 +10,25 @@ std::unique_ptr<FluxSink> FluxSink::create(const FluxSinkProto& config)
{
switch (config.type())
{
case FluxSinkProto::DRIVE:
case FluxSourceSinkType::DRIVE:
return createHardwareFluxSink(config.drive());
case FluxSinkProto::A2R:
case FluxSourceSinkType::A2R:
return createA2RFluxSink(config.a2r());
case FluxSinkProto::AU:
case FluxSourceSinkType::AU:
return createAuFluxSink(config.au());
case FluxSinkProto::VCD:
case FluxSourceSinkType::VCD:
return createVcdFluxSink(config.vcd());
case FluxSinkProto::SCP:
case FluxSourceSinkType::SCP:
return createScpFluxSink(config.scp());
case FluxSinkProto::FLUX:
case FluxSourceSinkType::FLUX:
return createFl2FluxSink(config.fl2());
default:
error("bad output disk config");
return std::unique_ptr<FluxSink>();
}
}

View File

@@ -29,17 +29,7 @@ message Fl2FluxSinkProto {
// Next: 10
message FluxSinkProto {
enum FluxSinkType {
NOT_SET = 0;
DRIVE = 1;
A2R = 2;
AU = 3;
VCD = 4;
SCP = 5;
FLUX = 6;
}
optional FluxSinkType type = 9 [default = NOT_SET, (help) = "flux sink type"];
optional FluxSourceSinkType type = 9 [default = NOT_SET, (help) = "flux sink type"];
optional HardwareFluxSinkProto drive = 2;
optional A2RFluxSinkProto a2r = 8;

View File

@@ -10,35 +10,34 @@ std::unique_ptr<FluxSource> FluxSource::create(const FluxSourceProto& config)
{
switch (config.type())
{
case FluxSourceProto::DRIVE:
case FluxSourceSinkType::DRIVE:
return createHardwareFluxSource(config.drive());
case FluxSourceProto::ERASE:
case FluxSourceSinkType::ERASE:
return createEraseFluxSource(config.erase());
case FluxSourceProto::KRYOFLUX:
case FluxSourceSinkType::KRYOFLUX:
return createKryofluxFluxSource(config.kryoflux());
case FluxSourceProto::TEST_PATTERN:
case FluxSourceSinkType::TEST_PATTERN:
return createTestPatternFluxSource(config.test_pattern());
case FluxSourceProto::SCP:
case FluxSourceSinkType::SCP:
return createScpFluxSource(config.scp());
case FluxSourceProto::A2R:
case FluxSourceSinkType::A2R:
return createA2rFluxSource(config.a2r());
case FluxSourceProto::CWF:
case FluxSourceSinkType::CWF:
return createCwfFluxSource(config.cwf());
case FluxSourceProto::FLUX:
case FluxSourceSinkType::FLUX:
return createFl2FluxSource(config.fl2());
case FluxSourceProto::FLX:
case FluxSourceSinkType::FLX:
return createFlxFluxSource(config.flx());
default:
error("bad input disk configuration");
return std::unique_ptr<FluxSource>();
}
}

View File

@@ -41,20 +41,7 @@ message FlxFluxSourceProto {
// NEXT: 12
message FluxSourceProto {
enum FluxSourceType {
NOT_SET = 0;
DRIVE = 1;
TEST_PATTERN = 2;
ERASE = 3;
KRYOFLUX = 4;
SCP = 5;
CWF = 6;
FLUX = 7;
FLX = 8;
A2R = 9;
}
optional FluxSourceType type = 9 [default = NOT_SET, (help) = "flux source type"];
optional FluxSourceSinkType type = 9 [default = NOT_SET, (help) = "flux source type"];
optional A2rFluxSourceProto a2r = 11;
optional CwfFluxSourceProto cwf = 7;

View File

@@ -2,6 +2,7 @@
#define PROTO_H
#include <google/protobuf/message.h>
#include "lib/common.pb.h"
#include "lib/config.pb.h"
class ProtoPathNotFoundException : public ErrorException

View File

@@ -236,7 +236,7 @@ std::unique_ptr<Filesystem> Filesystem::createFilesystemFromConfig()
fluxSource = globalConfig().getFluxSource();
decoder = globalConfig().getDecoder();
}
if (globalConfig()->flux_sink().type() == FluxSinkProto::DRIVE)
if (globalConfig()->flux_sink().type() == FluxSourceSinkType::DRIVE)
{
fluxSink = globalConfig().getFluxSink();
encoder = globalConfig().getEncoder();

View File

@@ -247,10 +247,10 @@ static void draw_x_graticules(Agg2D& painter,
int mainAnalyseDriveResponse(int argc, const char* argv[])
{
globalConfig().overrides()->mutable_flux_source()->set_type(
FluxSourceProto::DRIVE);
FluxSourceSinkType::DRIVE);
flags.parseFlagsWithConfigFiles(argc, argv, {});
if (globalConfig()->flux_sink().type() != FluxSinkProto::DRIVE)
if (globalConfig()->flux_sink().type() != FluxSourceSinkType::DRIVE)
error("this only makes sense with a real disk drive");
usbSetDrive(globalConfig()->drive().drive(),

View File

@@ -132,7 +132,7 @@ static nanoseconds_t guessClock(const Fluxmap& fluxmap)
int mainInspect(int argc, const char* argv[])
{
globalConfig().overrides()->mutable_flux_source()->set_type(
FluxSourceProto::DRIVE);
FluxSourceSinkType::DRIVE);
flags.parseFlagsWithConfigFiles(argc, argv, {});
auto& fluxSource = globalConfig().getFluxSource();

View File

@@ -57,10 +57,10 @@ int mainRawRead(int argc, const char* argv[])
if (argc == 1)
showProfiles("rawread", formats);
globalConfig().overrides()->mutable_flux_source()->set_type(
FluxSourceProto::DRIVE);
FluxSourceSinkType::DRIVE);
flags.parseFlagsWithConfigFiles(argc, argv, formats);
if (globalConfig()->flux_sink().type() == FluxSinkProto::DRIVE)
if (globalConfig()->flux_sink().type() == FluxSourceSinkType::DRIVE)
error("you can't use rawread to write to hardware");
std::shared_ptr<FluxSource> fluxSource = globalConfig().getFluxSource();

View File

@@ -49,7 +49,7 @@ static ActionFlag eraseFlag({"--erase"},
[]()
{
globalConfig().overrides()->mutable_flux_source()->set_type(
FluxSourceProto::ERASE);
FluxSourceSinkType::ERASE);
});
int mainRawWrite(int argc, const char* argv[])
@@ -60,10 +60,10 @@ int mainRawWrite(int argc, const char* argv[])
if (argc == 1)
showProfiles("rawwrite", formats);
globalConfig().overrides()->mutable_flux_sink()->set_type(
FluxSinkProto::DRIVE);
FluxSourceSinkType::DRIVE);
flags.parseFlagsWithConfigFiles(argc, argv, formats);
if (globalConfig()->flux_source().type() == FluxSourceProto::DRIVE)
if (globalConfig()->flux_source().type() == FluxSourceSinkType::DRIVE)
error("you can't use rawwrite to read from hardware");
auto& fluxSource = globalConfig().getFluxSource();

View File

@@ -64,7 +64,7 @@ int mainRead(int argc, const char* argv[])
globalConfig().set("flux_source.type", "DRIVE");
flags.parseFlagsWithConfigFiles(argc, argv, formats);
if (globalConfig()->decoder().copy_flux_to().type() == FluxSinkProto::DRIVE)
if (globalConfig()->decoder().copy_flux_to().type() == FluxSourceSinkType::DRIVE)
error("you cannot copy flux to a hardware device");
auto& fluxSource = globalConfig().getFluxSource();

View File

@@ -19,7 +19,7 @@ int mainRpm(int argc, const char* argv[])
{
flags.parseFlagsWithConfigFiles(argc, argv, {});
if (globalConfig()->flux_source().type() != FluxSourceProto::DRIVE)
if (globalConfig()->flux_source().type() != FluxSourceSinkType::DRIVE)
error("this only makes sense with a real disk drive");
usbSetDrive(globalConfig()->drive().drive(),

View File

@@ -23,7 +23,7 @@ int mainSeek(int argc, const char* argv[])
{
flags.parseFlagsWithConfigFiles(argc, argv, {});
if (globalConfig()->flux_source().type() != FluxSourceProto::DRIVE)
if (globalConfig()->flux_source().type() != FluxSourceSinkType::DRIVE)
error("this only makes sense with a real disk drive");
usbSetDrive(globalConfig()->drive().drive(),