Skip to content

Commit

Permalink
Add command-line options to disable the Windows-specific special log/…
Browse files Browse the repository at this point in the history
…console handling
  • Loading branch information
CelticMinstrel committed Mar 3, 2021
1 parent 191b246 commit b7c28a4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 31 deletions.
46 changes: 22 additions & 24 deletions src/commandline_options.cpp
Expand Up @@ -60,6 +60,14 @@ bad_commandline_tuple::bad_commandline_tuple(const std::string& str,
{
}


#ifdef _WIN32
#define IMPLY_WCONSOLE " Implies --wconsole."
#else
#define IMPLY_WCONSOLE
#endif // _WIN32


commandline_options::commandline_options(const std::vector<std::string>& args)
: bunzip2()
, bzip2()
Expand Down Expand Up @@ -173,7 +181,7 @@ commandline_options::commandline_options(const std::vector<std::string>& args)
("config-path", "prints the path of the userdata directory and exits. DEPRECATED: use userdata-path instead.")
("core", po::value<std::string>(), "overrides the loaded core with the one whose id is specified.")
("data-dir", po::value<std::string>(), "overrides the data directory with the one specified.")
("data-path", "prints the path of the data directory and exits.")
("data-path", "prints the path of the data directory and exits." IMPLY_WCONSOLE)
("debug,d", "enables additional command mode options in-game.")
("debug-lua", "enables some Lua debugging mechanisms")
("strict-lua", "disallow deprecated Lua API calls")
Expand All @@ -184,7 +192,7 @@ commandline_options::commandline_options(const std::vector<std::string>& args)
("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>.")
("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.")
("gzip", po::value<std::string>(), "compresses a file (<arg>) in gzip format, stores it as <arg>.gz and removes <arg>.")
("help,h", "prints this message and exits.")
("help,h", "prints this message and exits." IMPLY_WCONSOLE)
("language,L", po::value<std::string>(), "uses language <arg> (symbol) this session. Example: --language ang_GB@latin")
("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.")
("noaddons", "disables the loading of all add-ons.")
Expand All @@ -194,22 +202,10 @@ commandline_options::commandline_options(const std::vector<std::string>& args)
("nosound", "runs the game without sounds and music.")
("password", po::value<std::string>(), "uses <password> when connecting to a server, ignoring other preferences.")
("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.")
("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."
#ifdef _WIN32
" Implies --wconsole."
#endif // _WIN32
)
("report,R", "initializes game directories, prints build information suitable for use in bug reports, and exits."
#ifdef _WIN32
" Implies --wconsole."
#endif // _WIN32
)
("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." IMPLY_WCONSOLE)
("report,R", "initializes game directories, prints build information suitable for use in bug reports, and exits." IMPLY_WCONSOLE)
("rng-seed", po::value<unsigned int>(), "seeds the random number generator with number <arg>. Example: --rng-seed 0")
("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."
#ifdef _WIN32
" Implies --wconsole."
#endif // _WIN32
)
("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." IMPLY_WCONSOLE)
("script", po::value<std::string>(), "(experimental) file containing a Lua script to control the client")
("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.")
("strict-validation", "makes validation errors fatal")
Expand All @@ -218,13 +214,15 @@ commandline_options::commandline_options(const std::vector<std::string>& args)
("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.")
("userconfig-path", "prints the path of the user config directory and exits.")
("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.")
("userdata-path", "prints the path of the userdata directory and exits.")
("userdata-path", "prints the path of the userdata directory and exits." IMPLY_WCONSOLE)
("username", po::value<std::string>(), "uses <username> when connecting to a server, ignoring other preferences.")
("validcache", "assumes that the cache is valid. (dangerous)")
("version,v", "prints the game's version number and exits.")
("with-replay", "replays the file loaded with the --load option.")
#ifdef _WIN32
("wconsole", "attaches a console window on startup (Windows only). Implied by any option that prints something and exits.")
("wnoconsole", "don't attach a console window on startup (Windows only). Overrides options that imply --wconsole.")
("wnoredirect", "disables standard redirection of logging to a file (Windows only), allowing the output to be piped to another command")
#endif // _WIN32
;

Expand All @@ -248,7 +246,7 @@ commandline_options::commandline_options(const std::vector<std::string>& args)

po::options_description logging_opts("Logging options");
logging_opts.add_options()
("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.")
("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." IMPLY_WCONSOLE)
("log-error", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'error'. <arg> should be given as a comma-separated list of domains, wildcards are allowed. Example: --log-error=network,gui/*,engine/enemies")
("log-warning", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'warning'. Similar to --log-error.")
("log-info", po::value<std::string>(), "sets the severity level of the specified log domain(s) to 'info'. Similar to --log-error.")
Expand Down Expand Up @@ -289,14 +287,14 @@ commandline_options::commandline_options(const std::vector<std::string>& args)
po::options_description parsing_opts("WML parsing options");
parsing_opts.add_options()
("use-schema,S", po::value<std::string>(), "specify a schema to validate WML against (defaults to the core schema)")
("validate,V", po::value<std::string>(), "validate a specified WML file against a schema")
("validate,V", po::value<std::string>(), "validate a specified WML file against a schema" IMPLY_WCONSOLE)
("validate-addon", po::value<std::string>(), "validate the specified addon's WML against the schema. Requires the user to play the campaign (in the GUI) to trigger the validation.")
("validate-core", "validate the core WML against the schema")
("validate-schema", po::value<std::string>(), "validate a specified WML schema")
("diff,D", po::value<two_strings>()->multitoken(), "diff two preprocessed WML documents")
("validate-schema", po::value<std::string>(), "validate a specified WML schema" IMPLY_WCONSOLE)
("diff,D", po::value<two_strings>()->multitoken(), "diff two preprocessed WML documents" IMPLY_WCONSOLE)
("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")
("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.")
("patch,P", po::value<two_strings>()->multitoken(), "apply a patch to a preprocessed WML document" IMPLY_WCONSOLE)
("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_WCONSOLE)
("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.")
Expand Down
12 changes: 10 additions & 2 deletions src/log_windows.cpp
Expand Up @@ -465,12 +465,19 @@ std::string log_file_path()
return "";
}

void early_log_file_setup()
static bool disable_redirect;

void early_log_file_setup(bool disable)
{
if(lfm) {
return;
}

if(disable) {
disable_redirect = true;
return;
}

lfm.reset(new log_file_manager());
}

Expand All @@ -491,8 +498,9 @@ bool using_own_console()

void finish_log_file_setup()
{
if(disable_redirect) return;
// Make sure the LFM is actually set up just in case.
early_log_file_setup();
early_log_file_setup(false);

if(lfm->console_enabled()) {
// Nothing to do if running in console mode.
Expand Down
2 changes: 1 addition & 1 deletion src/log_windows.hpp
Expand Up @@ -57,7 +57,7 @@ std::string log_file_path();
* horribly wrong as soon as we try to use the logging facilities internally
* for debug messages.
*/
void early_log_file_setup();
void early_log_file_setup(bool disable);

/**
* Relocates the stdout+stderr log file to the user data directory.
Expand Down
22 changes: 18 additions & 4 deletions src/wesnoth.cpp
Expand Up @@ -87,6 +87,7 @@

#include <boost/iostreams/filtering_stream.hpp> // for filtering_stream
#include <boost/program_options/errors.hpp> // for error
#include <optional>

#include <algorithm> // for transform
#include <cerrno> // for ENOMEM
Expand Down Expand Up @@ -973,6 +974,9 @@ int main(int argc, char** argv)
}

#ifdef _WIN32
bool log_redirect = true, native_console_implied = false;
// This is optional<bool> instead of tribool because value_or() is exactly the required semantic
std::optional<bool> native_console_force;
// Some switches force a Windows console to be attached to the process even
// if Wesnoth is an IMAGE_SUBSYSTEM_WINDOWS_GUI executable because they
// turn it into a CLI application. Also, --wconsole in particular attaches
Expand All @@ -994,7 +998,7 @@ int main(int argc, char** argv)
// care about -- we just want to see if the switch is there.
static const std::set<std::string> wincon_arg_switches = {
"-D", "--diff", "-p", "--preprocess", "-P", "--patch", "--render-image",
"--screenshot", "-V", "--validate", "--validate-addon", "--validate-schema",
"--screenshot", "-V", "--validate", "--validate-schema",
};

auto switch_matches_arg = [&arg](const std::string& sw) {
Expand All @@ -1004,12 +1008,22 @@ int main(int argc, char** argv)

if(wincon_switches.find(arg) != wincon_switches.end() ||
std::find_if(wincon_arg_switches.begin(), wincon_arg_switches.end(), switch_matches_arg) != wincon_arg_switches.end()) {
lg::enable_native_console_output();
break;
native_console_implied = true;
}

if(arg == "--wnoconsole") {
native_console_force = false;
} else if(arg == "--wconsole") {
native_console_force = true;
} else if(arg == "--wnoredirect") {
log_redirect = false;
}
}

lg::early_log_file_setup();
if(native_console_force.value_or(native_console_implied)) {
lg::enable_native_console_output();
}
lg::early_log_file_setup(!log_redirect);
#endif

if(SDL_Init(SDL_INIT_TIMER) < 0) {
Expand Down

0 comments on commit b7c28a4

Please sign in to comment.