add a command line option to preprocess a string

This commit is contained in:
Subhraman Sarkar 2024-11-20 20:29:36 +05:30 committed by Gunter Labes
parent a50f047c7c
commit c475b0c684
5 changed files with 83 additions and 3 deletions

View file

@ -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 .

View file

@ -29,6 +29,7 @@
#include <boost/program_options/variables_map.hpp> // for variables_map, etc
#include <array>
#include <string>
namespace po = boost::program_options;
@ -291,6 +292,7 @@ commandline_options::commandline_options(const std::vector<std::string>& args)
("output,o", po::value<std::string>(), "output to specified file")
("patch,P", po::value<two_strings>()->multitoken(), "apply a patch to a preprocessed WML document." IMPLY_TERMINAL)
("preprocess,p", po::value<two_strings>()->multitoken(), "requires two arguments: <file/folder> <target directory>. 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<std::string>(), "preprocess given string" IMPLY_TERMINAL)
("preprocess-defines", po::value<std::string>(), "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<std::string>(), "used only by the '--preprocess' command. Specifies source file <arg> that contains [preproc_define]s to be included before preprocessing.")
("preprocess-output-macros", po::value<std::string>()->implicit_value(std::string()), "used only by the '--preprocess' command. Will output all preprocessed macros in the target file <arg>. 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<std::string>& args)
preprocess_path = vm["preprocess"].as<two_strings>().first;
preprocess_target = vm["preprocess"].as<two_strings>().second;
}
if(vm.count("preprocess-string"))
{
preprocess_source_string = vm["preprocess-string"].as<std::string>();
}
if(vm.count("diff"))
{
do_diff = true;

View file

@ -164,6 +164,8 @@ public:
utils::optional<std::string> preprocess_path;
/** Target (output) path that was given to the --preprocess option. */
utils::optional<std::string> preprocess_target;
/** String to preprocess */
utils::optional<std::string> preprocess_source_string;
/** Pair of AxB values specified after --resolution. Changes Wesnoth resolution. */
utils::optional<std::pair<int,int>> resolution;
/** RNG seed specified by --rng-seed option. Initializes RNG with given seed. */
@ -178,7 +180,7 @@ public:
utils::optional<std::string> render_image;
/** Output file to put rendered image path in. Optional second parameter after --render-image */
utils::optional<std::string> render_image_dst;
/** Path of which to generate a spritesheet */
/** Path of which to generate a spritesheet */
utils::optional<std::string> generate_spritesheet;
/** True if --screenshot was given on the command line. Starts Wesnoth in screenshot mode. */
bool screenshot;

View file

@ -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)

View file

@ -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) {