The Battle for Wesnoth  1.15.2+dev
commandline_options.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2018 by Lukasz Dobrogowski <lukasz.dobrogowski@gmail.com>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any lfooater version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include "commandline_options.hpp"
16 
17 #include "config.hpp"
18 #include "formatter.hpp"
19 #include "lexical_cast.hpp"
20 #include "log.hpp" // for logger, set_strict_severity, etc
21 #include "serialization/string_utils.hpp" // for split
22 #include "utils/general.hpp" // for clamp
23 
24 #include <boost/any.hpp> // for any
25 #include <boost/program_options/cmdline.hpp>
26 #include <boost/program_options/errors.hpp> // for validation_error, etc
27 #include <boost/program_options/parsers.hpp>
28 #include <boost/program_options/positional_options.hpp>
29 #include <boost/program_options/value_semantic.hpp> // for value, etc
30 #include <boost/program_options/variables_map.hpp> // for variables_map, etc
31 
32 #include <array>
33 #include <iostream> // for operator<<, basic_ostream, etc
34 
35 namespace po = boost::program_options;
36 
37 class two_strings : public std::pair<std::string,std::string> {};
38 
39 static void validate(boost::any& v, const std::vector<std::string>& values,
40  two_strings*, int)
41 {
42  two_strings ret_val;
43  if (values.size() != 2) {
44  throw po::validation_error(po::validation_error::invalid_option_value);
45  }
46  ret_val.first = values.at(0);
47  ret_val.second = values.at(1);
48  v = ret_val;
49 }
50 
52  : error(formatter() << "Invalid resolution \"" << resolution
53  << "\" (WIDTHxHEIGHT expected)")
54 {
55 }
56 
58  const std::string& expected_format)
59  : error(formatter() << "Invalid value set \"" << str
60  << "\" (" << expected_format << " expected)")
61 {
62 }
63 
64 commandline_options::commandline_options (const std::vector<std::string>& args) :
65  bunzip2(),
66  bzip2(),
67  campaign(),
68  campaign_difficulty(),
69  campaign_scenario(),
70  campaign_skip_story(false),
71  clock(false),
72  core_id(),
73  data_path(false),
74  data_dir(),
75  debug(false),
76  debug_lua(false),
77 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
78  debug_dot_domain(),
79  debug_dot_level(),
80 #endif
81  editor(),
82  fps(false),
83  fullscreen(false),
84  gunzip(),
85  gzip(),
86  help(),
87  language(),
88  log(),
89  load(),
90  logdomains(),
91  log_precise_timestamps(false),
92  multiplayer(false),
93  multiplayer_ai_config(),
94  multiplayer_algorithm(),
95  multiplayer_controller(),
96  multiplayer_era(),
97  multiplayer_exit_at_end(),
98  multiplayer_ignore_map_settings(),
99  multiplayer_label(),
100  multiplayer_parm(),
101  multiplayer_repeat(),
102  multiplayer_scenario(),
103  multiplayer_side(),
104  multiplayer_turns(),
105  max_fps(),
106  noaddons(false),
107  nocache(false),
108  nodelay(false),
109  nogui(false),
110  nomusic(false),
111  nosound(false),
112  new_widgets(false),
113  preprocess(false),
114  preprocess_defines(),
115  preprocess_input_macros(),
116  preprocess_output_macros(),
117  preprocess_path(),
118  preprocess_target(),
119  resolution(),
120  rng_seed(),
121  server(),
122  username(),
123  password(),
124  render_image(),
125  render_image_dst(),
126  screenshot(false),
127  screenshot_map_file(),
128  screenshot_output_file(),
129  script_file(),
130  plugin_file(),
131  script_unsafe_mode(false),
132  strict_validation(false),
133  test(),
134  unit_test(),
135  headless_unit_test(false),
136  timeout(),
137  noreplaycheck(false),
138  mptest(false),
139  userconfig_path(false),
140  userconfig_dir(),
141  userdata_path(false),
142  userdata_dir(),
143  validcache(false),
144  validate_core(false),
145  validate_addon(),
146  validate_schema(),
147  validate_wml(),
148  validate_with(),
149  do_diff(),
150  do_patch(),
151  diff_left(),
152  diff_right(),
153  version(false),
154  report(false),
155  windowed(false),
156  with_replay(false),
157  translation_percent(),
158  args_(args.begin() + 1 , args.end()),
159  args0_(*args.begin()),
160  all_(),
161  visible_(),
162  hidden_()
163 {
164  // When adding items don't forget to update doc/man/wesnoth.6
165  // Options are sorted alphabetically by --long-option.
166  po::options_description general_opts("General options");
167  general_opts.add_options()
168  ("all-translations", "Show all translations, even incomplete ones.")
169  ("bunzip2", po::value<std::string>(), "decompresses a file (<arg>.bz2) in bzip2 format and stores it without the .bz2 suffix. <arg>.bz2 will be removed.")
170  ("bzip2", po::value<std::string>(), "compresses a file (<arg>) in bzip2 format, stores it as <arg>.bz2 and removes <arg>.")
171  ("clock", "Adds the option to show a clock for testing the drawing timer.")
172  ("config-dir", po::value<std::string>(), "sets the path of the userdata directory to $HOME/<arg> or My Documents\\My Games\\<arg> for Windows. You can specify also an absolute path outside the $HOME or My Documents\\My Games directory. DEPRECATED: use userdata-dir instead.")
173  ("config-path", "prints the path of the userdata directory and exits. DEPRECATED: use userdata-path instead.")
174  ("core", po::value<std::string>(), "overrides the loaded core with the one whose id is specified.")
175  ("data-dir", po::value<std::string>(), "overrides the data directory with the one specified.")
176  ("data-path", "prints the path of the data directory and exits.")
177  ("debug,d", "enables additional command mode options in-game.")
178  ("debug-lua", "enables some Lua debugging mechanisms")
179 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
180  ("debug-dot-level", po::value<std::string>(), "sets the level of the debug dot files. <arg> should be a comma separated list of levels. These files are used for debugging the widgets especially the for the layout engine. When enabled the engine will produce dot files which can be converted to images with the dot tool. Available levels: size (generate the size info of the widget), state (generate the state info of the widget).")
181  ("debug-dot-domain", po::value<std::string>(), "sets the domain of the debug dot files. <arg> should be a comma separated list of domains. See --debug-dot-level for more info. Available domains: show (generate the data when the dialog is about to be shown), layout (generate the data during the layout phase - might result in multiple files). The data can also be generated when the F12 is pressed in a dialog.")
182 #endif
183  ("editor,e", po::value<std::string>()->implicit_value(std::string()), "starts the in-game map editor directly. If file <arg> is specified, equivalent to -e --load <arg>.")
184  ("gunzip", po::value<std::string>(), "decompresses a file (<arg>.gz) in gzip format and stores it without the .gz suffix. <arg>.gz will be removed.")
185  ("gzip", po::value<std::string>(), "compresses a file (<arg>) in gzip format, stores it as <arg>.gz and removes <arg>.")
186  ("help,h", "prints this message and exits.")
187  ("language,L", po::value<std::string>(), "uses language <arg> (symbol) this session. Example: --language ang_GB@latin")
188  ("load,l", po::value<std::string>(), "loads the save <arg> from the standard save game directory. When launching the map editor via -e, the map <arg> is loaded, relative to the current directory. If it is a directory, the editor will start with a load map dialog opened there.")
189  ("noaddons", "disables the loading of all add-ons.")
190  ("nocache", "disables caching of game data.")
191  ("nodelay", "runs the game without any delays.")
192  ("nomusic", "runs the game without music.")
193  ("nosound", "runs the game without sounds and music.")
194  ("password", po::value<std::string>(), "uses <password> when connecting to a server, ignoring other preferences.")
195  ("plugin", po::value<std::string>(), "(experimental) load a script which defines a wesnoth plugin. similar to --script below, but Lua file should return a function which will be run as a coroutine and periodically woken up with updates.")
196  ("render-image", po::value<two_strings>()->multitoken(), "takes two arguments: <image> <output>. Like screenshot, but instead of a map, takes a valid Wesnoth 'image path string' with image path functions, and writes it to a .png file."
197 #ifdef _WIN32
198  " Implies --wconsole."
199 #endif // _WIN32
200  )
201  ("report,R", "initializes game directories, prints build information suitable for use in bug reports, and exits."
202 #ifdef _WIN32
203  " Implies --wconsole."
204 #endif // _WIN32
205  )
206  ("rng-seed", po::value<unsigned int>(), "seeds the random number generator with number <arg>. Example: --rng-seed 0")
207  ("screenshot", po::value<two_strings>()->multitoken(), "takes two arguments: <map> <output>. Saves a screenshot of <map> to <output> without initializing a screen. Editor must be compiled in for this to work."
208 #ifdef _WIN32
209  " Implies --wconsole."
210 #endif // _WIN32
211  )
212  ("script", po::value<std::string>(), "(experimental) file containing a Lua script to control the client")
213  ("server,s", po::value<std::string>()->implicit_value(std::string()), "connects to the host <arg> if specified or to the first host in your preferences.")
214  ("strict-validation", "makes validation errors fatal")
215  ("translations-over", po::value<unsigned int>(), "Specify the standard for determining whether a translation is complete.")
216  ("unsafe-scripts", "makes the \'package\' package available to Lua scripts, so that they can load arbitrary packages. Do not do this with untrusted scripts! This action gives ua the same permissions as the Wesnoth executable.")
217  ("userconfig-dir", po::value<std::string>(), "sets the path of the user config directory to $HOME/<arg> or My Documents\\My Games\\<arg> for Windows. You can specify also an absolute path outside the $HOME or My Documents\\My Games directory. Defaults to $HOME/.config/wesnoth on X11 and to the userdata-dir on other systems.")
218  ("userconfig-path", "prints the path of the user config directory and exits.")
219  ("userdata-dir", po::value<std::string>(), "sets the path of the userdata directory to $HOME/<arg> or My Documents\\My Games\\<arg> for Windows. You can specify also an absolute path outside the $HOME or My Documents\\My Games directory.")
220  ("userdata-path", "prints the path of the userdata directory and exits.")
221  ("username", po::value<std::string>(), "uses <username> when connecting to a server, ignoring other preferences.")
222  ("validcache", "assumes that the cache is valid. (dangerous)")
223  ("version,v", "prints the game's version number and exits.")
224  ("with-replay", "replays the file loaded with the --load option.")
225 #ifdef _WIN32
226  ("wconsole", "attaches a console window on startup (Windows only). Implied by any option that prints something and exits.")
227 #endif // _WIN32
228  ;
229 
230  po::options_description campaign_opts("Campaign options");
231  campaign_opts.add_options()
232  ("campaign,c", po::value<std::string>()->implicit_value(std::string()), "goes directly to the campaign with id <arg>. A selection menu will appear if no id was specified.")
233  ("campaign-difficulty", po::value<int>(), "The difficulty of the specified campaign (1 to max). If none specified, the campaign difficulty selection widget will appear.")
234  ("campaign-scenario", po::value<std::string>(),"The id of the scenario from the specified campaign. The default is the first scenario.")
235  ("campaign-skip-story", "Skip [story] tags of the specified campaign.")
236  ;
237 
238  po::options_description display_opts("Display options");
239  display_opts.add_options()
240  ("fps", "displays the number of frames per second the game is currently running at, in a corner of the screen. Min/avg/max don't take the FPS limiter into account, act does.")
241  ("fullscreen,f", "runs the game in full screen mode.")
242  ("max-fps", po::value<int>(), "the maximum fps the game tries to run at. Values should be between 1 and 1000, the default is the display's refresh rate.")
243  ("new-widgets", "there is a new WIP widget toolkit this switch enables the new toolkit (VERY EXPERIMENTAL don't file bug reports since most are known). Parts of the library are deemed stable and will work without this switch.")
244  ("resolution,r", po::value<std::string>(), "sets the screen resolution. <arg> should have format XxY. Example: --resolution 800x600")
245  ("windowed,w", "runs the game in windowed mode.")
246  ;
247 
248  po::options_description logging_opts("Logging options");
249  logging_opts.add_options()
250  ("logdomains", po::value<std::string>()->implicit_value(std::string()), "lists defined log domains (only the ones containing <arg> filter if such is provided) and exits.")
251  ("log-error", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'error'. <arg> should be given as comma separated list of domains, wildcards are allowed. Example: --log-error=network,gui/*,engine/enemies")
252  ("log-warning", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'warning'. Similar to --log-error.")
253  ("log-info", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'info'. Similar to --log-error.")
254  ("log-debug", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'debug'. Similar to --log-error.")
255  ("log-none", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'none'. Similar to --log-error.")
256  ("log-precise", "shows the timestamps in the logfile with more precision.")
257  ;
258 
259  po::options_description multiplayer_opts("Multiplayer options");
260  multiplayer_opts.add_options()
261  ("multiplayer,m", "Starts a multiplayer game. There are additional options that can be used as explained below:")
262  ("ai-config", po::value<std::vector<std::string>>()->composing(), "selects a configuration file to load for this side. <arg> should have format side:value")
263  ("algorithm", po::value<std::vector<std::string>>()->composing(), "selects a non-standard algorithm to be used by the AI controller for this side. <arg> should have format side:value")
264  ("controller", po::value<std::vector<std::string>>()->composing(), "selects the controller for this side. <arg> should have format side:value")
265  ("era", po::value<std::string>(), "selects the era to be played in by its id.")
266  ("exit-at-end", "exit Wesnoth at the end of the scenario.")
267  ("ignore-map-settings", "do not use map settings.")
268  ("label", po::value<std::string>(), "sets the label for AIs.") //TODO is the description precise? this option was undocumented before.
269  ("multiplayer-repeat", po::value<unsigned int>(), "repeats a multiplayer game after it is finished <arg> times.")
270  ("nogui", "runs the game without the GUI.")
271  ("parm", po::value<std::vector<std::string>>()->composing(), "sets additional parameters for this side. <arg> should have format side:name:value.")
272  ("scenario", po::value<std::string>(), "selects a multiplayer scenario. The default scenario is \"multiplayer_The_Freelands\".")
273  ("side", po::value<std::vector<std::string>>()->composing(), "selects a faction of the current era for this side by id. <arg> should have format side:value.")
274  ("turns", po::value<std::string>(), "sets the number of turns. By default no turn limit is set.")
275  ;
276 
277  po::options_description testing_opts("Testing options");
278  testing_opts.add_options()
279  ("test,t", po::value<std::string>()->implicit_value(std::string()), "runs the game in a small test scenario. If specified, scenario <arg> will be used instead.")
280  ("unit,u", po::value<std::string>()->implicit_value(std::string()), "runs a unit test scenario. Works like test, except that the exit code of the program reflects the victory / defeat conditions of the scenario.\n\t0 - PASS\n\t1 - FAIL\n\t2 - FAIL (TIMEOUT)\n\t3 - FAIL (INVALID REPLAY)\n\t4 - FAIL (ERRORED REPLAY)")
281  ("showgui", "don't run headlessly (for debugging a failing test)")
282  ("timeout", po::value<unsigned int>(), "sets a timeout (milliseconds) for the unit test. (DEPRECATED)")
283  ("log-strict", po::value<std::string>(), "sets the strict level of the logger. any messages sent to log domains of this level or more severe will cause the unit test to fail regardless of the victory result.")
284  ("noreplaycheck", "don't try to validate replay of unit test.")
285  ("mp-test", "load the test mp scenarios.")
286  ;
287 
288  po::options_description parsing_opts("WML parsing options");
289  testing_opts.add_options()
290  ("use-schema,S", po::value<std::string>(), "specify a schema to validate WML against (defaults to the core schema)")
291  ("validate,V", po::value<std::string>(), "validate a specified WML file against a schema")
292  ("validate-addon", po::value<std::string>(), "validate the specified addon's WML against the schema")
293  ("validate-core", "validate the core WML against the schema")
294  ("validate-schema", po::value<std::string>(), "validate a specified WML schema")
295  ("diff,D", po::value<two_strings>()->multitoken(), "diff two preprocessed WML documents")
296  ("output,o", po::value<std::string>(), "output to specified file")
297  ("patch,P", po::value<two_strings>()->multitoken(), "apply a patch to a preprocessed WML document")
298  ("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.")
299  ("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")
300  ("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.")
301  ("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.")
302  ;
303 
304  po::options_description proxy_opts("Proxy options");
305  proxy_opts.add_options()
306  ("proxy", "enables usage of proxy for network connections.")
307  ("proxy-address", po::value<std::string>(), "specifies address of the proxy.")
308  ("proxy-port", po::value<std::string>(), "specifies port of the proxy.")
309  ("proxy-user", po::value<std::string>(), "specifies username to log in to the proxy.")
310  ("proxy-password", po::value<std::string>(), "specifies password to log in to the proxy.")
311  ;
312 
313  //hidden_.add_options()
314  // ("example-hidden-option", "")
315  // ;
316  visible_.add(general_opts).add(campaign_opts).add(display_opts).add(logging_opts).add(multiplayer_opts).add(testing_opts).add(parsing_opts).add(proxy_opts);
317 
318  all_.add(visible_).add(hidden_);
319 
320  po::positional_options_description positional;
321  positional.add("data-dir",1);
322 
323  po::variables_map vm;
324  const int parsing_style = po::command_line_style::default_style ^ po::command_line_style::allow_guessing;
325  po::store(po::command_line_parser(args_).options(all_).positional(positional).style(parsing_style).run(),vm);
326 
327  if (vm.count("ai-config"))
328  multiplayer_ai_config = parse_to_uint_string_tuples_(vm["ai-config"].as<std::vector<std::string>>());
329  if (vm.count("algorithm"))
330  multiplayer_algorithm = parse_to_uint_string_tuples_(vm["algorithm"].as<std::vector<std::string>>());
331  if (vm.count("bunzip2"))
332  bunzip2 = vm["bunzip2"].as<std::string>();
333  if (vm.count("bzip2"))
334  bzip2 = vm["bzip2"].as<std::string>();
335  if (vm.count("campaign"))
336  campaign = vm["campaign"].as<std::string>();
337  if (vm.count("campaign-difficulty"))
338  campaign_difficulty = vm["campaign-difficulty"].as<int>();
339  if (vm.count("campaign-scenario"))
340  campaign_scenario = vm["campaign-scenario"].as<std::string>();
341  if (vm.count("campaign-skip-story"))
342  campaign_skip_story = true;
343  if (vm.count("clock"))
344  clock = true;
345  if (vm.count("core"))
346  core_id = vm["core"].as<std::string>();
347  if (vm.count("config-dir"))
348  userdata_dir = vm["config-dir"].as<std::string>(); //TODO: complain and remove
349  if (vm.count("config-path"))
350  userdata_path = true; //TODO: complain and remove
351  if (vm.count("controller"))
352  multiplayer_controller = parse_to_uint_string_tuples_(vm["controller"].as<std::vector<std::string>>());
353  if (vm.count("data-dir"))
354  data_dir = vm["data-dir"].as<std::string>();
355  if (vm.count("data-path"))
356  data_path = true;
357  if (vm.count("debug"))
358  debug = true;
359  if (vm.count("debug-lua"))
360  debug_lua = true;
361 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
362  if (vm.count("debug-dot-domain")) {
363  debug_dot_domain = vm["debug-dot-domain"].as<std::string>();
364  }
365  if (vm.count("debug-dot-level")) {
366  debug_dot_level = vm["debug-dot-level"].as<std::string>();
367  }
368 #endif
369  if (vm.count("editor"))
370  editor = vm["editor"].as<std::string>();
371  if (vm.count("era"))
372  multiplayer_era = vm["era"].as<std::string>();
373  if (vm.count("exit-at-end"))
375  if (vm.count("fps"))
376  fps = true;
377  if (vm.count("fullscreen"))
378  fullscreen = true;
379  if (vm.count("gunzip"))
380  gunzip = vm["gunzip"].as<std::string>();
381  if (vm.count("gzip"))
382  gzip = vm["gzip"].as<std::string>();
383  if (vm.count("help"))
384  help = true;
385  if (vm.count("ignore-map-settings"))
387  if (vm.count("label"))
388  multiplayer_label = vm["label"].as<std::string>();
389  if (vm.count("language"))
390  language = vm["language"].as<std::string>();
391  if (vm.count("load"))
392  load = vm["load"].as<std::string>();
393  if (vm.count("log-error"))
394  parse_log_domains_(vm["log-error"].as<std::string>(),lg::err().get_severity());
395  if (vm.count("log-warning"))
396  parse_log_domains_(vm["log-warning"].as<std::string>(),lg::warn().get_severity());
397  if (vm.count("log-info"))
398  parse_log_domains_(vm["log-info"].as<std::string>(),lg::info().get_severity());
399  if (vm.count("log-debug"))
400  parse_log_domains_(vm["log-debug"].as<std::string>(),lg::debug().get_severity());
401  if (vm.count("log-none"))
402  parse_log_domains_(vm["log-none"].as<std::string>(),-1);
403  if (vm.count("logdomains"))
404  logdomains = vm["logdomains"].as<std::string>();
405  if (vm.count("log-precise"))
406  log_precise_timestamps = true;
407  if (vm.count("log-strict"))
408  parse_log_strictness(vm["log-strict"].as<std::string>());
409  if (vm.count("max-fps"))
410  max_fps = vm["max-fps"].as<int>();
411  if (vm.count("mp-test"))
412  mptest = true;
413  if (vm.count("multiplayer"))
414  multiplayer = true;
415  if (vm.count("multiplayer-repeat"))
416  multiplayer_repeat = vm["multiplayer-repeat"].as<unsigned int>();
417  if (vm.count("new-widgets"))
418  new_widgets = true;
419  if (vm.count("noaddons"))
420  noaddons = true;
421  if (vm.count("nocache"))
422  nocache = true;
423  if (vm.count("nodelay"))
424  nodelay = true;
425  if (vm.count("nomusic"))
426  nomusic = true;
427  if (vm.count("noreplaycheck"))
428  noreplaycheck = true;
429  if (vm.count("nosound"))
430  nosound = true;
431  if (vm.count("nogui"))
432  nogui = true;
433  if (vm.count("parm"))
434  multiplayer_parm = parse_to_uint_string_string_tuples_(vm["parm"].as<std::vector<std::string>>());
435  if (vm.count("preprocess"))
436  {
437  preprocess = true;
438  preprocess_path = vm["preprocess"].as<two_strings>().first;
439  preprocess_target = vm["preprocess"].as<two_strings>().second;
440  }
441  if (vm.count("diff"))
442  {
443  do_diff = true;
444  diff_left = vm["diff"].as<two_strings>().first;
445  diff_right = vm["diff"].as<two_strings>().second;
446  }
447  if (vm.count("patch"))
448  {
449  do_patch = true;
450  diff_left = vm["patch"].as<two_strings>().first;
451  diff_right = vm["patch"].as<two_strings>().second;
452  }
453  if (vm.count("output"))
454  {
455  output_file = vm["output"].as<std::string>();
456  }
457  if (vm.count("preprocess-defines"))
458  preprocess_defines = utils::split(vm["preprocess-defines"].as<std::string>(), ',');
459  if (vm.count("preprocess-input-macros"))
460  preprocess_input_macros = vm["preprocess-input-macros"].as<std::string>();
461  if (vm.count("preprocess-output-macros"))
462  preprocess_output_macros = vm["preprocess-output-macros"].as<std::string>();
463  if (vm.count("resolution"))
464  parse_resolution_(vm["resolution"].as<std::string>());
465  if (vm.count("rng-seed"))
466  rng_seed = vm["rng-seed"].as<unsigned int>();
467  if (vm.count("scenario"))
468  multiplayer_scenario = vm["scenario"].as<std::string>();
469  if (vm.count("render-image"))
470  {
471  render_image = vm["render-image"].as<two_strings>().first;
472  render_image_dst = vm["render-image"].as<two_strings>().second;
473  }
474  if (vm.count("screenshot"))
475  {
476  screenshot = true;
477  screenshot_map_file = vm["screenshot"].as<two_strings>().first;
478  screenshot_output_file = vm["screenshot"].as<two_strings>().second;
479  }
480  if (vm.count("script"))
481  script_file = vm["script"].as<std::string>();
482  if (vm.count("unsafe-scripts"))
483  script_unsafe_mode = true;
484  if (vm.count("plugin"))
485  plugin_file = vm["plugin"].as<std::string>();
486  if (vm.count("server"))
487  server = vm["server"].as<std::string>();
488  if (vm.count("username"))
489  username = vm["username"].as<std::string>();
490  if (vm.count("password"))
491  password = vm["password"].as<std::string>();
492  if (vm.count("report"))
493  report = true;
494  if (vm.count("side"))
495  multiplayer_side = parse_to_uint_string_tuples_(vm["side"].as<std::vector<std::string>>());
496  if (vm.count("test"))
497  test = vm["test"].as<std::string>();
498  if (vm.count("unit"))
499  {
500  unit_test = vm["unit"].as<std::string>();
501  headless_unit_test = true;
502  }
503  if (vm.count("showgui"))
504  headless_unit_test = false;
505  if (vm.count("timeout"))
506  timeout = vm["timeout"].as<unsigned int>();
507  if (vm.count("noreplaycheck"))
508  noreplaycheck = true;
509  if (vm.count("turns"))
510  multiplayer_turns = vm["turns"].as<std::string>();
511  if (vm.count("strict-validation"))
512  strict_validation = true;
513  if (vm.count("userconfig-dir"))
514  userconfig_dir = vm["userconfig-dir"].as<std::string>();
515  if (vm.count("userconfig-path"))
516  userconfig_path = true;
517  if (vm.count("userdata-dir"))
518  userdata_dir = vm["userdata-dir"].as<std::string>();
519  if (vm.count("userdata-path"))
520  userdata_path = true;
521  if (vm.count("validcache"))
522  validcache = true;
523  if (vm.count("validate"))
524  validate_wml = vm["validate"].as<std::string>();
525  if (vm.count("validate-core"))
526  validate_core = true;
527  if (vm.count("validate-addon"))
528  validate_addon = vm["validate-addon"].as<std::string>();
529  if (vm.count("validate-schema"))
530  validate_schema = vm["validate-schema"].as<std::string>();
531  if (vm.count("use-schema"))
532  validate_with = vm["use-schema"].as<std::string>();;
533  if (vm.count("version"))
534  version = true;
535  if (vm.count("windowed"))
536  windowed = true;
537  if (vm.count("with-replay"))
538  with_replay = true;
539  if(vm.count("all-translations"))
541  else if(vm.count("translations-over"))
542  translation_percent = utils::clamp<unsigned int>(vm["translations-over"].as<unsigned int>(), 0, 100);
543 }
544 
545 void commandline_options::parse_log_domains_(const std::string &domains_string, const int severity)
546 {
547  const std::vector<std::string> domains = utils::split(domains_string, ',');
548  for (const std::string& domain : domains)
549  {
550  if (!log)
551  log = std::vector<std::pair<int, std::string>>();
552  log->emplace_back(severity, domain);
553  }
554 }
555 
556 void commandline_options::parse_log_strictness (const std::string & severity ) {
557  static const std::array<lg::logger const*, 4> loggers {{&lg::err(), &lg::warn(), &lg::info(), &lg::debug()}};
558  for (const lg::logger * l : loggers ) {
559  if (severity == l->get_name()) {
561  return ;
562  }
563  }
564  std::cerr << "Unrecognized argument to --log-strict : " << severity << " . \nDisabling strict mode logging." << std::endl;
566 }
567 
568 void commandline_options::parse_resolution_ ( const std::string& resolution_string )
569 {
570  const std::vector<std::string> tokens = utils::split(resolution_string, 'x');
571  if (tokens.size() != 2) {
572  throw bad_commandline_resolution(resolution_string);
573  }
574 
575  int xres, yres;
576 
577  try {
578  xres = std::stoi(tokens[0]);
579  yres = std::stoi(tokens[1]);
580  } catch(const std::invalid_argument &) {
581  throw bad_commandline_resolution(resolution_string);
582  }
583 
584  resolution = std::make_pair(xres, yres);
585 }
586 
587 std::vector<std::pair<unsigned int,std::string>> commandline_options::parse_to_uint_string_tuples_(const std::vector<std::string> &strings, char separator)
588 {
589  std::vector<std::pair<unsigned int,std::string>> vec;
590  const std::string& expected_format
591  = std::string() + "UINT" + separator + "STRING";
592 
593  for (const std::string &s : strings)
594  {
595  const std::vector<std::string> tokens = utils::split(s, separator);
596  if(tokens.size() != 2) {
597  throw bad_commandline_tuple(s, expected_format);
598  }
599 
600  unsigned int temp;
601  try {
602  temp = lexical_cast<unsigned int>(tokens[0]);
603  } catch (const bad_lexical_cast &) {
604  throw bad_commandline_tuple(s, expected_format);
605  }
606 
607  vec.emplace_back(temp, tokens[1]);
608  }
609  return vec;
610 }
611 
612 std::vector<std::tuple<unsigned int,std::string,std::string>> commandline_options::parse_to_uint_string_string_tuples_(const std::vector<std::string> &strings, char separator)
613 {
614  std::vector<std::tuple<unsigned int,std::string,std::string>> vec;
615  const std::string& expected_format
616  = std::string() + "UINT" + separator + "STRING" + separator + "STRING";
617 
618  for (const std::string &s : strings)
619  {
620  const std::vector<std::string> tokens = utils::split(s, separator);
621  if(tokens.size() != 3) {
622  throw bad_commandline_tuple(s, expected_format);
623  }
624 
625  unsigned int temp;
626  try {
627  temp = lexical_cast<unsigned int>(tokens[0]);
628  } catch (const bad_lexical_cast &) {
629  throw bad_commandline_tuple(s, expected_format);
630  }
631 
632  vec.emplace_back(temp, tokens[1], tokens[2]);
633  }
634  return vec;
635 }
636 
637 std::ostream& operator<<(std::ostream &os, const commandline_options& cmdline_opts)
638 {
639  os << "Usage: " << cmdline_opts.args0_ << " [<options>] [<data-directory>]\n";
640  os << cmdline_opts.visible_;
641  return os;
642 }
643 
645  config ret;
646  if (server) {
647  ret["server"] = *server;
648  }
649  if (username) {
650  ret["username"] = *username;
651  }
652  if (password) {
653  ret["password"] = *password;
654  }
655  return ret;
656 }
boost::optional< std::string > core_id
Non-empty if –core was given on the command line. Chooses the core to be loaded. ...
bool log_precise_timestamps
True if –log-precise was given on the command line. Shows timestamps in log with more precision...
boost::optional< std::string > script_file
File to load lua script from.
bool new_widgets
Do we wish to use the new library or not.
Definition: settings.cpp:21
std::vector< std::string > args_
bool mptest
True if –mp-test was given on the command line.
static domain_map * domains
Definition: log.cpp:73
boost::program_options::options_description all_
bool nogui
True if –nogui was given on the command line. Disables GUI.
boost::optional< std::string > multiplayer_turns
Non-empty if –turns was given on the command line. Dependent on –multiplayer.
bool script_unsafe_mode
Whether to load the "package" package for the scripting environment. (This allows to load arbitrary l...
boost::optional< std::string > bzip2
Non-empty if –bzip2 was given on the command line. Compresses a file to .bz2 and exits...
std::vector< game_tip > load(const config &cfg)
Loads the tips from a config.
Definition: tips.cpp:35
commandline_options(const std::vector< std::string > &args)
std::vector< std::tuple< unsigned int, std::string, std::string > > parse_to_uint_string_string_tuples_(const std::vector< std::string > &strings, char separator=':')
A helper function splitting vector of strings of format unsigned int:string:string to vector of tuple...
boost::program_options::options_description hidden_
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:39
bool noaddons
True if –noaddons was given on the command line. Disables the loading of all add-ons.
New lexcical_cast header.
logger & info()
Definition: log.cpp:90
void parse_log_domains_(const std::string &domains_string, const int severity)
bool userdata_path
True if –userdata-path was given on the command line. Prints path to user data directory and exits...
boost::optional< std::string > multiplayer_scenario
Non-empty if –scenario was given on the command line. Dependent on –multiplayer.
bool multiplayer_ignore_map_settings
True if –ignore-map-settings was given at the command line. Do not use map settings.
boost::optional< std::string > username
Non-empty if –username was given on the command line. Forces Wesnoth to use this network username...
boost::optional< std::string > gunzip
Non-empty if –gunzip was given on the command line. Uncompresses a .gz file and exits.
boost::optional< std::string > campaign_scenario
Non-empty if –campaign-scenario was given on the command line. Chooses starting scenario in the camp...
boost::optional< int > max_fps
Max FPS specified by –max-fps option.
boost::optional< unsigned int > rng_seed
RNG seed specified by –rng-seed option. Initializes RNG with given seed.
bool fps
True if –fps was given on the command line. Shows number of fps.
boost::optional< std::string > data_dir
Non-empty if –data-dir was given on the command line. Sets the config dir to the specified one...
bool noreplaycheck
True if –noreplaycheck was given on the command line. Dependent on –unit.
boost::optional< std::string > multiplayer_era
Non-empty if –era was given on the command line. Dependent on –multiplayer.
void parse_resolution_(const std::string &resolution_string)
To lexical_cast(From value)
Lexical cast converts one type to another.
Definitions for the interface to Wesnoth Markup Language (WML).
bad_commandline_tuple(const std::string &str, const std::string &expected_format)
std::vector< std::string > split(const std::string &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
boost::optional< std::vector< std::pair< unsigned int, std::string > > > multiplayer_side
Non-empty if –side was given on the command line. Vector of pairs (side number, faction id)...
std::string diff_left
Files for diffing or patching.
boost::optional< std::string > plugin_file
File to load a lua plugin (similar to a script) from. Experimental / may replace script.
boost::optional< std::string > multiplayer_label
Non-empty if –label was given on the command line. Dependent on –multiplayer.
boost::optional< unsigned int > timeout
Non-empty if –timeout was given on the command line. Dependent on –unit.
boost::optional< std::string > load
Non-empty if –load was given on the command line. Savegame specified to load after start...
bool preprocess
True if –preprocess was given on the command line. Starts Wesnoth in preprocessor-only mode...
bool with_replay
True if –with-replay was given on the command line. Shows replay of the loaded file.
bool headless_unit_test
True if –unit is used and –showgui is not present.
const config & options()
Definition: game.cpp:593
boost::optional< std::string > validate_schema
Non-empty if –validate-schema was given on the command line. Makes Wesnoth validate a WML schema...
boost::optional< std::string > userconfig_dir
Non-empty if –userconfig-dir was given on the command line. Sets the user config dir to the specifie...
bool report
True if –report was given on the command line. Prints a bug report-style info dump and exits...
boost::optional< std::vector< std::pair< unsigned int, std::string > > > multiplayer_ai_config
Non-empty if –ai-config was given on the command line. Vector of pairs (side number, value). Dependent on –multiplayer.
std::ostringstream wrapper.
Definition: formatter.hpp:38
bool nodelay
True if –nodelay was given on the command line.
bool fullscreen()
Definition: general.cpp:394
boost::optional< unsigned int > translation_percent
Non-empty if –all-translations or –translations-over is given on the command line.
boost::optional< std::string > logdomains
Non-empty if –logdomains was given on the command line. Prints possible logdomains filtered by given...
bool windowed
True if –windowed was given on the command line. Starts Wesnoth in windowed mode.
std::vector< std::pair< unsigned int, std::string > > parse_to_uint_string_tuples_(const std::vector< std::string > &strings, char separator=':')
A helper function splitting vector of strings of format unsigned int:string to vector of tuples (unsi...
boost::optional< std::string > userdata_dir
Non-empty if –userdata-dir was given on the command line. Sets the user data dir to the specified on...
boost::optional< std::string > gzip
Non-empty if –gzip was given on the command line. Compresses a file to .gz and exits.
boost::optional< std::string > output_file
Output filename for WML diff or preprocessing.
boost::optional< std::string > preprocess_output_macros
Non-empty if –preprocess-output-macros was given on the command line. Outputs all preprocessed macro...
boost::optional< std::string > test
Non-empty if –test was given on the command line. Goes directly into test mode, into a scenario...
bool multiplayer
True if –multiplayer was given on the command line. Goes directly into multiplayer mode...
Manage the empty-palette in the editor.
Definition: action.cpp:29
logger & debug()
Definition: log.cpp:96
bool clock
True if –clock was given on the command line. Enables.
bool userconfig_path
True if –userconfig-path was given on the command line. Prints path to user config directory and exi...
boost::optional< std::vector< std::pair< unsigned int, std::string > > > multiplayer_algorithm
Non-empty if –algorithm was given on the command line. Vector of pairs (side number, value). Dependent on –multiplayer.
boost::optional< std::vector< std::pair< int, std::string > > > log
Contains parsed arguments of –log-* (e.g.
boost::optional< std::string > render_image
Image path to render. First parameter after –render-image.
boost::optional< int > campaign_difficulty
Non-empty if –campaign-difficulty was given on the command line. Numerical difficulty of the campaig...
bool nomusic
True if –nomusic was given on the command line. Disables music.
boost::optional< std::string > validate_wml
Non-empty if –validate was given on the command line. Makes Wesnoth validate a WML file against a sc...
boost::optional< std::string > password
Non-empty if –password was given on the command line. Forces Wesnoth to use this network password...
boost::optional< std::string > preprocess_target
Target (output) path that was given to the –preprocess option.
bool debug
True if –debug was given on the command line. Enables debug mode.
bool debug_lua
True if –debug-lua was given in the commandline. Enables some Lua debugging mechanisms.
bool nocache
True if –nocache was given on the command line. Disables cache usage.
logger & err()
Definition: log.cpp:78
boost::optional< std::string > screenshot_map_file
Map file to make a screenshot of. First parameter given after –screenshot.
boost::optional< std::string > preprocess_path
Path to parse that was given to the –preprocess option.
void set_strict_severity(int severity)
Definition: log.cpp:161
bool new_widgets
True if –new-widgets was given on the command line. Hidden option to enable the new widget toolkit...
static map_location::DIRECTION s
boost::optional< std::string > bunzip2
Non-empty if –bunzip2 was given on the command line. Uncompresses a .bz2 file and exits...
std::string password(const std::string &server, const std::string &login)
std::string language()
Definition: general.cpp:475
bad_commandline_resolution(const std::string &resolution)
boost::optional< std::vector< std::tuple< unsigned int, std::string, std::string > > > multiplayer_parm
Non-empty if –parm was given on the command line. Vector of pairs (side number, parm name...
static void validate(boost::any &v, const std::vector< std::string > &values, two_strings *, int)
#define debug(x)
bool campaign_skip_story
True if –skip-story was given on the command line. Skips [story] and [message]s through the end of t...
std::string core_id()
Definition: general.cpp:313
boost::optional< std::string > render_image_dst
Output file to put rendered image path in. Optional second parameter after –render-image.
void parse_log_strictness(const std::string &severity)
bool data_path
True if –data-path was given on the command line. Prints path to data directory and exits...
bool screenshot
True if –screenshot was given on the command line. Starts Wesnoth in screenshot mode.
boost::optional< std::string > unit_test
Non-empty if –unit was given on the command line. Goes directly into unit test mode, into a scenario, if specified.
logger & warn()
Definition: log.cpp:84
boost::optional< unsigned int > multiplayer_repeat
Repeats specified by –multiplayer-repeat option. Repeats a multiplayer game after it is finished...
bool version
True if –version was given on the command line. Prints version and exits.
bool validate_core
True if –validate-core was given on the command line. Makes Wesnoth validate the core WML...
Standard logging facilities (interface).
boost::optional< std::string > screenshot_output_file
Output file to put screenshot in. Second parameter given after –screenshot.
bool fullscreen
True if –fullscreen was given on the command line. Starts Wesnoth in fullscreen mode.
bool validcache
True if –validcache was given on the command line. Makes Wesnoth assume the cache is valid...
bool strict_validation
True if –strict-validation was given on the command line. Makes Wesnoth trust validation errors as f...
boost::optional< std::vector< std::string > > preprocess_defines
Defines that were given to the –preprocess option.
point resolution()
Definition: general.cpp:373
boost::optional< std::string > language
Non-empty if –language was given on the command line. Sets the language for this session...
Definition: help.cpp:55
bool nosound
True if –nosound was given on the command line. Disables sound.
boost::optional< std::string > preprocess_input_macros
Non-empty if –preprocess-input-macros was given on the command line. Specifies a file that contains ...
boost::optional< std::pair< int, int > > resolution
Pair of AxB values specified after –resolution. Changes Wesnoth resolution.
boost::program_options::options_description visible_
friend std::ostream & operator<<(std::ostream &os, const commandline_options &cmdline_opts)
To be used for printing help to the commandline.
bool multiplayer_exit_at_end
True if –exit-at-and was given on the command line. Dependent on –multiplayer.
boost::optional< std::string > campaign
Non-empty if –campaign was given on the command line. ID of the campaign we want to start...
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
int get_severity() const
Definition: log.hpp:128
Thrown when a lexical_cast fails.
boost::optional< std::vector< std::pair< unsigned int, std::string > > > multiplayer_controller
Non-empty if –controller was given on the command line. Vector of pairs (side number, controller). Dependent on –multiplayer.
boost::optional< std::string > validate_addon
Non-empty if –validate-addon was given on the command line. Makes Wesnoth validate an addon&#39;s WML...
boost::optional< std::string > server
Non-empty if –server was given on the command line. Connects Wesnoth to specified server...
boost::optional< std::string > validate_with
Non-empty if –use-schema was given on the command line. Specifies the schema for use with –validate...