7 * Implements all of the File Access word set that can be implemented in
12 pushIor(ficlVm
*vm
, int success
)
19 ficlStackPushInteger(vm
->dataStack
, ior
);
22 /* ( c-addr u fam -- fileid ior ) */
24 ficlFileOpen(ficlVm
*vm
, char *writeMode
)
26 int fam
= ficlStackPopInteger(vm
->dataStack
);
27 int length
= ficlStackPopInteger(vm
->dataStack
);
28 void *address
= (void *)ficlStackPopPointer(vm
->dataStack
);
31 char *filename
= (char *)malloc(length
+ 1);
32 memcpy(filename
, address
, length
);
37 switch (FICL_FAM_OPEN_MODE(fam
)) {
39 ficlStackPushPointer(vm
->dataStack
, NULL
);
40 ficlStackPushInteger(vm
->dataStack
, EINVAL
);
46 strcat(mode
, writeMode
);
48 case FICL_FAM_READ
| FICL_FAM_WRITE
:
49 strcat(mode
, writeMode
);
54 strcat(mode
, (fam
& FICL_FAM_BINARY
) ? "b" : "t");
56 f
= fopen(filename
, mode
);
58 ficlStackPushPointer(vm
->dataStack
, NULL
);
60 ficlFile
*ff
= (ficlFile
*)malloc(sizeof (ficlFile
));
61 strcpy(ff
->filename
, filename
);
63 ficlStackPushPointer(vm
->dataStack
, ff
);
65 fseek(f
, 0, SEEK_SET
);
67 pushIor(vm
, f
!= NULL
);
73 /* ( c-addr u fam -- fileid ior ) */
75 ficlPrimitiveOpenFile(ficlVm
*vm
)
77 ficlFileOpen(vm
, "a");
80 /* ( c-addr u fam -- fileid ior ) */
82 ficlPrimitiveCreateFile(ficlVm
*vm
)
84 ficlFileOpen(vm
, "w");
87 /* ( fileid -- ior ) */
89 ficlFileClose(ficlFile
*ff
)
96 /* ( fileid -- ior ) */
98 ficlPrimitiveCloseFile(ficlVm
*vm
)
100 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
101 pushIor(vm
, ficlFileClose(ff
));
104 /* ( c-addr u -- ior ) */
106 ficlPrimitiveDeleteFile(ficlVm
*vm
)
108 int length
= ficlStackPopInteger(vm
->dataStack
);
109 void *address
= (void *)ficlStackPopPointer(vm
->dataStack
);
111 char *filename
= (char *)malloc(length
+ 1);
112 memcpy(filename
, address
, length
);
113 filename
[length
] = 0;
115 pushIor(vm
, !unlink(filename
));
119 /* ( c-addr1 u1 c-addr2 u2 -- ior ) */
121 ficlPrimitiveRenameFile(ficlVm
*vm
)
128 length
= ficlStackPopInteger(vm
->dataStack
);
129 address
= (void *)ficlStackPopPointer(vm
->dataStack
);
130 to
= (char *)malloc(length
+ 1);
131 memcpy(to
, address
, length
);
134 length
= ficlStackPopInteger(vm
->dataStack
);
135 address
= (void *)ficlStackPopPointer(vm
->dataStack
);
137 from
= (char *)malloc(length
+ 1);
138 memcpy(from
, address
, length
);
141 pushIor(vm
, !rename(from
, to
));
147 /* ( c-addr u -- x ior ) */
149 ficlPrimitiveFileStatus(ficlVm
*vm
)
154 int length
= ficlStackPopInteger(vm
->dataStack
);
155 void *address
= (void *)ficlStackPopPointer(vm
->dataStack
);
157 char *filename
= (char *)malloc(length
+ 1);
158 memcpy(filename
, address
, length
);
159 filename
[length
] = 0;
161 ior
= ficlFileStatus(filename
, &status
);
164 ficlStackPushInteger(vm
->dataStack
, status
);
165 ficlStackPushInteger(vm
->dataStack
, ior
);
168 /* ( fileid -- ud ior ) */
170 ficlPrimitiveFilePosition(ficlVm
*vm
)
172 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
173 long ud
= ftell(ff
->f
);
174 ficlStackPushInteger(vm
->dataStack
, ud
);
175 pushIor(vm
, ud
!= -1);
178 /* ( fileid -- ud ior ) */
180 ficlPrimitiveFileSize(ficlVm
*vm
)
182 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
183 long ud
= ficlFileSize(ff
);
184 ficlStackPushInteger(vm
->dataStack
, ud
);
185 pushIor(vm
, ud
!= -1);
188 /* ( i*x fileid -- j*x ) */
191 ficlPrimitiveIncludeFile(ficlVm
*vm
)
193 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
194 ficlCell id
= vm
->sourceId
;
195 int except
= FICL_VM_STATUS_OUT_OF_TEXT
;
196 long currentPosition
, totalSize
;
199 vm
->sourceId
.p
= (void *)ff
;
201 currentPosition
= ftell(ff
->f
);
202 totalSize
= ficlFileSize(ff
);
203 size
= totalSize
- currentPosition
;
205 if ((totalSize
!= -1) && (currentPosition
!= -1) && (size
> 0)) {
206 char *buffer
= (char *)malloc(size
);
207 long got
= fread(buffer
, 1, size
, ff
->f
);
209 FICL_STRING_SET_POINTER(s
, buffer
);
210 FICL_STRING_SET_LENGTH(s
, size
);
211 except
= ficlVmExecuteString(vm
, s
);
215 if ((except
< 0) && (except
!= FICL_VM_STATUS_OUT_OF_TEXT
))
216 ficlVmThrow(vm
, except
);
219 * Pass an empty line with SOURCE-ID == -1 to flush
220 * any pending REFILLs (as required by FILE wordset)
223 FICL_STRING_SET_FROM_CSTRING(s
, "");
224 ficlVmExecuteString(vm
, s
);
230 /* ( c-addr u1 fileid -- u2 ior ) */
232 ficlPrimitiveReadFile(ficlVm
*vm
)
234 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
235 int length
= ficlStackPopInteger(vm
->dataStack
);
236 void *address
= (void *)ficlStackPopPointer(vm
->dataStack
);
240 result
= fread(address
, 1, length
, ff
->f
);
242 ficlStackPushInteger(vm
->dataStack
, result
);
243 pushIor(vm
, ferror(ff
->f
) == 0);
246 /* ( c-addr u1 fileid -- u2 flag ior ) */
248 ficlPrimitiveReadLine(ficlVm
*vm
)
250 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
251 int length
= ficlStackPopInteger(vm
->dataStack
);
252 char *address
= (char *)ficlStackPopPointer(vm
->dataStack
);
257 ficlStackPushInteger(vm
->dataStack
, -1);
258 ficlStackPushInteger(vm
->dataStack
, 0);
259 ficlStackPushInteger(vm
->dataStack
, 0);
265 fgets(address
, length
, ff
->f
);
267 error
= ferror(ff
->f
);
269 ficlStackPushInteger(vm
->dataStack
, -1);
270 ficlStackPushInteger(vm
->dataStack
, 0);
271 ficlStackPushInteger(vm
->dataStack
, error
);
275 length
= strlen(address
);
277 if (length
&& ((address
[length
- 1] == '\r') ||
278 (address
[length
- 1] == '\n')))
281 ficlStackPushInteger(vm
->dataStack
, length
);
282 ficlStackPushInteger(vm
->dataStack
, flag
);
283 ficlStackPushInteger(vm
->dataStack
, 0); /* ior */
286 /* ( c-addr u1 fileid -- ior ) */
288 ficlPrimitiveWriteFile(ficlVm
*vm
)
290 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
291 int length
= ficlStackPopInteger(vm
->dataStack
);
292 void *address
= (void *)ficlStackPopPointer(vm
->dataStack
);
295 fwrite(address
, 1, length
, ff
->f
);
296 pushIor(vm
, ferror(ff
->f
) == 0);
299 /* ( c-addr u1 fileid -- ior ) */
301 ficlPrimitiveWriteLine(ficlVm
*vm
)
303 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
304 size_t length
= (size_t)ficlStackPopInteger(vm
->dataStack
);
305 void *address
= (void *)ficlStackPopPointer(vm
->dataStack
);
308 if (fwrite(address
, 1, length
, ff
->f
) == length
)
309 fwrite("\n", 1, 1, ff
->f
);
310 pushIor(vm
, ferror(ff
->f
) == 0);
313 /* ( ud fileid -- ior ) */
315 ficlPrimitiveRepositionFile(ficlVm
*vm
)
317 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
318 size_t ud
= (size_t)ficlStackPopInteger(vm
->dataStack
);
320 pushIor(vm
, fseek(ff
->f
, ud
, SEEK_SET
) == 0);
323 /* ( fileid -- ior ) */
325 ficlPrimitiveFlushFile(ficlVm
*vm
)
327 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
328 pushIor(vm
, fflush(ff
->f
) == 0);
331 #if FICL_PLATFORM_HAS_FTRUNCATE
332 /* ( ud fileid -- ior ) */
334 ficlPrimitiveResizeFile(ficlVm
*vm
)
336 ficlFile
*ff
= (ficlFile
*)ficlStackPopPointer(vm
->dataStack
);
337 size_t ud
= (size_t)ficlStackPopInteger(vm
->dataStack
);
339 pushIor(vm
, ficlFileTruncate(ff
, ud
) == 0);
341 #endif /* FICL_PLATFORM_HAS_FTRUNCATE */
342 #endif /* FICL_WANT_FILE */
345 ficlSystemCompileFile(ficlSystem
*system
)
350 ficlDictionary
*dictionary
= ficlSystemGetDictionary(system
);
351 ficlDictionary
*environment
= ficlSystemGetEnvironment(system
);
353 FICL_SYSTEM_ASSERT(system
, dictionary
);
354 FICL_SYSTEM_ASSERT(system
, environment
);
356 ficlDictionarySetPrimitive(dictionary
, "create-file",
357 ficlPrimitiveCreateFile
, FICL_WORD_DEFAULT
);
358 ficlDictionarySetPrimitive(dictionary
, "open-file",
359 ficlPrimitiveOpenFile
, FICL_WORD_DEFAULT
);
360 ficlDictionarySetPrimitive(dictionary
, "close-file",
361 ficlPrimitiveCloseFile
, FICL_WORD_DEFAULT
);
362 ficlDictionarySetPrimitive(dictionary
, "include-file",
363 ficlPrimitiveIncludeFile
, FICL_WORD_DEFAULT
);
364 ficlDictionarySetPrimitive(dictionary
, "read-file",
365 ficlPrimitiveReadFile
, FICL_WORD_DEFAULT
);
366 ficlDictionarySetPrimitive(dictionary
, "read-line",
367 ficlPrimitiveReadLine
, FICL_WORD_DEFAULT
);
368 ficlDictionarySetPrimitive(dictionary
, "write-file",
369 ficlPrimitiveWriteFile
, FICL_WORD_DEFAULT
);
370 ficlDictionarySetPrimitive(dictionary
, "write-line",
371 ficlPrimitiveWriteLine
, FICL_WORD_DEFAULT
);
372 ficlDictionarySetPrimitive(dictionary
, "file-position",
373 ficlPrimitiveFilePosition
, FICL_WORD_DEFAULT
);
374 ficlDictionarySetPrimitive(dictionary
, "file-size",
375 ficlPrimitiveFileSize
, FICL_WORD_DEFAULT
);
376 ficlDictionarySetPrimitive(dictionary
, "reposition-file",
377 ficlPrimitiveRepositionFile
, FICL_WORD_DEFAULT
);
378 ficlDictionarySetPrimitive(dictionary
, "file-status",
379 ficlPrimitiveFileStatus
, FICL_WORD_DEFAULT
);
380 ficlDictionarySetPrimitive(dictionary
, "flush-file",
381 ficlPrimitiveFlushFile
, FICL_WORD_DEFAULT
);
383 ficlDictionarySetPrimitive(dictionary
, "delete-file",
384 ficlPrimitiveDeleteFile
, FICL_WORD_DEFAULT
);
385 ficlDictionarySetPrimitive(dictionary
, "rename-file",
386 ficlPrimitiveRenameFile
, FICL_WORD_DEFAULT
);
388 #if FICL_PLATFORM_HAS_FTRUNCATE
389 ficlDictionarySetPrimitive(dictionary
, "resize-file",
390 ficlPrimitiveResizeFile
, FICL_WORD_DEFAULT
);
392 ficlDictionarySetConstant(environment
, "file", FICL_TRUE
);
393 ficlDictionarySetConstant(environment
, "file-ext", FICL_TRUE
);
394 #else /* FICL_PLATFORM_HAS_FTRUNCATE */
395 ficlDictionarySetConstant(environment
, "file", FICL_FALSE
);
396 ficlDictionarySetConstant(environment
, "file-ext", FICL_FALSE
);
397 #endif /* FICL_PLATFORM_HAS_FTRUNCATE */
399 #endif /* !FICL_WANT_FILE */