#include "iolib.h"
static void ghostDestroy(void* g);
-naGhostType naIOGhostType = { ghostDestroy };
+naGhostType naIOGhostType = { ghostDestroy, "iofile" };
static struct naIOGhost* ioghost(naRef r)
{
naRef len = argc > 2 ? naNumValue(args[2]) : naNil();
if(!g || !MUTABLE(str) || !IS_NUM(len))
naRuntimeError(c, "bad argument to read()");
- if(PTR(str).str->len < (int)len.num)
+ if(naStr_len(str) < (int)len.num)
naRuntimeError(c, "string not big enough for read");
- return naNum(g->type->read(c, g->handle, (char*)PTR(str).str->data,
+ return naNum(g->type->read(c, g->handle, naStr_data(str),
(int)len.num));
}
naRef str = argc > 1 ? args[1] : naNil();
if(!g || !IS_STR(str))
naRuntimeError(c, "bad argument to write()");
- return naNum(g->type->write(c, g->handle, (char*)PTR(str).str->data,
- PTR(str).str->len));
+ return naNum(g->type->write(c, g->handle, naStr_data(str),
+ naStr_len(str)));
}
static naRef f_seek(naContext c, naRef me, int argc, naRef* args)
return naNum(g->type->tell(c, g->handle));
}
+static naRef f_flush(naContext c, naRef me, int argc, naRef* args)
+{
+ struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0;
+ if(!g)
+ naRuntimeError(c, "bad argument to flush()");
+ g->type->flush(c, g->handle);
+ return naNil();
+}
+
static void ghostDestroy(void* g)
{
struct naIOGhost* io = (struct naIOGhost*)g;
return n;
}
+static void ioflush(naContext c, void* f)
+{
+ if(fflush(f)) naRuntimeError(c, strerror(errno));
+}
+
static void iodestroy(void* f)
{
if(f != stdin && f != stdout && f != stderr)
}
struct naIOType naStdIOType = { ioclose, ioread, iowrite, ioseek,
- iotell, iodestroy };
+ iotell, ioflush, iodestroy };
naRef naIOGhost(naContext c, FILE* f)
{
naRef file = argc > 0 ? naStringValue(c, args[0]) : naNil();
naRef mode = argc > 1 ? naStringValue(c, args[1]) : naNil();
if(!IS_STR(file)) naRuntimeError(c, "bad argument to open()");
- f = fopen((char*)PTR(file).str->data,
- IS_STR(mode) ? (const char*)PTR(mode).str->data : "rb");
+ f = fopen(naStr_data(file), IS_STR(mode) ? naStr_data(mode) : "rb");
if(!f) naRuntimeError(c, strerror(errno));
return naIOGhost(c, f);
}
// frees buffer before tossing an error
static int getcguard(naContext ctx, FILE* f, void* buf)
{
- char c;
+ int c;
naModUnlock(); c = fgetc(f); naModLock();
if(ferror(f)) {
naFree(buf);
{
naRef result;
struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0;
- int i=0, sz = 128;
- char c, *buf;
+ int i=0, c, sz = 128;
+ char *buf;
if(!g || g->type != &naStdIOType)
naRuntimeError(ctx, "bad argument to readln()");
buf = naAlloc(sz);
c = getcguard(ctx, g->handle, buf);
if(c == EOF || c == '\n') break;
if(c == '\r') {
- char c2 = getcguard(ctx, g->handle, buf);
+ int c2 = getcguard(ctx, g->handle, buf);
if(c2 != EOF && c2 != '\n')
if(EOF == ungetc(c2, g->handle))
break;
return result;
}
+#ifdef _MSC_VER
+#define S_ISREG(m) (((m)&_S_IFMT)==_S_IFREG)
+#define S_ISDIR(m) (((m)&_S_IFMT)==_S_IFDIR)
+#define S_ISCHR(m) (((m)&_S_IFMT)==_S_IFCHR)
+#define S_ISFIFO(m) (((m)&_S_IFMT)==_S_IFIFO)
+#define S_ISBLK(m) 0
+#define S_ISLNK(m) 0
+#define S_ISSOCK(m) 0
+typedef unsigned short mode_t;
+#endif
+static naRef ftype(naContext ctx, mode_t m)
+{
+ const char* t = "unk";
+ if(S_ISREG(m)) t = "reg";
+ else if(S_ISDIR(m)) t = "dir"; else if(S_ISCHR(m)) t = "chr";
+ else if(S_ISBLK(m)) t = "blk"; else if(S_ISFIFO(m)) t = "fifo";
+ else if(S_ISLNK(m)) t = "lnk"; else if(S_ISSOCK(m)) t = "sock";
+ return naStr_fromdata(naNewString(ctx), t, strlen(t));
+}
+
static naRef f_stat(naContext ctx, naRef me, int argc, naRef* args)
{
int n=0;
struct stat s;
naRef result, path = argc > 0 ? naStringValue(ctx, args[0]) : naNil();
if(!IS_STR(path)) naRuntimeError(ctx, "bad argument to stat()");
- if(stat((char*)PTR(path).str->data, &s) < 0) {
+ if(stat(naStr_data(path), &s) < 0) {
if(errno == ENOENT) return naNil();
naRuntimeError(ctx, strerror(errno));
}
result = naNewVector(ctx);
- naVec_setsize(result, 11);
+ naVec_setsize(result, 12);
#define FLD(x) naVec_set(result, n++, naNum(s.st_##x));
FLD(dev); FLD(ino); FLD(mode); FLD(nlink); FLD(uid); FLD(gid);
FLD(rdev); FLD(size); FLD(atime); FLD(mtime); FLD(ctime);
#undef FLD
+ naVec_set(result, n++, ftype(ctx, s.st_mode));
return result;
}
{ "write", f_write },
{ "seek", f_seek },
{ "tell", f_tell },
+ { "flush", f_flush },
{ "open", f_open },
{ "readln", f_readln },
{ "stat", f_stat },