#ifndef _STANDALONE
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#include <termios.h>
#else
#include <stand.h>
#include <gfx_fb.h>
#include <sys/tem_impl.h>
#include "bootstrap.h"
#endif
#ifdef _STANDALONE
#include <uuid.h>
#else
#include <uuid/uuid.h>
#endif
#include <string.h>
#include <gfx_fb.h>
#include "ficl.h"
#ifdef _STANDALONE
void
ficl_term_putimage(ficlVm *pVM)
{
char *namep, *name;
ficlUnsigned names;
ficlInteger ret = FICL_FALSE;
uint32_t x1, y1, x2, y2, f;
png_t png;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 7, 1);
names = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
y2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
f = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x1 = tems.ts_p_offset.x + x1 * tems.ts_font.vf_width;
y1 = tems.ts_p_offset.y + y1 * tems.ts_font.vf_height;
if (x2 != 0) {
x2 = tems.ts_p_offset.x +
x2 * tems.ts_font.vf_width;
}
if (y2 != 0) {
y2 = tems.ts_p_offset.y +
y2 * tems.ts_font.vf_height;
}
name = ficlMalloc(names + 1);
if (!name)
ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(name, namep, names);
name[names] = '\0';
if (png_open(&png, name) == PNG_NO_ERROR) {
if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
ret = FICL_TRUE;
(void) png_close(&png);
}
ficlFree(name);
ficlStackPushInteger(ficlVmGetDataStack(pVM), ret);
}
#endif
void
ficl_fb_putimage(ficlVm *pVM)
{
char *namep, *name;
ficlUnsigned names;
ficlInteger ret = FICL_FALSE;
uint32_t x1, y1, x2, y2, f;
png_t png;
int error;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 7, 1);
names = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
y2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
f = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
name = ficlMalloc(names + 1);
if (!name)
ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(name, namep, names);
name[names] = '\0';
if ((error = png_open(&png, name)) != PNG_NO_ERROR) {
if (f & FL_PUTIMAGE_DEBUG)
printf("%s\n", png_error_string(error));
} else {
if (gfx_fb_putimage(&png, x1, y1, x2, y2, f) == 0)
ret = FICL_TRUE;
(void) png_close(&png);
}
ficlFree(name);
ficlStackPushInteger(ficlVmGetDataStack(pVM), ret);
}
void
ficl_fb_setpixel(ficlVm *pVM)
{
ficlUnsigned x, y;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0);
y = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
gfx_fb_setpixel(x, y);
}
void
ficl_fb_line(ficlVm *pVM)
{
ficlUnsigned x0, y0, x1, y1, wd;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 5, 0);
wd = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y0 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x0 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
gfx_fb_line(x0, y0, x1, y1, wd);
}
void
ficl_fb_bezier(ficlVm *pVM)
{
ficlUnsigned x0, y0, x1, y1, x2, y2, width;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 7, 0);
width = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y0 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x0 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
gfx_fb_bezier(x0, y0, x1, y1, x2, y2, width);
}
void
ficl_fb_drawrect(ficlVm *pVM)
{
ficlUnsigned x1, x2, y1, y2, fill;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 5, 0);
fill = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
gfx_fb_drawrect(x1, y1, x2, y2, fill);
}
void
ficl_term_drawrect(ficlVm *pVM)
{
ficlUnsigned x1, x2, y1, y2;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 4, 0);
y2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x2 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
y1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
x1 = ficlStackPopUnsigned(ficlVmGetDataStack(pVM));
gfx_term_drawrect(x1, y1, x2, y2);
}
void
ficlSetenv(ficlVm *pVM)
{
char *name, *value;
char *namep, *valuep;
int names, values;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 4, 0);
names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
values = ficlStackPopInteger(ficlVmGetDataStack(pVM));
valuep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
name = (char *)ficlMalloc(names+1);
if (!name)
ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(name, namep, names);
name[names] = '\0';
value = (char *)ficlMalloc(values+1);
if (!value)
ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(value, valuep, values);
value[values] = '\0';
(void) setenv(name, value, 1);
ficlFree(name);
ficlFree(value);
}
void
ficlSetenvq(ficlVm *pVM)
{
char *name, *value;
char *namep, *valuep;
int names, values, overwrite;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 5, 0);
overwrite = ficlStackPopInteger(ficlVmGetDataStack(pVM));
names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
values = ficlStackPopInteger(ficlVmGetDataStack(pVM));
valuep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
name = (char *)ficlMalloc(names+1);
if (!name)
(void) ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(name, namep, names);
name[names] = '\0';
value = (char *)ficlMalloc(values+1);
if (!value)
ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(value, valuep, values);
value[values] = '\0';
(void) setenv(name, value, overwrite);
ficlFree(name);
ficlFree(value);
}
void
ficlGetenv(ficlVm *pVM)
{
char *name, *value;
char *namep;
int names;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 2);
names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
name = (char *)ficlMalloc(names+1);
if (!name)
ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(name, namep, names);
name[names] = '\0';
value = getenv(name);
ficlFree(name);
if (value != NULL) {
ficlStackPushPointer(ficlVmGetDataStack(pVM), value);
ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(value));
} else
ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
}
void
ficlUnsetenv(ficlVm *pVM)
{
char *name;
char *namep;
int names;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0);
names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
name = (char *)ficlMalloc(names+1);
if (!name)
ficlVmThrowError(pVM, "Error: out of memory");
(void) strncpy(name, namep, names);
name[names] = '\0';
(void) unsetenv(name);
ficlFree(name);
}
void
ficlCopyin(ficlVm *pVM)
{
#ifdef _STANDALONE
void* src;
vm_offset_t dest;
size_t len;
#endif
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 0);
#ifdef _STANDALONE
len = ficlStackPopInteger(ficlVmGetDataStack(pVM));
dest = ficlStackPopInteger(ficlVmGetDataStack(pVM));
src = ficlStackPopPointer(ficlVmGetDataStack(pVM));
archsw.arch_copyin(src, dest, len);
#else
(void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
(void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
(void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
#endif
}
void
ficlCopyout(ficlVm *pVM)
{
#ifdef _STANDALONE
void* dest;
vm_offset_t src;
size_t len;
#endif
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 0);
#ifdef _STANDALONE
len = ficlStackPopInteger(ficlVmGetDataStack(pVM));
dest = ficlStackPopPointer(ficlVmGetDataStack(pVM));
src = ficlStackPopInteger(ficlVmGetDataStack(pVM));
archsw.arch_copyout(src, dest, len);
#else
(void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
(void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
(void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
#endif
}
void
ficlFindfile(ficlVm *pVM)
{
#ifdef _STANDALONE
char *name, *type;
char *namep, *typep;
int names, types;
#endif
struct preloaded_file *fp;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 4, 1);
#ifdef _STANDALONE
types = ficlStackPopInteger(ficlVmGetDataStack(pVM));
typep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
name = (char *)ficlMalloc(names+1);
if (!name)
ficlVmThrowError(pVM, "Error: out of memory");
strncpy(name, namep, names);
name[names] = '\0';
type = (char *)ficlMalloc(types+1);
if (!type)
ficlVmThrowError(pVM, "Error: out of memory");
strncpy(type, typep, types);
type[types] = '\0';
fp = file_findfile(name, type);
#else
(void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
(void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
(void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
(void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
fp = NULL;
#endif
ficlStackPushPointer(ficlVmGetDataStack(pVM), fp);
}
static void
ficlIsvirtualizedQ(ficlVm *pVM)
{
const char *hv;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 3);
#ifdef _STANDALONE
hv = (archsw.arch_hypervisor != NULL)
? (*archsw.arch_hypervisor)()
: NULL;
#else
hv = NULL;
#endif
if (hv != NULL) {
ficlStackPushPointer(ficlVmGetDataStack(pVM), (void *)hv);
ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(hv));
ficlStackPushInteger(ficlVmGetDataStack(pVM), FICL_TRUE);
} else {
ficlStackPushInteger(ficlVmGetDataStack(pVM), FICL_FALSE);
}
}
void
ficlCcall(ficlVm *pVM)
{
int (*func)(int, ...);
int result, p[10];
int nparam, i;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0);
func = (int (*)(int, ...))ficlStackPopPointer(ficlVmGetDataStack(pVM));
nparam = ficlStackPopInteger(ficlVmGetDataStack(pVM));
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), nparam, 1);
for (i = 0; i < nparam; i++)
p[i] = ficlStackPopInteger(ficlVmGetDataStack(pVM));
result = func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8],
p[9]);
ficlStackPushInteger(ficlVmGetDataStack(pVM), result);
}
void
ficlUuidFromString(ficlVm *pVM)
{
char *uuid;
char *uuid_ptr;
int uuid_size;
uuid_t *u;
#ifdef _STANDALONE
uint32_t status;
#else
int status;
#endif
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0);
uuid_size = ficlStackPopInteger(ficlVmGetDataStack(pVM));
uuid_ptr = ficlStackPopPointer(ficlVmGetDataStack(pVM));
uuid = ficlMalloc(uuid_size + 1);
if (!uuid)
ficlVmThrowError(pVM, "Error: out of memory");
(void) memcpy(uuid, uuid_ptr, uuid_size);
uuid[uuid_size] = '\0';
u = ficlMalloc(sizeof (*u));
#ifdef _STANDALONE
uuid_from_string(uuid, u, &status);
ficlFree(uuid);
if (status != uuid_s_ok) {
ficlFree(u);
u = NULL;
}
#else
status = uuid_parse(uuid, *u);
ficlFree(uuid);
if (status != 0) {
ficlFree(u);
u = NULL;
}
#endif
ficlStackPushPointer(ficlVmGetDataStack(pVM), u);
}
void
ficlUuidToString(ficlVm *pVM)
{
char *uuid;
uuid_t *u;
#ifdef _STANDALONE
uint32_t status;
#endif
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
u = ficlStackPopPointer(ficlVmGetDataStack(pVM));
#ifdef _STANDALONE
uuid_to_string(u, &uuid, &status);
if (status == uuid_s_ok) {
ficlStackPushPointer(ficlVmGetDataStack(pVM), uuid);
ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(uuid));
} else
#else
uuid = ficlMalloc(UUID_PRINTABLE_STRING_LENGTH);
if (uuid != NULL) {
uuid_unparse(*u, uuid);
ficlStackPushPointer(ficlVmGetDataStack(pVM), uuid);
ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(uuid));
} else
#endif
ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
}
#define nLINEBUF 256
int
ficlExecFD(ficlVm *pVM, int fd)
{
char cp[nLINEBUF];
int nLine = 0, rval = FICL_VM_STATUS_OUT_OF_TEXT;
char ch;
ficlCell id;
ficlString s;
id = pVM->sourceId;
pVM->sourceId.i = fd+1;
while (1) {
int status, i;
i = 0;
while ((status = read(fd, &ch, 1)) > 0 && ch != '\n')
cp[i++] = ch;
nLine++;
if (!i) {
if (status < 1)
break;
continue;
}
if (cp[i] == '\n')
cp[i] = '\0';
FICL_STRING_SET_POINTER(s, cp);
FICL_STRING_SET_LENGTH(s, i);
rval = ficlVmExecuteString(pVM, s);
if (rval != FICL_VM_STATUS_QUIT &&
rval != FICL_VM_STATUS_USER_EXIT &&
rval != FICL_VM_STATUS_OUT_OF_TEXT) {
pVM->sourceId = id;
(void) ficlVmEvaluate(pVM, "");
return (rval);
}
}
pVM->sourceId = id;
(void) ficlVmEvaluate(pVM, "");
if (rval == FICL_VM_STATUS_USER_EXIT)
ficlVmThrow(pVM, FICL_VM_STATUS_USER_EXIT);
return (rval);
}
static void displayCellNoPad(ficlVm *pVM)
{
ficlCell c;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
c = ficlStackPop(ficlVmGetDataStack(pVM));
(void) ficlLtoa((c).i, pVM->pad, pVM->base);
ficlVmTextOut(pVM, pVM->pad);
}
static void
isdirQuestion(ficlVm *pVM)
{
struct stat sb;
ficlInteger flag;
int fd;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 1);
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
flag = FICL_FALSE;
do {
if (fd < 0)
break;
if (fstat(fd, &sb) < 0)
break;
if (!S_ISDIR(sb.st_mode))
break;
flag = FICL_TRUE;
} while (0);
ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
}
extern char *get_dev(const char *);
static void
pfopen(ficlVm *pVM)
{
int mode, fd, count;
char *ptr, *name;
#ifndef _STANDALONE
char *tmp;
#endif
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
mode = ficlStackPopInteger(ficlVmGetDataStack(pVM));
count = ficlStackPopInteger(ficlVmGetDataStack(pVM));
ptr = ficlStackPopPointer(ficlVmGetDataStack(pVM));
if ((count < 0) || (ptr == NULL)) {
ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
return;
}
name = (char *)malloc(count+1);
bcopy(ptr, name, count);
name[count] = 0;
#ifndef _STANDALONE
tmp = get_dev(name);
free(name);
name = tmp;
#endif
fd = open(name, mode);
free(name);
ficlStackPushInteger(ficlVmGetDataStack(pVM), fd);
}
static void
pfclose(ficlVm *pVM)
{
int fd;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
if (fd != -1)
(void) close(fd);
}
static void
pfread(ficlVm *pVM)
{
int fd, len;
char *buf;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
len = ficlStackPopInteger(ficlVmGetDataStack(pVM));
buf = ficlStackPopPointer(ficlVmGetDataStack(pVM));
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
if (len > 0 && buf && fd != -1)
ficlStackPushInteger(ficlVmGetDataStack(pVM),
read(fd, buf, len));
else
ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
}
static void pfopendir(ficlVm *pVM)
{
#ifndef _STANDALONE
DIR *dir;
char *tmp;
#else
struct stat sb;
int fd;
#endif
ficlInteger count;
char *ptr, *name;
ficlInteger flag = FICL_FALSE;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 1);
count = ficlStackPopInteger(ficlVmGetDataStack(pVM));
ptr = ficlStackPopPointer(ficlVmGetDataStack(pVM));
if ((count < 0) || (ptr == NULL)) {
ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
return;
}
if ((name = malloc(count + 1)) == NULL) {
ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
return;
}
bcopy(ptr, name, count);
name[count] = 0;
#ifndef _STANDALONE
tmp = get_dev(name);
free(name);
name = tmp;
dir = opendir(name);
if (dir == NULL) {
ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
return;
} else
flag = FICL_TRUE;
ficlStackPushPointer(ficlVmGetDataStack(pVM), dir);
ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
#else
fd = open(name, O_RDONLY);
free(name);
do {
if (fd < 0)
break;
if (fstat(fd, &sb) < 0)
break;
if (!S_ISDIR(sb.st_mode))
break;
flag = FICL_TRUE;
ficlStackPushInteger(ficlVmGetDataStack(pVM), fd);
ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
return;
} while (0);
if (fd >= 0)
close(fd);
ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
#endif
}
static void
pfreaddir(ficlVm *pVM)
{
#ifndef _STANDALONE
static DIR *dir = NULL;
#else
int fd;
#endif
struct dirent *d = NULL;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 3);
#ifndef _STANDALONE
dir = ficlStackPopPointer(ficlVmGetDataStack(pVM));
if (dir != NULL)
do {
d = readdir(dir);
if (d != NULL && strcmp(d->d_name, ".") == 0)
continue;
if (d != NULL && strcmp(d->d_name, "..") == 0)
continue;
break;
} while (d != NULL);
#else
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
if (fd != -1)
do {
d = readdirfd(fd);
if (d != NULL && strcmp(d->d_name, ".") == 0)
continue;
if (d != NULL && strcmp(d->d_name, "..") == 0)
continue;
break;
} while (d != NULL);
#endif
if (d != NULL) {
ficlStackPushPointer(ficlVmGetDataStack(pVM), d->d_name);
ficlStackPushInteger(ficlVmGetDataStack(pVM),
strlen(d->d_name));
ficlStackPushInteger(ficlVmGetDataStack(pVM), FICL_TRUE);
} else {
ficlStackPushInteger(ficlVmGetDataStack(pVM), FICL_FALSE);
}
}
static void
pfclosedir(ficlVm *pVM)
{
#ifndef _STANDALONE
DIR *dir;
#else
int fd;
#endif
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
#ifndef _STANDALONE
dir = ficlStackPopPointer(ficlVmGetDataStack(pVM));
if (dir != NULL)
(void) closedir(dir);
#else
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
if (fd != -1)
(void) close(fd);
#endif
}
static void pfload(ficlVm *pVM)
{
int fd;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
if (fd != -1)
(void) ficlExecFD(pVM, fd);
}
static void
pfwrite(ficlVm *pVM)
{
int fd, len;
char *buf;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
len = ficlStackPopInteger(ficlVmGetDataStack(pVM));
buf = ficlStackPopPointer(ficlVmGetDataStack(pVM));
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
if (len > 0 && buf && fd != -1)
ficlStackPushInteger(ficlVmGetDataStack(pVM),
write(fd, buf, len));
else
ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
}
static void
pfseek(ficlVm *pVM)
{
int fd, pos, whence;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
whence = ficlStackPopInteger(ficlVmGetDataStack(pVM));
pos = ficlStackPopInteger(ficlVmGetDataStack(pVM));
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
ficlStackPushInteger(ficlVmGetDataStack(pVM), lseek(fd, pos, whence));
}
static void
key(ficlVm *pVM)
{
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1);
ficlStackPushInteger(ficlVmGetDataStack(pVM), getchar());
}
static void
keyQuestion(ficlVm *pVM)
{
#ifndef _STANDALONE
char ch = -1;
struct termios oldt;
struct termios newt;
#endif
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1);
#ifndef _STANDALONE
(void) tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
newt.c_cc[VMIN] = 0;
newt.c_cc[VTIME] = 0;
(void) tcsetattr(STDIN_FILENO, TCSANOW, &newt);
ch = getchar();
(void) tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
if (ch != -1)
(void) ungetc(ch, stdin);
ficlStackPushInteger(ficlVmGetDataStack(pVM),
ch != -1? FICL_TRUE : FICL_FALSE);
#else
ficlStackPushInteger(ficlVmGetDataStack(pVM),
ischar()? FICL_TRUE : FICL_FALSE);
#endif
}
static void
pseconds(ficlVm *pVM)
{
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1);
ficlStackPushUnsigned(ficlVmGetDataStack(pVM),
(ficlUnsigned) time(NULL));
}
static void
ms(ficlVm *pVM)
{
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
#ifndef _STANDALONE
(void) usleep(ficlStackPopUnsigned(ficlVmGetDataStack(pVM)) * 1000);
#else
delay(ficlStackPopUnsigned(ficlVmGetDataStack(pVM)) * 1000);
#endif
}
static void
fkey(ficlVm *pVM)
{
int i, fd;
char ch;
FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 1);
fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
i = read(fd, &ch, 1);
ficlStackPushInteger(ficlVmGetDataStack(pVM), i > 0 ? ch : -1);
}
static void
freeHeap(ficlVm *pVM)
{
ficlStackPushInteger(ficlVmGetDataStack(pVM),
ficlDictionaryCellsAvailable(ficlVmGetDictionary(pVM)));
}
void
ficlSystemCompilePlatform(ficlSystem *pSys)
{
ficlDictionary *dp = ficlSystemGetDictionary(pSys);
ficlDictionary *env = ficlSystemGetEnvironment(pSys);
#ifdef _STANDALONE
ficlCompileFcn **fnpp;
#endif
FICL_SYSTEM_ASSERT(pSys, dp);
FICL_SYSTEM_ASSERT(pSys, env);
(void) ficlDictionarySetPrimitive(dp, ".#", displayCellNoPad,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "isdir?", isdirQuestion,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fopen", pfopen,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fclose", pfclose,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fread", pfread,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fopendir", pfopendir,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "freaddir", pfreaddir,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fclosedir", pfclosedir,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fload", pfload,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fkey", fkey,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fseek", pfseek,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fwrite", pfwrite,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "key", key, FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "key?", keyQuestion,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "ms", ms, FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "seconds", pseconds,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "heap?", freeHeap,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "setenv", ficlSetenv,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "setenv?", ficlSetenvq,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "getenv", ficlGetenv,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "unsetenv", ficlUnsetenv,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "copyin", ficlCopyin,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "copyout", ficlCopyout,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "findfile", ficlFindfile,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "isvirtualized?",
ficlIsvirtualizedQ, FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "ccall", ficlCcall,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "uuid-from-string",
ficlUuidFromString, FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "uuid-to-string",
ficlUuidToString, FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fb-setpixel", ficl_fb_setpixel,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fb-line", ficl_fb_line,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fb-bezier", ficl_fb_bezier,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fb-drawrect", ficl_fb_drawrect,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "fb-putimage", ficl_fb_putimage,
FICL_WORD_DEFAULT);
(void) ficlDictionarySetPrimitive(dp, "term-drawrect",
ficl_term_drawrect, FICL_WORD_DEFAULT);
#ifdef _STANDALONE
(void) ficlDictionarySetPrimitive(dp, "term-putimage",
ficl_term_putimage, FICL_WORD_DEFAULT);
SET_FOREACH(fnpp, Xficl_compile_set)
(*fnpp)(pSys);
#endif
}