mirror of
				https://github.com/davidgiven/fluxengine.git
				synced 2025-10-24 11:11:02 -07:00 
			
		
		
		
	Add (pretty basic) config dumping and documentation help.
This commit is contained in:
		
							
								
								
									
										40
									
								
								lib/flags.cc
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								lib/flags.cc
									
									
									
									
									
								
							| @@ -3,6 +3,7 @@ | ||||
| #include "proto.h" | ||||
| #include "utils.h" | ||||
| #include "fmt/format.h" | ||||
| #include <google/protobuf/text_format.h> | ||||
| #include <regex> | ||||
|  | ||||
| static FlagGroup* currentFlagGroup; | ||||
| @@ -10,6 +11,8 @@ static std::vector<Flag*> all_flags; | ||||
| static std::map<const std::string, Flag*> flags_by_name; | ||||
|  | ||||
| static void doHelp(); | ||||
| static void doShowConfig(); | ||||
| static void doDoc(); | ||||
|  | ||||
| static FlagGroup helpGroup; | ||||
| static ActionFlag helpFlag = ActionFlag( | ||||
| @@ -17,6 +20,16 @@ static ActionFlag helpFlag = ActionFlag( | ||||
|     "Shows the help.", | ||||
|     doHelp); | ||||
|  | ||||
| static ActionFlag showConfigFlag = ActionFlag( | ||||
|     { "--show-config", "-c" }, | ||||
|     "Shows the currently set configuration and halts.", | ||||
|     doShowConfig); | ||||
|  | ||||
| static ActionFlag docFlag = ActionFlag( | ||||
|     { "--doc" }, | ||||
|     "Shows the available configuration options.", | ||||
|     doDoc); | ||||
|  | ||||
| FlagGroup::FlagGroup(const std::initializer_list<FlagGroup*> groups): | ||||
|     _groups(groups.begin(), groups.end()) | ||||
| { | ||||
| @@ -239,3 +252,30 @@ static void doHelp() | ||||
|     } | ||||
|     exit(0); | ||||
| } | ||||
|  | ||||
| static void doShowConfig() | ||||
| { | ||||
| 	std::string s; | ||||
| 	google::protobuf::TextFormat::PrintToString(config, &s); | ||||
| 	std::cout << s << '\n'; | ||||
|  | ||||
| 	exit(0); | ||||
| } | ||||
|  | ||||
| static void doDoc() | ||||
| { | ||||
| 	const auto fields = findAllProtoFields(&config); | ||||
| 	for (const auto field : fields) | ||||
| 	{ | ||||
| 		const std::string& path = field.first; | ||||
| 		const google::protobuf::FieldDescriptor* f = field.second; | ||||
|  | ||||
| 		if (f->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE) | ||||
| 			continue; | ||||
|  | ||||
| 		std::string helpText = f->options().GetExtension(help); | ||||
| 		std::cout << fmt::format("{}: {}\n", path, helpText); | ||||
| 	} | ||||
|  | ||||
| 	exit(0); | ||||
| } | ||||
|   | ||||
							
								
								
									
										21
									
								
								lib/proto.cc
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								lib/proto.cc
									
									
									
									
									
								
							| @@ -132,3 +132,24 @@ std::set<unsigned> iterate(const RangeProto& range) | ||||
| 	return set; | ||||
| } | ||||
|  | ||||
| std::map<std::string, const google::protobuf::FieldDescriptor*> findAllProtoFields(google::protobuf::Message* message) | ||||
| { | ||||
| 	std::map<std::string, const google::protobuf::FieldDescriptor*> fields; | ||||
| 	const auto* descriptor = message->GetDescriptor(); | ||||
|  | ||||
| 	std::function<void(const google::protobuf::Descriptor*, const std::string&)> recurse = | ||||
| 		[&](auto* d, const auto& s) { | ||||
| 			for (int i=0; i<d->field_count(); i++) | ||||
| 			{ | ||||
| 				const google::protobuf::FieldDescriptor* f = d->field(i); | ||||
| 				std::string n = s + f->name(); | ||||
| 				if (f->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE) | ||||
| 					recurse(f->message_type(), n + "."); | ||||
| 				fields[n] = f; | ||||
| 			} | ||||
| 		}; | ||||
|  | ||||
| 	recurse(descriptor, ""); | ||||
| 	return fields; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -12,6 +12,9 @@ extern void setProtoByString(google::protobuf::Message* message, const std::stri | ||||
|  | ||||
| extern std::set<unsigned> iterate(const RangeProto& range); | ||||
|  | ||||
| extern std::map<std::string, const google::protobuf::FieldDescriptor*> | ||||
| 		findAllProtoFields(google::protobuf::Message* message); | ||||
|  | ||||
| extern ConfigProto config; | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -28,11 +28,6 @@ int mainRead(int argc, const char* argv[]) | ||||
| 	if (!config.has_input() || !config.has_output()) | ||||
| 		Error() << "incomplete config (did you remember to specify the format?)"; | ||||
|  | ||||
| 	std::string s; | ||||
| 	google::protobuf::TextFormat::PrintToString(config, &s); | ||||
| 	std::cout << s << '\n'; | ||||
| 	exit(0); | ||||
|  | ||||
| 	std::unique_ptr<FluxSource> fluxSource(FluxSource::create(config.input().disk())); | ||||
| 	std::unique_ptr<AbstractDecoder> decoder(AbstractDecoder::create(config.decoder())); | ||||
| 	std::unique_ptr<ImageWriter> writer(ImageWriter::create(config.output().file())); | ||||
|   | ||||
| @@ -98,12 +98,31 @@ static void test_range(void) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void test_fields(void) | ||||
| { | ||||
| 	TestProto proto; | ||||
| 	auto fields = findAllProtoFields(&proto); | ||||
| 	AssertThat(fields, HasLength(13)); | ||||
| } | ||||
|  | ||||
| static void test_options(void) | ||||
| { | ||||
| 	TestProto proto; | ||||
| 	const auto* descriptor = proto.descriptor(); | ||||
| 	const auto* field = descriptor->FindFieldByName("i64"); | ||||
| 	const auto& options = field->options(); | ||||
| 	const std::string s = options.GetExtension(help); | ||||
| 	AssertThat(s, Equals("i64")); | ||||
| } | ||||
|  | ||||
| int main(int argc, const char* argv[]) | ||||
| { | ||||
| 	test_setting(); | ||||
| 	test_config(); | ||||
| 	test_load(); | ||||
| 	test_range(); | ||||
| 	test_fields(); | ||||
| 	test_options(); | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,11 +1,13 @@ | ||||
| syntax = "proto2"; | ||||
|  | ||||
| import "lib/common.proto"; | ||||
|  | ||||
| message TestProto { | ||||
| 	message SubMessageProto { | ||||
| 		optional string s = 1; | ||||
| 	} | ||||
|  | ||||
| 	optional int64 i64 = 1; | ||||
| 	optional int64 i64 = 1 [(help)="i64"]; | ||||
| 	optional int32 i32 = 2; | ||||
| 	optional uint64 u64 = 3; | ||||
| 	optional uint32 u32 = 4; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user