Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/runtime/internal/dmain2.d

Revision 1125:8208374e5bed, 7.0 kB (checked in by Frits van Bommel <fvbommel wxs.nl>, 3 years ago)

Apply fawzi's patch from #235.
This has some issues which are addressed in my next commit.

Line 
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     import memory;
19 }
20
21 version( Win32 )
22 {
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
28     //pragma(lib, "tango-win32-dmd.lib"); // links Tango's Win32 library to reduce EXE size
29 }
30
31 extern (C) void _STI_monitor_staticctor();
32 extern (C) void _STD_monitor_staticdtor();
33 extern (C) void _STI_critical_init();
34 extern (C) void _STD_critical_term();
35 extern (C) void gc_init();
36 extern (C) void gc_term();
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     _STI_monitor_staticctor();
92     _STI_critical_init();
93     initStaticDataPtrs();
94 }
95
96 alias void delegate( Exception ) ExceptionHandler;
97
98 // this is here so users can manually initialize the runtime
99 // for example, when there is no main function etc.
100 extern (C) bool rt_init( ExceptionHandler dg = null )
101 {
102     _d_criticalInit();
103
104     try
105     {
106         gc_init();
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     _STD_critical_term();
126     _STD_monitor_staticdtor();
127 }
128
129 // this is here so users can manually terminate the runtime
130 // for example, when there is no main function etc.
131 extern (C) bool rt_term( ExceptionHandler dg = null )
132 {
133     try
134     {
135         thread_joinAll();
136         _d_isHalting = true;
137         _moduleDtor();
138         gc_term();
139         return true;
140     }
141     catch( Exception e )
142     {
143         if( dg )
144             dg( e );
145     }
146     catch
147     {
148
149     }
150     finally
151     {
152         _d_criticalTerm();
153     }
154     return false;
155 }
156
157 /***********************************
158  * The D main() function supplied by the user's program
159  */
160 int main(char[][] args);
161
162 /***********************************
163  * Substitutes for the C main() function.
164  * It's purpose is to wrap the call to the D main()
165  * function and catch any unhandled exceptions.
166  */
167
168 extern (C) int main(int argc, char **argv, char** env)
169 {
170     char[][] args;
171     int result;
172
173     debug(PRINTF) printf("main ctors\n");
174     _STI_monitor_staticctor();
175     _STI_critical_init();
176     initStaticDataPtrs();
177
178     debug(PRINTF) printf("main args\n");
179     // GDC seems to get by without this Windows special case...
180     version (Win32)
181     {
182         wchar_t*  wcbuf = GetCommandLineW();
183         size_t    wclen = wcslen(wcbuf);
184         int       wargc = 0;
185         wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc);
186         assert(wargc == argc);
187
188         char*     cargp = null;
189         size_t    cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0);
190
191         cargp = cast(char*) alloca(cargl);
192         args  = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc];
193
194         for (size_t i = 0, p = 0; i < wargc; i++)
195         {
196             int wlen = wcslen( wargs[i] );
197             int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0);
198             args[i]  = cargp[p .. p+clen];
199             p += clen; assert(p <= cargl);
200             WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0);
201         }
202         LocalFree(wargs);
203         wargs = null;
204         wargc = 0;
205     }
206     else
207     {
208         char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof);
209         scope(exit) free(am);
210
211         for (size_t i = 0; i < argc; i++)
212         {
213             auto len = strlen(argv[i]);
214             am[i] = argv[i][0 .. len];
215         }
216         args = am[0 .. argc];
217     }
218
219     debug(PRINTF) printf("main trap exceptions\n");
220     bool trapExceptions = rt_trapExceptions;
221
222     void tryExec(void delegate() dg)
223     {
224         debug(PRINTF) printf("main try exec\n");
225         if (trapExceptions)
226         {
227             try
228             {
229                 dg();
230             }
231             catch (Exception e)
232             {
233                 e.writeOut(delegate void(char[]s){ console(s); });
234                 result = EXIT_FAILURE;
235             }
236             catch (Object o)
237             {
238                 // fprintf(stderr, "%.*s\n", o.toString());
239                 console (o.toString)("\n");
240                 result = EXIT_FAILURE;
241             }
242         }
243         else
244         {
245             dg();
246         }
247     }
248
249     // NOTE: The lifetime of a process is much like the lifetime of an object:
250     //       it is initialized, then used, then destroyed.  If initialization
251     //       fails, the successive two steps are never reached.  However, if
252     //       initialization succeeds, then cleanup will occur even if the use
253     //       step fails in some way.  Here, the use phase consists of running
254     //       the user's main function.  If main terminates with an exception,
255     //       the exception is handled and then cleanup begins.  An exception
256     //       thrown during cleanup, however, will abort the cleanup process.
257
258     void runMain()
259     {
260         debug(PRINTF) printf("main runMain\n");
261         result = main(args);
262     }
263
264     void runAll()
265     {
266         debug(PRINTF) printf("main runAll\n");
267         gc_init();
268         _moduleCtor();
269         if (runModuleUnitTests())
270             tryExec(&runMain);
271         thread_joinAll();
272         _d_isHalting = true;
273         _moduleDtor();
274         gc_term();
275     }
276
277     tryExec(&runAll);
278
279     debug(PRINTF) printf("main dtor\n");
280     _STD_critical_term();
281     _STD_monitor_staticdtor();
282
283     return result;
284 }
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.