Mercurial > projects > ddmd
annotate dmd/Util.d @ 123:9e39c7de8438
Make dmd test suite compile
author | korDen |
---|---|
date | Fri, 03 Sep 2010 20:46:58 +0400 |
parents | e28b18c23469 |
children | 010eb8f0e18d |
rev | line source |
---|---|
0 | 1 module dmd.Util; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.Loc; |
5 import dmd.Library; | |
6 import dmd.File; | |
7 import dmd.String; | |
8 import dmd.OutBuffer; | |
9 import dmd.FileName; | |
10 import dmd.Global; | |
11 import dmd.PREC; | |
12 import dmd.TOK; | |
13 | |
14 import std.process : getenv; | |
15 import std.c.string; | |
16 import std.stdio : writef, writefln, write; | |
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:
2
diff
changeset
|
17 version (Windows) |
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:
2
diff
changeset
|
18 { |
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:
2
diff
changeset
|
19 import std.c.process : spawnl, spawnlp; |
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:
2
diff
changeset
|
20 } |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
21 version (POSIX) |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
22 { |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
23 import core.sys.posix.unistd; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
24 } |
0 | 25 import core.stdc.stdlib; |
26 import core.stdc.ctype; | |
27 import core.stdc.stdarg; | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
28 public import core.stdc.stdio; |
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:
2
diff
changeset
|
29 version (Bug4054) import core.memory; |
0 | 30 |
31 extern(C) int putenv(char*); | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
32 /+version (LOG) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
33 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
34 static if( !is(typeof(printf)) ) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
35 extern (C) int printf(const char*,...); |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
36 }+/ |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
37 //version = LOG; |
0 | 38 |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
39 version (TARGET_OSX) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
40 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
41 version = TARGET_FOS; // FreeBSD, OS X, Solaris |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
42 } |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
43 version (TARGET_FREEBSD) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
44 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
45 version = TARGET_FOS; // FreeBSD, OS X, Solaris |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
46 } |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
47 version (TARGET_SOLARIS) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
48 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
49 version = TARGET_FOS; // FreeBSD, OS X, Solaris |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
50 } |
0 | 51 |
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:
2
diff
changeset
|
52 version (POSIX) |
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:
2
diff
changeset
|
53 { |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
54 import dmd.Array; |
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:
2
diff
changeset
|
55 import dmd.Gnuc; |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
56 import core.sys.posix.stdlib; |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
57 version (TARGET_FOS) import core.stdc.limits; |
0 | 58 } |
59 | |
60 enum MAX_PATH = 256; /// | |
61 | |
62 version (Windows) { | |
63 import core.sys.windows.windows : GetModuleFileNameA; | |
64 } | |
65 | |
66 string fromStringz(const(char)* s) | |
67 { | |
68 return s[0..strlen(s)].idup; | |
69 } | |
70 | |
71 void warning(T...)(string format, T t) | |
72 { | |
73 assert(false); | |
74 } | |
75 | |
76 void warning(T...)(Loc loc, string format, T t) | |
77 { | |
123 | 78 if (global.params.warnings && !global.gag) |
79 { | |
80 write("warning - "); | |
81 error(loc, format, t); | |
82 } | |
0 | 83 } |
84 | |
85 void error(T...)(Loc loc, string format, T t) | |
86 { | |
87 if (!global.gag) | |
88 { | |
89 string p = loc.toChars(); | |
90 | |
91 if (p.length != 0) | |
92 writef("%s: ", p); | |
93 | |
94 write("Error: "); | |
95 writefln(format, t); | |
96 | |
97 //halt(); | |
98 } | |
99 global.errors++; | |
100 } | |
101 | |
102 char* strupr(char* s) | |
103 { | |
104 char* t = s; | |
105 | |
106 while (*s) | |
107 { | |
108 *s = cast(char)toupper(*s); | |
109 s++; | |
110 } | |
111 | |
112 return t; | |
113 } | |
114 | |
115 char[] skipspace(char[] p) | |
116 { | |
117 foreach (i, c; p) { | |
118 if (!isspace(c)) { | |
119 return p[i..$]; | |
120 } | |
121 } | |
122 | |
123 return null; | |
124 } | |
125 | |
126 char* skipspace(char* p) | |
127 { | |
128 while (isspace(*p)) | |
129 p++; | |
130 | |
131 return p; | |
132 } | |
133 | |
134 void inifile(string argv0, string inifile) | |
135 { | |
136 char *path; // need path for @P macro | |
137 string filename; | |
138 int i; | |
139 int k; | |
140 int envsection = 0; | |
141 | |
142 version (LOG) { | |
143 writef("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile); | |
144 } | |
145 if (FileName.absolute(inifile)) { | |
146 filename = inifile; | |
147 } else { | |
148 /* Look for inifile in the following sequence of places: | |
149 * o current directory | |
150 * o home directory | |
151 * o directory off of argv0 | |
152 * o /etc/ | |
153 */ | |
154 if (FileName.exists(inifile)) { | |
155 filename = inifile; | |
156 } else { | |
157 filename = FileName.combine(getenv("HOME"), inifile); | |
158 if (!FileName.exists(filename)) { | |
159 version (_WIN32) { // This fix by Tim Matthews | |
160 char resolved_name_b[MAX_PATH + 1]; | |
161 auto resolved_name = resolved_name_b[].idup; | |
162 if (GetModuleFileNameA(null, resolved_name_b.ptr, MAX_PATH + 1) && FileName.exists(resolved_name)) | |
163 { | |
164 filename = FileName.replaceName(resolved_name, inifile); | |
165 if (FileName.exists(filename)) { | |
166 goto Ldone; | |
167 } | |
168 } | |
169 } | |
170 filename = FileName.replaceName(argv0, inifile); | |
171 if (!FileName.exists(filename)) { | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
172 version (POSIX) { /// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
173 version (POSIX) { /// __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne |
0 | 174 /* argv0 might be a symbolic link, |
175 * so try again looking past it to the real path | |
176 */ | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
177 version (TARGET_FOS) {/// #if __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
0 | 178 char resolved_name[PATH_MAX + 1]; |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
179 char* real_argv0 = realpath(toStringz(argv0), resolved_name); |
0 | 180 } else { |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
181 char* real_argv0 = realpath(toStringz(argv0), null); |
0 | 182 } |
183 //printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0); | |
184 if (real_argv0) { | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
185 filename = FileName.replaceName(fromStringz(real_argv0), inifile); |
0 | 186 version (linux) { |
2 | 187 ///free(real_argv0); |
0 | 188 } |
189 if (FileName.exists(filename)) { | |
190 goto Ldone; | |
191 } | |
192 } | |
193 } else { | |
194 static assert (false, "use of glibc non-standard extension realpath(char*, null)"); | |
195 } | |
196 if (true) { | |
197 // Search PATH for argv0 | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
198 const(char)* p = toStringz(getenv("PATH")); |
0 | 199 version (LOG) { |
200 writef("\tPATH='%s'\n", p); | |
201 } | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
202 auto paths = FileName.splitPath(fromStringz(p)); |
0 | 203 filename = FileName.searchPath(paths, argv0, 0); |
204 if (!filename) { | |
205 goto Letc; // argv0 not found on path | |
206 } | |
207 | |
208 filename = FileName.replaceName(filename, inifile); | |
209 if (FileName.exists(filename)) { | |
210 goto Ldone; | |
211 } | |
212 } | |
213 } | |
214 // Search /etc/ for inifile | |
215 Letc: | |
216 filename = FileName.combine("/etc/", inifile); | |
217 | |
218 Ldone: | |
219 ; | |
220 } | |
221 } | |
222 } | |
223 } | |
224 | |
225 path = cast(char*)toStringz(FileName.path(filename)); | |
226 | |
227 version (LOG) { | |
228 writef("\tpath = '%s', filename = '%s'\n", fromStringz(path), filename); | |
229 } | |
230 | |
231 scope File file = new File(filename); | |
232 | |
233 if (file.read()) { | |
234 return; // error reading file | |
235 } | |
236 | |
237 scope OutBuffer buf = new OutBuffer(); | |
238 | |
239 // Parse into lines | |
240 int eof = 0; | |
241 for (i = 0; i < file.len && !eof; i++) | |
242 { | |
243 int linestart = i; | |
244 | |
245 for (; i < file.len; i++) | |
246 { | |
247 switch (file.buffer[i]) | |
248 { | |
249 case '\r': | |
250 break; | |
251 | |
252 case '\n': | |
253 // Skip if it was preceded by '\r' | |
254 if (i && file.buffer[i - 1] == '\r') | |
255 goto Lskip; | |
256 break; | |
257 | |
258 case 0: | |
259 case 0x1A: | |
260 eof = 1; | |
261 break; | |
262 | |
263 default: | |
264 continue; | |
265 } | |
266 break; | |
267 } | |
268 | |
269 // The line is file.buffer[linestart..i] | |
270 char *line; | |
271 int len; | |
272 char *p; | |
273 char* pn; | |
274 | |
275 line = cast(char*)&file.buffer[linestart]; | |
276 len = i - linestart; | |
277 | |
278 buf.reset(); | |
279 | |
280 // First, expand the macros. | |
281 // Macros are bracketed by % characters. | |
282 | |
283 for (k = 0; k < len; k++) | |
284 { | |
285 if (line[k] == '%') | |
286 { | |
287 int j; | |
288 | |
289 for (j = k + 1; j < len; j++) | |
290 { | |
291 if (line[j] == '%') | |
292 { | |
293 if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0) | |
294 { | |
295 // %@P% is special meaning the path to the .ini file | |
296 p = path; | |
297 if (!*p) | |
298 p = cast(char*)"."; | |
299 } | |
300 else | |
301 { | |
302 int l = j - k; | |
303 char tmp[10]; // big enough most of the time | |
304 | |
305 if (l <= tmp.sizeof) | |
306 p = tmp.ptr; | |
307 else | |
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:
2
diff
changeset
|
308 { |
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:
2
diff
changeset
|
309 version (Bug4054) |
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:
2
diff
changeset
|
310 p = cast(char*)GC.malloc(l); |
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:
2
diff
changeset
|
311 else |
0 | 312 p = cast(char*)alloca(l); |
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:
2
diff
changeset
|
313 } |
0 | 314 l--; |
315 memcpy(p, &line[k + 1], l); | |
316 p[l] = 0; | |
317 strupr(p); | |
318 p = core.stdc.stdlib.getenv(p); | |
319 if (!p) | |
320 p = cast(char*)""; | |
321 } | |
322 buf.writestring(p[0..strlen(p)]); /// | |
323 k = j; | |
324 goto L1; | |
325 } | |
326 } | |
327 } | |
328 buf.writeByte(line[k]); | |
329 L1: | |
330 ; | |
331 } | |
332 | |
333 // Remove trailing spaces | |
334 while (buf.offset && isspace(buf.data[buf.offset - 1])) | |
335 buf.offset--; | |
336 | |
337 char[] pp = buf.getString(); | |
338 | |
339 // The expanded line is in p. | |
340 // Now parse it for meaning. | |
341 | |
342 pp = skipspace(pp); | |
343 if (pp.length != 0) { | |
344 switch (pp[0]) | |
345 { | |
346 case ';': // comment | |
347 break; | |
348 | |
349 case '[': // look for [Environment] | |
350 pp = skipspace(pp[1..$]); | |
351 for (pn = pp.ptr; isalnum(*pn); pn++) { | |
352 ; | |
353 } | |
354 | |
355 if (pn - pp.ptr == 11 && | |
356 memicmp(pp.ptr, "Environment", 11) == 0 && | |
357 *skipspace(pn) == ']' | |
358 ) | |
359 envsection = 1; | |
360 else | |
361 envsection = 0; | |
362 break; | |
363 | |
364 default: | |
365 if (envsection) | |
366 { | |
367 pn = pp.ptr; | |
368 | |
369 // Convert name to upper case; | |
370 // remove spaces bracketing = | |
371 auto p2 = pn; | |
372 for ( ; *p2; p2++) | |
373 { if (islower(*p2)) | |
374 *p2 &= ~0x20; | |
375 else if (isspace(*p)) | |
376 memmove(p2, p2 + 1, strlen(p2)); | |
377 else if (*p2 == '=') | |
378 { | |
379 p2++; | |
380 while (isspace(*p2)) | |
381 memmove(p2, p2 + 1, strlen(p2)); | |
382 break; | |
383 } | |
384 } | |
385 | |
386 //putenv(pn); | |
387 putenv(cast(char*)toStringz(pp)); | |
388 | |
389 version (LOG) { | |
390 writef("\tputenv('%s')\n", pn[0..strlen(pn)]); | |
391 //printf("getenv(\"TEST\") = '%s'\n",getenv("TEST")); | |
392 } | |
393 } | |
394 break; | |
395 } | |
396 } | |
397 | |
398 Lskip: | |
399 ; | |
400 } | |
401 } | |
402 | |
403 ///int response_expand(int *pargc, char ***pargv); | |
404 void browse(const(char)* url) | |
405 { | |
406 assert(false); | |
407 } | |
408 | |
409 string[] getenv_setargv(string envvar, string[] args) | |
410 { | |
411 char *p; | |
412 | |
413 string[] argv = args.dup; | |
414 int argc = args.length; | |
415 | |
416 int instring; | |
417 int slash; | |
418 char c; | |
419 | |
420 string ienv = getenv(envvar); | |
421 if (ienv is null) | |
422 return args; | |
423 | |
424 char[] env = ienv.dup; // create our own writable copy | |
425 | |
79 | 426 int j = 1; // leave argv[0] alone |
0 | 427 char* e = env.ptr; |
428 while (1) | |
429 { | |
79 | 430 int wildcard = 1; // do wildcard expansion |
0 | 431 switch (*e) |
432 { | |
433 case ' ': | |
434 case '\t': | |
435 e++; | |
436 break; | |
437 | |
438 case 0: | |
439 goto Ldone; | |
440 | |
441 case '"': | |
442 wildcard = 0; | |
443 default: | |
444 argv ~= assumeUnique(e[0..strlen(e)]); // append | |
445 //argv.insert(j, env); // insert at position j | |
446 j++; | |
447 argc++; | |
448 p = e; | |
449 slash = 0; | |
450 instring = 0; | |
451 c = 0; | |
452 | |
453 char* ecopy = e; | |
454 | |
455 while (1) | |
456 { | |
457 c = *e++; | |
458 switch (c) | |
459 { | |
460 case '"': | |
461 p -= (slash >> 1); | |
462 if (slash & 1) | |
463 { | |
464 p--; | |
465 goto Laddc; | |
466 } | |
467 instring ^= 1; | |
468 slash = 0; | |
469 continue; | |
470 | |
471 case '\\': | |
472 slash++; | |
473 *p++ = c; | |
474 continue; | |
475 | |
476 case ' ': | |
477 case '\t': | |
478 if (instring) | |
479 goto Laddc; | |
480 case 0: | |
481 *p = 0; | |
482 if (argv.length != 0) { | |
483 argv[$-1].length = p - argv[$-1].ptr; | |
484 } | |
485 //if (wildcard) | |
486 //wildcardexpand(); // not implemented | |
487 if (c == 0) goto Ldone; | |
488 break; | |
489 | |
490 default: | |
491 Laddc: | |
492 slash = 0; | |
493 *p++ = c; | |
494 continue; | |
495 } | |
496 break; | |
497 } | |
498 } | |
499 } | |
500 | |
501 Ldone: | |
502 return argv; | |
503 } | |
504 | |
505 void error(T...)(string format, T t) | |
506 { | |
507 writefln(format, t); | |
508 exit(EXIT_FAILURE); | |
509 } | |
510 | |
511 void usage() | |
512 { | |
513 writef("Digital Mars D Compiler %s\n%s %s\n", global.version_, global.copyright, global.written); | |
514 writef( | |
515 "Documentation: http://www.digitalmars.com/d/2.0/index.html\n" | |
516 "Usage:\n" | |
75
cfa3747ebe4c
Changed dmd to ddmd in the "usage" message and added "ported to D by community" to desription to distinguish from pure dmd build
korDen
parents:
22
diff
changeset
|
517 " ddmd files.d ... { -switch }\n" |
0 | 518 "\n" |
519 " files.d D source files\n" | |
520 " @cmdfile read arguments from cmdfile\n" | |
521 " -c do not link\n" | |
522 " -cov do code coverage analysis\n" | |
523 " -D generate documentation\n" | |
524 " -Dddocdir write documentation file to docdir directory\n" | |
525 " -Dffilename write documentation file to filename\n" | |
526 " -d allow deprecated features\n" | |
527 " -debug compile in debug code\n" | |
528 " -debug=level compile in debug code <= level\n" | |
529 " -debug=ident compile in debug code identified by ident\n" | |
530 " -debuglib=name set symbolic debug library to name\n" | |
531 " -defaultlib=name set default library to name\n" | |
532 " -deps=filename write module dependencies to filename\n" | |
533 " -g add symbolic debug info\n" | |
534 " -gc add symbolic debug info, pretend to be C\n" | |
535 " -H generate 'header' file\n" | |
79 | 536 " -Hddirectory write 'header' file to directory\n" |
0 | 537 " -Hffilename write 'header' file to filename\n" |
538 " --help print help\n" | |
539 " -Ipath where to look for imports\n" | |
540 " -ignore ignore unsupported pragmas\n" | |
541 " -inline do function inlining\n" | |
542 " -Jpath where to look for string imports\n" | |
543 " -Llinkerflag pass linkerflag to link\n" | |
544 " -lib generate library rather than object files\n" | |
545 " -man open web browser on manual page\n" | |
546 " -nofloat do not emit reference to floating point\n" | |
547 " -O optimize\n" | |
548 " -o- do not write object file\n" | |
549 " -odobjdir write object & library files to directory objdir\n" | |
550 " -offilename name output file to filename\n" | |
551 " -op do not strip paths from source file\n" | |
552 " -profile profile runtime performance of generated code\n" | |
553 " -quiet suppress unnecessary messages\n" | |
554 " -release compile release version\n" | |
555 " -run srcfile args... run resulting program, passing args\n" | |
556 " -safe safe memory model\n" | |
557 " -unittest compile in unit tests\n" | |
558 " -v verbose\n" | |
559 " -version=level compile in version code >= level\n" | |
560 " -version=ident compile in version code identified by ident\n" | |
561 " -vtls list all variables going into thread local storage\n" | |
562 " -w enable warnings\n" | |
79 | 563 " -X generate JSON file\n" |
564 " -Xffilename write JSON file to filename\n" | |
0 | 565 ); |
566 } | |
567 | |
568 void fatal() | |
569 { | |
570 static if (false) { | |
571 halt(); | |
572 } else { | |
573 exit(EXIT_FAILURE); | |
574 } | |
575 } | |
576 | |
577 void halt() | |
578 { | |
579 assert(false); | |
580 } | |
581 | |
582 void initPrecedence() | |
583 { | |
584 precedence[TOK.TOKdotvar] = PREC.PREC_primary; | |
585 precedence[TOK.TOKimport] = PREC.PREC_primary; | |
586 precedence[TOK.TOKidentifier] = PREC.PREC_primary; | |
587 precedence[TOK.TOKthis] = PREC.PREC_primary; | |
588 precedence[TOK.TOKsuper] = PREC.PREC_primary; | |
589 precedence[TOK.TOKint64] = PREC.PREC_primary; | |
590 precedence[TOK.TOKfloat64] = PREC.PREC_primary; | |
591 precedence[TOK.TOKnull] = PREC.PREC_primary; | |
592 precedence[TOK.TOKstring] = PREC.PREC_primary; | |
593 precedence[TOK.TOKarrayliteral] = PREC.PREC_primary; | |
594 precedence[TOK.TOKtypeid] = PREC.PREC_primary; | |
595 precedence[TOK.TOKis] = PREC.PREC_primary; | |
596 precedence[TOK.TOKassert] = PREC.PREC_primary; | |
597 precedence[TOK.TOKfunction] = PREC.PREC_primary; | |
598 precedence[TOK.TOKvar] = PREC.PREC_primary; | |
599 version (DMDV2) { | |
600 precedence[TOK.TOKdefault] = PREC.PREC_primary; | |
601 } | |
602 | |
603 // post | |
604 precedence[TOK.TOKdotti] = PREC.PREC_primary; | |
605 precedence[TOK.TOKdot] = PREC.PREC_primary; | |
606 // precedence[TOK.TOKarrow] = PREC.PREC_primary; | |
607 precedence[TOK.TOKplusplus] = PREC.PREC_primary; | |
608 precedence[TOK.TOKminusminus] = PREC.PREC_primary; | |
609 precedence[TOK.TOKcall] = PREC.PREC_primary; | |
610 precedence[TOK.TOKslice] = PREC.PREC_primary; | |
611 precedence[TOK.TOKarray] = PREC.PREC_primary; | |
612 | |
613 precedence[TOK.TOKaddress] = PREC.PREC_unary; | |
614 precedence[TOK.TOKstar] = PREC.PREC_unary; | |
615 precedence[TOK.TOKneg] = PREC.PREC_unary; | |
616 precedence[TOK.TOKuadd] = PREC.PREC_unary; | |
617 precedence[TOK.TOKnot] = PREC.PREC_unary; | |
618 precedence[TOK.TOKtobool] = PREC.PREC_add; | |
619 precedence[TOK.TOKtilde] = PREC.PREC_unary; | |
620 precedence[TOK.TOKdelete] = PREC.PREC_unary; | |
621 precedence[TOK.TOKnew] = PREC.PREC_unary; | |
622 precedence[TOK.TOKcast] = PREC.PREC_unary; | |
623 | |
624 precedence[TOK.TOKmul] = PREC.PREC_mul; | |
625 precedence[TOK.TOKdiv] = PREC.PREC_mul; | |
626 precedence[TOK.TOKmod] = PREC.PREC_mul; | |
627 | |
628 precedence[TOK.TOKadd] = PREC.PREC_add; | |
629 precedence[TOK.TOKmin] = PREC.PREC_add; | |
630 precedence[TOK.TOKcat] = PREC.PREC_add; | |
631 | |
632 precedence[TOK.TOKshl] = PREC.PREC_shift; | |
633 precedence[TOK.TOKshr] = PREC.PREC_shift; | |
634 precedence[TOK.TOKushr] = PREC.PREC_shift; | |
635 | |
636 precedence[TOK.TOKlt] = PREC.PREC_rel; | |
637 precedence[TOK.TOKle] = PREC.PREC_rel; | |
638 precedence[TOK.TOKgt] = PREC.PREC_rel; | |
639 precedence[TOK.TOKge] = PREC.PREC_rel; | |
640 precedence[TOK.TOKunord] = PREC.PREC_rel; | |
641 precedence[TOK.TOKlg] = PREC.PREC_rel; | |
642 precedence[TOK.TOKleg] = PREC.PREC_rel; | |
643 precedence[TOK.TOKule] = PREC.PREC_rel; | |
644 precedence[TOK.TOKul] = PREC.PREC_rel; | |
645 precedence[TOK.TOKuge] = PREC.PREC_rel; | |
646 precedence[TOK.TOKug] = PREC.PREC_rel; | |
647 precedence[TOK.TOKue] = PREC.PREC_rel; | |
648 precedence[TOK.TOKin] = PREC.PREC_rel; | |
649 | |
650 static if (false) { | |
651 precedence[TOK.TOKequal] = PREC.PREC_equal; | |
652 precedence[TOK.TOKnotequal] = PREC.PREC_equal; | |
653 precedence[TOK.TOKidentity] = PREC.PREC_equal; | |
654 precedence[TOK.TOKnotidentity] = PREC.PREC_equal; | |
655 } else { | |
656 /* Note that we changed precedence, so that < and != have the same | |
657 * precedence. This change is in the parser, too. | |
658 */ | |
659 precedence[TOK.TOKequal] = PREC.PREC_rel; | |
660 precedence[TOK.TOKnotequal] = PREC.PREC_rel; | |
661 precedence[TOK.TOKidentity] = PREC.PREC_rel; | |
662 precedence[TOK.TOKnotidentity] = PREC.PREC_rel; | |
663 } | |
664 | |
665 precedence[TOK.TOKand] = PREC.PREC_and; | |
666 | |
667 precedence[TOK.TOKxor] = PREC.PREC_xor; | |
668 | |
669 precedence[TOK.TOKor] = PREC.PREC_or; | |
670 | |
671 precedence[TOK.TOKandand] = PREC.PREC_andand; | |
672 | |
673 precedence[TOK.TOKoror] = PREC.PREC_oror; | |
674 | |
675 precedence[TOK.TOKquestion] = PREC.PREC_cond; | |
676 | |
677 precedence[TOK.TOKassign] = PREC.PREC_assign; | |
678 precedence[TOK.TOKconstruct] = PREC.PREC_assign; | |
679 precedence[TOK.TOKblit] = PREC.PREC_assign; | |
680 precedence[TOK.TOKaddass] = PREC.PREC_assign; | |
681 precedence[TOK.TOKminass] = PREC.PREC_assign; | |
682 precedence[TOK.TOKcatass] = PREC.PREC_assign; | |
683 precedence[TOK.TOKmulass] = PREC.PREC_assign; | |
684 precedence[TOK.TOKdivass] = PREC.PREC_assign; | |
685 precedence[TOK.TOKmodass] = PREC.PREC_assign; | |
686 precedence[TOK.TOKshlass] = PREC.PREC_assign; | |
687 precedence[TOK.TOKshrass] = PREC.PREC_assign; | |
688 precedence[TOK.TOKushrass] = PREC.PREC_assign; | |
689 precedence[TOK.TOKandass] = PREC.PREC_assign; | |
690 precedence[TOK.TOKorass] = PREC.PREC_assign; | |
691 precedence[TOK.TOKxorass] = PREC.PREC_assign; | |
692 | |
693 precedence[TOK.TOKcomma] = PREC.PREC_expr; | |
694 } | |
695 | |
696 int runLINK() | |
697 { | |
114 | 698 version (_WIN32) |
699 { | |
0 | 700 string p; |
701 int i; | |
702 int status; | |
703 scope OutBuffer cmdbuf = new OutBuffer(); | |
704 | |
705 global.params.libfiles.push(cast(void*)new String("user32")); | |
706 global.params.libfiles.push(cast(void*)new String("kernel32")); | |
707 | |
708 for (i = 0; i < global.params.objfiles.dim; i++) | |
709 { | |
710 if (i) | |
711 cmdbuf.writeByte('+'); | |
712 p = (cast(String)global.params.objfiles.data[i]).str; | |
713 string ext = FileName.ext(p); | |
714 if (ext) | |
715 // Write name sans extension | |
716 writeFilename(cmdbuf, p[0..p.length - ext.length - 1]); | |
717 else | |
718 writeFilename(cmdbuf, p); | |
719 } | |
720 cmdbuf.writeByte(','); | |
721 if (global.params.exefile) | |
722 writeFilename(cmdbuf, global.params.exefile); | |
723 else | |
724 { | |
725 /* Generate exe file name from first obj name. | |
726 * No need to add it to cmdbuf because the linker will default to it. | |
727 */ | |
728 string n = (cast(String)global.params.objfiles.data[0]).str; | |
729 n = FileName.name(n); | |
730 FileName fn = FileName.forceExt(n, "exe"); | |
731 global.params.exefile = fn.toChars(); | |
732 } | |
733 | |
734 // Make sure path to exe file exists | |
735 { | |
736 string pp = FileName.path(global.params.exefile); | |
737 FileName.ensurePathExists(pp); | |
738 } | |
739 | |
740 cmdbuf.writeByte(','); | |
741 if (global.params.run) | |
742 cmdbuf.writestring("nul"); | |
743 | |
744 // if (mapfile) | |
745 // cmdbuf.writestring(output); | |
746 cmdbuf.writeByte(','); | |
747 | |
748 for (i = 0; i < global.params.libfiles.dim; i++) | |
749 { | |
750 if (i) | |
751 cmdbuf.writeByte('+'); | |
752 writeFilename(cmdbuf, (cast(String)global.params.libfiles.data[i]).str); | |
753 } | |
754 | |
755 if (global.params.deffile) | |
756 { | |
757 cmdbuf.writeByte(','); | |
758 writeFilename(cmdbuf, global.params.deffile); | |
759 } | |
760 | |
761 /* Eliminate unnecessary trailing commas */ | |
762 while (1) | |
763 { | |
764 i = cmdbuf.offset; | |
765 if (!i || cmdbuf.data[i - 1] != ',') | |
766 break; | |
767 cmdbuf.offset--; | |
768 } | |
769 | |
770 if (global.params.resfile) | |
771 { | |
772 cmdbuf.writestring("/RC:"); | |
773 writeFilename(cmdbuf, global.params.resfile); | |
774 } | |
775 | |
776 static if (false) { | |
777 if (mapfile) | |
778 cmdbuf.writestring("/m"); | |
779 if (debuginfo) | |
780 cmdbuf.writestring("/li"); | |
781 if (codeview) | |
782 { | |
783 cmdbuf.writestring("/co"); | |
784 if (codeview3) | |
785 cmdbuf.writestring(":3"); | |
786 } | |
787 } else { | |
788 if (global.params.symdebug) | |
789 cmdbuf.writestring("/co"); | |
790 } | |
791 | |
792 cmdbuf.writestring("/noi"); | |
793 for (i = 0; i < global.params.linkswitches.dim; i++) | |
794 { | |
795 cmdbuf.writestring((cast(String)global.params.linkswitches.data[i]).str); | |
796 } | |
797 cmdbuf.writeByte(';'); | |
798 | |
799 p = cmdbuf.toChars(); | |
800 | |
801 FileName lnkfilename = null; | |
802 size_t plen = p.length; | |
803 if (plen > 7000) | |
804 { | |
805 lnkfilename = FileName.forceExt(global.params.exefile, "lnk"); | |
806 scope File flnk = new File(lnkfilename); | |
807 flnk.setbuffer(cast(void*)p.ptr, plen); | |
808 flnk.ref_ = 1; | |
809 if (flnk.write()) | |
810 error("error writing file %s", lnkfilename); | |
811 if (lnkfilename.len() < plen) | |
812 p = std.string.format("@%s", lnkfilename.toChars()); | |
813 } | |
814 | |
815 string linkcmd = getenv("LINKCMD"); | |
816 if (!linkcmd) | |
817 linkcmd = "link"; | |
818 | |
819 status = executecmd(linkcmd, p, 1); | |
820 if (lnkfilename) | |
821 { | |
822 remove(toStringz(lnkfilename.toChars())); | |
823 ///delete lnkfilename; | |
824 } | |
825 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:
2
diff
changeset
|
826 } else version (POSIX) {/// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
0 | 827 pid_t childpid; |
828 int i; | |
829 int status; | |
830 | |
831 // Build argv[] | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
832 Array argv = new Array(); |
0 | 833 |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
834 const(char)* cc = core.stdc.stdlib.getenv("CC"); |
0 | 835 if (!cc) |
836 cc = "gcc"; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
837 argv.push(cast(void *)cc); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
838 Array objfiles = new Array; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
839 for( i = 0; i < global.params.objfiles.dim; i++ ) |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
840 { string str = (cast(String)global.params.objfiles.data[i]).str; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
841 objfiles.push(cast(void*)toStringz(str)); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
842 } |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
843 argv.insert(1, objfiles); |
0 | 844 |
845 // None of that a.out stuff. Use explicit exe file name, or | |
846 // generate one from name of first source file. | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
847 argv.push(cast(void *)cast(char*)"-o"); |
0 | 848 if (global.params.exefile) |
849 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
850 argv.push(cast(void*)toStringz(global.params.exefile)); |
0 | 851 } |
852 else | |
853 { // Generate exe file name from first obj name | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
854 string n = (cast(String)global.params.objfiles.data[0]).str; |
0 | 855 n = FileName.name(n); |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
856 string e = FileName.ext(n); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
857 string ex = e ? n[0..$-(e.length+1)] : "a.out"; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
858 |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
859 argv.push(cast(void*)toStringz(ex)); |
0 | 860 global.params.exefile = ex; |
861 } | |
862 | |
863 // Make sure path to exe file exists | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
864 { string p = FileName.path(global.params.exefile); |
0 | 865 FileName.ensurePathExists(p); |
866 } | |
867 | |
868 if (global.params.symdebug) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
869 argv.push(cast(void *)cast(char*)"-g"); |
0 | 870 |
871 if (global.params.isX86_64) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
872 argv.push(cast(void *)cast(char*)"-m64"); |
0 | 873 else |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
874 argv.push(cast(void *)cast(char*)"-m32"); |
0 | 875 |
876 if (0 && global.params.exefile) | |
877 { | |
878 /* This switch enables what is known as 'smart linking' | |
879 * in the Windows world, where unreferenced sections | |
880 * are removed from the executable. It eliminates unreferenced | |
881 * functions, essentially making a 'library' out of a module. | |
882 * Although it is documented to work with ld version 2.13, | |
883 * in practice it does not, but just seems to be ignored. | |
884 * Thomas Kuehne has verified that it works with ld 2.16.1. | |
885 * BUG: disabled because it causes exception handling to fail | |
886 */ | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
887 argv.push(cast(void *)cast(char*)"-Xlinker"); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
888 argv.push(cast(void *)cast(char*)"--gc-sections"); |
0 | 889 } |
890 | |
891 for (i = 0; i < global.params.linkswitches.dim; i++) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
892 { char *p = cast(char *)global.params.linkswitches.data[i]; |
0 | 893 if (!p || !p[0] || !(p[0] == '-' && p[1] == 'l')) |
894 // Don't need -Xlinker if switch starts with -l | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
895 argv.push(cast(void *)cast(char*)"-Xlinker"); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
896 argv.push(cast(void *) p); |
0 | 897 } |
898 | |
899 /* Add each library, prefixing it with "-l". | |
900 * The order of libraries passed is: | |
901 * 1. any libraries passed with -L command line switch | |
902 * 2. libraries specified on the command line | |
903 * 3. libraries specified by pragma(lib), which were appended | |
904 * to global.params.libfiles. | |
905 * 4. standard libraries. | |
906 */ | |
907 for (i = 0; i < global.params.libfiles.dim; i++) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
908 { char *p = cast(char *)global.params.libfiles.data[i]; |
0 | 909 size_t plen = strlen(p); |
910 if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a') | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
911 argv.push(cast(void *)p); |
0 | 912 else |
913 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
914 char *s = cast(char *)malloc(plen + 3); |
0 | 915 s[0] = '-'; |
916 s[1] = 'l'; | |
917 memcpy(s + 2, p, plen + 1); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
918 argv.push(cast(void *)s); |
0 | 919 } |
920 } | |
921 | |
922 /* Standard libraries must go after user specified libraries | |
923 * passed with -l. | |
924 */ | |
925 const char *libname = (global.params.symdebug) | |
926 ? global.params.debuglibname | |
927 : global.params.defaultlibname; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
928 char *buf = cast(char *)malloc(2 + strlen(libname) + 1); |
0 | 929 strcpy(buf, "-l"); |
930 strcpy(buf + 2, libname); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
931 argv.push(cast(void *)buf); // turns into /usr/lib/libphobos2.a |
0 | 932 |
933 // argv.push((void *)"-ldruntime"); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
934 argv.push(cast(void *)cast(char*)"-lpthread"); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
935 argv.push(cast(void *)cast(char*)"-lm"); |
0 | 936 |
937 if (!global.params.quiet || global.params.verbose) | |
938 { | |
939 // Print it | |
940 for (i = 0; i < argv.dim; i++) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
941 printf("%s ", cast(char *)argv.data[i]); |
0 | 942 printf("\n"); |
943 fflush(stdout); | |
944 } | |
945 | |
946 argv.push(null); | |
947 childpid = fork(); | |
948 if (childpid == 0) | |
949 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
950 execvp(cast(char *)argv.data[0], cast(char **)argv.data); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
951 perror(cast(char *)argv.data[0]); // failed to execute |
0 | 952 return -1; |
953 } | |
954 | |
955 waitpid(childpid, &status, 0); | |
956 | |
957 status=WEXITSTATUS(status); | |
958 if (status) | |
959 printf("--- errorlevel %d\n", status); | |
960 return status; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
961 |
0 | 962 } else { |
963 writef ("Linking is not yet supported for this version of DMD.\n"); | |
964 return -1; | |
965 } | |
966 } | |
967 | |
968 int runProgram() | |
969 { | |
970 assert(false); | |
971 } | |
972 | |
973 void deleteExeFile() | |
974 { | |
975 assert(false); | |
976 } | |
977 | |
978 /**************************************** | |
979 * Write filename to cmdbuf, quoting if necessary. | |
980 */ | |
981 | |
982 void writeFilename(OutBuffer buf, string filename) | |
983 { | |
984 auto len = filename.length; | |
985 /* Loop and see if we need to quote | |
986 */ | |
987 for (size_t i = 0; i < len; i++) | |
988 { | |
989 char c = filename[i]; | |
990 | |
991 if (isalnum(c) || c == '_') | |
992 continue; | |
993 | |
994 /* Need to quote | |
995 */ | |
996 buf.writeByte('"'); | |
997 buf.writestring(filename); | |
998 buf.writeByte('"'); | |
999 return; | |
1000 } | |
1001 | |
1002 /* No quoting necessary | |
1003 */ | |
1004 buf.writestring(filename); | |
1005 } | |
1006 | |
1007 /****************************** | |
1008 * Execute a rule. Return the status. | |
1009 * cmd program to run | |
1010 * args arguments to cmd, as a string | |
1011 * useenv if cmd knows about _CMDLINE environment variable | |
1012 */ | |
1013 | |
1014 version (_WIN32) { | |
1015 int executecmd(string cmd, string args, int useenv) | |
1016 { | |
1017 int status; | |
1018 size_t len = args.length; | |
1019 | |
1020 if (!global.params.quiet || global.params.verbose) | |
1021 { | |
1022 printf("%s %s\n", cmd, args); | |
1023 fflush(stdout); | |
1024 } | |
1025 | |
1026 if (len > 255) | |
1027 { | |
1028 char* q; | |
1029 static char[9] envname = "@_CMDLINE"; | |
1030 | |
1031 envname[0] = '@'; | |
1032 switch (useenv) | |
1033 { | |
1034 case 0: goto L1; | |
1035 case 2: envname[0] = '%'; break; | |
1036 default: break; /// | |
1037 } | |
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:
2
diff
changeset
|
1038 version (Bug4054) |
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:
2
diff
changeset
|
1039 q = cast(char*) GC.malloc(envname.sizeof + len + 1); |
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:
2
diff
changeset
|
1040 else |
0 | 1041 q = cast(char*) alloca(envname.sizeof + len + 1); |
1042 sprintf(q, "%s=%s", envname.ptr + 1, args); | |
1043 status = putenv(q); | |
1044 if (status == 0) | |
1045 args = envname[].idup; | |
1046 else | |
1047 { | |
1048 L1: | |
1049 error("command line length of %d is too long",len); | |
1050 } | |
1051 } | |
1052 | |
1053 status = executearg0(cmd, args); | |
114 | 1054 version (Windows) { |
0 | 1055 if (status == -1) { |
1056 auto cmdZ = toStringz(cmd); | |
1057 auto argsZ = toStringz(args); | |
1058 status = spawnlp(0, cmdZ, cmdZ, argsZ, null); | |
1059 } | |
1060 } | |
1061 // if (global.params.verbose) | |
1062 // printf("\n"); | |
1063 if (status) | |
1064 { | |
1065 if (status == -1) | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1066 printf("Can't run '%.*s', check PATH\n", cmd); |
0 | 1067 else |
1068 printf("--- errorlevel %d\n", status); | |
1069 } | |
1070 return status; | |
1071 } | |
1072 } | |
1073 | |
1074 /************************************** | |
1075 * Attempt to find command to execute by first looking in the directory | |
1076 * where DMD was run from. | |
1077 * Returns: | |
1078 * -1 did not find command there | |
1079 * !=-1 exit status from command | |
1080 */ | |
1081 | |
1082 version (_WIN32) { | |
1083 int executearg0(string cmd, string args) | |
1084 { | |
1085 string file; | |
1086 string argv0 = global.params.argv0; | |
1087 | |
1088 //printf("argv0='%s', cmd='%s', args='%s'\n",argv0,cmd,args); | |
1089 | |
1090 // If cmd is fully qualified, we don't do this | |
1091 if (FileName.absolute(cmd)) | |
1092 return -1; | |
1093 | |
1094 file = FileName.replaceName(argv0, cmd); | |
1095 | |
1096 //printf("spawning '%s'\n",file); | |
1097 version (_WIN32) { | |
1098 auto fileZ = toStringz(file); | |
1099 auto argsZ = toStringz(args); | |
1100 return spawnl(0, fileZ, fileZ, argsZ, null); | |
114 | 1101 } else version (Posix) { ///#elif linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
0 | 1102 assert(false); |
1103 /+ | |
1104 char *full; | |
1105 int cmdl = strlen(cmd); | |
1106 | |
1107 full = (char*) mem.malloc(cmdl + strlen(args) + 2); | |
1108 if (full == null) | |
1109 return 1; | |
1110 strcpy(full, cmd); | |
1111 full [cmdl] = ' '; | |
1112 strcpy(full + cmdl + 1, args); | |
1113 | |
1114 int result = system(full); | |
1115 | |
1116 mem.free(full); | |
1117 return result; | |
1118 +/ | |
1119 } else { | |
1120 static assert(false); | |
1121 } | |
1122 } | |
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:
2
diff
changeset
|
1123 } |