Mercurial > projects > ldc
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 } |