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