4 #include <msp/debug/demangle.h>
5 #include <msp/debug/errorreporter.h>
6 #include <msp/fs/dir.h>
7 #include <msp/fs/path.h>
8 #include <msp/fs/utils.h>
9 #include <msp/io/print.h>
10 #include <msp/strings/utils.h>
11 #include "application.h"
19 Application *Application::_app = nullptr;
20 Application::Starter *Application::_starter = nullptr;
21 const char *Application::_argv0 = nullptr;
22 string Application::_name;
23 void *Application::_data = nullptr;
25 Application::Application(const string &n)
28 throw already_called("Application::Application");
33 _name = FS::basename(_argv0);
36 int Application::run(int argc, char **argv, void *data, void (*created_callback)(void *))
40 IO::cerr.write("Application::run called with no RegisteredApplication class!\n");
44 set_startup_info(argv[0], data);
50 _app = _starter->create_app(argc, argv);
52 catch(const usage_error &e)
54 IO::print(IO::cerr, "%s\n%s\n", e.what(), e.help());
59 created_callback(data);
61 int result = _app->main();
62 Application *a = _app;
67 catch(const exception &e)
70 if(const Debug::ErrorReporter *er = Debug::ErrorReporter::get_current())
71 handled = er->report_uncaught_exception(e);
75 IO::print(IO::cerr, "An uncaught exception occurred.\n");
76 IO::print(IO::cerr, " type: %s\n", Debug::demangle(typeid(e).name()));
77 vector<string> lines = split(e.what(), '\n');
79 IO::print(IO::cerr, " what(): %s\n", e.what());
82 IO::print(IO::cerr, " what(): %s\n", lines.front());
83 for(auto i=lines.begin(); ++i!=lines.end(); )
84 IO::print(IO::cerr, " %s\n", *i);
95 void Application::set_startup_info(const char *argv0, void *data)
98 throw already_called("Application::set_startup_info");
102 if(!argv0 || !*argv0)
105 argv0 = "application.exe";
107 argv0 = "./application";
111 bool has_slash = strchr(argv0, FS::DIRSEP);
113 exe = FS::path_lookup(argv0);
115 exe = FS::realpath(argv0);
117 _argv0 = exe.c_str();
121 void *Application::get_data()
126 const char *Application::get_argv0()
131 const std::string &Application::get_name()
136 int Application::main()
145 void Application::catch_signal(int s)
147 signal(s, &_sighandler);
150 void Application::exit(int c)
156 void Application::_sighandler(int s)
162 Application::Starter::Starter()
165 throw already_called("Application::Starter::Starter");