diff --git a/doc/man/wesnoth.6 b/doc/man/wesnoth.6 index 9e1045cb660..eef7bbbff61 100644 --- a/doc/man/wesnoth.6 +++ b/doc/man/wesnoth.6 @@ -249,9 +249,14 @@ Example: For details regarding the preprocessor visit: https://wiki.wesnoth.org/PreprocessorRef#Command-line_preprocessor. .TP +.BI --preprocess-string \ source-string +preprocesses a given string and writes the output to stdout. +.TP .BI --preprocess-defines= DEFINE1 , DEFINE2 , ... comma separated list of defines to be used by the .B --preprocess +or +.B --preprocess-string command. If .B SKIP_CORE is in the define list the "data/core" directory won't be preprocessed. @@ -259,6 +264,8 @@ is in the define list the "data/core" directory won't be preprocessed. .BI --preprocess-input-macros \ source-file used only by the .B --preprocess +or +.B --preprocess-string command. Specifies a file that contains .BR [preproc_define] s to be included before preprocessing. @@ -266,7 +273,9 @@ to be included before preprocessing. .BI --preprocess-output-macros[ =target-file ] used only by the .B --preprocess -command. Will output all preprocessed macros in the target file. If the file is not specified +command (But not by the +.B --preprocess-string +command). Will output all preprocessed macros in the target file. If the file is not specified the output will be file '_MACROS_.cfg' in the target directory of preprocess's command. The output file can be passed to .BR --preprocess-input-macros . diff --git a/src/commandline_options.cpp b/src/commandline_options.cpp index fd3eac1f87a..7f6db4dddf1 100644 --- a/src/commandline_options.cpp +++ b/src/commandline_options.cpp @@ -29,6 +29,7 @@ #include // for variables_map, etc #include +#include namespace po = boost::program_options; @@ -291,6 +292,7 @@ commandline_options::commandline_options(const std::vector& args) ("output,o", po::value(), "output to specified file") ("patch,P", po::value()->multitoken(), "apply a patch to a preprocessed WML document." IMPLY_TERMINAL) ("preprocess,p", po::value()->multitoken(), "requires two arguments: . Preprocesses a specified file/folder. The preprocessed file(s) will be written in the specified target directory: a plain cfg file and a processed cfg file." IMPLY_TERMINAL) + ("preprocess-string", po::value(), "preprocess given string" IMPLY_TERMINAL) ("preprocess-defines", po::value(), "comma separated list of defines to be used by '--preprocess' command. If 'SKIP_CORE' is in the define list the data/core won't be preprocessed. Example: --preprocess-defines=FOO,BAR") ("preprocess-input-macros", po::value(), "used only by the '--preprocess' command. Specifies source file that contains [preproc_define]s to be included before preprocessing.") ("preprocess-output-macros", po::value()->implicit_value(std::string()), "used only by the '--preprocess' command. Will output all preprocessed macros in the target file . If the file is not specified the output will be file '_MACROS_.cfg' in the target directory of preprocess's command.") @@ -413,6 +415,10 @@ commandline_options::commandline_options(const std::vector& args) preprocess_path = vm["preprocess"].as().first; preprocess_target = vm["preprocess"].as().second; } + if(vm.count("preprocess-string")) + { + preprocess_source_string = vm["preprocess-string"].as(); + } if(vm.count("diff")) { do_diff = true; diff --git a/src/commandline_options.hpp b/src/commandline_options.hpp index f8f6d248e79..41e75768d37 100644 --- a/src/commandline_options.hpp +++ b/src/commandline_options.hpp @@ -164,6 +164,8 @@ public: utils::optional preprocess_path; /** Target (output) path that was given to the --preprocess option. */ utils::optional preprocess_target; + /** String to preprocess */ + utils::optional preprocess_source_string; /** Pair of AxB values specified after --resolution. Changes Wesnoth resolution. */ utils::optional> resolution; /** RNG seed specified by --rng-seed option. Initializes RNG with given seed. */ @@ -178,7 +180,7 @@ public: utils::optional render_image; /** Output file to put rendered image path in. Optional second parameter after --render-image */ utils::optional render_image_dst; - /** Path of which to generate a spritesheet */ + /** Path of which to generate a spritesheet */ utils::optional generate_spritesheet; /** True if --screenshot was given on the command line. Starts Wesnoth in screenshot mode. */ bool screenshot; diff --git a/src/editor/map/map_context.cpp b/src/editor/map/map_context.cpp index 26fa1096b10..6d620d9c517 100644 --- a/src/editor/map/map_context.cpp +++ b/src/editor/map/map_context.cpp @@ -759,7 +759,7 @@ config map_context::to_config() config& mods = u.add_child("modifications"); if(unit.loyal()) { config trait_loyal; - read(trait_loyal, preprocess_string("{TRAIT_LOYAL}", &traits_map, "wesnoth-editor")); + read(trait_loyal, preprocess_string("{TRAIT_LOYAL}", &traits_map, "wesnoth-help")); mods.append(trait_loyal); } //TODO this entire block could also be replaced by unit.write(u, true) diff --git a/src/wesnoth.cpp b/src/wesnoth.cpp index 1d2f10047bb..776e7f2263e 100644 --- a/src/wesnoth.cpp +++ b/src/wesnoth.cpp @@ -123,6 +123,64 @@ static void safe_exit(int res) exit(res); } +static void handle_preprocess_string(const commandline_options& cmdline_opts) +{ + preproc_map defines_map; + + if(cmdline_opts.preprocess_input_macros) { + std::string file = *cmdline_opts.preprocess_input_macros; + if(!filesystem::file_exists(file)) { + PLAIN_LOG << "please specify an existing file. File " << file << " doesn't exist."; + return; + } + + PLAIN_LOG << "Reading cached defines from: " << file; + + config cfg; + + try { + filesystem::scoped_istream stream = filesystem::istream_file(file); + read(cfg, *stream); + } catch(const config::error& e) { + PLAIN_LOG << "Caught a config error while parsing file '" << file << "':\n" << e.message; + } + + int read = 0; + + // use static preproc_define::read_pair(config) to make a object + for(const auto [_, cfg] : cfg.all_children_view()) { + const preproc_map::value_type def = preproc_define::read_pair(cfg); + defines_map[def.first] = def.second; + ++read; + } + + PLAIN_LOG << "Read " << read << " defines."; + } + + if(cmdline_opts.preprocess_defines) { + // add the specified defines + for(const std::string& define : *cmdline_opts.preprocess_defines) { + if(define.empty()) { + PLAIN_LOG << "empty define supplied"; + continue; + } + + LOG_PREPROC << "adding define: " << define; + defines_map.emplace(define, preproc_define(define)); + } + } + + // add the WESNOTH_VERSION define + defines_map["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str()); + + // preprocess resource + PLAIN_LOG << "preprocessing specified string: " << *cmdline_opts.preprocess_source_string; + const utils::ms_optimer timer( + [](const auto& timer) { PLAIN_LOG << "preprocessing finished. Took " << timer << " ticks."; }); + std::cout << preprocess_string(*cmdline_opts.preprocess_source_string, &defines_map) << std::endl; + PLAIN_LOG << "added " << defines_map.size() << " defines."; +} + static void handle_preprocess_command(const commandline_options& cmdline_opts) { preproc_map input_macros; @@ -497,6 +555,11 @@ static int process_command_args(commandline_options& cmdline_opts) return 0; } + if(cmdline_opts.preprocess_source_string.has_value()) { + handle_preprocess_string(cmdline_opts); + return 0; + } + if(cmdline_opts.validate_wml) { std::string schema_path; if(cmdline_opts.validate_with) {