diff --git a/bench/harness.cpp b/bench/harness.cpp index 1f625c6..4180558 100644 --- a/bench/harness.cpp +++ b/bench/harness.cpp @@ -41,7 +41,7 @@ static bool RunBenchmark(std::function setupFn, } int main(int argc, char **argv) { - std::vector args = InitPlatform(argc, argv); + std::vector args = Platform::InitCli(argc, argv); std::string mode; Platform::Path filename; diff --git a/src/lib.cpp b/src/lib.cpp index c16206b..d1d54ff 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -11,8 +11,6 @@ Sketch SolveSpace::SK = {}; static System SYS; -static int IsInit = 0; - void SolveSpace::Platform::FatalError(const std::string &message) { fprintf(stderr, "%s", message.c_str()); abort(); @@ -69,10 +67,8 @@ void Slvs_MakeQuaternion(double ux, double uy, double uz, void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg) { - if(!IsInit) { - InitPlatform(0, NULL); - IsInit = 1; - } + // Create the temporary heap, if this is the first time we're solving. + FreeAllTemporary(); int i; for(i = 0; i < ssys->params; i++) { diff --git a/src/platform/entrycli.cpp b/src/platform/entrycli.cpp index c9efbf1..95d60a9 100644 --- a/src/platform/entrycli.cpp +++ b/src/platform/entrycli.cpp @@ -351,7 +351,7 @@ static bool RunCommand(const std::vector args) { } int main(int argc, char **argv) { - std::vector args = InitPlatform(argc, argv); + std::vector args = Platform::InitCli(argc, argv); if(args.size() == 1) { ShowUsage(args[0]); diff --git a/src/platform/entrygui.cpp b/src/platform/entrygui.cpp index 654d25e..30fd443 100644 --- a/src/platform/entrygui.cpp +++ b/src/platform/entrygui.cpp @@ -11,9 +11,8 @@ using namespace SolveSpace; int main(int argc, char** argv) { - std::vector args = InitPlatform(argc, argv); + std::vector args = Platform::InitGui(argc, argv); - Platform::InitGui(argc, argv); Platform::Open3DConnexion(); SS.Init(); diff --git a/src/platform/gui.h b/src/platform/gui.h index c5d082c..85a2abd 100644 --- a/src/platform/gui.h +++ b/src/platform/gui.h @@ -377,7 +377,7 @@ FileDialogRef CreateSaveFileDialog(WindowRef parentWindow); std::vector GetFontFiles(); void OpenInBrowser(const std::string &url); -void InitGui(int argc, char **argv); +std::vector InitGui(int argc, char **argv); void RunGui(); void ExitGui(); void ClearGui(); diff --git a/src/platform/guigtk.cpp b/src/platform/guigtk.cpp index 73fb01e..e68fd30 100644 --- a/src/platform/guigtk.cpp +++ b/src/platform/guigtk.cpp @@ -1432,7 +1432,7 @@ void OpenInBrowser(const std::string &url) { Gtk::Main *gtkMain; -void InitGui(int argc, char **argv) { +std::vector InitGui(int argc, char **argv) { // It would in principle be possible to judiciously use Glib::filename_{from,to}_utf8, // but it's not really worth the effort. // The setlocale() call is necessary for Glib::get_charset() to detect the system @@ -1445,8 +1445,12 @@ void InitGui(int argc, char **argv) { } setlocale(LC_ALL, "C"); + // Let GTK parse arguments and update argc/argv. (They're passed by reference.) gtkMain = new Gtk::Main(argc, argv, /*set_locale=*/false); + // Now that GTK arguments are removed, grab arguments for ourselves. + std::vector args = InitCli(argc, argv); + // Add our application-specific styles, to override GTK defaults. Glib::RefPtr style_provider = Gtk::CssProvider::create(); style_provider->load_from_data(R"( @@ -1468,6 +1472,8 @@ void InitGui(int argc, char **argv) { if(!*langNames) { SetLocale("en_US"); } + + return args; } void RunGui() { diff --git a/src/platform/guimac.mm b/src/platform/guimac.mm index cb939cf..47d67e0 100644 --- a/src/platform/guimac.mm +++ b/src/platform/guimac.mm @@ -1441,7 +1441,9 @@ namespace Platform { static SSApplicationDelegate *ssDelegate; -void InitGui(int argc, char **argv) { +std::vector InitGui(int argc, char **argv) { + std::vector args = InitCli(argc, argv); + ssDelegate = [[SSApplicationDelegate alloc] init]; NSApplication.sharedApplication.delegate = ssDelegate; @@ -1454,6 +1456,8 @@ void InitGui(int argc, char **argv) { if(languages.count == 0) { SolveSpace::SetLocale("en_US"); } + + return args; } void RunGui() { diff --git a/src/platform/guinone.cpp b/src/platform/guinone.cpp index 85beae3..ef3c6f3 100644 --- a/src/platform/guinone.cpp +++ b/src/platform/guinone.cpp @@ -148,7 +148,9 @@ std::vector GetFontFiles() { void OpenInBrowser(const std::string &url) {} -void InitGui(int argc, char **argv) {} +std::vector InitGui(int argc, char **argv) { + return {}; +} void RunGui() {} diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index 70160bb..8e40efc 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -1656,7 +1656,9 @@ void OpenInBrowser(const std::string &url) { ShellExecuteW(NULL, L"open", Widen(url).c_str(), NULL, NULL, SW_SHOWNORMAL); } -void InitGui(int argc, char **argv) { +std::vector InitGui(int argc, char **argv) { + std::vector args = InitCli(argc, argv); + INITCOMMONCONTROLSEX icc; icc.dwSize = sizeof(icc); icc.dwICC = ICC_STANDARD_CLASSES|ICC_BAR_CLASSES; @@ -1665,6 +1667,8 @@ void InitGui(int argc, char **argv) { if(!SetLocale((uint16_t)GetUserDefaultLCID())) { SetLocale("en_US"); } + + return args; } void RunGui() { diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp index e2382d4..9f8ff83 100644 --- a/src/platform/platform.cpp +++ b/src/platform/platform.cpp @@ -14,6 +14,7 @@ #if defined(WIN32) // Conversely, include Microsoft headers after solvespace.h to avoid clashes. # include +# include #else # include # include @@ -452,7 +453,7 @@ bool WriteFile(const Platform::Path &filename, const std::string &data) { } //----------------------------------------------------------------------------- -// Loading resources, on Windows +// Loading resources, on Windows. //----------------------------------------------------------------------------- #if defined(WIN32) @@ -470,7 +471,7 @@ const void *LoadResource(const std::string &name, size_t *size) { #endif //----------------------------------------------------------------------------- -// Loading resources, on *nix +// Loading resources, on *nix. //----------------------------------------------------------------------------- #if defined(__APPLE__) @@ -588,8 +589,49 @@ const void *LoadResource(const std::string &name, size_t *size) { #endif //----------------------------------------------------------------------------- -// Command-line argument handling +// Startup and command-line argument handling, on Windows. //----------------------------------------------------------------------------- +#if defined(WIN32) + +std::vector InitCli(int argc, char **argv) { +#if defined(_MSC_VER) + // We display our own message on abort; just call ReportFault. + _set_abort_behavior(_CALL_REPORTFAULT, _WRITE_ABORT_MSG|_CALL_REPORTFAULT); + int crtReportTypes[] = {_CRT_WARN, _CRT_ERROR, _CRT_ASSERT}; + for(int crtReportType : crtReportTypes) { + _CrtSetReportMode(crtReportType, _CRTDBG_MODE_FILE|_CRTDBG_MODE_DEBUG); + _CrtSetReportFile(crtReportType, _CRTDBG_FILE_STDERR); + } +#endif + + // Create the heap that we use to store Exprs and other temp stuff. + FreeAllTemporary(); + + // Extract the command-line arguments; the ones from main() are ignored, + // since they are in the OEM encoding. + int argcW; + LPWSTR *argvW = CommandLineToArgvW(GetCommandLineW(), &argcW); + std::vector args; + for(int i = 0; i < argcW; i++) + args.push_back(Platform::Narrow(argvW[i])); + LocalFree(argvW); + return args; +} + +#endif + +//----------------------------------------------------------------------------- +// Startup and command-line argument handling, on *nix. +//----------------------------------------------------------------------------- + +#if !defined(WIN32) + +std::vector InitCli(int argc, char **argv) { + return {&argv[0], &argv[argc]}; +} + +#endif + } } diff --git a/src/platform/platform.h b/src/platform/platform.h index 011dfcc..de3f985 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -64,6 +64,9 @@ void RemoveFile(const Platform::Path &filename); // Resource loading function. const void *LoadResource(const std::string &name, size_t *size); +// Startup and command-line argument handling. +std::vector InitCli(int argc, char **argv); + } #endif diff --git a/src/platform/utilunix.cpp b/src/platform/utilunix.cpp index 9a48426..fb38331 100644 --- a/src/platform/utilunix.cpp +++ b/src/platform/utilunix.cpp @@ -4,11 +4,7 @@ // Copyright 2008-2013 Jonathan Westhues. // Copyright 2013 Daniel Richard G. //----------------------------------------------------------------------------- -#include "config.h" #include "solvespace.h" -#if defined(HAVE_BACKTRACE) -# include BACKTRACE_HEADER -#endif namespace SolveSpace { @@ -61,13 +57,4 @@ void FreeAllTemporary() { Head = NULL; } -std::vector InitPlatform(int argc, char **argv) { - std::vector args; - args.reserve(argc); - for(int i = 0; i < argc; i++) { - args.emplace_back(argv[i]); - } - return args; -} - }; diff --git a/src/platform/utilwin.cpp b/src/platform/utilwin.cpp index b3a7b52..87a2fb0 100644 --- a/src/platform/utilwin.cpp +++ b/src/platform/utilwin.cpp @@ -7,10 +7,8 @@ // Include after solvespace.h to avoid identifier clashes. #include -#include namespace SolveSpace { -static HANDLE TempHeap; void dbp(const char *str, ...) { @@ -38,6 +36,8 @@ void dbp(const char *str, ...) // to be sloppy with our memory management, and just free everything at once // at the end. //----------------------------------------------------------------------------- +static HANDLE TempHeap; + void *AllocTemporary(size_t n) { void *v = HeapAlloc(TempHeap, HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, n); @@ -50,30 +50,4 @@ void FreeAllTemporary() TempHeap = HeapCreate(HEAP_NO_SERIALIZE, 1024*1024*20, 0); } -std::vector InitPlatform(int argc, char **argv) { -#if !defined(LIBRARY) && defined(_MSC_VER) - // We display our own message on abort; just call ReportFault. - _set_abort_behavior(_CALL_REPORTFAULT, _WRITE_ABORT_MSG|_CALL_REPORTFAULT); - int crtReportTypes[] = {_CRT_WARN, _CRT_ERROR, _CRT_ASSERT}; - for(int crtReportType : crtReportTypes) { - _CrtSetReportMode(crtReportType, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - _CrtSetReportFile(crtReportType, _CRTDBG_FILE_STDERR); - } -#endif - - // Create the heap that we use to store Exprs and other temp stuff. - FreeAllTemporary(); - - // Extract the command-line arguments; the ones from main() are ignored, - // since they are in the OEM encoding. - int argcW; - LPWSTR *argvW = CommandLineToArgvW(GetCommandLineW(), &argcW); - std::vector args; - for(int i = 0; i < argcW; i++) { - args.push_back(Platform::Narrow(argvW[i])); - } - LocalFree(argvW); - return args; -} - } diff --git a/src/solvespace.h b/src/solvespace.h index f0e6c0f..2227fa7 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -146,8 +146,6 @@ void dbp(const char *str, ...); dbp("tri: (%.3f %.3f %.3f) (%.3f %.3f %.3f) (%.3f %.3f %.3f)", \ CO((tri).a), CO((tri).b), CO((tri).c)) -std::vector InitPlatform(int argc, char **argv); - void *AllocTemporary(size_t n); void FreeAllTemporary(); diff --git a/test/debugtool.cpp b/test/debugtool.cpp index 546a79c..aa66c1f 100644 --- a/test/debugtool.cpp +++ b/test/debugtool.cpp @@ -6,7 +6,7 @@ #include "solvespace.h" int main(int argc, char **argv) { - std::vector args = InitPlatform(argc, argv); + std::vector args = Platform::InitCli(argc, argv); if(args.size() == 3 && args[1] == "expr") { std::string expr = args[2], err; diff --git a/test/harness.cpp b/test/harness.cpp index df7ada6..2eee037 100644 --- a/test/harness.cpp +++ b/test/harness.cpp @@ -335,7 +335,7 @@ int Test::Case::Register(Test::Case testCase) { } int main(int argc, char **argv) { - std::vector args = InitPlatform(argc, argv); + std::vector args = Platform::InitCli(argc, argv); std::regex filter(".*"); if(args.size() == 1) {