fixed warnings in squirrel
[supertux.git] / src / squirrel / sqstdlib / sqstdio.cpp
index 5d02f55..f3903e2 100644 (file)
-/* see copyright notice in squirrel.h */\r
-#include <new>\r
-#include <stdio.h>\r
-#include <squirrel.h>\r
-#include <sqstdio.h>\r
-#include "sqstdstream.h"\r
-\r
-#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)\r
-//basic API\r
-SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)\r
-{\r
-#ifndef _UNICODE\r
-       return (SQFILE)fopen(filename,mode);\r
-#else\r
-       return (SQFILE)_wfopen(filename,mode);\r
-#endif\r
-}\r
-\r
-SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)\r
-{\r
-       return (SQInteger)fread(buffer,size,count,(FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)\r
-{\r
-       return (SQInteger)fwrite(buffer,size,count,(FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fseek(SQFILE file, long offset, int origin)\r
-{\r
-       int realorigin;\r
-       switch(origin) {\r
-               case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;\r
-               case SQ_SEEK_END: realorigin = SEEK_END; break;\r
-               case SQ_SEEK_SET: realorigin = SEEK_SET; break;\r
-               default: return -1; //failed\r
-       }\r
-       return fseek((FILE *)file,offset,realorigin);\r
-}\r
-\r
-long sqstd_ftell(SQFILE file)\r
-{\r
-       return ftell((FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fflush(SQFILE file)\r
-{\r
-       return fflush((FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_fclose(SQFILE file)\r
-{\r
-       return fclose((FILE *)file);\r
-}\r
-\r
-SQInteger sqstd_feof(SQFILE file)\r
-{\r
-       return feof((FILE *)file);\r
-}\r
-\r
-//File\r
-struct SQFile : public SQStream {\r
-       SQFile() { _handle = NULL; _owns = false;}\r
-       SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}\r
-       ~SQFile() { Close(); }\r
-       bool Open(const SQChar *filename ,const SQChar *mode) {\r
-               Close();\r
-               if(_handle = sqstd_fopen(filename,mode)) {\r
-                       _owns = true;\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       void Close() {\r
-               if(_handle && _owns) { \r
-                       sqstd_fclose(_handle);\r
-                       _handle = NULL;\r
-                       _owns = false;\r
-               }\r
-       }\r
-       SQInteger Read(void *buffer,SQInteger size) {\r
-               return sqstd_fread(buffer,1,size,_handle);\r
-       }\r
-       SQInteger Write(void *buffer,SQInteger size) {\r
-               return sqstd_fwrite(buffer,1,size,_handle);\r
-       }\r
-       int Flush() {\r
-               return sqstd_fflush(_handle);\r
-       }\r
-       long Tell() {\r
-               return sqstd_ftell(_handle);\r
-       }\r
-       SQInteger Len() {\r
-               int prevpos=Tell();\r
-               Seek(0,SQ_SEEK_END);\r
-               int size=Tell();\r
-               Seek(prevpos,SQ_SEEK_SET);\r
-               return size;\r
-       }\r
-       SQInteger Seek(long offset, int origin) {\r
-               return sqstd_fseek(_handle,offset,origin);\r
-       }\r
-       bool IsValid() { return _handle?true:false; }\r
-       bool EOS() { return Tell()==Len()?true:false;}\r
-       SQFILE GetHandle() {return _handle;}\r
-private:\r
-       SQFILE _handle;\r
-       bool _owns;\r
-};\r
-\r
-static int _file__typeof(HSQUIRRELVM v)\r
-{\r
-       sq_pushstring(v,_SC("file"),-1);\r
-       return 1;\r
-}\r
-\r
-static int _file_releasehook(SQUserPointer p, int size)\r
-{\r
-       SQFile *self = (SQFile*)p;\r
-       delete self;\r
-       return 1;\r
-}\r
-\r
-static int _file_constructor(HSQUIRRELVM v)\r
-{\r
-       const SQChar *filename,*mode;\r
-       bool owns = true;\r
-       SQFile *f;\r
-       SQFILE newf;\r
-       if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {\r
-               sq_getstring(v, 2, &filename);\r
-               sq_getstring(v, 3, &mode);\r
-               newf = sqstd_fopen(filename, mode);\r
-               if(!newf) return sq_throwerror(v, _SC("cannot open file"));\r
-       } else if(sq_gettype(v,2) == OT_USERPOINTER) {\r
-               owns = !(sq_gettype(v,3) == OT_NULL);\r
-               sq_getuserpointer(v,2,&newf);\r
-       } else {\r
-               return sq_throwerror(v,_SC("wrong parameter"));\r
-       }\r
-       f = new SQFile(newf,owns);\r
-       if(SQ_FAILED(sq_setinstanceup(v,1,f))) {\r
-               delete f;\r
-               return sq_throwerror(v, _SC("cannot create blob with negative size"));\r
-       }\r
-       sq_setreleasehook(v,1,_file_releasehook);\r
-       return 0;\r
-}\r
-\r
-//bindings\r
-#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}\r
-static SQRegFunction _file_methods[] = {\r
-       _DECL_FILE_FUNC(constructor,3,_SC("x")),\r
-       _DECL_FILE_FUNC(_typeof,1,_SC("x")),\r
-       {0,0,0,0},\r
-};\r
-\r
-\r
-\r
-SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)\r
-{\r
-       int top = sq_gettop(v);\r
-       sq_pushregistrytable(v);\r
-       sq_pushstring(v,_SC("std_file"),-1);\r
-       if(SQ_SUCCEEDED(sq_get(v,-2))) {\r
-               sq_remove(v,-2); //removes the registry\r
-               sq_pushroottable(v); // push the this\r
-               sq_pushuserpointer(v,file); //file\r
-               if(own){\r
-                       sq_pushinteger(v,1); //true\r
-               }\r
-               else{\r
-                       sq_pushnull(v); //false\r
-               }\r
-               if(SQ_SUCCEEDED( sq_call(v,3,SQTrue) )) {\r
-                       sq_remove(v,-2);\r
-                       return SQ_OK;\r
-               }\r
-       }\r
-       sq_settop(v,top);\r
-       return SQ_OK;\r
-}\r
-\r
-SQRESULT sqstd_getfile(HSQUIRRELVM v, int idx, SQFILE *file)\r
-{\r
-       SQFile *fileobj = NULL;\r
-       if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,SQSTD_FILE_TYPE_TAG))) {\r
-               *file = fileobj->GetHandle();\r
-               return SQ_OK;\r
-       }\r
-       return sq_throwerror(v,_SC("not a file"));\r
-}\r
-\r
-\r
-static SQInteger _io_file_lexfeedASCII(SQUserPointer file)\r
-{\r
-       int ret;\r
-       char c;\r
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )\r
-               return c;\r
-       return 0;\r
-}\r
-\r
-static SQInteger _io_file_lexfeedWCHAR(SQUserPointer file)\r
-{\r
-       int ret;\r
-       wchar_t c;\r
-       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )\r
-               return (SQChar)c;\r
-       return 0;\r
-}\r
-\r
-int file_read(SQUserPointer file,SQUserPointer buf,int size)\r
-{\r
-       int ret;\r
-       if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;\r
-       return -1;\r
-}\r
-\r
-int file_write(SQUserPointer file,SQUserPointer p,int size)\r
-{\r
-       return sqstd_fwrite(p,1,size,(SQFILE)file);\r
-}\r
-\r
-SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)\r
-{\r
-       SQFILE file = sqstd_fopen(filename,_SC("rb"));\r
-       int ret;\r
-       unsigned short uc;\r
-       SQLEXREADFUNC func = _io_file_lexfeedASCII;\r
-       if(file && (ret=sqstd_fread(&uc,1,2,file))){\r
-               if(ret!=2) {\r
-                       sqstd_fclose(file);\r
-                       return sq_throwerror(v,_SC("io error"));\r
-               }\r
-               if(uc==SQ_BYTECODE_STREAM_TAG) { //BYTECODE\r
-                       sqstd_fseek(file,0,SQ_SEEK_SET);\r
-                       if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {\r
-                               sqstd_fclose(file);\r
-                               return SQ_OK;\r
-                       }\r
-               }\r
-               else { //SCRIPT\r
-                       if(uc==0xFEFF)\r
-                               func = _io_file_lexfeedWCHAR;\r
-                       else\r
-                               sqstd_fseek(file,0,SQ_SEEK_SET);\r
-\r
-                       if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){\r
-                               sqstd_fclose(file);\r
-                               return SQ_OK;\r
-                       }\r
-               }\r
-               sqstd_fclose(file);\r
-               return SQ_ERROR;\r
-       }\r
-       return sq_throwerror(v,_SC("cannot open the file"));\r
-}\r
-\r
-SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)\r
-{\r
-       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {\r
-               sq_push(v,-2);\r
-               int ntop = sq_gettop(v);\r
-               if(SQ_SUCCEEDED(sq_call(v,1,retval))) {\r
-                       sq_remove(v,retval?-2:-1); //removes the closure\r
-                       return 1;\r
-               }\r
-               sq_pop(v,1); //removes the closure\r
-       }\r
-       return SQ_ERROR;\r
-}\r
-\r
-SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)\r
-{\r
-       SQFILE file = sqstd_fopen(filename,_SC("wb+"));\r
-       if(!file) return sq_throwerror(v,_SC("cannot open the file"));\r
-       if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {\r
-               sqstd_fclose(file);\r
-               return SQ_OK;\r
-       }\r
-       sqstd_fclose(file);\r
-       return SQ_ERROR; //forward the error\r
-}\r
-\r
-int _g_io_loadfile(HSQUIRRELVM v)\r
-{\r
-       const SQChar *filename;\r
-       SQBool printerror = SQFalse;\r
-       sq_getstring(v,2,&filename);\r
-       if(sq_gettop(v) >= 3) {\r
-               sq_getbool(v,3,&printerror);\r
-       }\r
-       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))\r
-               return 1;\r
-       return SQ_ERROR; //propagates the error\r
-}\r
-\r
-int _g_io_dofile(HSQUIRRELVM v)\r
-{\r
-       const SQChar *filename;\r
-       SQBool printerror = SQFalse;\r
-       sq_getstring(v,2,&filename);\r
-       if(sq_gettop(v) >= 3) {\r
-               sq_getbool(v,3,&printerror);\r
-       }\r
-       sq_push(v,1); //repush the this\r
-       if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))\r
-               return 1;\r
-       return SQ_ERROR; //propagates the error\r
-}\r
-\r
-#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}\r
-static SQRegFunction iolib_funcs[]={\r
-       _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),\r
-       _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),\r
-       {0,0}\r
-};\r
-\r
-SQRESULT sqstd_register_iolib(HSQUIRRELVM v)\r
-{\r
-       int top = sq_gettop(v);\r
-       //create delegate\r
-       declare_stream(v,_SC("file"),SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);\r
-       sq_pushstring(v,_SC("stdout"),-1);\r
-       sqstd_createfile(v,stdout,0);\r
-       sq_createslot(v,-3);\r
-       sq_pushstring(v,_SC("stdin"),-1);\r
-       sqstd_createfile(v,stdin,0);\r
-       sq_createslot(v,-3);\r
-       sq_pushstring(v,_SC("stderr"),-1);\r
-       sqstd_createfile(v,stderr,0);\r
-       sq_createslot(v,-3);\r
-       sq_settop(v,top);\r
-       return SQ_OK;\r
-}\r
+/* see copyright notice in squirrel.h */
+#include <new>
+#include <stdio.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include "sqstdstream.h"
+
+#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
+//basic API
+SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
+{
+#ifndef _UNICODE
+       return (SQFILE)fopen(filename,mode);
+#else
+       return (SQFILE)_wfopen(filename,mode);
+#endif
+}
+
+SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
+{
+       return (SQInteger)fread(buffer,size,count,(FILE *)file);
+}
+
+SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
+{
+       return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
+}
+
+SQInteger sqstd_fseek(SQFILE file, long offset, int origin)
+{
+       int realorigin;
+       switch(origin) {
+               case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
+               case SQ_SEEK_END: realorigin = SEEK_END; break;
+               case SQ_SEEK_SET: realorigin = SEEK_SET; break;
+               default: return -1; //failed
+       }
+       return fseek((FILE *)file,offset,realorigin);
+}
+
+long sqstd_ftell(SQFILE file)
+{
+       return ftell((FILE *)file);
+}
+
+SQInteger sqstd_fflush(SQFILE file)
+{
+       return fflush((FILE *)file);
+}
+
+SQInteger sqstd_fclose(SQFILE file)
+{
+       return fclose((FILE *)file);
+}
+
+SQInteger sqstd_feof(SQFILE file)
+{
+       return feof((FILE *)file);
+}
+
+//File
+struct SQFile : public SQStream {
+       SQFile() { _handle = NULL; _owns = false;}
+       SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
+       virtual ~SQFile() { Close(); }
+       bool Open(const SQChar *filename ,const SQChar *mode) {
+               Close();
+               if( (_handle = sqstd_fopen(filename,mode)) ) {
+                       _owns = true;
+                       return true;
+               }
+               return false;
+       }
+       void Close() {
+               if(_handle && _owns) { 
+                       sqstd_fclose(_handle);
+                       _handle = NULL;
+                       _owns = false;
+               }
+       }
+       SQInteger Read(void *buffer,SQInteger size) {
+               return sqstd_fread(buffer,1,size,_handle);
+       }
+       SQInteger Write(void *buffer,SQInteger size) {
+               return sqstd_fwrite(buffer,1,size,_handle);
+       }
+       int Flush() {
+               return sqstd_fflush(_handle);
+       }
+       long Tell() {
+               return sqstd_ftell(_handle);
+       }
+       SQInteger Len() {
+               int prevpos=Tell();
+               Seek(0,SQ_SEEK_END);
+               int size=Tell();
+               Seek(prevpos,SQ_SEEK_SET);
+               return size;
+       }
+       SQInteger Seek(long offset, int origin) {
+               return sqstd_fseek(_handle,offset,origin);
+       }
+       bool IsValid() { return _handle?true:false; }
+       bool EOS() { return Tell()==Len()?true:false;}
+       SQFILE GetHandle() {return _handle;}
+private:
+       SQFILE _handle;
+       bool _owns;
+};
+
+static int _file__typeof(HSQUIRRELVM v)
+{
+       sq_pushstring(v,_SC("file"),-1);
+       return 1;
+}
+
+static int _file_releasehook(SQUserPointer p, int size)
+{
+       (void) size;
+       SQFile *self = (SQFile*)p;
+       delete self;
+       return 1;
+}
+
+static int _file_constructor(HSQUIRRELVM v)
+{
+       const SQChar *filename,*mode;
+       bool owns = true;
+       SQFile *f;
+       SQFILE newf;
+       if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
+               sq_getstring(v, 2, &filename);
+               sq_getstring(v, 3, &mode);
+               newf = sqstd_fopen(filename, mode);
+               if(!newf) return sq_throwerror(v, _SC("cannot open file"));
+       } else if(sq_gettype(v,2) == OT_USERPOINTER) {
+               owns = !(sq_gettype(v,3) == OT_NULL);
+               sq_getuserpointer(v,2,&newf);
+       } else {
+               return sq_throwerror(v,_SC("wrong parameter"));
+       }
+       f = new SQFile(newf,owns);
+       if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
+               delete f;
+               return sq_throwerror(v, _SC("cannot create blob with negative size"));
+       }
+       sq_setreleasehook(v,1,_file_releasehook);
+       return 0;
+}
+
+//bindings
+#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
+static SQRegFunction _file_methods[] = {
+       _DECL_FILE_FUNC(constructor,3,_SC("x")),
+       _DECL_FILE_FUNC(_typeof,1,_SC("x")),
+       {0,0,0,0},
+};
+
+
+
+SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
+{
+       int top = sq_gettop(v);
+       sq_pushregistrytable(v);
+       sq_pushstring(v,_SC("std_file"),-1);
+       if(SQ_SUCCEEDED(sq_get(v,-2))) {
+               sq_remove(v,-2); //removes the registry
+               sq_pushroottable(v); // push the this
+               sq_pushuserpointer(v,file); //file
+               if(own){
+                       sq_pushinteger(v,1); //true
+               }
+               else{
+                       sq_pushnull(v); //false
+               }
+               if(SQ_SUCCEEDED( sq_call(v,3,SQTrue) )) {
+                       sq_remove(v,-2);
+                       return SQ_OK;
+               }
+       }
+       sq_settop(v,top);
+       return SQ_OK;
+}
+
+SQRESULT sqstd_getfile(HSQUIRRELVM v, int idx, SQFILE *file)
+{
+       SQFile *fileobj = NULL;
+       if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,SQSTD_FILE_TYPE_TAG))) {
+               *file = fileobj->GetHandle();
+               return SQ_OK;
+       }
+       return sq_throwerror(v,_SC("not a file"));
+}
+
+
+static SQInteger _io_file_lexfeedASCII(SQUserPointer file)
+{
+       int ret;
+       char c;
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
+               return c;
+       return 0;
+}
+
+static SQInteger _io_file_lexfeedWCHAR(SQUserPointer file)
+{
+       int ret;
+       wchar_t c;
+       if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
+               return (SQChar)c;
+       return 0;
+}
+
+int file_read(SQUserPointer file,SQUserPointer buf,int size)
+{
+       int ret;
+       if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
+       return -1;
+}
+
+int file_write(SQUserPointer file,SQUserPointer p,int size)
+{
+       return sqstd_fwrite(p,1,size,(SQFILE)file);
+}
+
+SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
+{
+       SQFILE file = sqstd_fopen(filename,_SC("rb"));
+       int ret;
+       unsigned short uc;
+       SQLEXREADFUNC func = _io_file_lexfeedASCII;
+       if(file && (ret=sqstd_fread(&uc,1,2,file))){
+               if(ret!=2) {
+                       sqstd_fclose(file);
+                       return sq_throwerror(v,_SC("io error"));
+               }
+               if(uc==SQ_BYTECODE_STREAM_TAG) { //BYTECODE
+                       sqstd_fseek(file,0,SQ_SEEK_SET);
+                       if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
+                               sqstd_fclose(file);
+                               return SQ_OK;
+                       }
+               }
+               else { //SCRIPT
+                       if(uc==0xFEFF)
+                               func = _io_file_lexfeedWCHAR;
+                       else
+                               sqstd_fseek(file,0,SQ_SEEK_SET);
+
+                       if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
+                               sqstd_fclose(file);
+                               return SQ_OK;
+                       }
+               }
+               sqstd_fclose(file);
+               return SQ_ERROR;
+       }
+       return sq_throwerror(v,_SC("cannot open the file"));
+}
+
+SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
+{
+       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
+               sq_push(v,-2);
+               //int ntop = sq_gettop(v);
+               if(SQ_SUCCEEDED(sq_call(v,1,retval))) {
+                       sq_remove(v,retval?-2:-1); //removes the closure
+                       return 1;
+               }
+               sq_pop(v,1); //removes the closure
+       }
+       return SQ_ERROR;
+}
+
+SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
+{
+       SQFILE file = sqstd_fopen(filename,_SC("wb+"));
+       if(!file) return sq_throwerror(v,_SC("cannot open the file"));
+       if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
+               sqstd_fclose(file);
+               return SQ_OK;
+       }
+       sqstd_fclose(file);
+       return SQ_ERROR; //forward the error
+}
+
+int _g_io_loadfile(HSQUIRRELVM v)
+{
+       const SQChar *filename;
+       SQBool printerror = SQFalse;
+       sq_getstring(v,2,&filename);
+       if(sq_gettop(v) >= 3) {
+               sq_getbool(v,3,&printerror);
+       }
+       if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
+               return 1;
+       return SQ_ERROR; //propagates the error
+}
+
+int _g_io_dofile(HSQUIRRELVM v)
+{
+       const SQChar *filename;
+       SQBool printerror = SQFalse;
+       sq_getstring(v,2,&filename);
+       if(sq_gettop(v) >= 3) {
+               sq_getbool(v,3,&printerror);
+       }
+       sq_push(v,1); //repush the this
+       if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
+               return 1;
+       return SQ_ERROR; //propagates the error
+}
+
+#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
+static SQRegFunction iolib_funcs[]={
+       _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
+       _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
+       {0,0,0,0}
+};
+
+SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
+{
+       int top = sq_gettop(v);
+       //create delegate
+       declare_stream(v,_SC("file"),SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
+       sq_pushstring(v,_SC("stdout"),-1);
+       sqstd_createfile(v,stdout,0);
+       sq_createslot(v,-3);
+       sq_pushstring(v,_SC("stdin"),-1);
+       sqstd_createfile(v,stdin,0);
+       sq_createslot(v,-3);
+       sq_pushstring(v,_SC("stderr"),-1);
+       sqstd_createfile(v,stderr,0);
+       sq_createslot(v,-3);
+       sq_settop(v,top);
+       return SQ_OK;
+}