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