2 * Placed into the Public Domain.
3 * written by Walter Bright
8 * Modified by Sean Kelly for use with the D Runtime Project
23 extern (Windows) void* LocalFree(void*);
24 extern (Windows) wchar_t* GetCommandLineW();
25 extern (Windows) wchar_t** CommandLineToArgvW(wchar_t*, int*);
26 extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
27 pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
30 extern (C) void _STI_monitor_staticctor();
31 extern (C) void _STD_monitor_staticdtor();
32 extern (C) void _STI_critical_init();
33 extern (C) void _STD_critical_term();
34 extern (C) void gc_init();
35 extern (C) void gc_term();
36 extern (C) void _minit();
37 extern (C) void _moduleCtor();
38 extern (C) void _moduleDtor();
39 extern (C) void thread_joinAll();
41 /***********************************
42 * These functions must be defined for any D program linked
43 * against this library.
45 extern (C) void onAssertError( string file, size_t line );
46 extern (C) void onAssertErrorMsg( string file, size_t line, string msg );
47 extern (C) void onArrayBoundsError( string file, size_t line );
48 extern (C) void onSwitchError( string file, size_t line );
49 extern (C) bool runModuleUnitTests();
51 // this function is called from the utf module
52 //extern (C) void onUnicodeError( string msg, size_t idx );
54 /***********************************
55 * These are internal callbacks for various language errors.
57 extern (C) void _d_assert( string file, uint line )
59 onAssertError( file, line );
62 extern (C) static void _d_assert_msg( string msg, string file, uint line )
64 onAssertErrorMsg( file, line, msg );
67 extern (C) void _d_array_bounds( string file, uint line )
69 onArrayBoundsError( file, line );
72 extern (C) void _d_switch_error( string file, uint line )
74 onSwitchError( file, line );
77 extern (C) void _d_hidden_func()
79 // TODO: Figure out what to do with this routine
82 bool _d_isHalting = false;
84 extern (C) bool rt_isHalting()
89 extern (C) bool rt_trapExceptions = true;
91 void _d_criticalInit()
95 _STI_monitor_staticctor();
100 alias void delegate( Exception ) ExceptionHandler;
102 extern (C) bool rt_init( ExceptionHandler dg = null )
127 void _d_criticalTerm()
131 _STD_critical_term();
132 _STD_monitor_staticdtor();
136 extern (C) bool rt_term( ExceptionHandler dg = null )
162 /***********************************
163 * The D main() function supplied by the user's program
165 int main(char[][] args);
167 /***********************************
168 * Substitutes for the C main() function.
169 * It's purpose is to wrap the call to the D main()
170 * function and catch any unhandled exceptions.
173 extern (C) int main(int argc, char **argv)
180 _STI_monitor_staticctor();
181 _STI_critical_init();
186 wchar_t* wcbuf = GetCommandLineW();
187 size_t wclen = wcslen(wcbuf);
189 wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
190 assert(wargc == argc);
193 size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
195 cargp = cast(char*) alloca(cargl);
196 args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
198 for (size_t i = 0, p = 0; i < wargc; i++)
200 int wlen = wcslen( wargs[i] );
201 int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
202 args[i] = cargp[p .. p+clen];
203 p += clen; assert(p <= cargl);
204 WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
212 char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
213 scope(exit) free(am);
215 for (size_t i = 0; i < argc; i++)
217 auto len = strlen(argv[i]);
218 am[i] = argv[i][0 .. len];
220 args = am[0 .. argc];
223 bool trapExceptions = rt_trapExceptions;
225 void tryExec(void delegate() dg)
240 // fprintf(stderr, "%.*s(%u): %.*s\n", e.file, e.line, e.msg);
241 console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.toString)("\n");
245 // fprintf(stderr, "%.*s\n", e.toString());
246 console (e.classinfo.name)(": ")(e.toString)("\n");
250 console ("----------------\n");
258 result = EXIT_FAILURE;
262 // fprintf(stderr, "%.*s\n", o.toString());
263 console (o.toString)("\n");
264 result = EXIT_FAILURE;
273 // NOTE: The lifetime of a process is much like the lifetime of an object:
274 // it is initialized, then used, then destroyed. If initialization
275 // fails, the successive two steps are never reached. However, if
276 // initialization succeeds, then cleanup will occur even if the use
277 // step fails in some way. Here, the use phase consists of running
278 // the user's main function. If main terminates with an exception,
279 // the exception is handled and then cleanup begins. An exception
280 // thrown during cleanup, however, will abort the cleanup process.
293 if (runModuleUnitTests())
305 _STD_critical_term();
306 _STD_monitor_staticdtor();