15 #include "addon/manager.hpp" 57 #include "widgets/button.hpp" 72 #include <boost/iostreams/categories.hpp> 73 #include <boost/iostreams/copy.hpp> 74 #include <boost/iostreams/filter/bzip2.hpp> 78 #pragma warning(disable : 4456) 79 #pragma warning(disable : 4458) 82 #include <boost/iostreams/filter/gzip.hpp> 88 #include <boost/iostreams/filtering_stream.hpp> 89 #include <boost/program_options/errors.hpp> 111 #ifdef INADDR_BROADCAST 112 #undef INADDR_BROADCAST 123 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS 127 class end_level_exception;
134 #define LOG_CONFIG LOG_STREAM(info, log_config) 136 #define LOG_GENERAL LOG_STREAM(info, lg::general()) 139 #define LOG_PREPROC LOG_STREAM(info, log_preprocessor) 146 LOG_GENERAL <<
"exiting with code " << res <<
"\n";
151 template<
typename filter>
152 static void encode(
const std::string& input_file,
const std::string& output_file)
155 std::ifstream ifile(input_file.c_str(),
std::ios_base::in | std::ios_base::binary);
159 std::cerr <<
"Input file " << input_file
160 <<
" is not good for reading. Exiting to prevent bzip2 from segfaulting\n";
164 std::ofstream ofile(output_file.c_str(), std::ios_base::out | std::ios_base::binary);
166 boost::iostreams::filtering_stream<boost::iostreams::output> stream;
167 stream.push(filter());
170 boost::iostreams::copy(ifile, stream);
175 std::cerr <<
"IO error: " << e.
what() <<
"\n";
179 template<
typename filter>
180 static void decode(
const std::string& input_file,
const std::string& output_file)
183 std::ofstream ofile(output_file.c_str(), std::ios_base::out | std::ios_base::binary);
184 std::ifstream ifile(input_file.c_str(),
std::ios_base::in | std::ios_base::binary);
186 boost::iostreams::filtering_stream<boost::iostreams::input> stream;
187 stream.push(filter());
190 boost::iostreams::copy(stream, ofile);
195 std::cerr <<
"IO error: " << e.
what() <<
"\n";
199 static void gzip_encode(
const std::string& input_file,
const std::string& output_file)
201 encode<boost::iostreams::gzip_compressor>(input_file, output_file);
204 static void gzip_decode(
const std::string& input_file,
const std::string& output_file)
206 decode<boost::iostreams::gzip_decompressor>(input_file, output_file);
209 static void bzip2_encode(
const std::string& input_file,
const std::string& output_file)
211 encode<boost::iostreams::bzip2_compressor>(input_file, output_file);
214 static void bzip2_decode(
const std::string& input_file,
const std::string& output_file)
216 decode<boost::iostreams::bzip2_decompressor>(input_file, output_file);
226 std::cerr <<
"please specify an existing file. File " << file <<
" doesn't exist.\n";
230 std::cerr << SDL_GetTicks() <<
" Reading cached defines from: " << file <<
"\n";
238 std::cerr <<
"Caught a config error while parsing file '" << file <<
"':\n" << e.
message << std::endl;
246 input_macros[def.first] = def.second;
250 std::cerr << SDL_GetTicks() <<
" Read " << read <<
" defines.\n";
256 uint32_t startTime = SDL_GetTicks();
259 bool skipCore =
false;
260 bool skipTerrainGFX =
false;
269 std::cerr <<
"empty define supplied\n";
273 LOG_PREPROC <<
"adding define: " << define <<
'\n';
276 if(define ==
"SKIP_CORE") {
277 std::cerr <<
"'SKIP_CORE' defined.\n";
279 }
else if(define ==
"NO_TERRAIN_GFX") {
280 std::cerr <<
"'NO_TERRAIN_GFX' defined." << std::endl;
281 skipTerrainGFX =
true;
289 std::cerr <<
"added " << defines_map.size() <<
" defines.\n";
292 if(skipCore ==
false) {
293 std::cerr <<
"preprocessing common macros from 'data/core' ...\n";
298 if(skipTerrainGFX ==
false) {
302 std::cerr <<
"acquired " << (defines_map.size() - input_macros.size()) <<
" 'data/core' defines.\n";
304 std::cerr <<
"skipped 'data/core'\n";
308 std::cerr <<
"preprocessing specified resource: " << resourceToProcess <<
" ...\n";
311 std::cerr <<
"acquired " << (defines_map.size() - input_macros.size()) <<
" total defines.\n";
314 std::string outputFileName =
"_MACROS_.cfg";
319 std::string outputPath = targetDir +
"/" + outputFileName;
321 std::cerr <<
"writing '" << outputPath <<
"' with " << defines_map.size() <<
" defines.\n";
327 for(
auto& define_pair : defines_map) {
328 define_pair.second.write(writer, define_pair.first);
331 std::cerr <<
"couldn't open the file.\n";
335 std::cerr <<
"preprocessing finished. Took " << SDL_GetTicks() - startTime <<
" ticks.\n";
340 for(
const std::string& define : defines) {
342 std::cerr <<
"empty define supplied\n";
346 LOG_PREPROC <<
"adding define: " << define <<
'\n';
349 std::cout <<
"Validating " << file <<
" against schema " << validator.
name_ << std::endl;
353 read(result, *stream, &validator);
355 std::cout <<
"validation failed\n";
357 std::cout <<
"validation succeeded\n";
367 if(cmdline_opts.
log) {
368 for(
const auto& log_pair : *cmdline_opts.
log) {
369 const std::string log_domain = log_pair.second;
370 const int severity = log_pair.first;
372 std::cerr <<
"unknown log domain: " << log_domain <<
'\n';
397 const std::string datadir = *cmdline_opts.
data_dir;
400 if(datadir.c_str()[1] ==
':') {
402 if(datadir[0] ==
'/') {
435 const std::string input_file(*cmdline_opts.
gunzip);
437 std::cerr <<
"file '" << input_file <<
"'isn't a .gz file\n";
441 const std::string output_file(input_file, 0, input_file.length() - 3);
446 const std::string input_file(*cmdline_opts.
bunzip2);
448 std::cerr <<
"file '" << input_file <<
"'isn't a .bz2 file\n";
452 const std::string output_file(input_file, 0, input_file.length() - 4);
456 if(cmdline_opts.
gzip) {
457 const std::string input_file(*cmdline_opts.
gzip);
458 const std::string output_file(*cmdline_opts.
gzip +
".gz");
462 if(cmdline_opts.
bzip2) {
463 const std::string input_file(*cmdline_opts.
bzip2);
464 const std::string output_file(*cmdline_opts.
bzip2 +
".bz2");
468 if(cmdline_opts.
help) {
469 std::cout << cmdline_opts;
487 SDL_setenv(
"SDL_VIDEODRIVER",
"dummy", 1);
515 std::ifstream in_left(cmdline_opts.
diff_left);
516 std::ifstream in_right(cmdline_opts.
diff_right);
518 read(right, in_right);
519 std::ostream* os = &std::cout;
525 if(os != &std::cout)
delete os;
531 std::ifstream in_base(cmdline_opts.
diff_left);
532 std::ifstream in_diff(cmdline_opts.
diff_right);
536 std::ostream* os = &std::cout;
542 if(os != &std::cout)
delete os;
554 std::string schema_path;
569 std::cerr <<
"That --preprocess-* option is only supported when using --preprocess or --validate-wml.\n";
586 #if defined _WIN32 || defined __APPLE__ 587 setlocale(LC_ALL,
"English");
589 std::setlocale(LC_ALL,
"C");
612 <<
"An error at this point during initialization usually indicates that the data\n" 613 <<
"directory above was not correctly set or detected. Try passing the correct path\n" 614 <<
"in the command line with the --data-dir switch or as the only argument.\n";
623 static bool first_time =
true;
642 if(_controlfp_s(&f_control, 0, 0) == 0) {
644 uint32_t rounding_mode = f_control & _MCW_RC;
646 if(rounding_mode != _RC_NEAR) {
647 std::cerr <<
"Floating point rounding mode is currently '" 648 << ((rounding_mode == _RC_CHOP)
650 : (rounding_mode == _RC_UP)
652 : (rounding_mode == _RC_DOWN)
654 : (rounding_mode == _RC_NEAR) ?
"near" :
"unknown")
655 <<
"' setting to 'near'\n";
657 if(_controlfp_s(&unused, _RC_NEAR, _MCW_RC)) {
658 std::cerr <<
"failed to set floating point rounding type to 'near'\n";
663 uint32_t precision_mode = f_control & _MCW_PC;
664 if(precision_mode != _PC_53) {
665 std::cerr <<
"Floating point precision mode is currently '" 666 << ((precision_mode == _PC_53)
668 : (precision_mode == _PC_24)
670 : (precision_mode == _PC_64) ?
"double extended" :
"unknown")
671 <<
"' setting to 'double'\n";
673 if(_controlfp_s(&unused, _PC_53, _MCW_PC)) {
674 std::cerr <<
"failed to set floating point precision type to 'double'\n";
680 std::cerr <<
"_controlfp_s failed.\n";
686 switch(fegetround()) {
690 std::cerr <<
"Floating point precision mode is currently 'downward'";
693 std::cerr <<
"Floating point precision mode is currently 'toward-zero'";
696 std::cerr <<
"Floating point precision mode is currently 'upward'";
699 std::cerr <<
"Floating point precision mode is currently 'unknown'";
702 std::cerr <<
"setting to 'nearest'";
703 fesetround(FE_TONEAREST);
715 srand(std::time(
nullptr));
724 std::cerr <<
"Press enter to continue..." << std::endl;
732 const auto game = std::make_unique<game_launcher>(cmdline_opts);
733 const int start_ticks = SDL_GetTicks();
744 std::cerr <<
"could not initialize fonts\n";
750 res =
game->init_language();
752 std::cerr <<
"could not initialize the language\n";
756 res =
game->init_video();
758 std::cerr <<
"could not initialize display\n";
766 #if(defined(_X11) && !defined(__APPLE__)) || defined(_WIN32) 767 SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
780 std::cerr <<
"could not initialize game config\n";
788 std::cerr <<
"could not re-initialize fonts for the current language\n";
803 LOG_CONFIG <<
"time elapsed: " << (SDL_GetTicks() - start_ticks) <<
" ms\n";
822 if(!
game->has_load_data()) {
829 config title_music_config;
831 title_music_config[
"append"] =
true;
832 title_music_config[
"immediate"] =
true;
846 return static_cast<int>(
game->unit_test());
849 if(
game->play_test() ==
false) {
853 if(
game->play_screenshot_mode() ==
false) {
857 if(
game->play_render_image_mode() ==
false) {
862 if(
game->goto_campaign() ==
false) {
863 if(
game->jump_to_campaign_id().empty())
871 if(
game->goto_multiplayer() ==
false) {
876 if(
game->play_multiplayer_commandline() ==
false) {
880 if(
game->goto_editor() ==
false) {
889 if(
game->has_load_data() &&
game->load_game()) {
923 game->start_editor();
926 gui2::dialogs::end_credits::display();
945 #define error_exit(res) \ 947 if(lg::using_own_console()) { \ 948 std::cerr << "Press enter to continue..." << std::endl; \ 954 #define error_exit(res) return res 961 int main(
int argc,
char** argv)
965 assert(!args.empty());
968 bool nobanner =
false;
969 for(
const auto& arg : args) {
970 if(arg ==
"--nobanner") {
977 bool log_redirect =
true, native_console_implied =
false;
979 std::optional<bool> native_console_force;
989 for(
const auto& arg : args) {
991 static const std::set<std::string> wincon_switches = {
992 "--wconsole",
"-h",
"--help",
"-v",
"--version",
"-R",
"--report",
"--logdomains",
993 "--data-path",
"--userdata-path",
"--userconfig-path",
999 static const std::set<std::string> wincon_arg_switches = {
1000 "-D",
"--diff",
"-p",
"--preprocess",
"-P",
"--patch",
"--render-image",
1001 "--screenshot",
"-V",
"--validate",
"--validate-schema",
1004 auto switch_matches_arg = [&arg](
const std::string&
sw) {
1005 const auto pos = arg.find(
'=');
1006 return pos == std::string::npos ? arg ==
sw : arg.substr(0, pos) ==
sw;
1009 if(wincon_switches.find(arg) != wincon_switches.end() ||
1010 std::find_if(wincon_arg_switches.begin(), wincon_arg_switches.end(), switch_matches_arg) != wincon_arg_switches.end()) {
1011 native_console_implied =
true;
1014 if(arg ==
"--wnoconsole") {
1015 native_console_force =
false;
1016 }
else if(arg ==
"--wconsole") {
1017 native_console_force =
true;
1018 }
else if(arg ==
"--wnoredirect") {
1019 log_redirect =
false;
1023 if(native_console_force.value_or(native_console_implied)) {
1029 if(SDL_Init(SDL_INIT_TIMER) < 0) {
1030 fprintf(stderr,
"Couldn't initialize SDL: %s\n", SDL_GetError());
1035 struct sigaction terminate_handler;
1037 terminate_handler.sa_flags = 0;
1039 sigemptyset(&terminate_handler.sa_mask);
1040 sigaction(SIGTERM, &terminate_handler,
nullptr);
1041 sigaction(SIGINT, &terminate_handler,
nullptr);
1046 #if defined(__APPLE__) && !defined(__IPHONEOS__) 1047 SDL_EventState(SDL_FINGERMOTION, SDL_DISABLE);
1048 SDL_EventState(SDL_FINGERDOWN, SDL_DISABLE);
1049 SDL_EventState(SDL_FINGERUP, SDL_DISABLE);
1055 SDL_StartTextInput();
1060 const std::time_t
t = std::time(
nullptr);
1061 std::cerr <<
"Started on " << ctime(&t) <<
"\n";
1065 if(!exe_dir.empty()) {
1068 std::string auto_dir;
1087 if(!auto_dir.empty()) {
1088 if(!nobanner) std::cerr <<
"Automatically found a possible data directory at " <<
filesystem::sanitize_path(auto_dir) <<
'\n';
1096 std::cerr <<
"Error in command line: " << e.what() <<
'\n';
1099 std::cerr <<
"Could not initialize video.\n\n" << e.
what() <<
"\n\nExiting.\n";
1102 std::cerr <<
"Could not initialize fonts.\n\n" << e.
what() <<
"\n\nExiting.\n";
1105 std::cerr << e.
message <<
"\n";
1108 std::cerr <<
"Could not create button: Image could not be found\n";
1113 std::cerr <<
"caught return_to_play_side_exception, please report this bug (quitting)\n";
1115 std::cerr <<
"caught quit_game_exception (quitting)\n";
1117 std::cerr <<
"WML exception:\nUser message: " << e.
user_message <<
"\nDev message: " << e.
dev_message <<
'\n';
1120 std::cerr << e.
what() <<
"\n\nGame will be aborted.\n";
1123 std::cerr << e.
what();
1128 }
catch(
const std::bad_alloc&) {
1129 std::cerr <<
"Ran out of memory. Aborted.\n";
1131 #if !defined(NO_CATCH_AT_GAME_END) 1132 }
catch(
const std::exception& e) {
1134 std::cerr <<
"Caught general '" <<
typeid(
e).name() <<
"' exception:\n" << e.what() << std::endl;
1136 }
catch(
const std::string& e) {
1137 std::cerr <<
"Caught a string thrown as an exception:\n" << e << std::endl;
1139 }
catch(
const char* e) {
1140 std::cerr <<
"Caught a string thrown as an exception:\n" << e << std::endl;
1147 std::cerr <<
"Caught unspecified general exception. Terminating." << std::endl;
bool log_precise_timestamps
True if –log-precise was given on the command line.
std::optional< std::string > preprocess_path
Path to parse that was given to the –preprocess option.
static void wesnoth_terminate_handler(int)
std::vector< Reg > reg_vec
std::optional< std::string > output_file
Output filename for WML diff or preprocessing.
void set_callback(const std::string &name, callback_function)
std::optional< std::string > preprocess_output_macros
Non-empty if –preprocess-output-macros was given on the command line.
static int handle_validate_command(const std::string &file, abstract_validator &validator, const std::vector< std::string > &defines)
void bind_textdomain(const char *domain, const char *directory, const char *)
const_all_children_itors all_children_range() const
In-order iteration over all children.
bool using_own_console()
Returns true if a console was allocated by the Wesnoth process.
void write(const config &cfg)
bool play_multiplayer(mp_mode mode)
void set(CURSOR_TYPE type)
Use the default parameter to reset cursors.
std::string library_versions_report()
Produce a plain-text report of library versions suitable for stdout/stderr.
static void bzip2_encode(const std::string &input_file, const std::string &output_file)
static void bzip2_decode(const std::string &input_file, const std::string &output_file)
Interfaces for manipulating version numbers of engine, add-ons, etc.
static lg::log_domain log_preprocessor("preprocessor")
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
std::string optional_features_report()
Produce a plain-text report of features suitable for stdout/stderr.
static l_noret error(LoadState *S, const char *why)
bool noaddons
True if –noaddons was given on the command line.
Exception used to escape form the ai or ui code to playsingle_controller::play_side.
void set_user_data_dir(std::string newprefdir)
static bool file_exists(const bfs::path &fpath)
child_itors child_range(config_key_type key)
bool userdata_path
True if –userdata-path was given on the command line.
static void gzip_decode(const std::string &input_file, const std::string &output_file)
static void progress(loading_stage stage=loading_stage::none)
filesystem::scoped_istream istream_file(const std::string &fname, bool treat_failure_as_error)
std::string user_message
The message for the user explaining what went wrong.
This class implements the title screen.
std::optional< std::string > preprocess_target
Target (output) path that was given to the –preprocess option.
std::optional< std::string > preprocess_input_macros
Non-empty if –preprocess-input-macros was given on the command line.
Type that can be thrown as an exception to quit to desktop.
std::optional< std::string > userconfig_dir
Non-empty if –userconfig-dir was given on the command line.
void preprocess_resource(const std::string &res_name, preproc_map *defines_map, bool write_cfg, bool write_plain_cfg, const std::string &parent_directory)
std::vector< std::string > unit_test
Non-empty if –unit was given on the command line.
void early_log_file_setup(bool disable)
Sets up the initial temporary log file.
Don't reload if the previous defines equal the new defines.
static void safe_exit(int res)
std::string normalize_path(const std::string &fpath, bool normalize_separators, bool resolve_dot_entries)
Returns the absolute path of a file.
Contains the exception interfaces used to signal completion of a scenario, campaign or turn...
bool show(const unsigned auto_close_time=0)
Shows the window.
Definitions for the interface to Wesnoth Markup Language (WML).
static void decode(const std::string &input_file, const std::string &output_file)
std::string diff_left
Files for diffing or patching.
bool preprocess
True if –preprocess was given on the command line.
config get_diff(const config &c) const
A function to get the differences between this object, and 'c', as another config object...
One of the realizations of serialization/validator.hpp abstract validator.
unsigned in
If equal to search_counter, the node is off the list.
Used in parsing config file.
static void warn_early_init_failure()
Print an alert and instructions to stderr about early initialization errors.
bool report
True if –report was given on the command line.
std::optional< std::string > gzip
Non-empty if –gzip was given on the command line.
void read(config &cfg, std::istream &in, abstract_validator *validator)
Class for writing a config out to a file in pieces.
std::string get_user_data_dir()
std::optional< unsigned int > rng_seed
RNG seed specified by –rng-seed option.
std::optional< std::vector< std::pair< int, std::string > > > log
Contains parsed arguments of –log-* (e.g.
std::string get_intl_dir()
static lg::log_domain log_config("config")
bool strict_validation_enabled
void init()
Initializes the GUI subsystems.
const game_config_view & game_config() const
std::optional< std::string > bunzip2
Non-empty if –bunzip2 was given on the command line.
void enable_native_console_output()
Switches to using a native console instead of log file redirection.
bool is_directory(const std::string &fname)
Returns true if the given file is a directory.
std::unique_ptr< std::istream > scoped_istream
std::string build_arch()
Obtain the processor architecture for this build.
void set_default_textdomain(const char *domain)
void refresh_addon_version_info_cache()
Refreshes the per-session cache of add-on's version information structs.
std::string sanitize_path(const std::string &path)
Sanitizes a path to remove references to the user's name.
void apply_diff(const config &diff, bool track=false)
A function to apply a diff config onto this config object.
const char * what() const noexcept
bool userconfig_path
True if –userconfig-path was given on the command line.
static int writer(lua_State *L, const void *b, size_t size, void *ud)
std::optional< std::string > bzip2
Non-empty if –bzip2 was given on the command line.
static void handle_preprocess_command(const commandline_options &cmdline_opts)
bool nobanner
True if –nobanner was given on the command line.
int main(int argc, char **argv)
std::optional< std::string > logdomains
Non-empty if –logdomains was given on the command line.
std::optional< std::string > render_image
Image path to render.
Helper class, don't construct this directly.
static int do_gameloop(const std::vector< std::string > &args)
Setups the game environment and enters the titlescreen or game loops.
std::string dev_message
The message for developers telling which problem was triggered, this shouldn't be translated...
static void gzip_encode(const std::string &input_file, const std::string &output_file)
std::unique_ptr< std::ostream > scoped_ostream
bool is_gzip_file(const std::string &filename)
Returns true if the file ends with '.gz'.
Some defines: VERSION, PACKAGE, MIN_SAVEGAME_VERSION.
static void handle_lua_script_args(game_launcher *game, commandline_options &)
Handles the lua script command line arguments if present.
std::string get_exe_dir()
static void init_locale()
I would prefer to setup locale first so that early error messages can get localized, but we need the game_launcher initialized to have filesystem::get_intl_dir() to work.
Log file control routines for Windows.
void set_user_config_dir(const std::string &newconfigdir)
bool debug_lua
True if –debug-lua was given in the commandline.
std::string get_wml_location(const std::string &filename, const std::string ¤t_dir)
Returns a complete path to the actual WML file or directory or an empty string if the file isn't pres...
Default, unset return value.
const std::string revision
void set_strict_severity(int severity)
static int process_command_args(const commandline_options &cmdline_opts)
Process commandline-arguments.
bool strict_lua
True if –strict-lua was given in the commandline.
std::optional< std::string > gunzip
Non-empty if –gunzip was given on the command line.
An exception object used when an IO error occurs.
structure which will hide all current floating labels, and cause floating labels instantiated after i...
std::optional< std::string > userdata_dir
Non-empty if –userdata-dir was given on the command line.
Declarations for File-IO.
Contains a basic exception class for SDL operations.
const version_info wesnoth_version(VERSION)
static map_location::DIRECTION sw
bool set_log_domain_severity(const std::string &name, int severity)
std::optional< std::string > data_dir
Non-empty if –data-dir was given on the command line.
bool data_path
True if –data-path was given on the command line.
std::vector< std::string > read_argv([[maybe_unused]] int argc, [[maybe_unused]] char **argv)
std::string get_user_config_dir()
bool screenshot
True if –screenshot was given on the command line.
bool is_bzip2_file(const std::string &filename)
Returns true if the file ends with '.bz2'.
int get_retval() const
Returns the cached window exit code.
static void display(std::function< void()> f)
std::vector< aReg > areg_vec
Contains the SDL_Rect helper code.
Base class for all the errors encountered by the engine.
void play_music_config(const config &music_node, bool allow_interrupt_current_track, int i)
std::string list_logdomains(const std::string &filter)
bool version
True if –version was given on the command line.
Standard logging facilities (interface).
std::string str() const
Serializes the version number into string form.
std::optional< std::string > validate_with
Non-empty if –use-schema was given on the command line.
std::optional< std::string > validate_wml
Non-empty if –validate was given on the command line.
bool strict_validation
True if –strict-validation was given on the command line.
std::map< std::string, struct preproc_define > preproc_map
std::optional< std::vector< std::string > > preprocess_defines
Defines that were given to the –preprocess option.
static void encode(const std::string &input_file, const std::string &output_file)
Realization of serialization/validator.hpp abstract validator.
void reload_changed_game_config()
void set_create_exceptions(bool value)
A config object defines a single node in a WML file, with access to child nodes.
filesystem::scoped_istream preprocess_file(const std::string &fname, preproc_map *defines)
Function to use the WML preprocessor on a file.
static preproc_map::value_type read_pair(const config &)
int wesnoth_main(int argc, char **argv)
std::optional< std::string > validate_schema
Non-empty if –validate-schema was given on the command line.
bool init_game_config(FORCE_RELOAD_CONFIG force_reload)
bool help
True if –help was given on the command line.
const config & child(config_key_type key) const
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
std::string full_build_report()
Produce a bug report-style info dump.
std::string wesnoth_program_dir
void precise_timestamps(bool pt)
void set_debug(bool new_debug)
filesystem::scoped_ostream ostream_file(const std::string &fname, bool create_directory)