]> git.mxchange.org Git - simgear.git/blobdiff - simgear/nasal/iolib.c
Removal of PLIB/SG from SimGear
[simgear.git] / simgear / nasal / iolib.c
index b9c81f33a0cc186f2fde0af1b37bf39dc4975d96..b4dbc93df7f1110b6af8bb4cb53dbf1c5f9d9dca 100644 (file)
@@ -7,11 +7,11 @@
 #include "iolib.h"
 
 static void ghostDestroy(void* g);
-naGhostType naIOGhostType = { ghostDestroy };
+naGhostType naIOGhostType = { ghostDestroy, "iofile" };
 
 static struct naIOGhost* ioghost(naRef r)
 {
-    if(naGhost_type(r) == &naIOGhostType)
+    if(naGhost_type(r) == &naIOGhostType && IOGHOST(r)->handle)
         return naGhost_ptr(r);
     return 0;
 }
@@ -32,9 +32,9 @@ static naRef f_read(naContext c, naRef me, int argc, naRef* args)
     naRef len = argc > 2 ? naNumValue(args[2]) : naNil();
     if(!g || !MUTABLE(str) || !IS_NUM(len))
         naRuntimeError(c, "bad argument to read()");
-    if(str.ref.ptr.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*)str.ref.ptr.str->data,
+    return naNum(g->type->read(c, g->handle, naStr_data(str),
                                (int)len.num));
 }
 
@@ -44,8 +44,8 @@ static naRef f_write(naContext c, naRef me, int argc, naRef* args)
     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*)str.ref.ptr.str->data,
-                                str.ref.ptr.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)
@@ -67,6 +67,15 @@ static naRef f_tell(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;
@@ -111,13 +120,19 @@ static int iotell(naContext c, void* f)
     return n;
 }
 
+static void ioflush(naContext c, void* f)
+{
+    if(fflush(f)) naRuntimeError(c, strerror(errno));
+}
+
 static void iodestroy(void* f)
 {
-    ioclose(0, f);
+    if(f != stdin && f != stdout && f != stderr)
+        ioclose(0, f);
 }
 
 struct naIOType naStdIOType = { ioclose, ioread, iowrite, ioseek,
-                                iotell, iodestroy };
+                                iotell, ioflush, iodestroy };
 
 naRef naIOGhost(naContext c, FILE* f)
 {
@@ -133,8 +148,7 @@ static naRef f_open(naContext c, naRef me, int argc, naRef* args)
     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*)file.ref.ptr.str->data,
-              IS_STR(mode) ? (const char*)mode.ref.ptr.str->data : "r");
+    f = fopen(naStr_data(file), IS_STR(mode) ? naStr_data(mode) : "rb");
     if(!f) naRuntimeError(c, strerror(errno));
     return naIOGhost(c, f);
 }
@@ -142,7 +156,7 @@ static naRef f_open(naContext c, naRef me, int argc, naRef* args)
 // 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);
@@ -158,8 +172,8 @@ static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args)
 {
     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);
@@ -167,9 +181,10 @@ static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args)
         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')
-                ungetc(c2, g->handle);
+                if(EOF == ungetc(c2, g->handle))
+                    break;
             break;
         }
         buf[i++] = c;
@@ -180,54 +195,69 @@ static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args)
     return result;
 }
 
+#ifdef _WIN32
+#define S_ISLNK(m) 0
+#define S_ISSOCK(m) 0
+#endif
+#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
+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*)path.ref.ptr.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;
 }
 
-static struct func { char* name; naCFunction func; } funcs[] = {
+static naCFuncItem funcs[] = {
     { "close", f_close },
     { "read", f_read },
     { "write", f_write },
     { "seek", f_seek },
     { "tell", f_tell },
+    { "flush", f_flush },
     { "open", f_open },
     { "readln", f_readln },
     { "stat", f_stat },
+    { 0 }
 };
 
-static void setsym(naContext c, naRef hash, char* sym, naRef val)
-{
-    naRef name = naStr_fromdata(naNewString(c), sym, strlen(sym));
-    naHash_set(hash, naInternSymbol(name), val);
-}
-
-naRef naIOLib(naContext c)
+naRef naInit_io(naContext c)
 {
-    naRef ns = naNewHash(c);
-    int i, n = sizeof(funcs)/sizeof(struct func);
-    for(i=0; i<n; i++)
-        setsym(c, ns, funcs[i].name,
-               naNewFunc(c, naNewCCode(c, funcs[i].func)));
-    setsym(c, ns, "SEEK_SET", naNum(SEEK_SET));
-    setsym(c, ns, "SEEK_CUR", naNum(SEEK_CUR));
-    setsym(c, ns, "SEEK_END", naNum(SEEK_END));
-    setsym(c, ns, "stdin", naIOGhost(c, stdin));
-    setsym(c, ns, "stdout", naIOGhost(c, stdout));
-    setsym(c, ns, "stderr", naIOGhost(c, stderr));
+    naRef ns = naGenLib(c, funcs);
+    naAddSym(c, ns, "SEEK_SET", naNum(SEEK_SET));
+    naAddSym(c, ns, "SEEK_CUR", naNum(SEEK_CUR));
+    naAddSym(c, ns, "SEEK_END", naNum(SEEK_END));
+    naAddSym(c, ns, "stdin", naIOGhost(c, stdin));
+    naAddSym(c, ns, "stdout", naIOGhost(c, stdout));
+    naAddSym(c, ns, "stderr", naIOGhost(c, stderr));
     return ns;
 }