Mercurial > projects > ddmd
annotate dmd/File.d @ 178:e3afd1303184
Many small bugs fixed
Made all classes derive from TObject to detect memory leaks (functionality is disabled for now)
Began work on overriding backend memory allocations (to avoid memory leaks)
author | korDen |
---|---|
date | Sun, 17 Oct 2010 07:42:00 +0400 |
parents | af724d3510d7 |
children | 190ba98276b3 |
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 | |
114 off_t size = 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 } |