Mercurial > projects > ddmd
annotate dmd/File.d @ 183:190ba98276b3
Several changes to make it build on posix systems.
I've only tried to build on Mac OS X but it should build on Linux now as well.
This should also fix ticket #9.
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 25 Oct 2010 15:36:13 +0200 |
parents | e3afd1303184 |
children | a4c9de8e39b3 |
rev | line source |
---|---|
0 | 1 module dmd.File; |
2 | |
114 | 3 import dmd.common; |
0 | 4 import dmd.FileName; |
5 import dmd.Array; | |
6 import dmd.Util; | |
7 | |
8 import core.stdc.stdlib; | |
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:
4
diff
changeset
|
9 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:
4
diff
changeset
|
10 { |
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:
4
diff
changeset
|
11 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:
4
diff
changeset
|
12 } |
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:
4
diff
changeset
|
13 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:
4
diff
changeset
|
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:
4
diff
changeset
|
15 import core.sys.posix.fcntl; |
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:
4
diff
changeset
|
16 import core.stdc.errno; |
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:
4
diff
changeset
|
17 import core.sys.posix.unistd; |
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:
4
diff
changeset
|
18 import core.sys.posix.utime; |
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:
4
diff
changeset
|
19 import core.stdc.stdio; |
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:
4
diff
changeset
|
20 } |
0 | 21 |
22 import std.string : toStringz; | |
174 | 23 import std.stdio; |
0 | 24 |
4 | 25 import core.memory; |
2 | 26 |
178 | 27 import dmd.TObject; |
28 | |
29 class File : TObject | |
0 | 30 { |
31 int ref_; // != 0 if this is a reference to someone else's buffer | |
32 ubyte* buffer; // data for our file | |
33 uint len; // amount of data in buffer[] | |
34 void* touchtime; // system time to use for file | |
35 | |
36 FileName name; // name of our file | |
37 | |
38 this(string n) | |
39 { | |
178 | 40 register(); |
0 | 41 name = new FileName(n); |
42 } | |
43 | |
44 this(FileName n) | |
45 { | |
178 | 46 register(); |
0 | 47 name = n; |
48 } | |
49 | |
50 ~this() | |
51 { | |
52 if (buffer !is null) { | |
53 if (ref_ == 0) { | |
2 | 54 ///free(buffer); |
0 | 55 } else { |
114 | 56 version (Windows) { |
0 | 57 if (ref_ == 2) { |
58 UnmapViewOfFile(buffer); | |
59 } | |
60 } | |
61 } | |
62 } | |
63 | |
64 if (touchtime !is null) { | |
2 | 65 ///free(touchtime); |
0 | 66 } |
67 } | |
68 | |
69 void mark() | |
70 { | |
71 ///mem.mark(buffer); | |
72 ///mem.mark(touchtime); | |
73 ///mem.mark(name); | |
74 } | |
75 | |
76 string toChars() | |
77 { | |
78 return name.toChars(); | |
79 } | |
80 | |
81 /* Read file, return !=0 if error | |
82 */ | |
83 | |
84 int read() | |
85 { | |
114 | 86 version (Posix) |
87 { | |
0 | 88 int result = 0; |
89 | |
90 string name = this.name.toChars(); | |
91 | |
174 | 92 //writefln("File::read('%s')\n",name); |
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:
4
diff
changeset
|
93 int fd = open(toStringz(name), O_RDONLY); |
0 | 94 if (fd == -1) { |
95 result = errno; | |
16
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
96 printf("file: %s\n", toStringz(name)); |
5c9b78899f5d
Implemented methods for Tuples, fixed some linking issues.
Robert Clipsham <robert@octarineparrot.com>
parents:
14
diff
changeset
|
97 printf("\topen error, errno = %d\n", errno); |
0 | 98 goto err1; |
99 } | |
100 | |
101 if (ref_ == 0) { | |
2 | 102 ///free(buffer); |
0 | 103 } |
104 | |
105 ref_ = 0; // we own the buffer now | |
106 | |
107 //printf("\tfile opened\n"); | |
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:
4
diff
changeset
|
108 stat_t buf; |
0 | 109 if (fstat(fd, &buf)) { |
110 printf("\tfstat error, errno = %d\n", errno); | |
111 goto err2; | |
112 } | |
113 | |
183
190ba98276b3
Several changes to make it build on posix systems.
Jacob Carlborg <doob@me.com>
parents:
178
diff
changeset
|
114 size_t size = cast(size_t) buf.st_size; |
2 | 115 buffer = cast(ubyte*)GC.malloc(size + 2); |
0 | 116 if (buffer is null) { |
117 printf("\tmalloc error, errno = %d\n", errno); | |
118 goto err2; | |
119 } | |
120 | |
121 ssize_t numread = .read(fd, buffer, size); | |
122 if (numread != size) { | |
123 printf("\tread error, errno = %d\n",errno); | |
124 goto err2; | |
125 } | |
126 | |
127 if (touchtime !is null) { | |
128 memcpy(touchtime, &buf, buf.sizeof); | |
129 } | |
130 | |
131 if (close(fd) == -1) { | |
132 printf("\tclose error, errno = %d\n",errno); | |
133 goto err; | |
134 } | |
135 | |
136 len = size; | |
137 | |
138 // Always store a wchar ^Z past end of buffer so scanner has a sentinel | |
139 buffer[size] = 0; // ^Z is obsolete, use 0 | |
140 buffer[size + 1] = 0; | |
141 | |
142 return 0; | |
143 | |
144 err2: | |
145 close(fd); | |
146 | |
147 err: | |
2 | 148 ///free(buffer); |
0 | 149 buffer = null; |
150 len = 0; | |
151 | |
152 err1: | |
153 result = 1; | |
154 return result; | |
114 | 155 } else version (Windows) { |
0 | 156 DWORD size; |
157 DWORD numread; | |
158 HANDLE h; | |
159 int result = 0; | |
160 | |
161 string name = this.name.toChars(); | |
174 | 162 //writeln("Open file ", name); |
0 | 163 |
164 h = CreateFileA(toStringz(name), GENERIC_READ, FILE_SHARE_READ, null, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, HANDLE.init); | |
165 if (h == INVALID_HANDLE_VALUE) { | |
166 goto err1; | |
167 } | |
168 | |
169 if (!ref_) { | |
2 | 170 ///free(buffer); |
0 | 171 } |
172 ref_ = 0; | |
173 | |
174 size = GetFileSize(h, null); | |
2 | 175 buffer = cast(ubyte*) GC.malloc(size + 2); |
0 | 176 if (!buffer) |
177 goto err2; | |
178 | |
179 if (ReadFile(h, buffer, size, &numread, null) != TRUE) | |
180 goto err2; | |
181 | |
182 if (numread != size) | |
183 goto err2; | |
184 | |
185 if (touchtime) { | |
186 if (!GetFileTime(h, null, null, &(cast(WIN32_FIND_DATA*)touchtime).ftLastWriteTime)) | |
187 goto err2; | |
188 } | |
189 | |
190 if (!CloseHandle(h)) | |
191 goto err; | |
192 | |
193 len = size; | |
194 | |
195 // Always store a wchar ^Z past end of buffer so scanner has a sentinel | |
196 buffer[size] = 0; // ^Z is obsolete, use 0 | |
197 buffer[size + 1] = 0; | |
198 return 0; | |
199 | |
200 err2: | |
201 CloseHandle(h); | |
202 err: | |
2 | 203 ///free(buffer); |
0 | 204 buffer = null; |
205 len = 0; | |
206 | |
207 err1: | |
208 result = 1; | |
209 return result; | |
210 } else { | |
211 static assert(0); | |
212 } | |
213 } | |
214 | |
215 /* Write file, either succeed or fail | |
216 * with error message & exit. | |
217 */ | |
218 | |
219 void readv() | |
220 { | |
221 if (read()) | |
222 error("Error reading file '%s'\n",name.toChars()); | |
223 } | |
224 | |
225 /* Read file, return !=0 if error | |
226 */ | |
227 | |
228 int mmread() | |
229 { | |
230 assert(false); | |
231 } | |
232 | |
233 /* Write file, either succeed or fail | |
234 * with error message & exit. | |
235 */ | |
236 | |
237 void mmreadv() | |
238 { | |
239 assert(false); | |
240 } | |
241 | |
242 /* Write file, return !=0 if error | |
243 */ | |
244 | |
245 /********************************************* | |
246 * Write a file. | |
247 * Returns: | |
248 * 0 success | |
249 */ | |
250 int write() | |
251 { | |
252 version (POSIX) { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
253 //assert(false); |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
254 |
0 | 255 int fd; |
256 ssize_t numwritten; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
257 const(char)* name = toStringz(this.name.toChars()); |
0 | 258 fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644); |
259 if (fd == -1) | |
260 goto err; | |
261 | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
262 numwritten = core.sys.posix.unistd.write(fd, buffer, len); |
0 | 263 if (len != numwritten) |
264 goto err2; | |
265 | |
266 if (close(fd) == -1) | |
267 goto err; | |
268 | |
269 if (touchtime) | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
270 { utimbuf ubuf; |
0 | 271 |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
272 ubuf.actime = (cast(stat_t *)touchtime).st_atime; |
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
273 ubuf.modtime = (cast(stat_t *)touchtime).st_mtime; |
0 | 274 if (utime(name, &ubuf)) |
275 goto err; | |
276 } | |
277 return 0; | |
278 | |
279 err2: | |
280 close(fd); | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
281 .remove(name); |
0 | 282 err: |
283 return 1; | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
16
diff
changeset
|
284 |
114 | 285 } else version (Windows) { |
0 | 286 HANDLE h; |
287 DWORD numwritten; | |
288 | |
289 const(char)* name = toStringz(this.name.toChars()); | |
290 h = CreateFileA(name, GENERIC_WRITE, 0, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, null); | |
291 if (h == INVALID_HANDLE_VALUE) | |
292 goto err; | |
293 | |
294 if (WriteFile(h, buffer, len, &numwritten, null) != TRUE) | |
295 goto err2; | |
296 | |
297 if (len != numwritten) | |
298 goto err2; | |
299 | |
300 if (touchtime) { | |
301 SetFileTime(h, null, null, &(cast(WIN32_FIND_DATA*)touchtime).ftLastWriteTime); | |
302 } | |
303 if (!CloseHandle(h)) | |
304 goto err; | |
305 return 0; | |
306 | |
307 err2: | |
308 CloseHandle(h); | |
309 DeleteFileA(name); | |
310 err: | |
311 return 1; | |
312 } else { | |
313 static assert(false); | |
314 } | |
315 } | |
316 | |
317 /* Write file, either succeed or fail | |
318 * with error message & exit. | |
319 */ | |
320 | |
321 void writev() | |
322 { | |
323 if (write()) { | |
324 error("Error writing file '%s'\n", name.toChars()); | |
325 } | |
326 } | |
327 | |
328 /* Return !=0 if file exists. | |
329 * 0: file doesn't exist | |
330 * 1: normal file | |
331 * 2: directory | |
332 */ | |
333 | |
334 /* Append to file, return !=0 if error | |
335 */ | |
336 | |
337 int append() | |
338 { | |
339 assert(false); | |
340 } | |
341 | |
342 /* Append to file, either succeed or fail | |
343 * with error message & exit. | |
344 */ | |
345 | |
346 void appendv() | |
347 { | |
348 assert(false); | |
349 } | |
350 | |
351 /* Return !=0 if file exists. | |
352 * 0: file doesn't exist | |
353 * 1: normal file | |
354 * 2: directory | |
355 */ | |
356 | |
357 int exists() | |
358 { | |
359 assert(false); | |
360 } | |
361 | |
362 /* Given wildcard filespec, return an array of | |
363 * matching File's. | |
364 */ | |
365 | |
366 static Array match(char*) | |
367 { | |
368 assert(false); | |
369 } | |
370 | |
371 static Array match(FileName *) | |
372 { | |
373 assert(false); | |
374 } | |
375 | |
376 // Compare file times. | |
377 // Return <0 this < f | |
378 // =0 this == f | |
379 // >0 this > f | |
380 int compareTime(File f) | |
381 { | |
382 assert(false); | |
383 } | |
384 | |
385 // Read system file statistics | |
386 void stat() | |
387 { | |
388 assert(false); | |
389 } | |
390 | |
391 /* Set buffer | |
392 */ | |
393 | |
394 void setbuffer(void* buffer, uint len) | |
395 { | |
396 this.buffer = cast(ubyte*)buffer; | |
397 this.len = len; | |
398 } | |
399 | |
400 void checkoffset(size_t offset, size_t nbytes) | |
401 { | |
402 assert(false); | |
403 } | |
404 | |
405 void remove() // delete file | |
406 { | |
407 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:
4
diff
changeset
|
408 .remove(toStringz(this.name.toChars())); |
0 | 409 } else version (_WIN32) { |
410 DeleteFileA(toStringz(this.name.toChars())); | |
411 } else { | |
412 assert(0); | |
413 } | |
414 } | |
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:
4
diff
changeset
|
415 } |