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"
18 Application *Application::app_ = 0;
19 Application::Starter *Application::starter_ = 0;
20 const char *Application::argv0_ = 0;
21 string Application::name_;
22 void *Application::data_ = 0;
24 Application::Application(const string &n)
27 throw logic_error("instance already exists");
32 name_ = FS::basename(argv0_);
35 int Application::run(int argc, char **argv, void *data, void (*created_callback)(void *))
39 IO::cerr.write("Application::run called with no RegisteredApplication class!\n");
43 set_startup_info(argv[0], data);
49 app_ = starter_->create_app(argc, argv);
51 catch(const usage_error &e)
53 IO::print(IO::cerr, "%s\n%s\n", e.what(), e.help());
58 created_callback(data);
60 int result = app_->main();
61 Application *a = app_;
66 catch(const exception &e)
69 if(const Debug::ErrorReporter *er = Debug::ErrorReporter::get_current())
70 handled = er->report_uncaught_exception(e);
74 IO::print(IO::cerr, "An uncaught exception occurred.\n");
75 IO::print(IO::cerr, " type: %s\n", Debug::demangle(typeid(e).name()));
76 vector<string> lines = split(e.what(), '\n');
78 IO::print(IO::cerr, " what(): %s\n", e.what());
81 IO::print(IO::cerr, " what(): %s\n", lines.front());
82 for(auto i=lines.begin(); ++i!=lines.end(); )
83 IO::print(IO::cerr, " %s\n", *i);
94 void Application::set_startup_info(const char *argv0, void *data)
97 throw logic_error("startup info already set");
101 if(!argv0 || !*argv0)
104 argv0 = "application.exe";
106 argv0 = "./application";
110 bool has_slash = strchr(argv0, FS::DIRSEP);
112 exe = FS::path_lookup(argv0);
114 exe = FS::realpath(argv0);
116 argv0_ = exe.c_str();
120 int Application::main()
129 void Application::catch_signal(int s)
131 signal(s, &sighandler_);
134 void Application::exit(int c)
140 void Application::sighandler_(int s)
146 Application::Starter::Starter()
149 throw logic_error("Can't create more than one Starter instance");