mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-21 00:33:28 +00:00
added --preprocess, --preprocess-defines and --preprocess-input-macros...
...to commandline_options
This commit is contained in:
parent
508f710707
commit
6957c82245
@ -20,6 +20,19 @@
|
||||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
class two_strings : public boost::tuple<std::string,std::string> {};
|
||||
|
||||
void validate(boost::any& v, const std::vector<std::string>& values,
|
||||
two_strings*, int)
|
||||
{
|
||||
two_strings ret_val;
|
||||
if (values.size() != 2)
|
||||
throw po::validation_error(po::validation_error::invalid_option_value);
|
||||
ret_val.get<0>() = values.at(0);
|
||||
ret_val.get<1>() = values.at(1);
|
||||
v = ret_val;
|
||||
}
|
||||
|
||||
commandline_options::commandline_options ( int argc, char** argv ) :
|
||||
bpp(),
|
||||
campaign(),
|
||||
@ -107,6 +120,9 @@ commandline_options::commandline_options ( int argc, char** argv ) :
|
||||
("new-syntax", "enables the new campaign syntax parsing.")
|
||||
("nocache", "disables caching of game data.")
|
||||
("path", "prints the path to the data directory and exits.")
|
||||
("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.")
|
||||
("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.")
|
||||
("rng-seed", po::value<unsigned int>(), "seeds the random number generator with number <arg>. Example: --rng-seed 0")
|
||||
("validcache", "assumes that the cache is valid. (dangerous)")
|
||||
@ -135,7 +151,8 @@ commandline_options::commandline_options ( int argc, char** argv ) :
|
||||
all_.add(visible_).add(hidden_);
|
||||
|
||||
po::variables_map vm;
|
||||
po::store(po::parse_command_line(argc_,argv_,all_),vm);
|
||||
const int parsing_style = po::command_line_style::default_style ^ po::command_line_style::allow_guessing;
|
||||
po::store(po::parse_command_line(argc_,argv_,all_,parsing_style),vm);
|
||||
|
||||
if (vm.count("ai-config"))
|
||||
multiplayer_ai_config = parse_to_int_string_tuples_(vm["ai-config"].as<std::vector<std::string> >());
|
||||
@ -175,6 +192,16 @@ commandline_options::commandline_options ( int argc, char** argv ) :
|
||||
nocache = true;
|
||||
if (vm.count("path"))
|
||||
path = true;
|
||||
if (vm.count("preprocess"))
|
||||
{
|
||||
preprocess = true;
|
||||
preprocess_path = vm["preprocess"].as<two_strings>().get<0>();
|
||||
preprocess_target = vm["preprocess"].as<two_strings>().get<1>();
|
||||
}
|
||||
if (vm.count("preprocess-defines"))
|
||||
preprocess_defines = utils::split(vm["preprocess-defines"].as<std::string>(), ',');
|
||||
if (vm.count("preprocess-input-macros"))
|
||||
preprocess_input_macros = vm["preprocess-input-macros"].as<std::string>();
|
||||
if (vm.count("preprocess-output-macros"))
|
||||
preprocess_output_macros = vm["preprocess-output-macros"].as<std::string>();
|
||||
if (vm.count("rng-seed"))
|
||||
|
261
src/game.cpp
261
src/game.cpp
@ -167,6 +167,7 @@ static int process_command_args(int argc, char** argv, const commandline_options
|
||||
game_config::wesnoth_program_dir = directory_name(program);
|
||||
preprocess_options preproc;
|
||||
|
||||
// Options that don't change behaviour based on any others should be checked alphabetically below.
|
||||
if(cmdline_opts.config_dir) {
|
||||
set_preferences_dir(*cmdline_opts.config_dir);
|
||||
}
|
||||
@ -224,7 +225,31 @@ static int process_command_args(int argc, char** argv, const commandline_options
|
||||
std::cout << game_config::path << "\n";
|
||||
return 0;
|
||||
}
|
||||
if (cmdline_opts.preprocess_output_macros) {
|
||||
if(cmdline_opts.preprocess_input_macros) {
|
||||
std::string file = *cmdline_opts.preprocess_input_macros;
|
||||
if (file_exists(file) == false)
|
||||
{
|
||||
std::cerr << "please specify an existing file. File "<< file <<" doesn't exist.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cerr << SDL_GetTicks() << " Reading cached defines from: " << file << "\n";
|
||||
|
||||
config cfg;
|
||||
std::string error_log;
|
||||
scoped_istream stream = istream_file(file);
|
||||
read(cfg, *stream);
|
||||
|
||||
int read = 0;
|
||||
// use static preproc_define::read_pair(config) to make a object
|
||||
foreach (const config::any_child &value, cfg.all_children_range()) {
|
||||
const preproc_map::value_type def = preproc_define::read_pair(value.cfg);
|
||||
preproc.input_macros_[def.first] = def.second;
|
||||
++read;
|
||||
}
|
||||
std::cerr << SDL_GetTicks() << " Read " << read << " defines.\n";
|
||||
}
|
||||
if(cmdline_opts.preprocess_output_macros) {
|
||||
if (cmdline_opts.preprocess_output_macros->empty())
|
||||
preproc.output_macros_path_ = "true";
|
||||
else
|
||||
@ -238,6 +263,100 @@ static int process_command_args(int argc, char** argv, const commandline_options
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Options changing their behaviour dependant on some others should be checked below.
|
||||
|
||||
//TODO should be rewritten so that preprocess_input_macros and preprocess_output_macros are used inside, not before
|
||||
if (cmdline_opts.preprocess) {
|
||||
const std::string resourceToProcess(*cmdline_opts.preprocess_path);
|
||||
const std::string targetDir(*cmdline_opts.preprocess_target);
|
||||
|
||||
Uint32 startTime = SDL_GetTicks();
|
||||
// if the users add the SKIP_CORE define we won't preprocess data/core
|
||||
bool skipCore = false;
|
||||
bool skipTerrainGFX = false;
|
||||
// the 'core_defines_map' is the one got from data/core macros
|
||||
preproc_map defines_map(preproc.input_macros_);
|
||||
std::string error_log;
|
||||
|
||||
if (cmdline_opts.preprocess_defines)
|
||||
{
|
||||
// add the specified defines
|
||||
foreach (const std::string &define, *cmdline_opts.preprocess_defines)
|
||||
{
|
||||
if (define.empty()){
|
||||
std::cerr << "empty define supplied\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_PREPROC<<"adding define: "<< define<<'\n';
|
||||
defines_map.insert(std::make_pair(define,
|
||||
preproc_define(define)));
|
||||
if (define == "SKIP_CORE")
|
||||
{
|
||||
std::cerr << "'SKIP_CORE' defined.\n";
|
||||
skipCore = true;
|
||||
}
|
||||
else if (define == "NO_TERRAIN_GFX")
|
||||
{
|
||||
std::cerr << "'NO_TERRAIN_GFX' defined.\n";
|
||||
skipTerrainGFX = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "added " << defines_map.size() << " defines.\n";
|
||||
|
||||
// preprocess core macros first if we don't skip the core
|
||||
if (skipCore == false)
|
||||
{
|
||||
std::cerr << "preprocessing common macros from 'data/core' ...\n";
|
||||
|
||||
// process each folder explicitly to gain speed
|
||||
preprocess_resource(game_config::path + "/data/core/macros",&defines_map);
|
||||
if (skipTerrainGFX == false)
|
||||
preprocess_resource(game_config::path + "/data/core/terrain-graphics",&defines_map);
|
||||
|
||||
std::cerr << "acquired " << (defines_map.size() - preproc.input_macros_.size())
|
||||
<< " 'data/core' defines.\n";
|
||||
}
|
||||
else
|
||||
std::cerr << "skipped 'data/core'\n";
|
||||
|
||||
// preprocess resource
|
||||
std::cerr << "preprocessing specified resource: "
|
||||
<< resourceToProcess << " ...\n";
|
||||
preprocess_resource(resourceToProcess, &defines_map, true,true, targetDir);
|
||||
std::cerr << "acquired " << (defines_map.size() - preproc.input_macros_.size())
|
||||
<< " total defines.\n";
|
||||
|
||||
if (preproc.output_macros_path_ != "false")
|
||||
{
|
||||
std::string outputPath = targetDir + "/_MACROS_.cfg";
|
||||
if (preproc.output_macros_path_ != "true")
|
||||
outputPath = preproc.output_macros_path_;
|
||||
|
||||
std::cerr << "writing '" << outputPath << "' with "
|
||||
<< defines_map.size() << " defines.\n";
|
||||
|
||||
scoped_ostream out = ostream_file(outputPath);
|
||||
if (!out->fail())
|
||||
{
|
||||
config_writer writer(*out,false);
|
||||
|
||||
for(preproc_map::iterator itor = defines_map.begin();
|
||||
itor != defines_map.end(); ++itor)
|
||||
{
|
||||
(*itor).second.write(writer, (*itor).first);
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cerr << "couldn't open the file.\n";
|
||||
}
|
||||
|
||||
std::cerr << "preprocessing finished. Took "<< SDL_GetTicks() - startTime << " ticks.\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
//parse arguments that shouldn't require a display device
|
||||
int arg;
|
||||
for(arg = 1; arg != argc; ++arg) {
|
||||
@ -276,146 +395,6 @@ static int process_command_args(int argc, char** argv, const commandline_options
|
||||
}
|
||||
p = q;
|
||||
}
|
||||
} else if (val == "--preprocess-input-macros") {
|
||||
if (arg + 1 < argc)
|
||||
{
|
||||
++arg;
|
||||
std::string file = argv[arg];
|
||||
if (file_exists(file) == false)
|
||||
{
|
||||
std::cerr << "please specify an existing file. File "<< file <<" doesn't exist.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cerr << SDL_GetTicks() << " Reading cached defines from: " << file << "\n";
|
||||
|
||||
config cfg;
|
||||
std::string error_log;
|
||||
scoped_istream stream = istream_file(file);
|
||||
read(cfg, *stream);
|
||||
|
||||
int read = 0;
|
||||
// use static preproc_define::read_pair(config) to make a object
|
||||
foreach (const config::any_child &value, cfg.all_children_range()) {
|
||||
const preproc_map::value_type def = preproc_define::read_pair(value.cfg);
|
||||
preproc.input_macros_[def.first] = def.second;
|
||||
++read;
|
||||
}
|
||||
std::cerr << SDL_GetTicks() << " Read " << read << " defines.\n";
|
||||
}
|
||||
else {
|
||||
std::cerr << "please specify input macros file.\n";
|
||||
return 2;
|
||||
}
|
||||
} else if (val.find("--preprocess") == 0 || val.find("-p") == 0){
|
||||
if (arg + 2 < argc){
|
||||
++arg;
|
||||
const std::string resourceToProcess(argv[arg]);
|
||||
++arg;
|
||||
const std::string targetDir(argv[arg]);
|
||||
|
||||
Uint32 startTime = SDL_GetTicks();
|
||||
// if the users add the SKIP_CORE define we won't preprocess data/core
|
||||
bool skipCore = false;
|
||||
bool skipTerrainGFX = false;
|
||||
// the 'core_defines_map' is the one got from data/core macros
|
||||
preproc_map defines_map(preproc.input_macros_);
|
||||
std::string error_log;
|
||||
|
||||
// add the specified defines
|
||||
size_t pos=std::string::npos;
|
||||
if (val.find("--preprocess=") == 0)
|
||||
pos = val.find("=");
|
||||
else if (val.find("-p=") == 0)
|
||||
pos = val.find("=");
|
||||
|
||||
// we have some defines specified
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string tmp_val = val.substr(pos+1);
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
size_t tmpPos = val.find(',', pos+1);
|
||||
tmp_val = val.substr(pos + 1,
|
||||
tmpPos == std::string::npos ? tmpPos : tmpPos - (pos+1));
|
||||
pos = tmpPos;
|
||||
|
||||
if (tmp_val.empty()){
|
||||
std::cerr << "empty define supplied\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_PREPROC<<"adding define: "<< tmp_val<<'\n';
|
||||
defines_map.insert(std::make_pair(tmp_val,
|
||||
preproc_define(tmp_val)));
|
||||
if (tmp_val == "SKIP_CORE")
|
||||
{
|
||||
std::cerr << "'SKIP_CORE' defined.\n";
|
||||
skipCore = true;
|
||||
}
|
||||
else if (tmp_val == "NO_TERRAIN_GFX")
|
||||
{
|
||||
std::cerr << "'NO_TERRAIN_GFX' defined.\n";
|
||||
skipTerrainGFX = true;
|
||||
}
|
||||
}
|
||||
std::cerr << "added " << defines_map.size() << " defines.\n";
|
||||
}
|
||||
|
||||
// preprocess core macros first if we don't skip the core
|
||||
if (skipCore == false)
|
||||
{
|
||||
std::cerr << "preprocessing common macros from 'data/core' ...\n";
|
||||
|
||||
// process each folder explicitly to gain speed
|
||||
preprocess_resource(game_config::path + "/data/core/macros",&defines_map);
|
||||
if (skipTerrainGFX == false)
|
||||
preprocess_resource(game_config::path + "/data/core/terrain-graphics",&defines_map);
|
||||
|
||||
std::cerr << "acquired " << (defines_map.size() - preproc.input_macros_.size())
|
||||
<< " 'data/core' defines.\n";
|
||||
}
|
||||
else
|
||||
std::cerr << "skipped 'data/core'\n";
|
||||
|
||||
// preprocess resource
|
||||
std::cerr << "preprocessing specified resource: "
|
||||
<< resourceToProcess << " ...\n";
|
||||
preprocess_resource(resourceToProcess, &defines_map, true,true, targetDir);
|
||||
std::cerr << "acquired " << (defines_map.size() - preproc.input_macros_.size())
|
||||
<< " total defines.\n";
|
||||
|
||||
if (preproc.output_macros_path_ != "false")
|
||||
{
|
||||
std::string outputPath = targetDir + "/_MACROS_.cfg";
|
||||
if (preproc.output_macros_path_ != "true")
|
||||
outputPath = preproc.output_macros_path_;
|
||||
|
||||
std::cerr << "writing '" << outputPath << "' with "
|
||||
<< defines_map.size() << " defines.\n";
|
||||
|
||||
scoped_ostream out = ostream_file(outputPath);
|
||||
if (!out->fail())
|
||||
{
|
||||
config_writer writer(*out,false);
|
||||
|
||||
for(preproc_map::iterator itor = defines_map.begin();
|
||||
itor != defines_map.end(); ++itor)
|
||||
{
|
||||
(*itor).second.write(writer, (*itor).first);
|
||||
}
|
||||
}
|
||||
else
|
||||
std::cerr << "couldn't open the file.\n";
|
||||
}
|
||||
|
||||
std::cerr << "preprocessing finished. Took "<< SDL_GetTicks() - startTime << " ticks.\n";
|
||||
return 0;
|
||||
}
|
||||
else{
|
||||
std::cerr << "Please specify a source file/folder and a target folder\n";
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +195,9 @@ BOOST_AUTO_TEST_CASE (test_full_options)
|
||||
"--new-widgets",
|
||||
"--nocache",
|
||||
"--path",
|
||||
"--preprocess", "preppathfoo", "preptargfoo",
|
||||
"--preprocess-defines=DEFFOO,DEFBAR",
|
||||
"--preprocess-input-macros=inmfoo",
|
||||
"--preprocess-output-macros=outmfoo",
|
||||
"--rng-seed=1234",
|
||||
"--validcache",
|
||||
@ -228,9 +231,9 @@ BOOST_AUTO_TEST_CASE (test_full_options)
|
||||
BOOST_CHECK(co.logdomains && *co.logdomains == "filterfoo");
|
||||
BOOST_CHECK(co.multiplayer);
|
||||
BOOST_CHECK(co.multiplayer_ai_config);
|
||||
BOOST_CHECK((*co.multiplayer_ai_config).size() == 2);
|
||||
BOOST_CHECK((*co.multiplayer_ai_config)[0].get<0>() == 1 && (*co.multiplayer_ai_config)[0].get<1>() == "aifoo");
|
||||
BOOST_CHECK((*co.multiplayer_ai_config)[1].get<0>() == 2 && (*co.multiplayer_ai_config)[1].get<1>() == "aibar");
|
||||
BOOST_CHECK(co.multiplayer_ai_config->size() == 2);
|
||||
BOOST_CHECK(co.multiplayer_ai_config->at(0).get<0>() == 1 && co.multiplayer_ai_config->at(0).get<1>() == "aifoo");
|
||||
BOOST_CHECK(co.multiplayer_ai_config->at(1).get<0>() == 2 && co.multiplayer_ai_config->at(1).get<1>() == "aibar");
|
||||
BOOST_CHECK(!co.multiplayer_algorithm);
|
||||
BOOST_CHECK(!co.multiplayer_controller);
|
||||
BOOST_CHECK(!co.multiplayer_era);
|
||||
@ -248,12 +251,12 @@ BOOST_AUTO_TEST_CASE (test_full_options)
|
||||
BOOST_CHECK(co.new_syntax);
|
||||
BOOST_CHECK(co.new_widgets);
|
||||
BOOST_CHECK(co.path);
|
||||
BOOST_CHECK(!co.preprocess);
|
||||
BOOST_CHECK(!co.preprocess_defines);
|
||||
BOOST_CHECK(!co.preprocess_input_macros);
|
||||
BOOST_CHECK(co.preprocess && co.preprocess_path && co.preprocess_target);
|
||||
BOOST_CHECK(*co.preprocess_path == "preppathfoo" && *co.preprocess_target == "preptargfoo");
|
||||
BOOST_CHECK(co.preprocess_defines && co.preprocess_defines->size() == 2);
|
||||
BOOST_CHECK(co.preprocess_defines->at(0) == "DEFFOO" && co.preprocess_defines->at(1) == "DEFBAR");
|
||||
BOOST_CHECK(co.preprocess_input_macros && *co.preprocess_input_macros == "inmfoo");
|
||||
BOOST_CHECK(co.preprocess_output_macros && *co.preprocess_output_macros == "outmfoo");
|
||||
BOOST_CHECK(!co.preprocess_path);
|
||||
BOOST_CHECK(!co.preprocess_target);
|
||||
BOOST_CHECK(!co.proxy);
|
||||
BOOST_CHECK(!co.proxy_address);
|
||||
BOOST_CHECK(!co.proxy_password);
|
||||
|
Loading…
x
Reference in New Issue
Block a user