Mercurial > projects > ddmd
annotate dmd/Util.d @ 179:cd48cb899aee
Updated to dmd2.040
author | korDen |
---|---|
date | Sun, 17 Oct 2010 20:56:07 +0400 |
parents | e3afd1303184 |
children | 190ba98276b3 |
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" | |
179 | 562 " -map generate linker .map file\n" |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
563 " -noboundscheck turns off array bounds checking for all functions\n" |
0 | 564 " -nofloat do not emit reference to floating point\n" |
565 " -O optimize\n" | |
566 " -o- do not write object file\n" | |
567 " -odobjdir write object & library files to directory objdir\n" | |
568 " -offilename name output file to filename\n" | |
569 " -op do not strip paths from source file\n" | |
570 " -profile profile runtime performance of generated code\n" | |
571 " -quiet suppress unnecessary messages\n" | |
572 " -release compile release version\n" | |
573 " -run srcfile args... run resulting program, passing args\n" | |
574 " -unittest compile in unit tests\n" | |
575 " -v verbose\n" | |
576 " -version=level compile in version code >= level\n" | |
577 " -version=ident compile in version code identified by ident\n" | |
578 " -vtls list all variables going into thread local storage\n" | |
579 " -w enable warnings\n" | |
79 | 580 " -X generate JSON file\n" |
581 " -Xffilename write JSON file to filename\n" | |
0 | 582 ); |
583 } | |
584 | |
585 void fatal() | |
586 { | |
587 static if (false) { | |
588 halt(); | |
589 } else { | |
590 exit(EXIT_FAILURE); | |
591 } | |
592 } | |
593 | |
594 void halt() | |
595 { | |
596 assert(false); | |
597 } | |
598 | |
599 void initPrecedence() | |
600 { | |
601 precedence[TOK.TOKdotvar] = PREC.PREC_primary; | |
602 precedence[TOK.TOKimport] = PREC.PREC_primary; | |
603 precedence[TOK.TOKidentifier] = PREC.PREC_primary; | |
604 precedence[TOK.TOKthis] = PREC.PREC_primary; | |
605 precedence[TOK.TOKsuper] = PREC.PREC_primary; | |
606 precedence[TOK.TOKint64] = PREC.PREC_primary; | |
607 precedence[TOK.TOKfloat64] = PREC.PREC_primary; | |
608 precedence[TOK.TOKnull] = PREC.PREC_primary; | |
609 precedence[TOK.TOKstring] = PREC.PREC_primary; | |
610 precedence[TOK.TOKarrayliteral] = PREC.PREC_primary; | |
611 precedence[TOK.TOKtypeid] = PREC.PREC_primary; | |
612 precedence[TOK.TOKis] = PREC.PREC_primary; | |
613 precedence[TOK.TOKassert] = PREC.PREC_primary; | |
614 precedence[TOK.TOKfunction] = PREC.PREC_primary; | |
615 precedence[TOK.TOKvar] = PREC.PREC_primary; | |
616 version (DMDV2) { | |
617 precedence[TOK.TOKdefault] = PREC.PREC_primary; | |
618 } | |
619 | |
620 // post | |
621 precedence[TOK.TOKdotti] = PREC.PREC_primary; | |
622 precedence[TOK.TOKdot] = PREC.PREC_primary; | |
623 // precedence[TOK.TOKarrow] = PREC.PREC_primary; | |
624 precedence[TOK.TOKplusplus] = PREC.PREC_primary; | |
625 precedence[TOK.TOKminusminus] = PREC.PREC_primary; | |
626 precedence[TOK.TOKcall] = PREC.PREC_primary; | |
627 precedence[TOK.TOKslice] = PREC.PREC_primary; | |
628 precedence[TOK.TOKarray] = PREC.PREC_primary; | |
629 | |
630 precedence[TOK.TOKaddress] = PREC.PREC_unary; | |
631 precedence[TOK.TOKstar] = PREC.PREC_unary; | |
632 precedence[TOK.TOKneg] = PREC.PREC_unary; | |
633 precedence[TOK.TOKuadd] = PREC.PREC_unary; | |
634 precedence[TOK.TOKnot] = PREC.PREC_unary; | |
635 precedence[TOK.TOKtobool] = PREC.PREC_add; | |
636 precedence[TOK.TOKtilde] = PREC.PREC_unary; | |
637 precedence[TOK.TOKdelete] = PREC.PREC_unary; | |
638 precedence[TOK.TOKnew] = PREC.PREC_unary; | |
639 precedence[TOK.TOKcast] = PREC.PREC_unary; | |
640 | |
135 | 641 precedence[TOK.TOKpow] = PREC.PREC_pow; |
642 | |
0 | 643 precedence[TOK.TOKmul] = PREC.PREC_mul; |
644 precedence[TOK.TOKdiv] = PREC.PREC_mul; | |
645 precedence[TOK.TOKmod] = PREC.PREC_mul; | |
130
60bb0fe4563e
dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
129
diff
changeset
|
646 precedence[TOKpow] = PREC.PREC_mul; |
178 | 647 |
0 | 648 precedence[TOK.TOKadd] = PREC.PREC_add; |
649 precedence[TOK.TOKmin] = PREC.PREC_add; | |
650 precedence[TOK.TOKcat] = PREC.PREC_add; | |
651 | |
652 precedence[TOK.TOKshl] = PREC.PREC_shift; | |
653 precedence[TOK.TOKshr] = PREC.PREC_shift; | |
654 precedence[TOK.TOKushr] = PREC.PREC_shift; | |
655 | |
656 precedence[TOK.TOKlt] = PREC.PREC_rel; | |
657 precedence[TOK.TOKle] = PREC.PREC_rel; | |
658 precedence[TOK.TOKgt] = PREC.PREC_rel; | |
659 precedence[TOK.TOKge] = PREC.PREC_rel; | |
660 precedence[TOK.TOKunord] = PREC.PREC_rel; | |
661 precedence[TOK.TOKlg] = PREC.PREC_rel; | |
662 precedence[TOK.TOKleg] = PREC.PREC_rel; | |
663 precedence[TOK.TOKule] = PREC.PREC_rel; | |
664 precedence[TOK.TOKul] = PREC.PREC_rel; | |
665 precedence[TOK.TOKuge] = PREC.PREC_rel; | |
666 precedence[TOK.TOKug] = PREC.PREC_rel; | |
667 precedence[TOK.TOKue] = PREC.PREC_rel; | |
668 precedence[TOK.TOKin] = PREC.PREC_rel; | |
669 | |
670 static if (false) { | |
671 precedence[TOK.TOKequal] = PREC.PREC_equal; | |
672 precedence[TOK.TOKnotequal] = PREC.PREC_equal; | |
673 precedence[TOK.TOKidentity] = PREC.PREC_equal; | |
674 precedence[TOK.TOKnotidentity] = PREC.PREC_equal; | |
675 } else { | |
676 /* Note that we changed precedence, so that < and != have the same | |
677 * precedence. This change is in the parser, too. | |
678 */ | |
679 precedence[TOK.TOKequal] = PREC.PREC_rel; | |
680 precedence[TOK.TOKnotequal] = PREC.PREC_rel; | |
681 precedence[TOK.TOKidentity] = PREC.PREC_rel; | |
682 precedence[TOK.TOKnotidentity] = PREC.PREC_rel; | |
683 } | |
684 | |
685 precedence[TOK.TOKand] = PREC.PREC_and; | |
686 | |
687 precedence[TOK.TOKxor] = PREC.PREC_xor; | |
688 | |
689 precedence[TOK.TOKor] = PREC.PREC_or; | |
690 | |
691 precedence[TOK.TOKandand] = PREC.PREC_andand; | |
692 | |
693 precedence[TOK.TOKoror] = PREC.PREC_oror; | |
694 | |
695 precedence[TOK.TOKquestion] = PREC.PREC_cond; | |
696 | |
697 precedence[TOK.TOKassign] = PREC.PREC_assign; | |
698 precedence[TOK.TOKconstruct] = PREC.PREC_assign; | |
699 precedence[TOK.TOKblit] = PREC.PREC_assign; | |
700 precedence[TOK.TOKaddass] = PREC.PREC_assign; | |
701 precedence[TOK.TOKminass] = PREC.PREC_assign; | |
702 precedence[TOK.TOKcatass] = PREC.PREC_assign; | |
703 precedence[TOK.TOKmulass] = PREC.PREC_assign; | |
704 precedence[TOK.TOKdivass] = PREC.PREC_assign; | |
705 precedence[TOK.TOKmodass] = PREC.PREC_assign; | |
135 | 706 precedence[TOK.TOKpowass] = PREC.PREC_assign; |
0 | 707 precedence[TOK.TOKshlass] = PREC.PREC_assign; |
708 precedence[TOK.TOKshrass] = PREC.PREC_assign; | |
709 precedence[TOK.TOKushrass] = PREC.PREC_assign; | |
710 precedence[TOK.TOKandass] = PREC.PREC_assign; | |
711 precedence[TOK.TOKorass] = PREC.PREC_assign; | |
712 precedence[TOK.TOKxorass] = PREC.PREC_assign; | |
713 | |
714 precedence[TOK.TOKcomma] = PREC.PREC_expr; | |
715 } | |
716 | |
717 int runLINK() | |
718 { | |
114 | 719 version (_WIN32) |
720 { | |
0 | 721 string p; |
722 int i; | |
723 int status; | |
724 scope OutBuffer cmdbuf = new OutBuffer(); | |
725 | |
726 global.params.libfiles.push(cast(void*)new String("user32")); | |
727 global.params.libfiles.push(cast(void*)new String("kernel32")); | |
728 | |
729 for (i = 0; i < global.params.objfiles.dim; i++) | |
730 { | |
731 if (i) | |
732 cmdbuf.writeByte('+'); | |
733 p = (cast(String)global.params.objfiles.data[i]).str; | |
734 string ext = FileName.ext(p); | |
735 if (ext) | |
736 // Write name sans extension | |
737 writeFilename(cmdbuf, p[0..p.length - ext.length - 1]); | |
738 else | |
739 writeFilename(cmdbuf, p); | |
740 } | |
741 cmdbuf.writeByte(','); | |
742 if (global.params.exefile) | |
743 writeFilename(cmdbuf, global.params.exefile); | |
744 else | |
178 | 745 { |
0 | 746 /* Generate exe file name from first obj name. |
747 * No need to add it to cmdbuf because the linker will default to it. | |
748 */ | |
749 string n = (cast(String)global.params.objfiles.data[0]).str; | |
750 n = FileName.name(n); | |
751 FileName fn = FileName.forceExt(n, "exe"); | |
752 global.params.exefile = fn.toChars(); | |
753 } | |
754 | |
755 // Make sure path to exe file exists | |
178 | 756 { |
0 | 757 string pp = FileName.path(global.params.exefile); |
758 FileName.ensurePathExists(pp); | |
759 } | |
760 | |
761 cmdbuf.writeByte(','); | |
179 | 762 |
763 if (global.params.mapfile) | |
764 cmdbuf.writestring(global.params.mapfile); | |
765 else if (global.params.run) | |
0 | 766 cmdbuf.writestring("nul"); |
767 | |
768 cmdbuf.writeByte(','); | |
769 | |
770 for (i = 0; i < global.params.libfiles.dim; i++) | |
771 { | |
772 if (i) | |
773 cmdbuf.writeByte('+'); | |
774 writeFilename(cmdbuf, (cast(String)global.params.libfiles.data[i]).str); | |
775 } | |
776 | |
777 if (global.params.deffile) | |
778 { | |
779 cmdbuf.writeByte(','); | |
780 writeFilename(cmdbuf, global.params.deffile); | |
781 } | |
782 | |
783 /* Eliminate unnecessary trailing commas */ | |
784 while (1) | |
178 | 785 { |
0 | 786 i = cmdbuf.offset; |
787 if (!i || cmdbuf.data[i - 1] != ',') | |
788 break; | |
789 cmdbuf.offset--; | |
790 } | |
791 | |
792 if (global.params.resfile) | |
793 { | |
794 cmdbuf.writestring("/RC:"); | |
795 writeFilename(cmdbuf, global.params.resfile); | |
796 } | |
797 | |
179 | 798 if (global.params.map || global.params.mapfile) |
799 cmdbuf.writestring("/m"); | |
800 | |
0 | 801 static if (false) { |
802 if (debuginfo) | |
803 cmdbuf.writestring("/li"); | |
804 if (codeview) | |
805 { | |
806 cmdbuf.writestring("/co"); | |
807 if (codeview3) | |
808 cmdbuf.writestring(":3"); | |
809 } | |
810 } else { | |
811 if (global.params.symdebug) | |
812 cmdbuf.writestring("/co"); | |
813 } | |
814 | |
815 cmdbuf.writestring("/noi"); | |
816 for (i = 0; i < global.params.linkswitches.dim; i++) | |
817 { | |
818 cmdbuf.writestring((cast(String)global.params.linkswitches.data[i]).str); | |
819 } | |
820 cmdbuf.writeByte(';'); | |
821 | |
822 p = cmdbuf.toChars(); | |
823 | |
824 FileName lnkfilename = null; | |
825 size_t plen = p.length; | |
826 if (plen > 7000) | |
827 { | |
828 lnkfilename = FileName.forceExt(global.params.exefile, "lnk"); | |
829 scope File flnk = new File(lnkfilename); | |
830 flnk.setbuffer(cast(void*)p.ptr, plen); | |
831 flnk.ref_ = 1; | |
832 if (flnk.write()) | |
833 error("error writing file %s", lnkfilename); | |
834 if (lnkfilename.len() < plen) | |
835 p = std.string.format("@%s", lnkfilename.toChars()); | |
836 } | |
837 | |
838 string linkcmd = getenv("LINKCMD"); | |
839 if (!linkcmd) | |
840 linkcmd = "link"; | |
841 | |
842 status = executecmd(linkcmd, p, 1); | |
843 if (lnkfilename) | |
844 { | |
845 remove(toStringz(lnkfilename.toChars())); | |
846 ///delete lnkfilename; | |
847 } | |
848 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
|
849 } else version (POSIX) {/// linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
0 | 850 pid_t childpid; |
851 int i; | |
852 int status; | |
853 | |
854 // Build argv[] | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
855 Array argv = new Array(); |
0 | 856 |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
857 const(char)* cc = core.stdc.stdlib.getenv("CC"); |
0 | 858 if (!cc) |
859 cc = "gcc"; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
860 argv.push(cast(void *)cc); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
861 Array objfiles = new Array; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
862 for( i = 0; i < global.params.objfiles.dim; i++ ) |
178 | 863 { 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
|
864 objfiles.push(cast(void*)toStringz(str)); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
865 } |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
866 argv.insert(1, objfiles); |
0 | 867 |
868 // None of that a.out stuff. Use explicit exe file name, or | |
869 // 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
|
870 argv.push(cast(void *)cast(char*)"-o"); |
0 | 871 if (global.params.exefile) |
872 { | |
179 | 873 argv.push(cast(void*)toStringz(global.params.exefile)); |
0 | 874 } |
875 else | |
179 | 876 { |
877 // Generate exe file name from first obj name | |
878 string n = (cast(String)global.params.objfiles.data[0]).str; | |
879 n = FileName.name(n); | |
880 string e = FileName.ext(n); | |
881 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
|
882 |
179 | 883 argv.push(cast(void*)toStringz(ex)); |
884 global.params.exefile = ex; | |
0 | 885 } |
886 | |
887 // Make sure path to exe file exists | |
179 | 888 { |
889 string p = FileName.path(global.params.exefile); | |
890 FileName.ensurePathExists(p); | |
0 | 891 } |
892 | |
893 if (global.params.symdebug) | |
179 | 894 argv.push(cast(void*)"-g".ptr); |
0 | 895 |
896 if (global.params.isX86_64) | |
179 | 897 argv.push(cast(void*)"-m64".ptr); |
0 | 898 else |
179 | 899 argv.push(cast(void*)"-m32".ptr); |
900 | |
901 if (global.params.map || global.params.mapfile) | |
902 { | |
903 argv.push(cast(void*)"-Xlinker".ptr); | |
904 version (__APPLE__) { | |
905 argv.push(cast(void*)"-map".ptr); | |
906 } else { | |
907 argv.push(cast(void *)"-Map".ptr); | |
908 } | |
909 if (!global.params.mapfile) | |
910 { | |
911 size_t elen = global.params.exefile.length; | |
912 size_t extlen = global.map_ext.length; | |
913 size_t mlen = elen + 1 + extlen; | |
914 char* m = cast(char*)GC.malloc(mlen + 1); | |
915 memcpy(m, global.params.exefile.ptr, elen); | |
916 m[elen] = '.'; | |
917 memcpy(m + elen + 1, global.map_ext.ptr, extlen); | |
918 m[mlen] = 0; | |
919 global.params.mapfile = cast(string)m[0..mlen]; | |
920 } | |
921 argv.push(cast(void*)"-Xlinker".ptr); | |
922 argv.push(global.params.mapfile.ptr); | |
923 } | |
0 | 924 |
925 if (0 && global.params.exefile) | |
926 { | |
179 | 927 /* This switch enables what is known as 'smart linking' |
928 * in the Windows world, where unreferenced sections | |
929 * are removed from the executable. It eliminates unreferenced | |
930 * functions, essentially making a 'library' out of a module. | |
931 * Although it is documented to work with ld version 2.13, | |
932 * in practice it does not, but just seems to be ignored. | |
933 * Thomas Kuehne has verified that it works with ld 2.16.1. | |
934 * BUG: disabled because it causes exception handling to fail | |
935 * because EH sections are "unreferenced" and elided | |
936 */ | |
937 argv.push(cast(void *)"-Xlinker".ptr); | |
938 argv.push(cast(void *)"--gc-sections".ptr); | |
0 | 939 } |
940 | |
941 for (i = 0; i < global.params.linkswitches.dim; i++) | |
179 | 942 { |
943 char* p = cast(char*)global.params.linkswitches.data[i]; | |
944 if (!p || !p[0] || !(p[0] == '-' && p[1] == 'l')) | |
945 // Don't need -Xlinker if switch starts with -l | |
946 argv.push(cast(void *)"-Xlinker".ptr); | |
947 argv.push(cast(void*)p); | |
0 | 948 } |
949 | |
950 /* Add each library, prefixing it with "-l". | |
951 * The order of libraries passed is: | |
952 * 1. any libraries passed with -L command line switch | |
953 * 2. libraries specified on the command line | |
954 * 3. libraries specified by pragma(lib), which were appended | |
955 * to global.params.libfiles. | |
956 * 4. standard libraries. | |
957 */ | |
958 for (i = 0; i < global.params.libfiles.dim; i++) | |
179 | 959 { |
960 char* p = cast(char*)global.params.libfiles.data[i]; | |
961 size_t plen = strlen(p); | |
962 if (plen > 2 && p[plen - 2] == '.' && p[plen -1] == 'a') | |
963 argv.push(cast(void *)p); | |
964 else | |
965 { | |
966 char *s = cast(char *)GC.malloc(plen + 3); | |
967 s[0] = '-'; | |
968 s[1] = 'l'; | |
969 memcpy(s + 2, p, plen + 1); | |
970 argv.push(cast(void *)s); | |
971 } | |
0 | 972 } |
973 | |
974 /* Standard libraries must go after user specified libraries | |
975 * passed with -l. | |
976 */ | |
179 | 977 const char* libname = (global.params.symdebug) |
0 | 978 ? global.params.debuglibname |
979 : global.params.defaultlibname; | |
179 | 980 char* buf = cast(char*)GC.malloc(2 + strlen(libname) + 1); |
0 | 981 strcpy(buf, "-l"); |
982 strcpy(buf + 2, libname); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
983 argv.push(cast(void *)buf); // turns into /usr/lib/libphobos2.a |
0 | 984 |
985 // argv.push((void *)"-ldruntime"); | |
179 | 986 argv.push(cast(void *)"-lpthread".ptr); |
987 argv.push(cast(void *)"-lm".ptr); | |
0 | 988 |
989 if (!global.params.quiet || global.params.verbose) | |
990 { | |
179 | 991 // Print it |
992 for (i = 0; i < argv.dim; i++) | |
993 printf("%s ", cast(char *)argv.data[i]); | |
994 printf("\n"); | |
995 fflush(stdout); | |
0 | 996 } |
997 | |
998 argv.push(null); | |
999 childpid = fork(); | |
1000 if (childpid == 0) | |
1001 { | |
179 | 1002 execvp(cast(char *)argv.data[0], cast(char **)argv.data); |
1003 perror(cast(char *)argv.data[0]); // failed to execute | |
1004 return -1; | |
0 | 1005 } |
1006 | |
1007 waitpid(childpid, &status, 0); | |
1008 | |
1009 status=WEXITSTATUS(status); | |
1010 if (status) | |
179 | 1011 printf("--- errorlevel %d\n", status); |
0 | 1012 return status; |
178 | 1013 |
0 | 1014 } else { |
1015 writef ("Linking is not yet supported for this version of DMD.\n"); | |
1016 return -1; | |
1017 } | |
1018 } | |
1019 | |
1020 int runProgram() | |
1021 { | |
1022 assert(false); | |
1023 } | |
1024 | |
1025 void deleteExeFile() | |
1026 { | |
1027 assert(false); | |
1028 } | |
1029 | |
1030 /**************************************** | |
1031 * Write filename to cmdbuf, quoting if necessary. | |
1032 */ | |
1033 | |
1034 void writeFilename(OutBuffer buf, string filename) | |
1035 { | |
1036 auto len = filename.length; | |
1037 /* Loop and see if we need to quote | |
1038 */ | |
1039 for (size_t i = 0; i < len; i++) | |
178 | 1040 { |
0 | 1041 char c = filename[i]; |
1042 | |
1043 if (isalnum(c) || c == '_') | |
1044 continue; | |
1045 | |
1046 /* Need to quote | |
1047 */ | |
1048 buf.writeByte('"'); | |
1049 buf.writestring(filename); | |
1050 buf.writeByte('"'); | |
1051 return; | |
1052 } | |
1053 | |
1054 /* No quoting necessary | |
1055 */ | |
1056 buf.writestring(filename); | |
1057 } | |
1058 | |
1059 /****************************** | |
1060 * Execute a rule. Return the status. | |
1061 * cmd program to run | |
1062 * args arguments to cmd, as a string | |
1063 * useenv if cmd knows about _CMDLINE environment variable | |
1064 */ | |
1065 | |
1066 version (_WIN32) { | |
1067 int executecmd(string cmd, string args, int useenv) | |
1068 { | |
1069 int status; | |
1070 size_t len = args.length; | |
1071 | |
1072 if (!global.params.quiet || global.params.verbose) | |
1073 { | |
1074 printf("%s %s\n", cmd, args); | |
1075 fflush(stdout); | |
1076 } | |
1077 | |
1078 if (len > 255) | |
178 | 1079 { |
0 | 1080 char* q; |
175 | 1081 char[9] envname = "@_CMDLINE"; |
0 | 1082 |
1083 envname[0] = '@'; | |
1084 switch (useenv) | |
178 | 1085 { |
0 | 1086 case 0: goto L1; |
1087 case 2: envname[0] = '%'; break; | |
1088 default: break; /// | |
1089 } | |
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
|
1090 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
|
1091 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
|
1092 else |
0 | 1093 q = cast(char*) alloca(envname.sizeof + len + 1); |
1094 sprintf(q, "%s=%s", envname.ptr + 1, args); | |
1095 status = putenv(q); | |
1096 if (status == 0) | |
1097 args = envname[].idup; | |
1098 else | |
1099 { | |
1100 L1: | |
1101 error("command line length of %d is too long",len); | |
1102 } | |
1103 } | |
1104 | |
1105 status = executearg0(cmd, args); | |
114 | 1106 version (Windows) { |
0 | 1107 if (status == -1) { |
1108 auto cmdZ = toStringz(cmd); | |
1109 auto argsZ = toStringz(args); | |
1110 status = spawnlp(0, cmdZ, cmdZ, argsZ, null); | |
1111 } | |
1112 } | |
1113 // if (global.params.verbose) | |
1114 // printf("\n"); | |
1115 if (status) | |
1116 { | |
1117 if (status == -1) | |
94
3a0b150c9841
Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents:
79
diff
changeset
|
1118 printf("Can't run '%.*s', check PATH\n", cmd); |
0 | 1119 else |
1120 printf("--- errorlevel %d\n", status); | |
1121 } | |
1122 return status; | |
1123 } | |
1124 } | |
1125 | |
1126 /************************************** | |
1127 * Attempt to find command to execute by first looking in the directory | |
1128 * where DMD was run from. | |
1129 * Returns: | |
1130 * -1 did not find command there | |
1131 * !=-1 exit status from command | |
1132 */ | |
1133 | |
1134 version (_WIN32) { | |
1135 int executearg0(string cmd, string args) | |
1136 { | |
1137 string file; | |
1138 string argv0 = global.params.argv0; | |
1139 | |
1140 //printf("argv0='%s', cmd='%s', args='%s'\n",argv0,cmd,args); | |
1141 | |
1142 // If cmd is fully qualified, we don't do this | |
1143 if (FileName.absolute(cmd)) | |
1144 return -1; | |
1145 | |
1146 file = FileName.replaceName(argv0, cmd); | |
1147 | |
1148 //printf("spawning '%s'\n",file); | |
1149 version (_WIN32) { | |
1150 auto fileZ = toStringz(file); | |
1151 auto argsZ = toStringz(args); | |
1152 return spawnl(0, fileZ, fileZ, argsZ, null); | |
114 | 1153 } else version (Posix) { ///#elif linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 |
0 | 1154 assert(false); |
1155 /+ | |
1156 char *full; | |
1157 int cmdl = strlen(cmd); | |
1158 | |
1159 full = (char*) mem.malloc(cmdl + strlen(args) + 2); | |
1160 if (full == null) | |
1161 return 1; | |
1162 strcpy(full, cmd); | |
1163 full [cmdl] = ' '; | |
1164 strcpy(full + cmdl + 1, args); | |
1165 | |
1166 int result = system(full); | |
1167 | |
1168 mem.free(full); | |
1169 return result; | |
1170 +/ | |
1171 } else { | |
1172 static assert(false); | |
1173 } | |
1174 } | |
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
|
1175 } |
178 | 1176 |
174 | 1177 extern(C++) void util_assert(char* file,int line) |
1178 { | |
1179 fflush(stdout); | |
1180 printf("Internal error: %s %d\n",file,line); | |
1181 throw new Exception("Internal error"); | |
1182 } | |
178 | 1183 /* |
174 | 1184 extern (C++) { |
1185 void* mem_malloc(uint size) | |
1186 { | |
1187 return GC.malloc(size); | |
1188 } | |
178 | 1189 |
174 | 1190 void* mem_calloc(uint size) |
1191 { | |
1192 return GC.calloc(size); | |
1193 } | |
178 | 1194 |
174 | 1195 void* mem_realloc(void* ptr, uint size) |
1196 { | |
1197 return GC.realloc(ptr, size); | |
1198 } | |
178 | 1199 |
174 | 1200 void mem_free(void* ptr) |
1201 { | |
1202 GC.free(ptr); | |
1203 } | |
178 | 1204 |
174 | 1205 void* mem_fmalloc(uint size) |
1206 { | |
1207 return mem_malloc(size); | |
1208 } | |
178 | 1209 |
174 | 1210 void* mem_fcalloc(uint size) |
1211 { | |
1212 return mem_calloc(size); | |
1213 } | |
178 | 1214 } |
1215 */ |