Mercurial > projects > ddmd
annotate dmd/FileName.d @ 175:94b6033c07f3
get rid of globals
malloc -> GC.malloc
author | korDen |
---|---|
date | Sun, 10 Oct 2010 03:48:06 +0400 |
parents | af724d3510d7 |
children | e3afd1303184 |
rev | line source |
---|---|
0 | 1 module dmd.FileName; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.String; |
5 import dmd.Array; | |
6 import dmd.OutBuffer; | |
7 import dmd.File; | |
8 | |
4 | 9 import core.memory; |
2 | 10 |
5
63623152e82a
Fixed memory corruption bug which was introduced when attempting to restore GC functionality
dkoroskin <>
parents:
4
diff
changeset
|
11 import core.stdc.stdlib : malloc, alloca; |
0 | 12 import core.stdc.string : memcpy, strlen; |
13 import core.stdc.ctype : isspace; | |
14 | |
34 | 15 import std.exception : assumeUnique; |
0 | 16 import std.string : cmp, icmp; |
17 import std.file : mkdirRecurse; | |
18 | |
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:
5
diff
changeset
|
19 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:
5
diff
changeset
|
20 { |
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:
5
diff
changeset
|
21 import core.sys.windows.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:
5
diff
changeset
|
22 } |
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:
5
diff
changeset
|
23 |
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:
5
diff
changeset
|
24 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:
5
diff
changeset
|
25 { |
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:
5
diff
changeset
|
26 import core.stdc.stdlib; |
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:
5
diff
changeset
|
27 import core.sys.posix.sys.stat; |
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:
5
diff
changeset
|
28 import std.conv; |
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:
5
diff
changeset
|
29 } |
0 | 30 |
31 class FileName : String | |
32 { | |
33 this(string str) | |
34 { | |
35 super(str); | |
36 } | |
37 | |
38 this(string path, string name) | |
39 { | |
40 super(combine(path, name)); | |
41 } | |
42 | |
72 | 43 override hash_t hashCode() |
0 | 44 { |
114 | 45 version (Windows) |
46 { | |
0 | 47 // We need a different hashCode because it must be case-insensitive |
48 size_t len = str.length; | |
49 hash_t hash = 0; | |
50 ubyte* s = cast(ubyte*)str.ptr; | |
51 | |
52 for (;;) | |
53 { | |
54 switch (len) | |
55 { | |
56 case 0: | |
57 return hash; | |
58 | |
59 case 1: | |
60 hash *= 37; | |
61 hash += *(cast(ubyte*)s) | 0x20; | |
62 return hash; | |
63 | |
64 case 2: | |
65 hash *= 37; | |
66 hash += *(cast(ushort*)s) | 0x2020; | |
67 return hash; | |
68 | |
69 case 3: | |
70 hash *= 37; | |
71 hash += (*cast(ushort*)s) << 8 + | |
72 ((cast(ubyte*)s)[2]) | 0x202020; | |
73 break; | |
74 | |
75 default: | |
76 hash *= 37; | |
77 hash += (*cast(int*)s) | 0x20202020; | |
78 s += 4; | |
79 len -= 4; | |
80 break; | |
81 } | |
82 } | |
83 } else { | |
84 // darwin HFS is case insensitive, though... | |
85 return super.hashCode(); | |
86 } | |
87 } | |
88 | |
72 | 89 override bool opEquals(Object obj) |
0 | 90 { |
91 return opCmp(obj) == 0; | |
92 } | |
93 | |
45 | 94 static bool equals(string name1, string name2) |
0 | 95 { |
96 return compare(name1, name2) == 0; | |
97 } | |
98 | |
72 | 99 override int opCmp(Object obj) |
0 | 100 { |
101 return compare(str, (cast(FileName)obj).str); | |
102 } | |
103 | |
104 static int compare(string name1, string name2) | |
105 { | |
106 version (_WIN32) { | |
107 return icmp(name1, name2); | |
108 } else { | |
109 return cmp(name1, name2); | |
110 } | |
111 } | |
112 | |
81 | 113 static pure bool absolute(const(char)[] name) |
0 | 114 { |
114 | 115 version (Windows) |
81 | 116 { |
117 return (name[0] == '\\') || | |
118 (name[0] == '/') || | |
102
3ddadd0c4534
wrong name.length check fixed (greetings to Trass3r!)
korDen
parents:
101
diff
changeset
|
119 ((name.length > 1) && (name[1] == ':')); |
81 | 120 } |
121 else version (POSIX) | |
122 { | |
123 return (name[0] == '/'); | |
124 } | |
125 else | |
126 { | |
127 static assert(false); | |
0 | 128 } |
129 } | |
130 | |
131 /******************************** | |
132 * Return filename extension (read-only). | |
133 * Points past '.' of extension. | |
134 * If there isn't one, return NULL. | |
135 */ | |
136 static string ext(string str) | |
137 { | |
138 foreach_reverse (i, c; str) | |
139 { | |
140 switch (c) | |
141 { | |
142 case '.': | |
143 return str[i+1..$]; | |
144 version (POSIX) { | |
145 case '/': | |
146 return null; | |
147 } | |
114 | 148 version (Windows) |
149 { | |
0 | 150 case '\\': |
151 case ':': | |
152 case '/': | |
153 return null; | |
154 | |
155 } default: | |
156 break; | |
157 } | |
158 } | |
174 | 159 |
0 | 160 return null; |
161 } | |
162 | |
163 string ext() | |
164 { | |
165 return ext(str); | |
166 } | |
174 | 167 |
0 | 168 /******************************** |
169 * Return filename with extension removed. | |
170 */ | |
171 | |
172 static string removeExt(string str) | |
173 { | |
174 string e = ext(str); | |
175 if (e !is null) | |
176 { | |
177 size_t len = (e.ptr - str.ptr - 1); | |
178 return str[0..len]; | |
179 } | |
180 | |
181 return str; | |
182 } | |
174 | 183 |
0 | 184 /******************************** |
185 * Return filename name excluding path (read-only). | |
186 */ | |
187 | |
188 static string name(string str) | |
189 { | |
190 foreach_reverse(i, c; str) | |
191 { | |
192 switch (c) | |
193 { | |
114 | 194 version (Posix) |
195 { | |
0 | 196 case '/': |
197 return str[i+1..$]; | |
198 } | |
114 | 199 version (Windows) |
200 { | |
0 | 201 case '/': |
202 case '\\': | |
203 return str[i+1..$]; | |
204 case ':': | |
205 /* The ':' is a drive letter only if it is the second | |
206 * character or the last character, | |
207 * otherwise it is an ADS (Alternate Data Stream) separator. | |
208 * Consider ADS separators as part of the file name. | |
209 */ | |
210 if (i == 1 || i == str.length - 1) | |
211 return str[i+1..$]; | |
212 } | |
213 default: | |
214 break; | |
215 } | |
216 } | |
217 | |
218 return str; | |
219 } | |
220 | |
221 string name() | |
222 { | |
223 return name(str); | |
224 } | |
174 | 225 |
0 | 226 /************************************** |
227 * Return path portion of str. | |
228 * Path will does not include trailing path separator. | |
229 */ | |
230 | |
231 static string path(string str) | |
232 { | |
233 auto n = name(str).ptr; | |
234 | |
235 if (n > str.ptr) | |
236 { | |
237 auto p = n - 1; | |
114 | 238 version (Posix) |
239 { | |
0 | 240 if (*p == '/') |
241 n--; | |
114 | 242 } else version (Windows) |
243 { | |
0 | 244 if (*p == '\\' || *p == '/') |
245 n--; | |
114 | 246 } else |
247 { | |
0 | 248 static assert(false); |
249 } | |
250 } | |
251 | |
252 size_t pathlen = n - str.ptr; | |
253 return str[0..pathlen]; | |
254 } | |
174 | 255 |
0 | 256 /************************************** |
257 * Replace filename portion of path. | |
258 */ | |
174 | 259 |
0 | 260 static string replaceName(string path, string name) |
261 { | |
262 if (absolute(name)) | |
263 return name; | |
264 | |
265 string n = FileName.name(path); | |
266 if (n is path) | |
267 return name; | |
268 | |
269 size_t pathlen = n.ptr - path.ptr; | |
270 size_t namelen = name.length; | |
271 | |
2 | 272 char* f = cast(char*)GC.malloc(pathlen + 1 + namelen + 1); |
0 | 273 memcpy(f, path.ptr, pathlen); |
114 | 274 version (Posix) |
275 { | |
0 | 276 if (path[pathlen - 1] != '/') |
277 { | |
278 f[pathlen] = '/'; | |
279 pathlen++; | |
280 } | |
114 | 281 } |
282 else version (Windows) | |
283 { | |
0 | 284 if (path[pathlen - 1] != '\\' && |
285 path[pathlen - 1] != '/' && | |
286 path[pathlen - 1] != ':') | |
287 { | |
288 f[pathlen] = '\\'; | |
289 pathlen++; | |
290 } | |
114 | 291 } |
292 else | |
293 { | |
0 | 294 static assert(false); |
295 } | |
296 memcpy(f + pathlen, name.ptr, namelen + 1); | |
174 | 297 |
0 | 298 return assumeUnique(f[0..pathlen+namelen]); |
299 } | |
300 | |
301 static string combine(string path, string name) | |
302 { | |
303 size_t pathlen; | |
304 size_t namelen; | |
305 | |
306 if (path.length == 0) | |
307 return name; | |
308 | |
309 pathlen = path.length; | |
310 namelen = name.length; | |
311 | |
2 | 312 char* f = cast(char*)GC.malloc(pathlen + 1 + namelen + 1); |
0 | 313 |
314 memcpy(f, path.ptr, pathlen); | |
315 | |
114 | 316 version (Posix) { |
0 | 317 if (path[pathlen - 1] != '/') |
318 { | |
319 f[pathlen] = '/'; | |
320 pathlen++; | |
321 } | |
114 | 322 } |
323 else version (Windows) | |
324 { | |
174 | 325 if (path[pathlen - 1] != '\\' && |
0 | 326 path[pathlen - 1] != '/' && |
327 path[pathlen - 1] != ':') | |
328 { | |
329 f[pathlen] = '\\'; | |
330 pathlen++; | |
331 } | |
114 | 332 } |
333 else | |
334 { | |
0 | 335 static assert(0); |
336 } | |
337 memcpy(f + pathlen, name.ptr, namelen + 1); | |
338 | |
339 return assumeUnique(f[0..pathlen+namelen]); | |
340 } | |
174 | 341 |
0 | 342 static string[] splitPath(const(char)[] spath) |
343 { | |
344 char c = 0; // unnecessary initializer is for VC /W4 | |
345 | |
346 scope OutBuffer buf = new OutBuffer(); | |
347 string[] array; | |
174 | 348 |
0 | 349 if (spath !is null) |
350 { | |
351 const(char)* p = spath.ptr; | |
352 int len = spath.length; | |
353 do | |
354 { | |
355 char instring = 0; | |
356 | |
357 while (len > 0 && isspace(*p)) { // skip leading whitespace | |
358 p++; | |
359 --len; | |
360 } | |
174 | 361 |
0 | 362 buf.reserve(len + 1); // guess size of path |
363 for (; len; p++, len--) | |
364 { | |
365 c = *p; | |
366 switch (c) | |
367 { | |
368 case '"': | |
369 instring ^= 1; // toggle inside/outside of string | |
370 continue; | |
371 | |
372 version (MACINTOSH) { | |
373 case ',': | |
374 } | |
114 | 375 version (Windows) { |
0 | 376 case ';': |
377 } | |
114 | 378 version (Posix) { |
0 | 379 case ':': |
380 } | |
381 p++; | |
382 break; // note that ; cannot appear as part | |
383 // of a path, quotes won't protect it | |
384 | |
385 case 0x1A: // ^Z means end of file | |
386 //case 0: | |
387 break; | |
388 | |
389 case '\r': | |
390 continue; // ignore carriage returns | |
391 | |
392 version (POSIX) { | |
393 case '~': | |
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:
5
diff
changeset
|
394 buf.writestring(to!string(getenv("HOME"))); |
0 | 395 continue; |
396 } | |
397 | |
398 version (disabled) { | |
399 case ' ': | |
400 case '\t': // tabs in filenames? | |
401 if (!instring) // if not in string | |
402 break; // treat as end of path | |
403 } | |
404 default: | |
405 buf.writeByte(c); | |
406 continue; | |
407 } | |
408 break; | |
409 } | |
410 if (buf.offset) // if path is not empty | |
411 { | |
412 //buf.writeByte(0); // to asciiz | |
413 array ~= buf.extractString(); | |
414 } | |
415 } while (len > 0); | |
416 } | |
174 | 417 |
0 | 418 return array; |
419 } | |
174 | 420 |
0 | 421 static FileName defaultExt(string name, string ext) |
422 { | |
423 string e = FileName.ext(name); | |
424 if (e !is null) { | |
425 // if already has an extension | |
426 return new FileName(name); | |
427 } | |
428 | |
429 size_t len = name.length; | |
430 size_t extlen = ext.length; | |
2 | 431 char* s = cast(char*)GC.malloc(len + 1 + extlen + 1); |
0 | 432 memcpy(s, name.ptr, len); |
433 s[len] = '.'; | |
434 memcpy(s + len + 1, ext.ptr, extlen + 1); | |
435 | |
436 return new FileName(assumeUnique(s[0..len+1+extlen])); | |
437 } | |
438 | |
439 static FileName forceExt(string name, string ext) | |
440 { | |
441 string e = FileName.ext(name); | |
442 if (e !is null) // if already has an extension | |
443 { | |
444 size_t len = e.ptr - name.ptr; | |
445 size_t extlen = ext.length; | |
446 | |
175 | 447 char* s = cast(char*)GC.malloc(len + extlen + 1); /// ! |
0 | 448 memcpy(s, name.ptr, len); |
449 memcpy(s + len, ext.ptr, extlen + 1); | |
450 return new FileName(assumeUnique(s[0..len+extlen])); | |
451 } | |
452 | |
453 return defaultExt(name, ext); // doesn't have one | |
454 } | |
174 | 455 |
0 | 456 /****************************** |
457 * Return true if extensions match. | |
458 */ | |
174 | 459 |
0 | 460 bool equalsExt(string ext) |
461 { | |
462 string e = FileName.ext(); | |
463 if (e.length == 0 && ext.length == 0) | |
464 return true; | |
465 | |
466 if (e.length == 0 || ext.length == 0) | |
467 return false; | |
468 | |
469 version (POSIX) { | |
470 return cmp(e,ext) == 0; | |
114 | 471 } else version (Windows) { |
0 | 472 return icmp(e,ext) == 0; |
473 } else { | |
474 static assert(0); | |
475 } | |
476 } | |
174 | 477 |
0 | 478 /************************************* |
479 * Copy file from this to to. | |
480 */ | |
481 | |
482 void CopyTo(FileName to) | |
483 { | |
484 scope File file = new File(this); | |
485 | |
114 | 486 version (Win32) { |
2 | 487 file.touchtime = GC.malloc(WIN32_FIND_DATA.sizeof); // keep same file time |
114 | 488 } else version (Posix) { |
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:
5
diff
changeset
|
489 file.touchtime = GC.malloc(stat_t.sizeof); // keep same file time |
0 | 490 } else { |
491 static assert(0); | |
492 } | |
493 file.readv(); | |
494 file.name = to; | |
495 file.writev(); | |
496 } | |
174 | 497 |
0 | 498 /************************************* |
499 * Search Path for file. | |
500 * Input: | |
501 * cwd if true, search current directory before searching path | |
502 */ | |
503 | |
504 static string searchPath(Array path, string name, bool cwd) | |
505 { | |
506 if (absolute(name)) { | |
507 return exists(name) ? name : null; | |
508 } | |
174 | 509 |
0 | 510 if (cwd) { |
511 if (exists(name)) { | |
512 return name; | |
513 } | |
514 } | |
174 | 515 |
0 | 516 if (path !is null) { |
517 foreach (i; 0..path.dim) | |
518 { | |
519 String p = cast(String)path.data[i]; | |
520 string n = combine(p.str, name); | |
521 | |
522 if (exists(n)) | |
523 return n; | |
524 } | |
525 } | |
174 | 526 |
0 | 527 return null; |
528 } | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
529 |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
530 static string searchPath(string[] path, string name, bool cwd) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
531 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
532 if (absolute(name)) { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
533 return exists(name) ? name : null; |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
534 } |
174 | 535 |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
536 if (cwd) { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
537 if (exists(name)) { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
538 return name; |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
539 } |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
540 } |
174 | 541 |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
542 if (path !is null) { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
543 foreach (i, p; path) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
544 { |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
545 string n = combine(p, name); |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
546 |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
547 if (exists(n)) |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
548 return n; |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
549 } |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
550 } |
174 | 551 |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
552 return null; |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
553 } |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
554 |
0 | 555 static int exists(string name) |
556 { | |
114 | 557 version (Posix) { |
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:
5
diff
changeset
|
558 stat_t st; |
0 | 559 |
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:
5
diff
changeset
|
560 if (stat(toStringz(name), &st) < 0) |
0 | 561 return 0; |
562 if (S_ISDIR(st.st_mode)) | |
563 return 2; | |
564 return 1; | |
114 | 565 } else version (Win32) { |
0 | 566 HANDLE h = CreateFileA(toStringz(name), GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, HANDLE.init); /// |
567 if (h == INVALID_HANDLE_VALUE) { | |
568 return 0; | |
569 } | |
174 | 570 |
0 | 571 CloseHandle(h); |
572 | |
573 DWORD dw = GetFileAttributesA(name.ptr); /// CARE! | |
574 if (dw == -1L) { | |
575 assert(false); | |
576 return 0; | |
577 } else if (dw & FILE_ATTRIBUTE_DIRECTORY) { | |
578 return 2; | |
579 } else { | |
580 return 1; | |
581 } | |
582 } else { | |
583 static assert(0); | |
584 } | |
585 } | |
174 | 586 |
0 | 587 static void ensurePathExists(string path) |
588 { | |
136 | 589 if (path.length == 0) |
590 return; | |
0 | 591 try { |
592 mkdirRecurse(path); | |
593 } catch { | |
594 } | |
595 } | |
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:
5
diff
changeset
|
596 } |