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