Mercurial > projects > ddmd
annotate main.d @ 74:7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Sun, 29 Aug 2010 09:43:40 +0100 |
parents | 6bdecc3f4569 |
children | 43073c7c7769 |
rev | line source |
---|---|
0 | 1 module main; |
2 | |
3 import dmd.Array; | |
4 import dmd.Module; | |
5 import dmd.Global; | |
6 import dmd.VersionCondition; | |
7 import dmd.DebugCondition; | |
8 import dmd.Loc; | |
9 import dmd.Lexer; | |
10 import dmd.OutBuffer; | |
11 import dmd.FileName; | |
12 import dmd.Type; | |
13 import dmd.File; | |
14 import dmd.Id; | |
15 import dmd.Identifier; | |
16 import dmd.Library; | |
17 import dmd.TOK; | |
18 import dmd.String; | |
19 import dmd.backend.glue; | |
20 | |
21 import std.stdarg; | |
22 import std.string : toStringz; | |
34 | 23 import std.exception; |
0 | 24 |
25 import core.stdc.string; | |
26 import core.stdc.stdio; | |
27 import core.stdc.ctype; | |
28 import core.stdc.errno; | |
29 import core.stdc.stdlib; | |
30 import core.stdc.limits; | |
31 | |
32 import core.memory; | |
33 | |
70 | 34 import dbg.CallStackInfo; |
0 | 35 |
36 import dmd.Util; | |
37 | |
38 enum ExitCode | |
39 { | |
40 EXIT_SUCCESS = 0, | |
41 } | |
42 | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
43 version(Linux) |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
44 { |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
45 extern (C) extern __gshared bool rt_trapExceptions; |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
46 |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
47 static this() { |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
48 rt_trapExceptions = false; |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
49 } |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
50 |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
51 } |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
52 |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
53 version(Windows) |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
54 { |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
55 |
70 | 56 version (Windows) |
57 { | |
58 private import core.stdc.wchar_; | |
59 | |
60 extern (Windows) alias int function() FARPROC; | |
61 extern (Windows) FARPROC GetProcAddress(void*, in char*); | |
62 extern (Windows) void* LoadLibraryA(in char*); | |
63 extern (Windows) int FreeLibrary(void*); | |
64 extern (Windows) void* LocalFree(void*); | |
65 extern (Windows) wchar_t* GetCommandLineW(); | |
66 extern (Windows) wchar_t** CommandLineToArgvW(wchar_t*, int*); | |
67 extern (Windows) export int WideCharToMultiByte(uint, uint, wchar_t*, int, char*, int, char*, int); | |
68 pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW | |
69 } | |
70 | |
71 shared bool _d_isHalting = false; | |
72 __gshared string[] _d_args = null; | |
73 | |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
74 version(Posix) |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
75 { |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
76 extern (C) void _STI_monitor_staticctor(); |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
77 extern (C) void _STD_monitor_staticdtor(); |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
78 extern (C) void _STI_critical_init(); |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
79 extern (C) void _STD_critical_term(); |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
80 } |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
81 |
70 | 82 extern (C) void gc_init(); |
83 extern (C) void gc_term(); | |
84 extern (C) void _minit(); | |
85 extern (C) void _moduleCtor(); | |
86 extern (C) void _moduleDtor(); | |
87 extern (C) bool runModuleUnitTests(); | |
88 extern (C) void thread_joinAll(); | |
89 | |
90 import rt.memory; | |
91 | |
92 extern (C) int main(int argc, char** argv) | |
93 { | |
94 char[][] args; | |
95 int result; | |
96 | |
97 version (OSX) | |
98 { /* OSX does not provide a way to get at the top of the | |
99 * stack, except for the magic value 0xC0000000. | |
100 * But as far as the gc is concerned, argv is at the top | |
101 * of the main thread's stack, so save the address of that. | |
102 */ | |
103 __osx_stack_end = cast(void*)&argv; | |
104 } | |
105 | |
106 version (FreeBSD) version (D_InlineAsm_X86) | |
107 { | |
108 /* | |
109 * FreeBSD/i386 sets the FPU precision mode to 53 bit double. | |
110 * Make it 64 bit extended. | |
111 */ | |
112 ushort fpucw; | |
113 asm | |
114 { | |
115 fstsw fpucw; | |
116 or fpucw, 0b11_00_111111; // 11: use 64 bit extended-precision | |
117 // 111111: mask all FP exceptions | |
118 fldcw fpucw; | |
119 } | |
120 } | |
121 | |
122 version (Posix) | |
123 { | |
124 _STI_monitor_staticctor(); | |
125 _STI_critical_init(); | |
126 } | |
0 | 127 |
70 | 128 version (Windows) |
129 { | |
130 wchar_t* wcbuf = GetCommandLineW(); | |
131 size_t wclen = wcslen(wcbuf); | |
132 int wargc = 0; | |
133 wchar_t** wargs = CommandLineToArgvW(wcbuf, &wargc); | |
134 assert(wargc == argc); | |
135 | |
136 char* cargp = null; | |
137 size_t cargl = WideCharToMultiByte(65001, 0, wcbuf, wclen, null, 0, null, 0); | |
138 | |
139 cargp = cast(char*) alloca(cargl); | |
140 args = ((cast(char[]*) alloca(wargc * (char[]).sizeof)))[0 .. wargc]; | |
141 | |
142 for (size_t i = 0, p = 0; i < wargc; i++) | |
143 { | |
144 int wlen = wcslen(wargs[i]); | |
145 int clen = WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, null, 0, null, 0); | |
146 args[i] = cargp[p .. p+clen]; | |
147 p += clen; assert(p <= cargl); | |
148 WideCharToMultiByte(65001, 0, &wargs[i][0], wlen, &args[i][0], clen, null, 0); | |
149 } | |
150 LocalFree(wargs); | |
151 wargs = null; | |
152 wargc = 0; | |
153 } | |
154 else version (Posix) | |
155 { | |
156 char[]* am = cast(char[]*) malloc(argc * (char[]).sizeof); | |
157 scope(exit) free(am); | |
158 | |
159 for (size_t i = 0; i < argc; i++) | |
160 { | |
161 auto len = strlen(argv[i]); | |
162 am[i] = argv[i][0 .. len]; | |
163 } | |
164 args = am[0 .. argc]; | |
165 } | |
166 _d_args = cast(string[]) args; | |
167 | |
168 void runMain() | |
169 { | |
170 result = main(_d_args); | |
171 } | |
172 | |
173 void runAll() | |
174 { | |
175 gc_init(); | |
176 initStaticDataGC(); | |
177 version (Windows) | |
178 _minit(); | |
179 _moduleCtor(); | |
180 _moduleTlsCtor(); | |
181 if (runModuleUnitTests()) | |
182 runMain(); | |
183 else | |
184 result = EXIT_FAILURE; | |
185 _moduleTlsDtor(); | |
186 thread_joinAll(); | |
187 _d_isHalting = true; | |
188 _moduleDtor(); | |
189 gc_term(); | |
190 } | |
191 | |
192 runAll(); | |
193 | |
194 version (Posix) | |
195 { | |
196 _STD_critical_term(); | |
197 _STD_monitor_staticdtor(); | |
198 } | |
199 return result; | |
0 | 200 } |
25 | 201 |
74
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
202 } |
7e0d548de9e6
Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
70
diff
changeset
|
203 |
0 | 204 int main(string[] args) |
205 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
206 GC.disable(); |
34 | 207 CrashHandlerInit(); |
208 | |
0 | 209 Array files = new Array(); |
210 Array libmodules = new Array(); | |
211 Module m; | |
212 int status = ExitCode.EXIT_SUCCESS; | |
213 int argcstart = args.length; | |
214 int setdebuglib = 0; | |
215 | |
216 global = new Global(); | |
217 | |
218 /// if (response_expand(&argc,&argv)) // expand response files | |
219 /// error("can't open response file"); | |
220 | |
221 files.reserve(args.length - 1); | |
222 | |
223 // Set default values | |
224 global.params.argv0 = args[0]; | |
225 global.params.link = 1; | |
226 global.params.useAssert = 1; | |
227 global.params.useInvariants = 1; | |
228 global.params.useIn = 1; | |
229 global.params.useOut = 1; | |
230 global.params.useArrayBounds = 1; | |
231 global.params.useSwitchError = 1; | |
232 global.params.useInline = 0; | |
233 global.params.obj = 1; | |
234 global.params.Dversion = 2; | |
235 global.params.quiet = 1; | |
236 | |
237 global.params.linkswitches = new Array(); | |
238 global.params.libfiles = new Array(); | |
239 global.params.objfiles = new Array(); | |
240 global.params.ddocfiles = new Array(); | |
241 | |
242 version (TARGET_WINDOS) { | |
243 global.params.defaultlibname = "phobos"; | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
4
diff
changeset
|
244 } else version (POSIX) { //#elif TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS |
0 | 245 global.params.defaultlibname = "phobos2"; |
246 } else version (TARGET_NET) { | |
247 } else { | |
248 static assert(false, "fix this"); | |
249 } | |
250 | |
251 // Predefine version identifiers | |
252 VersionCondition.addPredefinedGlobalIdent("DigitalMars"); | |
253 | |
254 version (TARGET_WINDOS) { | |
255 VersionCondition.addPredefinedGlobalIdent("Windows"); | |
256 global.params.isWindows = 1; | |
257 version (TARGET_NET) { | |
258 // TARGET_NET macro is NOT mutually-exclusive with TARGET_WINDOS | |
259 VersionCondition.addPredefinedGlobalIdent("D_NET"); | |
260 } | |
261 } else version (TARGET_LINUX) { | |
262 VersionCondition.addPredefinedGlobalIdent("Posix"); | |
263 VersionCondition.addPredefinedGlobalIdent("linux"); | |
264 global.params.isLinux = 1; | |
265 } else version (TARGET_OSX) { | |
266 VersionCondition.addPredefinedGlobalIdent("Posix"); | |
267 VersionCondition.addPredefinedGlobalIdent("OSX"); | |
268 global.params.isOSX = 1; | |
269 | |
270 // For legacy compatibility | |
271 VersionCondition.addPredefinedGlobalIdent("darwin"); | |
272 } else version (TARGET_FREEBSD) { | |
273 VersionCondition.addPredefinedGlobalIdent("Posix"); | |
274 VersionCondition.addPredefinedGlobalIdent("FreeBSD"); | |
275 global.params.isFreeBSD = 1; | |
276 } else version (TARGET_SOLARIS) { | |
277 VersionCondition.addPredefinedGlobalIdent("Posix"); | |
278 VersionCondition.addPredefinedGlobalIdent("Solaris"); | |
279 global.params.isSolaris = 1; | |
280 } else { | |
281 static assert (false, "fix this"); | |
282 } | |
283 | |
284 VersionCondition.addPredefinedGlobalIdent("LittleEndian"); | |
285 //VersionCondition.addPredefinedGlobalIdent("D_Bits"); | |
286 version (DMDV2) { | |
287 VersionCondition.addPredefinedGlobalIdent("D_Version2"); | |
288 } | |
289 VersionCondition.addPredefinedGlobalIdent("all"); | |
290 | |
291 version (_WIN32) { | |
292 inifile(args[0], "sc.ini"); | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
4
diff
changeset
|
293 } else version (POSIX) {///linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
4
diff
changeset
|
294 inifile(args[0], "dmd.conf"); |
0 | 295 } else { |
296 static assert (false, "fix this"); | |
297 } | |
298 args = getenv_setargv("DFLAGS", args); | |
299 | |
300 version (disabled) { | |
301 for (i = 0; i < argc; i++) | |
302 { | |
303 writef("argv[%d] = '%s'\n", i, argv[i]); | |
304 } | |
305 } | |
306 | |
307 foreach(i; 1..args.length) | |
308 { | |
309 auto arg = args[i]; | |
310 auto p = arg.ptr; | |
311 if (*p == '-') | |
312 { | |
313 arg = arg[1..$]; | |
314 if (arg == "d") | |
315 global.params.useDeprecated = 1; | |
316 else if (arg == "c") | |
317 global.params.link = 0; | |
318 else if (arg == "cov") | |
319 global.params.cov = 1; | |
320 ///version (XXX) {// TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS | |
321 /// else if (arg == "fPIC") | |
322 /// global.params.pic = 1; | |
323 ///} | |
324 else if (arg == "multiobj") | |
325 global.params.multiobj = 1; | |
326 else if (arg == "g") | |
327 global.params.symdebug = 1; | |
328 else if (arg == "gc") | |
329 global.params.symdebug = 2; | |
330 else if (arg == "gt") | |
331 { error("use -profile instead of -gt\n"); | |
332 global.params.trace = 1; | |
333 } | |
334 else if (arg == "m64") | |
335 global.params.isX86_64 = 1; | |
336 else if (arg == "profile") | |
337 global.params.trace = 1; | |
338 else if (arg == "v") | |
339 global.params.verbose = 1; | |
340 ///version (DMDV2) { | |
341 else if (arg == "vtls") | |
342 global.params.vtls = 1; | |
343 ///} | |
344 else if (arg == "v1") | |
345 { | |
346 version (DMDV1) { | |
347 global.params.Dversion = 1; | |
348 } else { | |
349 error("use DMD 1.0 series compilers for -v1 switch"); | |
350 break; | |
351 } | |
352 } | |
353 else if (arg == "w") | |
354 global.params.warnings = 1; | |
355 else if (arg == "O") | |
356 global.params.optimize = 1; | |
357 else if (p[1] == 'o') | |
358 { | |
359 switch (p[2]) | |
360 { | |
361 case '-': | |
362 global.params.obj = 0; | |
363 break; | |
364 | |
365 case 'd': | |
366 if (!p[3]) | |
367 goto Lnoarg; | |
368 global.params.objdir = arg[(p - arg.ptr) + 3..$]; | |
369 break; | |
370 | |
371 case 'f': | |
372 { | |
373 if (!p[3]) | |
374 goto Lnoarg; | |
375 | |
376 global.params.objname = arg[(p - arg.ptr) + 3..$]; | |
377 break; | |
378 } | |
379 | |
380 case 'p': | |
381 if (p[3]) | |
382 goto Lerror; | |
383 global.params.preservePaths = 1; | |
384 break; | |
385 | |
386 case 0: | |
387 error("-o no longer supported, use -of or -od"); | |
388 break; | |
389 | |
390 default: | |
391 goto Lerror; | |
392 } | |
393 } | |
394 else if (p[1] == 'D') | |
395 { global.params.doDocComments = 1; | |
396 switch (p[2]) | |
397 { | |
398 case 'd': | |
399 if (!p[3]) | |
400 goto Lnoarg; | |
401 global.params.docdir = arg[(p - arg.ptr) + 3..$]; | |
402 break; | |
403 case 'f': | |
404 if (!p[3]) | |
405 goto Lnoarg; | |
406 global.params.docname = arg[(p - arg.ptr) + 3..$]; | |
407 break; | |
408 | |
409 case 0: | |
410 break; | |
411 | |
412 default: | |
413 goto Lerror; | |
414 } | |
415 } | |
416 ///version (_DH) { | |
417 else if (p[1] == 'H') | |
418 { global.params.doHdrGeneration = 1; | |
419 switch (p[2]) | |
420 { | |
421 case 'd': | |
422 if (!p[3]) | |
423 goto Lnoarg; | |
424 global.params.hdrdir = arg[(p - arg.ptr) + 3..$]; | |
425 break; | |
426 | |
427 case 'f': | |
428 if (!p[3]) | |
429 goto Lnoarg; | |
430 global.params.hdrname = arg[(p - arg.ptr) + 3..$]; | |
431 break; | |
432 | |
433 case 0: | |
434 break; | |
435 | |
436 default: | |
437 goto Lerror; | |
438 } | |
439 } | |
440 ///} | |
441 else if (arg == "ignore") | |
442 global.params.ignoreUnsupportedPragmas = 1; | |
443 else if (arg == "inline") | |
444 global.params.useInline = 1; | |
445 else if (arg == "lib") | |
446 global.params.lib = 1; | |
447 else if (arg == "nofloat") | |
448 global.params.nofloat = 1; | |
449 else if (arg == "quiet") | |
450 global.params.quiet = 1; | |
451 else if (arg == "release") | |
452 global.params.release = 1; | |
453 ///version (DMDV2) { | |
454 else if (arg == "safe") | |
455 global.params.safe = 1; | |
456 ///} | |
457 else if (arg == "unittest") | |
458 global.params.useUnitTests = 1; | |
459 else if (p[1] == 'I') | |
460 { | |
461 if (!global.params.imppath) | |
462 global.params.imppath = new Array(); | |
463 global.params.imppath.push(cast(void*)new String(arg[(p - arg.ptr) + 2..$])); /// | |
464 } | |
465 else if (p[1] == 'J') | |
466 { | |
467 if (!global.params.fileImppath) | |
468 global.params.fileImppath = new Array(); | |
469 global.params.fileImppath.push(cast(void*)new String(arg[(p - arg.ptr) + 2..$])); | |
470 } | |
471 else if (memcmp(p + 1, "debug".ptr, 5) == 0 && p[6] != 'l') | |
472 { | |
473 // Parse: | |
474 // -debug | |
475 // -debug=number | |
476 // -debug=identifier | |
477 if (p[6] == '=') | |
478 { | |
479 if (isdigit(p[7])) | |
480 { long level; | |
481 | |
482 errno = 0; | |
483 level = strtol(p + 7, cast(char**)&p, 10); | |
484 if (*p || errno || level > INT_MAX) | |
485 goto Lerror; | |
486 DebugCondition.setGlobalLevel(cast(int)level); | |
487 } | |
488 else if (Lexer.isValidIdentifier(arg[(p - arg.ptr) + 7..$])) /// | |
489 DebugCondition.addGlobalIdent(p + 7); | |
490 else | |
491 goto Lerror; | |
492 } | |
493 else if (p[6]) | |
494 goto Lerror; | |
495 else | |
496 global.params.debuglevel = 1; | |
497 } | |
498 else if (memcmp(p + 1, "version".ptr, 5) == 0) | |
499 { | |
500 // Parse: | |
501 // -version=number | |
502 // -version=identifier | |
503 if (p[8] == '=') | |
504 { | |
505 if (isdigit(p[9])) | |
506 { long level; | |
507 | |
508 errno = 0; | |
509 level = strtol(p + 9, cast(char**)&p, 10); /// | |
510 if (*p || errno || level > INT_MAX) | |
511 goto Lerror; | |
512 VersionCondition.setGlobalLevel(cast(int)level); | |
513 } | |
514 else if (Lexer.isValidIdentifier(arg[(p - arg.ptr) + 9..$])) /// | |
515 VersionCondition.addGlobalIdent(arg[(p - arg.ptr) + 9..$]); | |
516 else | |
517 goto Lerror; | |
518 } | |
519 else | |
520 goto Lerror; | |
521 } | |
522 else if (arg == "-b") | |
523 global.params.debugb = 1; | |
524 else if (arg == "-c") | |
525 global.params.debugc = 1; | |
526 else if (arg == "-f") | |
527 global.params.debugf = 1; | |
528 else if (arg == "-help") | |
529 { usage(); | |
530 exit(EXIT_SUCCESS); | |
531 } | |
532 else if (arg == "-r") | |
533 global.params.debugr = 1; | |
534 else if (arg == "-x") | |
535 global.params.debugx = 1; | |
536 else if (arg == "-y") | |
537 global.params.debugy = 1; | |
538 else if (p[1] == 'L') | |
539 { | |
540 global.params.linkswitches.push(cast(void*)p + 2); | |
541 } | |
542 else if (memcmp(p + 1, "defaultlib=".ptr, 11) == 0) | |
543 { | |
544 global.params.defaultlibname = p + 1 + 11; | |
545 } | |
546 else if (memcmp(p + 1, "debuglib=".ptr, 9) == 0) | |
547 { | |
548 setdebuglib = 1; | |
549 global.params.debuglibname = p + 1 + 9; | |
550 } | |
551 else if (memcmp(p + 1, "deps=".ptr, 5) == 0) | |
552 { | |
553 global.params.moduleDepsFile = arg[(p - arg.ptr) + 1 + 5..$]; | |
554 if (!global.params.moduleDepsFile[0]) | |
555 goto Lnoarg; | |
556 global.params.moduleDeps = new OutBuffer; | |
557 } | |
558 else if (memcmp(p + 1, "man".ptr, 3) == 0) | |
559 { | |
560 version (_WIN32) { | |
561 version (DMDV1) { | |
562 browse("http://www.digitalmars.com/d/1.0/dmd-windows.html"); | |
563 } else { | |
564 browse("http://www.digitalmars.com/d/2.0/dmd-windows.html"); | |
565 } | |
566 } | |
567 version (linux) { | |
568 version (DMDV1) { | |
569 browse("http://www.digitalmars.com/d/1.0/dmd-linux.html"); | |
570 } else { | |
571 browse("http://www.digitalmars.com/d/2.0/dmd-linux.html"); | |
572 } | |
573 } | |
574 version (__APPLE__) { | |
575 version (DMDV1) { | |
576 browse("http://www.digitalmars.com/d/1.0/dmd-osx.html"); | |
577 } else { | |
578 browse("http://www.digitalmars.com/d/2.0/dmd-osx.html"); | |
579 } | |
580 } | |
581 version (__FreeBSD__) { | |
582 version (DMDV1) { | |
583 browse("http://www.digitalmars.com/d/1.0/dmd-freebsd.html"); | |
584 } else { | |
585 browse("http://www.digitalmars.com/d/2.0/dmd-freebsd.html"); | |
586 } | |
587 } | |
588 exit(EXIT_SUCCESS); | |
589 } | |
590 else if (arg == "run") | |
591 { global.params.run = 1; | |
592 global.params.runargs_length = ((i >= argcstart) ? args.length : argcstart) - i - 1; | |
593 if (global.params.runargs_length) | |
594 { | |
595 files.push(cast(void*)args[i + 1].ptr); | |
596 global.params.runargs = args[i + 2..$]; | |
597 i += global.params.runargs_length; | |
598 global.params.runargs_length--; | |
599 } | |
600 else | |
601 { global.params.run = 0; | |
602 goto Lnoarg; | |
603 } | |
604 } | |
605 else | |
606 { | |
607 Lerror: | |
608 error("unrecognized switch '%s'", args[i]); | |
609 continue; | |
610 | |
611 Lnoarg: | |
612 error("argument expected for switch '%s'", args[i]); | |
613 continue; | |
614 } | |
615 } | |
616 else | |
617 { | |
618 version (TARGET_WINDOS) { | |
619 string ext = FileName.ext(p[0..arg.length]); | |
620 if (ext != null && FileName.compare(ext, "exe") == 0) | |
621 { | |
622 global.params.objname = arg[(p - arg.ptr)..$]; | |
623 continue; | |
624 } | |
625 } | |
626 files.push(cast(void*)new String(arg[(p - arg.ptr)..$])); | |
627 } | |
628 } | |
629 if (global.errors) | |
630 { | |
631 fatal(); | |
632 } | |
633 if (files.dim == 0) | |
634 { usage(); | |
635 return EXIT_FAILURE; | |
636 } | |
637 | |
638 if (!setdebuglib) | |
639 global.params.debuglibname = global.params.defaultlibname; | |
640 | |
641 version (TARGET_OSX) { | |
642 global.params.pic = 1; | |
643 } | |
644 | |
645 if (global.params.release) | |
646 { global.params.useInvariants = 0; | |
647 global.params.useIn = 0; | |
648 global.params.useOut = 0; | |
649 global.params.useAssert = 0; | |
650 global.params.useArrayBounds = 0; | |
651 global.params.useSwitchError = 0; | |
652 } | |
653 | |
654 if (global.params.run) | |
655 global.params.quiet = 1; | |
656 | |
657 if (global.params.useUnitTests) | |
658 global.params.useAssert = 1; | |
659 | |
660 if (!global.params.obj || global.params.lib) | |
661 global.params.link = 0; | |
662 | |
663 if (global.params.link) | |
664 { | |
665 global.params.exefile = global.params.objname; | |
666 global.params.oneobj = 1; | |
667 if (global.params.objname) | |
668 { | |
669 /* Use this to name the one object file with the same | |
670 * name as the exe file. | |
671 */ | |
672 global.params.objname = FileName.forceExt(global.params.objname, global.obj_ext).toChars(); | |
673 | |
674 /* If output directory is given, use that path rather than | |
675 * the exe file path. | |
676 */ | |
677 if (global.params.objdir) | |
678 { | |
679 string name = FileName.name(global.params.objname); | |
680 global.params.objname = FileName.combine(global.params.objdir, name); | |
681 } | |
682 } | |
683 } | |
684 else if (global.params.lib) | |
685 { | |
686 global.params.libname = global.params.objname; | |
687 global.params.objname = null; | |
688 | |
689 // Haven't investigated handling these options with multiobj | |
690 if (!global.params.cov && !global.params.trace) | |
691 global.params.multiobj = 1; | |
692 } | |
693 else if (global.params.run) | |
694 { | |
695 error("flags conflict with -run"); | |
696 fatal(); | |
697 } | |
698 else | |
699 { | |
700 if (global.params.objname && files.dim > 1) | |
701 { | |
702 global.params.oneobj = 1; | |
703 //error("multiple source files, but only one .obj name"); | |
704 //fatal(); | |
705 } | |
706 } | |
707 if (global.params.isX86_64) | |
708 { | |
709 VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86_64"); | |
710 VersionCondition.addPredefinedGlobalIdent("X86_64"); | |
711 VersionCondition.addPredefinedGlobalIdent("D_LP64"); | |
712 version (TARGET_WINDOS) { | |
713 VersionCondition.addPredefinedGlobalIdent("Win64"); | |
714 } | |
715 } | |
716 else | |
717 { | |
718 VersionCondition.addPredefinedGlobalIdent("D_InlineAsm"); | |
719 VersionCondition.addPredefinedGlobalIdent("D_InlineAsm_X86"); | |
720 VersionCondition.addPredefinedGlobalIdent("X86"); | |
721 version (TARGET_WINDOS) { | |
722 VersionCondition.addPredefinedGlobalIdent("Win32"); | |
723 } | |
724 } | |
725 if (global.params.doDocComments) | |
726 VersionCondition.addPredefinedGlobalIdent("D_Ddoc"); | |
727 if (global.params.cov) | |
728 VersionCondition.addPredefinedGlobalIdent("D_Coverage"); | |
729 if (global.params.pic) | |
730 VersionCondition.addPredefinedGlobalIdent("D_PIC"); | |
731 version (DMDV2) { | |
732 if (global.params.useUnitTests) | |
733 VersionCondition.addPredefinedGlobalIdent("unittest"); | |
734 } | |
735 | |
736 // Initialization | |
737 Type.init(); | |
738 Id.initialize(); | |
739 Module.init(); | |
740 initPrecedence(); | |
741 | |
742 backend_init(); | |
743 | |
744 //printf("%d source files\n",files.dim); | |
745 | |
746 // Build import search path | |
747 if (global.params.imppath) | |
748 { | |
749 for (int i = 0; i < global.params.imppath.dim; i++) | |
750 { | |
751 string path = (cast(String)global.params.imppath.data[i]).str; | |
752 string[] a = FileName.splitPath(path); | |
753 | |
754 global.path ~= a; | |
755 } | |
756 } | |
757 | |
758 // Build string import search path | |
759 if (global.params.fileImppath) | |
760 { | |
761 for (int i = 0; i < global.params.fileImppath.dim; i++) | |
762 { | |
763 string path = (cast(String)global.params.fileImppath.data[i]).str; | |
764 string[] a = FileName.splitPath(path); | |
765 | |
766 global.filePath ~= a; | |
767 } | |
768 } | |
769 | |
770 // Create Modules | |
771 Array modules = new Array(); | |
772 modules.reserve(files.dim); | |
773 int firstmodule = 1; | |
774 for (int i = 0; i < files.dim; i++) | |
775 { | |
776 string ext; | |
777 string name; | |
778 | |
779 String s = cast(String) files.data[i]; | |
780 string mp = s.str; | |
781 | |
782 version (_WIN32) { | |
783 char[] copy = null; | |
784 // Convert / to \ so linker will work | |
785 foreach (j, c; mp) | |
786 { | |
787 if (c == '/') { | |
788 if (copy is null) copy = mp.dup; | |
789 copy[j] = '\\'; | |
790 } | |
791 } | |
792 | |
793 if (copy !is null) mp = assumeUnique(copy); | |
794 } | |
795 string p = mp; | |
796 | |
797 p = FileName.name(p); // strip path | |
798 ext = FileName.ext(p); | |
799 | |
800 if (ext.length != 0) | |
801 { /* Deduce what to do with a file based on its extension | |
802 */ | |
803 if (FileName.equals(ext, global.obj_ext)) | |
804 { | |
805 global.params.objfiles.push(files.data[i]); | |
806 libmodules.push(files.data[i]); | |
807 continue; | |
808 } | |
809 | |
810 if (FileName.equals(ext, global.lib_ext)) | |
811 { | |
812 global.params.libfiles.push(files.data[i]); | |
813 libmodules.push(files.data[i]); | |
814 continue; | |
815 } | |
816 | |
817 if (ext == global.ddoc_ext) | |
818 { | |
819 global.params.ddocfiles.push(files.data[i]); | |
820 continue; | |
821 } | |
822 | |
823 version (TARGET_WINDOS) { | |
824 if (FileName.equals(ext, "res")) | |
825 { | |
826 global.params.resfile = (cast(immutable(char)*)files.data[i])[0..0]; /// !!! | |
827 continue; | |
828 } | |
829 | |
830 if (FileName.equals(ext, "def")) | |
831 { | |
832 global.params.deffile = (cast(immutable(char)*)files.data[i])[0..0]; | |
833 continue; | |
834 } | |
835 | |
836 if (FileName.equals(ext, "exe")) | |
837 { | |
838 assert(0); // should have already been handled | |
839 } | |
840 } | |
841 | |
842 /* Examine extension to see if it is a valid | |
843 * D source file extension | |
844 */ | |
845 if (FileName.equals(ext, global.mars_ext) || | |
846 FileName.equals(ext, global.hdr_ext) || | |
847 FileName.equals(ext, "dd") || | |
848 FileName.equals(ext, "htm") || | |
849 FileName.equals(ext, "html") || | |
850 FileName.equals(ext, "xhtml")) | |
851 { | |
852 immutable(char)* e = ext.ptr; | |
853 e--; // skip onto '.' | |
854 assert(*e == '.'); | |
855 | |
856 immutable(char)* n = p.ptr; | |
857 | |
858 name = n[0..(e-n)]; // strip extension | |
859 | |
860 if (name.length == 0 || name == ".." || name == ".") | |
861 { | |
862 Linvalid: | |
863 error("invalid file name '%s'", (cast(String)files.data[i]).str); | |
864 fatal(); | |
865 } | |
866 } | |
867 else | |
868 { error("unrecognized file extension %s\n", ext); | |
869 fatal(); | |
870 } | |
871 } | |
872 else | |
873 { | |
874 name = p; | |
875 if (!*name) | |
876 goto Linvalid; | |
877 } | |
878 | |
879 /* At this point, name is the D source file name stripped of | |
880 * its path and extension. | |
881 */ | |
882 | |
883 Identifier id = new Identifier(name, TOK.TOKreserved); | |
884 m = new Module((cast(String) files.data[i]).str, id, global.params.doDocComments, global.params.doHdrGeneration); | |
885 modules.push(cast(void*)m); | |
886 | |
887 if (firstmodule) | |
888 { | |
889 global.params.objfiles.push(cast(void*)m.objfile.name); | |
890 firstmodule = 0; | |
891 } | |
892 } | |
893 | |
894 // Read files | |
895 //version = ASYNCREAD; | |
896 version (ASYNCREAD) { | |
897 // Multi threaded | |
898 AsyncRead *aw = AsyncRead.create(modules.dim); | |
899 for (i = 0; i < modules.dim; i++) | |
900 { | |
901 m = cast(Module *)modules.data[i]; | |
902 aw.addFile(m.srcfile); | |
903 } | |
904 aw.start(); | |
905 } else { | |
906 // Single threaded | |
907 for (int i = 0; i < modules.dim; i++) | |
908 { | |
909 m = cast(Module)modules.data[i]; | |
910 m.read(Loc(0)); | |
911 } | |
912 } | |
913 | |
914 // Parse files | |
915 int anydocfiles = 0; | |
916 for (int i = 0; i < modules.dim; i++) | |
917 { | |
918 m = cast(Module)modules.data[i]; | |
919 if (global.params.verbose) | |
920 writef("parse %s\n", m.toChars()); | |
921 if (!Module.rootModule) | |
922 Module.rootModule = m; | |
923 m.importedFrom = m; | |
924 if (!global.params.oneobj || i == 0 || m.isDocFile) | |
925 m.deleteObjFile(); | |
926 version (ASYNCREAD) { | |
927 if (aw.read(i)) | |
928 { | |
929 error("cannot read file %s", m.srcfile.name.toChars()); | |
930 } | |
931 } | |
932 | |
933 //while (loop) {} | |
934 m.parse(); | |
935 if (m.isDocFile) | |
936 { | |
937 anydocfiles = 1; | |
938 m.gendocfile(); | |
939 | |
940 // Remove m from list of modules | |
941 modules.remove(i); | |
942 i--; | |
943 | |
944 // Remove m's object file from list of object files | |
945 for (int j = 0; j < global.params.objfiles.dim; j++) | |
946 { | |
947 if (m.objfile.name.str == (cast(FileName)global.params.objfiles.data[j]).str) | |
948 { | |
949 global.params.objfiles.remove(j); | |
950 break; | |
951 } | |
952 } | |
953 | |
954 if (global.params.objfiles.dim == 0) | |
955 global.params.link = 0; | |
956 } | |
957 } | |
958 version (ASYNCREAD) { | |
959 AsyncRead.dispose(aw); | |
960 } | |
961 | |
962 if (anydocfiles && modules.dim && | |
963 (global.params.oneobj || global.params.objname)) | |
964 { | |
965 error("conflicting Ddoc and obj generation options"); | |
966 fatal(); | |
967 } | |
968 if (global.errors) | |
969 fatal(); | |
970 version (_DH) { | |
971 if (global.params.doHdrGeneration) | |
972 { | |
973 /* Generate 'header' import files. | |
974 * Since 'header' import files must be independent of command | |
975 * line switches and what else is imported, they are generated | |
976 * before any semantic analysis. | |
977 */ | |
978 for (i = 0; i < modules.dim; i++) | |
979 { | |
980 m = cast(Module *)modules.data[i]; | |
981 if (global.params.verbose) | |
982 writef("import %s\n", m.toChars()); | |
983 m.genhdrfile(); | |
984 } | |
985 } | |
986 if (global.errors) | |
987 fatal(); | |
988 } | |
989 | |
990 // Do semantic analysis | |
991 for (int i = 0; i < modules.dim; i++) | |
992 { | |
993 m = cast(Module)modules.data[i]; | |
994 if (global.params.verbose) | |
995 writef("semantic %s\n", m.toChars()); | |
996 m.semantic(); | |
997 } | |
998 if (global.errors) | |
999 fatal(); | |
1000 | |
1001 // Do pass 2 semantic analysis | |
1002 for (int i = 0; i < modules.dim; i++) | |
1003 { | |
1004 m = cast(Module)modules.data[i]; | |
1005 if (global.params.verbose) | |
1006 writef("semantic2 %s\n", m.toChars()); | |
1007 m.semantic2(); | |
1008 } | |
1009 if (global.errors) | |
1010 fatal(); | |
1011 | |
1012 // Do pass 3 semantic analysis | |
1013 for (int i = 0; i < modules.dim; i++) | |
1014 { | |
1015 m = cast(Module)modules.data[i]; | |
1016 if (global.params.verbose) | |
1017 writef("semantic3 %s\n", m.toChars()); | |
1018 m.semantic3(); | |
1019 } | |
1020 if (global.errors) | |
1021 fatal(); | |
1022 | |
1023 if (global.params.moduleDeps !is null) | |
1024 { | |
1025 assert(global.params.moduleDepsFile !is null); | |
1026 | |
1027 File deps = new File(global.params.moduleDepsFile); | |
1028 OutBuffer ob = global.params.moduleDeps; | |
1029 deps.setbuffer(cast(void*)ob.data, ob.offset); | |
1030 deps.writev(); | |
1031 } | |
1032 | |
1033 | |
1034 // Scan for functions to inline | |
1035 if (global.params.useInline) | |
1036 { | |
1037 /* The problem with useArrayBounds and useAssert is that the | |
1038 * module being linked to may not have generated them, so if | |
1039 * we inline functions from those modules, the symbols for them will | |
1040 * not be found at link time. | |
1041 */ | |
1042 if (!global.params.useArrayBounds && !global.params.useAssert) | |
1043 { | |
1044 // Do pass 3 semantic analysis on all imported modules, | |
1045 // since otherwise functions in them cannot be inlined | |
1046 for (int i = 0; i < Module.amodules.dim; i++) | |
1047 { | |
1048 m = cast(Module)Module.amodules.data[i]; | |
1049 if (global.params.verbose) | |
1050 writef("semantic3 %s\n", m.toChars()); | |
1051 m.semantic3(); | |
1052 } | |
1053 if (global.errors) | |
1054 fatal(); | |
1055 } | |
1056 | |
1057 for (int i = 0; i < modules.dim; i++) | |
1058 { | |
1059 m = cast(Module)modules.data[i]; | |
1060 if (global.params.verbose) | |
1061 writef("inline scan %s\n", m.toChars()); | |
1062 | |
1063 m.inlineScan(); | |
1064 } | |
1065 } | |
1066 if (global.errors) | |
1067 fatal(); | |
1068 | |
1069 Library library = null; | |
1070 if (global.params.lib) | |
1071 { | |
1072 library = new Library(); | |
1073 library.setFilename(global.params.objdir, global.params.libname); | |
1074 | |
1075 // Add input object and input library files to output library | |
1076 for (int i = 0; i < libmodules.dim; i++) | |
1077 { | |
1078 string p = (cast(String)libmodules.data[i]).str; | |
1079 library.addObject(p, null, 0); | |
1080 } | |
1081 } | |
1082 | |
1083 // Generate output files | |
1084 if (global.params.oneobj) | |
1085 { | |
1086 for (int i = 0; i < modules.dim; i++) | |
1087 { | |
1088 m = cast(Module)modules.data[i]; | |
1089 if (global.params.verbose) | |
1090 writef("code %s\n", m.toChars()); | |
1091 if (i == 0) | |
1092 obj_start(cast(char*)toStringz(m.srcfile.toChars())); | |
1093 m.genobjfile(0); | |
1094 if (!global.errors && global.params.doDocComments) | |
1095 m.gendocfile(); | |
1096 } | |
1097 if (!global.errors && modules.dim) | |
1098 { | |
1099 obj_end(library, (cast(Module)modules.data[0]).objfile); | |
1100 } | |
1101 } | |
1102 else | |
1103 { | |
1104 for (int i = 0; i < modules.dim; i++) | |
1105 { | |
1106 m = cast(Module)modules.data[i]; | |
1107 if (global.params.verbose) | |
1108 writef("code %s\n", m.toChars()); | |
1109 if (global.params.obj) | |
1110 { | |
1111 obj_start(cast(char*)toStringz(m.srcfile.toChars())); | |
1112 m.genobjfile(global.params.multiobj); | |
1113 obj_end(library, m.objfile); | |
1114 obj_write_deferred(library); | |
1115 } | |
1116 if (global.errors) | |
1117 { | |
1118 if (!global.params.lib) | |
1119 m.deleteObjFile(); | |
1120 } | |
1121 else | |
1122 { | |
1123 if (global.params.doDocComments) | |
1124 m.gendocfile(); | |
1125 } | |
1126 } | |
1127 } | |
1128 | |
1129 if (global.params.lib && !global.errors) | |
1130 library.write(); | |
1131 | |
1132 backend_term(); | |
1133 if (global.errors) | |
1134 fatal(); | |
1135 | |
1136 if (!global.params.objfiles.dim) | |
1137 { | |
1138 if (global.params.link) | |
1139 error("no object files to link"); | |
1140 } | |
1141 else | |
1142 { | |
1143 if (global.params.link) | |
1144 status = runLINK(); | |
1145 | |
1146 if (global.params.run) | |
1147 { | |
1148 if (!status) | |
1149 { | |
1150 status = runProgram(); | |
1151 | |
1152 /* Delete .obj files and .exe file | |
1153 */ | |
1154 for (int i = 0; i < modules.dim; i++) | |
1155 { | |
1156 m = cast(Module)modules.data[i]; | |
1157 m.deleteObjFile(); | |
1158 if (global.params.oneobj) | |
1159 break; | |
1160 } | |
1161 deleteExeFile(); | |
1162 } | |
1163 } | |
1164 } | |
1165 | |
1166 return status; | |
14
2cc604139636
Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents:
4
diff
changeset
|
1167 } |