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