mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-24 11:11:02 -07:00
Preparse ConfigProto objects.
This commit is contained in:
2
Makefile
2
Makefile
@@ -48,7 +48,7 @@ AR ?= $(CCPREFIX)ar
|
||||
PKG_CONFIG ?= pkg-config
|
||||
WX_CONFIG ?= wx-config
|
||||
PROTOC ?= protoc
|
||||
CFLAGS ?= -g -Os
|
||||
CFLAGS ?= -g -O3
|
||||
CXXFLAGS += -std=c++17
|
||||
LDFLAGS ?=
|
||||
PLATFORM ?= UNIX
|
||||
|
||||
13
lib/flags.cc
13
lib/flags.cc
@@ -279,7 +279,7 @@ void FlagGroup::parseFlags(int argc,
|
||||
|
||||
void FlagGroup::parseFlagsWithConfigFiles(int argc,
|
||||
const char* argv[],
|
||||
const std::map<std::string, std::string>& configFiles)
|
||||
const std::map<std::string, const ConfigProto*>& configFiles)
|
||||
{
|
||||
parseFlags(argc,
|
||||
argv,
|
||||
@@ -291,16 +291,11 @@ void FlagGroup::parseFlagsWithConfigFiles(int argc,
|
||||
}
|
||||
|
||||
ConfigProto FlagGroup::parseSingleConfigFile(const std::string& filename,
|
||||
const std::map<std::string, std::string>& configFiles)
|
||||
const std::map<std::string, const ConfigProto*>& configFiles)
|
||||
{
|
||||
const auto& it = configFiles.find(filename);
|
||||
if (it != configFiles.end())
|
||||
{
|
||||
ConfigProto config;
|
||||
if (!config.ParseFromString(it->second))
|
||||
Error() << "couldn't load built-in config proto";
|
||||
return config;
|
||||
}
|
||||
return *it->second;
|
||||
else
|
||||
{
|
||||
std::ifstream f(filename, std::ios::out);
|
||||
@@ -319,7 +314,7 @@ ConfigProto FlagGroup::parseSingleConfigFile(const std::string& filename,
|
||||
}
|
||||
|
||||
void FlagGroup::parseConfigFile(const std::string& filename,
|
||||
const std::map<std::string, std::string>& configFiles)
|
||||
const std::map<std::string, const ConfigProto*>& configFiles)
|
||||
{
|
||||
auto newConfig = parseSingleConfigFile(filename, configFiles);
|
||||
|
||||
|
||||
@@ -31,19 +31,19 @@ public:
|
||||
});
|
||||
void parseFlagsWithConfigFiles(int argc,
|
||||
const char* argv[],
|
||||
const std::map<std::string, std::string>& configFiles);
|
||||
const std::map<std::string, const ConfigProto*>& configFiles);
|
||||
|
||||
/* Load one config file (or internal config file), without expanding
|
||||
* includes. */
|
||||
|
||||
static ConfigProto parseSingleConfigFile(const std::string& filename,
|
||||
const std::map<std::string, std::string>& configFiles);
|
||||
const std::map<std::string, const ConfigProto*>& configFiles);
|
||||
|
||||
/* Load a top-level config file (or internal config file), expanding
|
||||
* includes. */
|
||||
|
||||
static void parseConfigFile(const std::string& filename,
|
||||
const std::map<std::string, std::string>& configFiles);
|
||||
const std::map<std::string, const ConfigProto*>& configFiles);
|
||||
|
||||
/* Modify the current config to engage the named option. */
|
||||
|
||||
|
||||
@@ -246,3 +246,12 @@ findAllProtoFields(google::protobuf::Message* message)
|
||||
recurse(descriptor, "");
|
||||
return fields;
|
||||
}
|
||||
|
||||
ConfigProto parseConfigBytes(const std::string_view& data)
|
||||
{
|
||||
ConfigProto proto;
|
||||
if (!proto.ParseFromArray(data.begin(), data.size()))
|
||||
Error() << "invalid internal config data";
|
||||
return proto;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ extern std::set<unsigned> iterate(unsigned start, unsigned count);
|
||||
extern std::map<std::string, const google::protobuf::FieldDescriptor*>
|
||||
findAllProtoFields(google::protobuf::Message* message);
|
||||
|
||||
extern ConfigProto parseConfigBytes(const std::string_view& bytes);
|
||||
|
||||
extern ConfigProto config;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,15 +3,11 @@
|
||||
#include "lib/flags.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
extern const std::map<std::string, std::string> formats;
|
||||
extern const std::map<std::string, const ConfigProto*> formats;
|
||||
|
||||
static ConfigProto findConfig(std::string name)
|
||||
static const ConfigProto& findConfig(std::string name)
|
||||
{
|
||||
const auto data = formats.at(name);
|
||||
ConfigProto config;
|
||||
if (!config.ParseFromString(data))
|
||||
Error() << "bad config name: " + name;
|
||||
return config;
|
||||
return *formats.at(name);
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
#!/bin/sh
|
||||
echo "#include <string>"
|
||||
echo "#include <map>"
|
||||
echo "class ConfigProto;"
|
||||
|
||||
word=$1
|
||||
shift
|
||||
|
||||
for a in "$@"; do
|
||||
echo "extern std::string ${word}_${a}_pb();"
|
||||
echo "extern const ConfigProto ${word}_${a}_pb;"
|
||||
done
|
||||
|
||||
echo "extern const std::map<std::string, std::string> ${word};"
|
||||
echo "const std::map<std::string, std::string> ${word} = {"
|
||||
echo "extern const std::map<std::string, const ConfigProto*> ${word};"
|
||||
echo "const std::map<std::string, const ConfigProto*> ${word} = {"
|
||||
for a in "$@"; do
|
||||
echo " { \"${a}\", ${word}_${a}_pb() },"
|
||||
echo " { \"${a}\", &${word}_${a}_pb },"
|
||||
done
|
||||
echo "};"
|
||||
|
||||
|
||||
@@ -12,100 +12,100 @@
|
||||
|
||||
static uint32_t readu8(std::string::iterator& it, std::string::iterator end)
|
||||
{
|
||||
int len;
|
||||
int len;
|
||||
uint32_t c = *it++;
|
||||
if (c < 0x80)
|
||||
{
|
||||
/* Do nothing! */
|
||||
len = 0;
|
||||
len = 0;
|
||||
}
|
||||
else if (c < 0xc0)
|
||||
{
|
||||
/* Invalid character */
|
||||
c = -1;
|
||||
len = 0;
|
||||
len = 0;
|
||||
}
|
||||
else if (c < 0xe0)
|
||||
{
|
||||
/* One trailing byte */
|
||||
c &= 0x1f;
|
||||
len = 1;
|
||||
len = 1;
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
/* Two trailing bytes */
|
||||
c &= 0x0f;
|
||||
len = 2;
|
||||
len = 2;
|
||||
}
|
||||
else if (c < 0xf8)
|
||||
{
|
||||
/* Three trailing bytes */
|
||||
c &= 0x07;
|
||||
len = 3;
|
||||
len = 3;
|
||||
}
|
||||
else if (c < 0xfc)
|
||||
{
|
||||
/* Four trailing bytes */
|
||||
c &= 0x03;
|
||||
len = 4;
|
||||
len = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Five trailing bytes */
|
||||
c &= 0x01;
|
||||
len = 5;
|
||||
len = 5;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if (it == end)
|
||||
break;
|
||||
while (len)
|
||||
{
|
||||
if (it == end)
|
||||
break;
|
||||
|
||||
uint8_t d = *it++;
|
||||
c <<= 6;
|
||||
c += d & 0x3f;
|
||||
}
|
||||
uint8_t d = *it++;
|
||||
c <<= 6;
|
||||
c += d & 0x3f;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
PROTO message;
|
||||
PROTO message;
|
||||
|
||||
std::ifstream input(argv[1]);
|
||||
if (!input)
|
||||
{
|
||||
perror("couldn't open input file");
|
||||
exit(1);
|
||||
}
|
||||
std::ifstream input(argv[1]);
|
||||
if (!input)
|
||||
{
|
||||
perror("couldn't open input file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
std::string s;
|
||||
while (std::getline(input, s, '\n'))
|
||||
{
|
||||
if (s == "<<<")
|
||||
{
|
||||
while (std::getline(input, s, '\n'))
|
||||
{
|
||||
if (s == ">>>")
|
||||
break;
|
||||
std::stringstream ss;
|
||||
std::string s;
|
||||
while (std::getline(input, s, '\n'))
|
||||
{
|
||||
if (s == "<<<")
|
||||
{
|
||||
while (std::getline(input, s, '\n'))
|
||||
{
|
||||
if (s == ">>>")
|
||||
break;
|
||||
|
||||
ss << '"';
|
||||
auto it = s.begin();
|
||||
for (;;)
|
||||
{
|
||||
uint32_t u = readu8(it, s.end());
|
||||
if (!u)
|
||||
break;
|
||||
ss << '"';
|
||||
auto it = s.begin();
|
||||
for (;;)
|
||||
{
|
||||
uint32_t u = readu8(it, s.end());
|
||||
if (!u)
|
||||
break;
|
||||
|
||||
ss << fmt::format("\\u{:04x}", u);
|
||||
}
|
||||
ss << "\\n\"\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
ss << s << '\n';
|
||||
}
|
||||
ss << fmt::format("\\u{:04x}", u);
|
||||
}
|
||||
ss << "\\n\"\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
ss << s << '\n';
|
||||
}
|
||||
|
||||
if (!google::protobuf::TextFormat::ParseFromString(ss.str(), &message))
|
||||
{
|
||||
@@ -113,34 +113,39 @@ int main(int argc, const char* argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
std::ofstream output(argv[2]);
|
||||
if (!output)
|
||||
{
|
||||
perror("couldn't open output file");
|
||||
exit(1);
|
||||
}
|
||||
std::ofstream output(argv[2]);
|
||||
if (!output)
|
||||
{
|
||||
perror("couldn't open output file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
auto data = message.SerializeAsString();
|
||||
|
||||
output << "#include <string>\n"
|
||||
<< "static const unsigned char data[] = {\n";
|
||||
output << "#include \"lib/proto.h\"\n"
|
||||
<< "#include <string_view>\n"
|
||||
<< "static const uint8_t rawData[] = {";
|
||||
|
||||
int count = 0;
|
||||
for (char c : data)
|
||||
{
|
||||
int count = 0;
|
||||
for (char c : data)
|
||||
{
|
||||
if (count == 0)
|
||||
output << "\n\t";
|
||||
else
|
||||
output << ' ';
|
||||
output << fmt::format("0x{:02x},", (unsigned char)c);
|
||||
|
||||
count = (count+1) & 7;
|
||||
}
|
||||
count = (count + 1) & 7;
|
||||
}
|
||||
|
||||
output << "};\n"
|
||||
<< fmt::format("extern std::string {}();\n", argv[3])
|
||||
<< fmt::format("std::string {}()\n", argv[3])
|
||||
<< "{ return std::string((const char*)data, sizeof(data)); }\n";
|
||||
output << "\n};\n";
|
||||
output << "extern const std::string_view " << argv[3] << "_data;\n";
|
||||
output << "const std::string_view " << argv[3]
|
||||
<< "_data = std::string_view((const char*)rawData, " << data.size()
|
||||
<< ");\n";
|
||||
output << "extern const ConfigProto " << argv[3] << ";\n";
|
||||
output << "const ConfigProto " << argv[3] << " = parseConfigBytes("
|
||||
<< argv[3] << "_data);\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ struct Command
|
||||
static command_cb mainAnalyse;
|
||||
static command_cb mainTest;
|
||||
|
||||
// clang-format off
|
||||
static std::vector<Command> commands =
|
||||
{
|
||||
{ "inspect", mainInspect, "Low-level analysis and inspection of a disk." },
|
||||
@@ -70,10 +71,13 @@ static std::vector<Command> testables =
|
||||
{ "bandwidth", mainTestBandwidth, "Measures your USB bandwidth.", },
|
||||
{ "voltages", mainTestVoltages, "Measures the FDD bus voltages.", },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static void extendedHelp(std::vector<Command>& subcommands, const std::string& command)
|
||||
static void extendedHelp(
|
||||
std::vector<Command>& subcommands, const std::string& command)
|
||||
{
|
||||
std::cout << "fluxengine: syntax: fluxengine " << command << " <format> [<flags>...]\n"
|
||||
std::cout << "fluxengine: syntax: fluxengine " << command
|
||||
<< " <format> [<flags>...]\n"
|
||||
"These subcommands are supported:\n";
|
||||
|
||||
for (Command& c : subcommands)
|
||||
@@ -82,8 +86,10 @@ static void extendedHelp(std::vector<Command>& subcommands, const std::string& c
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int mainExtended(std::vector<Command>& subcommands, const std::string& command,
|
||||
int argc, const char* argv[])
|
||||
static int mainExtended(std::vector<Command>& subcommands,
|
||||
const std::string& command,
|
||||
int argc,
|
||||
const char* argv[])
|
||||
{
|
||||
if (argc == 1)
|
||||
extendedHelp(subcommands, command);
|
||||
@@ -95,7 +101,7 @@ static int mainExtended(std::vector<Command>& subcommands, const std::string& co
|
||||
for (Command& c : subcommands)
|
||||
{
|
||||
if (format == c.name)
|
||||
return c.main(argc-1, argv+1);
|
||||
return c.main(argc - 1, argv + 1);
|
||||
}
|
||||
|
||||
std::cerr << "fluxengine: unrecognised format (try --help)\n";
|
||||
@@ -103,10 +109,14 @@ static int mainExtended(std::vector<Command>& subcommands, const std::string& co
|
||||
}
|
||||
|
||||
static int mainAnalyse(int argc, const char* argv[])
|
||||
{ return mainExtended(analysables, "analyse", argc, argv); }
|
||||
{
|
||||
return mainExtended(analysables, "analyse", argc, argv);
|
||||
}
|
||||
|
||||
static int mainTest(int argc, const char* argv[])
|
||||
{ return mainExtended(testables, "test", argc, argv); }
|
||||
{
|
||||
return mainExtended(testables, "test", argc, argv);
|
||||
}
|
||||
|
||||
static void globalHelp()
|
||||
{
|
||||
@@ -119,34 +129,32 @@ static void globalHelp()
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void showProfiles(const std::string& command, const std::map<std::string, std::string>& profiles)
|
||||
void showProfiles(const std::string& command,
|
||||
const std::map<std::string, const ConfigProto*>& profiles)
|
||||
{
|
||||
std::cout << "syntax: fluxengine " << command << " <profile> [<extensions...>] [<options>...]\n"
|
||||
"Use --help for option help.\n"
|
||||
"Available profiles include:\n";
|
||||
std::cout << "syntax: fluxengine " << command
|
||||
<< " <profile> [<extensions...>] [<options>...]\n"
|
||||
"Use --help for option help.\n"
|
||||
"Available profiles include:\n";
|
||||
|
||||
for (const auto& it : profiles)
|
||||
{
|
||||
ConfigProto config;
|
||||
if (!config.ParseFromString(it.second))
|
||||
Error() << "couldn't load config proto";
|
||||
if (!config.is_extension())
|
||||
std::cout << fmt::format(" {}: {}\n", it.first, config.comment());
|
||||
}
|
||||
for (const auto& it : profiles)
|
||||
{
|
||||
const auto& config = *it.second;
|
||||
if (!config.is_extension())
|
||||
std::cout << fmt::format(" {}: {}\n", it.first, config.comment());
|
||||
}
|
||||
|
||||
std::cout << "Available profile options include:\n";
|
||||
std::cout << "Available profile options include:\n";
|
||||
|
||||
for (const auto& it : profiles)
|
||||
{
|
||||
ConfigProto config;
|
||||
if (!config.ParseFromString(it.second))
|
||||
Error() << "couldn't load config proto";
|
||||
if (config.is_extension() && (it.first[0] != '_'))
|
||||
std::cout << fmt::format(" {}: {}\n", it.first, config.comment());
|
||||
}
|
||||
for (const auto& it : profiles)
|
||||
{
|
||||
const auto& config = *it.second;
|
||||
if (config.is_extension() && (it.first[0] != '_'))
|
||||
std::cout << fmt::format(" {}: {}\n", it.first, config.comment());
|
||||
}
|
||||
|
||||
std::cout << "Profiles and extensions may also be textpb files .\n";
|
||||
exit(1);
|
||||
std::cout << "Profiles and extensions may also be textpb files .\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
@@ -161,17 +169,17 @@ int main(int argc, const char* argv[])
|
||||
for (Command& c : commands)
|
||||
{
|
||||
if (command == c.name)
|
||||
{
|
||||
try
|
||||
{
|
||||
return c.main(argc-1, argv+1);
|
||||
}
|
||||
catch (const ErrorException& e)
|
||||
{
|
||||
e.print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
{
|
||||
try
|
||||
{
|
||||
return c.main(argc - 1, argv + 1);
|
||||
}
|
||||
catch (const ErrorException& e)
|
||||
{
|
||||
e.print();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "fluxengine: unrecognised command (try --help)\n";
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef FLUXENGINE_H
|
||||
#define FLUXENGINE_H
|
||||
|
||||
extern void showProfiles(const std::string& command, const std::map<std::string, std::string>& profiles);
|
||||
extern void showProfiles(const std::string& command,
|
||||
const std::map<std::string, const ConfigProto*>& profiles);
|
||||
|
||||
extern const std::map<std::string, std::string> formats;
|
||||
extern const std::map<std::string, const ConfigProto*> formats;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -67,6 +67,7 @@ $(OBJDIR)/scripts/mkdoc.o: scripts/mkdoc.cc
|
||||
|
||||
$(call use-library, $(OBJDIR)/mkdoc.exe, $(OBJDIR)/scripts/mkdoc.o, PROTO)
|
||||
$(call use-library, $(OBJDIR)/mkdoc.exe, $(OBJDIR)/scripts/mkdoc.o, LIBFORMATS)
|
||||
$(call use-library, $(OBJDIR)/mkdoc.exe, $(OBJDIR)/scripts/mkdoc.o, LIBFLUXENGINE)
|
||||
|
||||
|
||||
docs: $(patsubst %, doc/disk-%.md, $(FORMATS))
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include ".obj/extras/fluxfile.h"
|
||||
#include ".obj/extras/imagefile.h"
|
||||
|
||||
extern const std::map<std::string, std::string> formats;
|
||||
extern const std::map<std::string, const ConfigProto*> formats;
|
||||
|
||||
#define CONFIG_SELECTEDSOURCE "SelectedSource"
|
||||
#define CONFIG_DEVICE "Device"
|
||||
@@ -76,8 +76,7 @@ public:
|
||||
for (const auto& it : formats)
|
||||
{
|
||||
auto config = std::make_unique<ConfigProto>();
|
||||
if (!config->ParseFromString(it.second))
|
||||
continue;
|
||||
*config = *it.second;
|
||||
if (config->is_extension())
|
||||
continue;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "lib/bytes.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
extern const std::map<std::string, std::string> formats;
|
||||
extern const std::map<std::string, const ConfigProto*> formats;
|
||||
|
||||
bool failed = false;
|
||||
|
||||
@@ -41,13 +41,12 @@ struct fmt::formatter<std::vector<std::string>>
|
||||
}
|
||||
};
|
||||
|
||||
static ConfigProto findConfig(std::string name)
|
||||
static const ConfigProto& findConfig(std::string name)
|
||||
{
|
||||
const auto data = formats.at(name);
|
||||
ConfigProto config;
|
||||
if (!config.ParseFromString(data))
|
||||
const auto it = formats.find(name);
|
||||
if (it == formats.end())
|
||||
error("{}: couldn't load", name);
|
||||
return config;
|
||||
return *it->second;
|
||||
}
|
||||
|
||||
static std::vector<std::vector<std::string>> generateCombinations(
|
||||
|
||||
@@ -81,10 +81,10 @@ static void test_config(void)
|
||||
|
||||
static void test_load(void)
|
||||
{
|
||||
extern std::string testproto_pb();
|
||||
extern std::string_view testproto_pb_data;
|
||||
|
||||
TestProto proto;
|
||||
bool r = proto.ParseFromString(testproto_pb());
|
||||
bool r = proto.ParseFromArray(testproto_pb_data.begin(), testproto_pb_data.size());
|
||||
|
||||
std::string s;
|
||||
google::protobuf::TextFormat::PrintToString(proto, &s);
|
||||
|
||||
Reference in New Issue
Block a user