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