comparison tango/lib/compiler/llvmdc/dmain2.d @ 133:44a95ac7368a trunk

[svn r137] Many fixes towards tango.io.Console working, but not quite there yet... In particular, assertions has been fixed to include file/line info, and much more!
author lindquist
date Mon, 14 Jan 2008 05:11:54 +0100
parents
children 56a1c1c52142
comparison
equal deleted inserted replaced
132:1700239cab2e 133:44a95ac7368a
1 /*
2 * Placed into the Public Domain.
3 * written by Walter Bright
4 * www.digitalmars.com
5 */
6
7 /*
8 * Modified by Sean Kelly <sean@f4.ca> for use with Tango.
9 */
10
11 private
12 {
13 import util.console;
14
15 import tango.stdc.stddef;
16 import tango.stdc.stdlib;
17 import tango.stdc.string;
18 }
19
20 version( Win32 )
21 {
22 extern (Windows) void* LocalFree(void*);
23 extern (Windows) wchar_t* GetCommandLineW();
24 extern (Windows) wchar_t** CommandLineToArgvW(wchar_t*, int*);
25 extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int);
26 pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
27 pragma(lib, "tango-win32-dmd.lib"); // links Tango's Win32 library to reduce EXE size
28 }
29
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();
40
41 //debug=PRINTF;
42 debug(PRINTF) extern (C) int printf(char*, ...);
43
44 /***********************************
45 * These functions must be defined for any D program linked
46 * against this library.
47 */
48 extern (C) void onAssertError( char[] file, size_t line );
49 extern (C) void onAssertErrorMsg( char[] file, size_t line, char[] msg );
50 extern (C) void onArrayBoundsError( char[] file, size_t line );
51 extern (C) void onSwitchError( char[] file, size_t line );
52 extern (C) bool runModuleUnitTests();
53
54 // this function is called from the utf module
55 //extern (C) void onUnicodeError( char[] msg, size_t idx );
56
57 /***********************************
58 * These are internal callbacks for various language errors.
59 */
60 extern (C) void _d_assert( char[] file, uint line )
61 {
62 onAssertError( file, line );
63 }
64
65 extern (C) void _d_assert_msg( char[] msg, char[] file, uint line )
66 {
67 onAssertErrorMsg( file, line, msg );
68 }
69
70 extern (C) void _d_array_bounds( char[] file, uint line )
71 {
72 onArrayBoundsError( file, line );
73 }
74
75 extern (C) void _d_switch_error( char[] file, uint line )
76 {
77 onSwitchError( file, line );
78 }
79
80 bool _d_isHalting = false;
81
82 extern (C) bool rt_isHalting()
83 {
84 return _d_isHalting;
85 }
86
87 extern (C) bool rt_trapExceptions = true;
88
89 void _d_criticalInit()
90 {
91 version (linux)
92 {
93 _STI_monitor_staticctor();
94 _STI_critical_init();
95 }
96 }
97
98 extern (C) bool rt_init( void delegate( Exception ) dg = null )
99 {
100 _d_criticalInit();
101
102 try
103 {
104 gc_init();
105 version (Win32)
106 _minit();
107 _moduleCtor();
108 return true;
109 }
110 catch( Exception e )
111 {
112 if( dg )
113 dg( e );
114 }
115 catch
116 {
117
118 }
119 _d_criticalTerm();
120 return false;
121 }
122
123 void _d_criticalTerm()
124 {
125 version (linux)
126 {
127 _STD_critical_term();
128 _STD_monitor_staticdtor();
129 }
130 }
131
132 extern (C) bool rt_term( void delegate( Exception ) dg = null )
133 {
134 try
135 {
136 thread_joinAll();
137 _d_isHalting = true;
138 _moduleDtor();
139 gc_term();
140 return true;
141 }
142 catch( Exception e )
143 {
144 if( dg )
145 dg( e );
146 }
147 catch
148 {
149
150 }
151 finally
152 {
153 _d_criticalTerm();
154 }
155 return false;
156 }
157
158 /***********************************
159 * The D main() function supplied by the user's program
160 */
161 int main(char[][] args);
162
163 /***********************************
164 * Substitutes for the C main() function.
165 * It's purpose is to wrap the call to the D main()
166 * function and catch any unhandled exceptions.
167 */
168
169 extern (C) int main(int argc, char **argv, char** env)
170 {
171 char[][] args;
172 int result;
173
174 version (linux)
175 {
176 debug(PRINTF) printf("main ctors\n");
177 _STI_monitor_staticctor();
178 _STI_critical_init();
179 }
180
181 debug(PRINTF) printf("main args\n");
182 version (Win32)
183 {
184 wchar_t* wcbuf = GetCommandLineW();
185 size_t wclen = wcslen(wcbuf);
186 int wargc = 0;
187 wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
188 assert(wargc == argc);
189
190 char* cargp = null;
191 size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
192
193 cargp = cast(char*) alloca(cargl);
194 args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
195
196 for (size_t i = 0, p = 0; i < wargc; i++)
197 {
198 int wlen = wcslen( wargs[i] );
199 int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
200 args[i] = cargp[p .. p+clen];
201 p += clen; assert(p <= cargl);
202 WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
203 }
204 LocalFree(wargs);
205 wargs = null;
206 wargc = 0;
207 }
208 else version (linux)
209 {
210 char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
211 scope(exit) free(am);
212
213 for (size_t i = 0; i < argc; i++)
214 {
215 auto len = strlen(argv[i]);
216 am[i] = argv[i][0 .. len];
217 }
218 args = am[0 .. argc];
219 }
220
221 debug(PRINTF) printf("main trap exceptions\n");
222 bool trapExceptions = rt_trapExceptions;
223
224 void tryExec(void delegate() dg)
225 {
226 debug(PRINTF) printf("main try exec\n");
227 if (trapExceptions)
228 {
229 try
230 {
231 dg();
232 }
233 catch (Exception e)
234 {
235 while (e)
236 {
237 if (e.file)
238 {
239 debug(PRINTF) printf("%.*s(%u): %.*s\n", e.file.length, e.file.ptr, e.line, e.msg.length, e.msg.ptr);
240 console (e.classinfo.name)("@")(e.file)("(")(e.line)("): ")(e.msg)("\n");
241 }
242 else
243 {
244 // debug(PRINTF) printf("%.*s\n", e.toString());
245 console (e.classinfo.name)(": ")(e.toString)("\n");
246 }
247 e = e.next;
248 }
249 result = EXIT_FAILURE;
250 }
251 catch (Object o)
252 {
253 // fprintf(stderr, "%.*s\n", o.toString());
254 console (o.toString)("\n");
255 result = EXIT_FAILURE;
256 }
257 }
258 else
259 {
260 dg();
261 }
262 }
263
264 // NOTE: The lifetime of a process is much like the lifetime of an object:
265 // it is initialized, then used, then destroyed. If initialization
266 // fails, the successive two steps are never reached. However, if
267 // initialization succeeds, then cleanup will occur even if the use
268 // step fails in some way. Here, the use phase consists of running
269 // the user's main function. If main terminates with an exception,
270 // the exception is handled and then cleanup begins. An exception
271 // thrown during cleanup, however, will abort the cleanup process.
272
273 void runMain()
274 {
275 debug(PRINTF) printf("main runMain\n");
276 result = main(args);
277 }
278
279 void runAll()
280 {
281 debug(PRINTF) printf("main runAll\n");
282 gc_init();
283 version (Win32)
284 _minit();
285 _moduleCtor();
286 if (runModuleUnitTests())
287 tryExec(&runMain);
288 thread_joinAll();
289 _d_isHalting = true;
290 _moduleDtor();
291 gc_term();
292 }
293
294 tryExec(&runAll);
295
296 version (linux)
297 {
298 debug(PRINTF) printf("main dtor\n");
299 _STD_critical_term();
300 _STD_monitor_staticdtor();
301 }
302 return result;
303 }