summaryrefslogtreecommitdiff
path: root/fileaccess.c
diff options
context:
space:
mode:
Diffstat (limited to 'fileaccess.c')
-rw-r--r--fileaccess.c364
1 files changed, 164 insertions, 200 deletions
diff --git a/fileaccess.c b/fileaccess.c
index 98cf986ed1c1c..a10f38b75339e 100644
--- a/fileaccess.c
+++ b/fileaccess.c
@@ -3,7 +3,6 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#include <sys/stat.h>
#include "ficl.h"
#if FICL_WANT_FILE
@@ -15,27 +14,26 @@
**
*/
-static void pushIor(FICL_VM *pVM, int success)
+static void pushIor(ficlVm *vm, int success)
{
int ior;
if (success)
ior = 0;
else
ior = errno;
- stackPushINT(pVM->pStack, ior);
+ ficlStackPushInteger(vm->dataStack, ior);
}
-static void ficlFopen(FICL_VM *pVM, char *writeMode) /* ( c-addr u fam -- fileid ior ) */
+static void ficlFileOpen(ficlVm *vm, char *writeMode) /* ( c-addr u fam -- fileid ior ) */
{
- int fam = stackPopINT(pVM->pStack);
- int length = stackPopINT(pVM->pStack);
- void *address = (void *)stackPopPtr(pVM->pStack);
+ int fam = ficlStackPopInteger(vm->dataStack);
+ int length = ficlStackPopInteger(vm->dataStack);
+ void *address = (void *)ficlStackPopPointer(vm->dataStack);
char mode[4];
FILE *f;
-
- char *filename = (char *)alloca(length + 1);
+ char *filename = (char *)malloc(length + 1);
memcpy(filename, address, length);
filename[length] = 0;
@@ -44,9 +42,9 @@ static void ficlFopen(FICL_VM *pVM, char *writeMode) /* ( c-addr u fam -- fileid
switch (FICL_FAM_OPEN_MODE(fam))
{
case 0:
- stackPushPtr(pVM->pStack, NULL);
- stackPushINT(pVM->pStack, EINVAL);
- return;
+ ficlStackPushPointer(vm->dataStack, NULL);
+ ficlStackPushInteger(vm->dataStack, EINVAL);
+ goto EXIT;
case FICL_FAM_READ:
strcat(mode, "r");
break;
@@ -63,242 +61,201 @@ static void ficlFopen(FICL_VM *pVM, char *writeMode) /* ( c-addr u fam -- fileid
f = fopen(filename, mode);
if (f == NULL)
- stackPushPtr(pVM->pStack, NULL);
+ ficlStackPushPointer(vm->dataStack, NULL);
else
{
- ficlFILE *ff = (ficlFILE *)malloc(sizeof(ficlFILE));
+ ficlFile *ff = (ficlFile *)malloc(sizeof(ficlFile));
strcpy(ff->filename, filename);
ff->f = f;
- stackPushPtr(pVM->pStack, ff);
+ ficlStackPushPointer(vm->dataStack, ff);
fseek(f, 0, SEEK_SET);
}
- pushIor(pVM, f != NULL);
+ pushIor(vm, f != NULL);
+
+EXIT:
+ free(filename);
}
-static void ficlOpenFile(FICL_VM *pVM) /* ( c-addr u fam -- fileid ior ) */
+static void ficlPrimitiveOpenFile(ficlVm *vm) /* ( c-addr u fam -- fileid ior ) */
{
- ficlFopen(pVM, "a");
+ ficlFileOpen(vm, "a");
}
-static void ficlCreateFile(FICL_VM *pVM) /* ( c-addr u fam -- fileid ior ) */
+static void ficlPrimitiveCreateFile(ficlVm *vm) /* ( c-addr u fam -- fileid ior ) */
{
- ficlFopen(pVM, "w");
+ ficlFileOpen(vm, "w");
}
-static int closeFiclFILE(ficlFILE *ff) /* ( fileid -- ior ) */
+static int ficlFileClose(ficlFile *ff) /* ( fileid -- ior ) */
{
FILE *f = ff->f;
free(ff);
return !fclose(f);
}
-static void ficlCloseFile(FICL_VM *pVM) /* ( fileid -- ior ) */
+static void ficlPrimitiveCloseFile(ficlVm *vm) /* ( fileid -- ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- pushIor(pVM, closeFiclFILE(ff));
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ pushIor(vm, ficlFileClose(ff));
}
-static void ficlDeleteFile(FICL_VM *pVM) /* ( c-addr u -- ior ) */
+static void ficlPrimitiveDeleteFile(ficlVm *vm) /* ( c-addr u -- ior ) */
{
- int length = stackPopINT(pVM->pStack);
- void *address = (void *)stackPopPtr(pVM->pStack);
+ int length = ficlStackPopInteger(vm->dataStack);
+ void *address = (void *)ficlStackPopPointer(vm->dataStack);
- char *filename = (char *)alloca(length + 1);
+ char *filename = (char *)malloc(length + 1);
memcpy(filename, address, length);
filename[length] = 0;
- pushIor(pVM, !unlink(filename));
+ pushIor(vm, !unlink(filename));
+ free(filename);
}
-static void ficlRenameFile(FICL_VM *pVM) /* ( c-addr1 u1 c-addr2 u2 -- ior ) */
+static void ficlPrimitiveRenameFile(ficlVm *vm) /* ( c-addr1 u1 c-addr2 u2 -- ior ) */
{
int length;
void *address;
char *from;
char *to;
- length = stackPopINT(pVM->pStack);
- address = (void *)stackPopPtr(pVM->pStack);
- to = (char *)alloca(length + 1);
+ length = ficlStackPopInteger(vm->dataStack);
+ address = (void *)ficlStackPopPointer(vm->dataStack);
+ to = (char *)malloc(length + 1);
memcpy(to, address, length);
to[length] = 0;
- length = stackPopINT(pVM->pStack);
- address = (void *)stackPopPtr(pVM->pStack);
+ length = ficlStackPopInteger(vm->dataStack);
+ address = (void *)ficlStackPopPointer(vm->dataStack);
- from = (char *)alloca(length + 1);
+ from = (char *)malloc(length + 1);
memcpy(from, address, length);
from[length] = 0;
- pushIor(pVM, !rename(from, to));
+ pushIor(vm, !rename(from, to));
+
+ free(from);
+ free(to);
}
-static void ficlFileStatus(FICL_VM *pVM) /* ( c-addr u -- x ior ) */
+static void ficlPrimitiveFileStatus(ficlVm *vm) /* ( c-addr u -- x ior ) */
{
- struct stat statbuf;
+ int status;
+ int ior;
+
+ int length = ficlStackPopInteger(vm->dataStack);
+ void *address = (void *)ficlStackPopPointer(vm->dataStack);
- int length = stackPopINT(pVM->pStack);
- void *address = (void *)stackPopPtr(pVM->pStack);
-
- char *filename = (char *)alloca(length + 1);
+ char *filename = (char *)malloc(length + 1);
memcpy(filename, address, length);
filename[length] = 0;
- if (stat(filename, &statbuf) == 0)
- {
- /*
- ** the "x" left on the stack is implementation-defined.
- ** I push the file's access mode (readable, writeable, is directory, etc)
- ** as defined by ANSI C.
- */
- stackPushINT(pVM->pStack, statbuf.st_mode);
- stackPushINT(pVM->pStack, 0);
- }
- else
- {
- stackPushINT(pVM->pStack, -1);
- stackPushINT(pVM->pStack, ENOENT);
- }
-}
-
+ ior = ficlFileStatus(filename, &status);
+ free(filename);
-static void ficlFilePosition(FICL_VM *pVM) /* ( fileid -- ud ior ) */
-{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- long ud = ftell(ff->f);
- stackPushINT(pVM->pStack, ud);
- pushIor(pVM, ud != -1);
+ ficlStackPushInteger(vm->dataStack, status);
+ ficlStackPushInteger(vm->dataStack, ior);
}
-
-static long fileSize(FILE *f)
+static void ficlPrimitiveFilePosition(ficlVm *vm) /* ( fileid -- ud ior ) */
{
- struct stat statbuf;
- statbuf.st_size = -1;
- if (fstat(fileno(f), &statbuf) != 0)
- return -1;
- return statbuf.st_size;
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ long ud = ftell(ff->f);
+ ficlStackPushInteger(vm->dataStack, ud);
+ pushIor(vm, ud != -1);
}
-static void ficlFileSize(FICL_VM *pVM) /* ( fileid -- ud ior ) */
+static void ficlPrimitiveFileSize(ficlVm *vm) /* ( fileid -- ud ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- long ud = fileSize(ff->f);
- stackPushINT(pVM->pStack, ud);
- pushIor(pVM, ud != -1);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ long ud = ficlFileSize(ff);
+ ficlStackPushInteger(vm->dataStack, ud);
+ pushIor(vm, ud != -1);
}
#define nLINEBUF 256
-static void ficlIncludeFile(FICL_VM *pVM) /* ( i*x fileid -- j*x ) */
+static void ficlPrimitiveIncludeFile(ficlVm *vm) /* ( i*x fileid -- j*x ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- CELL id = pVM->sourceID;
- int result = VM_OUTOFTEXT;
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ ficlCell id = vm->sourceId;
+ int except = FICL_VM_STATUS_OUT_OF_TEXT;
long currentPosition, totalSize;
long size;
- pVM->sourceID.p = (void *)ff;
+ ficlString s;
+ vm->sourceId.p = (void *)ff;
currentPosition = ftell(ff->f);
- totalSize = fileSize(ff->f);
+ totalSize = ficlFileSize(ff);
size = totalSize - currentPosition;
if ((totalSize != -1) && (currentPosition != -1) && (size > 0))
- {
+ {
char *buffer = (char *)malloc(size);
long got = fread(buffer, 1, size, ff->f);
if (got == size)
- result = ficlExecC(pVM, buffer, size);
- }
-
-#if 0
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- CELL id = pVM->sourceID;
- char cp[nLINEBUF];
- int nLine = 0;
- int keepGoing;
- int result;
- pVM->sourceID.p = (void *)ff;
-
- /* feed each line to ficlExec */
- keepGoing = TRUE;
- while (keepGoing && fgets(cp, nLINEBUF, ff->f))
- {
- int len = strlen(cp) - 1;
-
- nLine++;
- if (len <= 0)
- continue;
-
- if (cp[len] == '\n')
- cp[len] = '\0';
-
- result = ficlExec(pVM, cp);
-
- switch (result)
- {
- case VM_OUTOFTEXT:
- case VM_USEREXIT:
- break;
-
- default:
- pVM->sourceID = id;
- keepGoing = FALSE;
- break;
- }
+ {
+ FICL_STRING_SET_POINTER(s, buffer);
+ FICL_STRING_SET_LENGTH(s, size);
+ except = ficlVmExecuteString(vm, s);
+ }
}
-#endif /* 0 */
+
+ if ((except < 0) && (except != FICL_VM_STATUS_OUT_OF_TEXT))
+ ficlVmThrow(vm, except);
+
/*
** Pass an empty line with SOURCE-ID == -1 to flush
** any pending REFILLs (as required by FILE wordset)
*/
- pVM->sourceID.i = -1;
- ficlExec(pVM, "");
+ vm->sourceId.i = -1;
+ FICL_STRING_SET_FROM_CSTRING(s, "");
+ ficlVmExecuteString(vm, s);
- pVM->sourceID = id;
- closeFiclFILE(ff);
+ vm->sourceId = id;
+ ficlFileClose(ff);
}
-static void ficlReadFile(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 ior ) */
+static void ficlPrimitiveReadFile(ficlVm *vm) /* ( c-addr u1 fileid -- u2 ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- int length = stackPopINT(pVM->pStack);
- void *address = (void *)stackPopPtr(pVM->pStack);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ int length = ficlStackPopInteger(vm->dataStack);
+ void *address = (void *)ficlStackPopPointer(vm->dataStack);
int result;
clearerr(ff->f);
result = fread(address, 1, length, ff->f);
- stackPushINT(pVM->pStack, result);
- pushIor(pVM, ferror(ff->f) == 0);
+ ficlStackPushInteger(vm->dataStack, result);
+ pushIor(vm, ferror(ff->f) == 0);
}
-static void ficlReadLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 flag ior ) */
+static void ficlPrimitiveReadLine(ficlVm *vm) /* ( c-addr u1 fileid -- u2 flag ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- int length = stackPopINT(pVM->pStack);
- char *address = (char *)stackPopPtr(pVM->pStack);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ int length = ficlStackPopInteger(vm->dataStack);
+ char *address = (char *)ficlStackPopPointer(vm->dataStack);
int error;
int flag;
if (feof(ff->f))
{
- stackPushINT(pVM->pStack, -1);
- stackPushINT(pVM->pStack, 0);
- stackPushINT(pVM->pStack, 0);
+ ficlStackPushInteger(vm->dataStack, -1);
+ ficlStackPushInteger(vm->dataStack, 0);
+ ficlStackPushInteger(vm->dataStack, 0);
return;
}
@@ -309,9 +266,9 @@ static void ficlReadLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 flag ior ) */
error = ferror(ff->f);
if (error != 0)
{
- stackPushINT(pVM->pStack, -1);
- stackPushINT(pVM->pStack, 0);
- stackPushINT(pVM->pStack, error);
+ ficlStackPushInteger(vm->dataStack, -1);
+ ficlStackPushInteger(vm->dataStack, 0);
+ ficlStackPushInteger(vm->dataStack, error);
return;
}
@@ -320,104 +277,111 @@ static void ficlReadLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 flag ior ) */
if (length && ((address[length - 1] == '\r') || (address[length - 1] == '\n')))
length--;
- stackPushINT(pVM->pStack, length);
- stackPushINT(pVM->pStack, flag);
- stackPushINT(pVM->pStack, 0); /* ior */
+ ficlStackPushInteger(vm->dataStack, length);
+ ficlStackPushInteger(vm->dataStack, flag);
+ ficlStackPushInteger(vm->dataStack, 0); /* ior */
}
-static void ficlWriteFile(FICL_VM *pVM) /* ( c-addr u1 fileid -- ior ) */
+static void ficlPrimitiveWriteFile(ficlVm *vm) /* ( c-addr u1 fileid -- ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- int length = stackPopINT(pVM->pStack);
- void *address = (void *)stackPopPtr(pVM->pStack);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ int length = ficlStackPopInteger(vm->dataStack);
+ void *address = (void *)ficlStackPopPointer(vm->dataStack);
clearerr(ff->f);
fwrite(address, 1, length, ff->f);
- pushIor(pVM, ferror(ff->f) == 0);
+ pushIor(vm, ferror(ff->f) == 0);
}
-static void ficlWriteLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- ior ) */
+static void ficlPrimitiveWriteLine(ficlVm *vm) /* ( c-addr u1 fileid -- ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- size_t length = (size_t)stackPopINT(pVM->pStack);
- void *address = (void *)stackPopPtr(pVM->pStack);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ size_t length = (size_t)ficlStackPopInteger(vm->dataStack);
+ void *address = (void *)ficlStackPopPointer(vm->dataStack);
clearerr(ff->f);
if (fwrite(address, 1, length, ff->f) == length)
fwrite("\n", 1, 1, ff->f);
- pushIor(pVM, ferror(ff->f) == 0);
+ pushIor(vm, ferror(ff->f) == 0);
}
-static void ficlRepositionFile(FICL_VM *pVM) /* ( ud fileid -- ior ) */
+static void ficlPrimitiveRepositionFile(ficlVm *vm) /* ( ud fileid -- ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- size_t ud = (size_t)stackPopINT(pVM->pStack);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ size_t ud = (size_t)ficlStackPopInteger(vm->dataStack);
- pushIor(pVM, fseek(ff->f, ud, SEEK_SET) == 0);
+ pushIor(vm, fseek(ff->f, ud, SEEK_SET) == 0);
}
-static void ficlFlushFile(FICL_VM *pVM) /* ( fileid -- ior ) */
+static void ficlPrimitiveFlushFile(ficlVm *vm) /* ( fileid -- ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- pushIor(pVM, fflush(ff->f) == 0);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ pushIor(vm, fflush(ff->f) == 0);
}
-#if FICL_HAVE_FTRUNCATE
+#if FICL_PLATFORM_HAS_FTRUNCATE
-static void ficlResizeFile(FICL_VM *pVM) /* ( ud fileid -- ior ) */
+static void ficlPrimitiveResizeFile(ficlVm *vm) /* ( ud fileid -- ior ) */
{
- ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack);
- size_t ud = (size_t)stackPopINT(pVM->pStack);
+ ficlFile *ff = (ficlFile *)ficlStackPopPointer(vm->dataStack);
+ size_t ud = (size_t)ficlStackPopInteger(vm->dataStack);
- pushIor(pVM, ftruncate(fileno(ff->f), ud) == 0);
+ pushIor(vm, ficlFileTruncate(ff, ud) == 0);
}
-#endif /* FICL_HAVE_FTRUNCATE */
+#endif /* FICL_PLATFORM_HAS_FTRUNCATE */
#endif /* FICL_WANT_FILE */
-void ficlCompileFile(FICL_SYSTEM *pSys)
+void ficlSystemCompileFile(ficlSystem *system)
{
-#if FICL_WANT_FILE
- FICL_DICT *dp = pSys->dp;
- assert(dp);
-
- dictAppendWord(dp, "create-file", ficlCreateFile, FW_DEFAULT);
- dictAppendWord(dp, "open-file", ficlOpenFile, FW_DEFAULT);
- dictAppendWord(dp, "close-file", ficlCloseFile, FW_DEFAULT);
- dictAppendWord(dp, "include-file", ficlIncludeFile, FW_DEFAULT);
- dictAppendWord(dp, "read-file", ficlReadFile, FW_DEFAULT);
- dictAppendWord(dp, "read-line", ficlReadLine, FW_DEFAULT);
- dictAppendWord(dp, "write-file", ficlWriteFile, FW_DEFAULT);
- dictAppendWord(dp, "write-line", ficlWriteLine, FW_DEFAULT);
- dictAppendWord(dp, "file-position", ficlFilePosition, FW_DEFAULT);
- dictAppendWord(dp, "file-size", ficlFileSize, FW_DEFAULT);
- dictAppendWord(dp, "reposition-file", ficlRepositionFile, FW_DEFAULT);
- dictAppendWord(dp, "file-status", ficlFileStatus, FW_DEFAULT);
- dictAppendWord(dp, "flush-file", ficlFlushFile, FW_DEFAULT);
-
- dictAppendWord(dp, "delete-file", ficlDeleteFile, FW_DEFAULT);
- dictAppendWord(dp, "rename-file", ficlRenameFile, FW_DEFAULT);
-
-#ifdef FICL_HAVE_FTRUNCATE
- dictAppendWord(dp, "resize-file", ficlResizeFile, FW_DEFAULT);
-
- ficlSetEnv(pSys, "file", FICL_TRUE);
- ficlSetEnv(pSys, "file-ext", FICL_TRUE);
-#endif /* FICL_HAVE_FTRUNCATE */
+#if !FICL_WANT_FILE
+ FICL_IGNORE(system);
#else
- &pSys;
-#endif /* FICL_WANT_FILE */
+ ficlDictionary *dictionary = ficlSystemGetDictionary(system);
+ ficlDictionary *environment = ficlSystemGetEnvironment(system);
+
+ FICL_SYSTEM_ASSERT(system, dictionary);
+ FICL_SYSTEM_ASSERT(system, environment);
+
+ ficlDictionarySetPrimitive(dictionary, "create-file", ficlPrimitiveCreateFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "open-file", ficlPrimitiveOpenFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "close-file", ficlPrimitiveCloseFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "include-file", ficlPrimitiveIncludeFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "read-file", ficlPrimitiveReadFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "read-line", ficlPrimitiveReadLine, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "write-file", ficlPrimitiveWriteFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "write-line", ficlPrimitiveWriteLine, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "file-position", ficlPrimitiveFilePosition, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "file-size", ficlPrimitiveFileSize, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "reposition-file", ficlPrimitiveRepositionFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "file-status", ficlPrimitiveFileStatus, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "flush-file", ficlPrimitiveFlushFile, FICL_WORD_DEFAULT);
+
+ ficlDictionarySetPrimitive(dictionary, "delete-file", ficlPrimitiveDeleteFile, FICL_WORD_DEFAULT);
+ ficlDictionarySetPrimitive(dictionary, "rename-file", ficlPrimitiveRenameFile, FICL_WORD_DEFAULT);
+
+#if FICL_PLATFORM_HAS_FTRUNCATE
+ ficlDictionarySetPrimitive(dictionary, "resize-file", ficlPrimitiveResizeFile, FICL_WORD_DEFAULT);
+
+ ficlDictionarySetConstant(environment, "file", FICL_TRUE);
+ ficlDictionarySetConstant(environment, "file-ext", FICL_TRUE);
+#else /* FICL_PLATFORM_HAS_FTRUNCATE */
+ ficlDictionarySetConstant(environment, "file", FICL_FALSE);
+ ficlDictionarySetConstant(environment, "file-ext", FICL_FALSE);
+#endif /* FICL_PLATFORM_HAS_FTRUNCATE */
+
+#endif /* !FICL_WANT_FILE */
}