The Squirrel interpreter. See http://www.squirrel-lang.org/

Dependents:   Squirrel

Committer:
jhnwkmn
Date:
Tue Dec 16 11:39:42 2014 +0000
Revision:
3:7268a3ceaffc
Parent:
0:97a4f8cc534c
Accepts \r as line terminator as well.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jhnwkmn 0:97a4f8cc534c 1 /* see copyright notice in squirrel.h */
jhnwkmn 0:97a4f8cc534c 2 #include <new>
jhnwkmn 0:97a4f8cc534c 3 #include <stdio.h>
jhnwkmn 0:97a4f8cc534c 4 #include <squirrel.h>
jhnwkmn 0:97a4f8cc534c 5 #include <sqstdio.h>
jhnwkmn 0:97a4f8cc534c 6 #include "sqstdstream.h"
jhnwkmn 0:97a4f8cc534c 7
jhnwkmn 0:97a4f8cc534c 8 #define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001)
jhnwkmn 0:97a4f8cc534c 9 //basic API
jhnwkmn 0:97a4f8cc534c 10 SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode)
jhnwkmn 0:97a4f8cc534c 11 {
jhnwkmn 0:97a4f8cc534c 12 #ifndef SQUNICODE
jhnwkmn 0:97a4f8cc534c 13 return (SQFILE)fopen(filename,mode);
jhnwkmn 0:97a4f8cc534c 14 #else
jhnwkmn 0:97a4f8cc534c 15 return (SQFILE)_wfopen(filename,mode);
jhnwkmn 0:97a4f8cc534c 16 #endif
jhnwkmn 0:97a4f8cc534c 17 }
jhnwkmn 0:97a4f8cc534c 18
jhnwkmn 0:97a4f8cc534c 19 SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file)
jhnwkmn 0:97a4f8cc534c 20 {
jhnwkmn 0:97a4f8cc534c 21 return (SQInteger)fread(buffer,size,count,(FILE *)file);
jhnwkmn 0:97a4f8cc534c 22 }
jhnwkmn 0:97a4f8cc534c 23
jhnwkmn 0:97a4f8cc534c 24 SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file)
jhnwkmn 0:97a4f8cc534c 25 {
jhnwkmn 0:97a4f8cc534c 26 return (SQInteger)fwrite(buffer,size,count,(FILE *)file);
jhnwkmn 0:97a4f8cc534c 27 }
jhnwkmn 0:97a4f8cc534c 28
jhnwkmn 0:97a4f8cc534c 29 SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin)
jhnwkmn 0:97a4f8cc534c 30 {
jhnwkmn 0:97a4f8cc534c 31 SQInteger realorigin;
jhnwkmn 0:97a4f8cc534c 32 switch(origin) {
jhnwkmn 0:97a4f8cc534c 33 case SQ_SEEK_CUR: realorigin = SEEK_CUR; break;
jhnwkmn 0:97a4f8cc534c 34 case SQ_SEEK_END: realorigin = SEEK_END; break;
jhnwkmn 0:97a4f8cc534c 35 case SQ_SEEK_SET: realorigin = SEEK_SET; break;
jhnwkmn 0:97a4f8cc534c 36 default: return -1; //failed
jhnwkmn 0:97a4f8cc534c 37 }
jhnwkmn 0:97a4f8cc534c 38 return fseek((FILE *)file,(long)offset,(int)realorigin);
jhnwkmn 0:97a4f8cc534c 39 }
jhnwkmn 0:97a4f8cc534c 40
jhnwkmn 0:97a4f8cc534c 41 SQInteger sqstd_ftell(SQFILE file)
jhnwkmn 0:97a4f8cc534c 42 {
jhnwkmn 0:97a4f8cc534c 43 return ftell((FILE *)file);
jhnwkmn 0:97a4f8cc534c 44 }
jhnwkmn 0:97a4f8cc534c 45
jhnwkmn 0:97a4f8cc534c 46 SQInteger sqstd_fflush(SQFILE file)
jhnwkmn 0:97a4f8cc534c 47 {
jhnwkmn 0:97a4f8cc534c 48 return fflush((FILE *)file);
jhnwkmn 0:97a4f8cc534c 49 }
jhnwkmn 0:97a4f8cc534c 50
jhnwkmn 0:97a4f8cc534c 51 SQInteger sqstd_fclose(SQFILE file)
jhnwkmn 0:97a4f8cc534c 52 {
jhnwkmn 0:97a4f8cc534c 53 return fclose((FILE *)file);
jhnwkmn 0:97a4f8cc534c 54 }
jhnwkmn 0:97a4f8cc534c 55
jhnwkmn 0:97a4f8cc534c 56 SQInteger sqstd_feof(SQFILE file)
jhnwkmn 0:97a4f8cc534c 57 {
jhnwkmn 0:97a4f8cc534c 58 return feof((FILE *)file);
jhnwkmn 0:97a4f8cc534c 59 }
jhnwkmn 0:97a4f8cc534c 60
jhnwkmn 0:97a4f8cc534c 61 //File
jhnwkmn 0:97a4f8cc534c 62 struct SQFile : public SQStream {
jhnwkmn 0:97a4f8cc534c 63 SQFile() { _handle = NULL; _owns = false;}
jhnwkmn 0:97a4f8cc534c 64 SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;}
jhnwkmn 0:97a4f8cc534c 65 virtual ~SQFile() { Close(); }
jhnwkmn 0:97a4f8cc534c 66 bool Open(const SQChar *filename ,const SQChar *mode) {
jhnwkmn 0:97a4f8cc534c 67 Close();
jhnwkmn 0:97a4f8cc534c 68 if( (_handle = sqstd_fopen(filename,mode)) ) {
jhnwkmn 0:97a4f8cc534c 69 _owns = true;
jhnwkmn 0:97a4f8cc534c 70 return true;
jhnwkmn 0:97a4f8cc534c 71 }
jhnwkmn 0:97a4f8cc534c 72 return false;
jhnwkmn 0:97a4f8cc534c 73 }
jhnwkmn 0:97a4f8cc534c 74 void Close() {
jhnwkmn 0:97a4f8cc534c 75 if(_handle && _owns) {
jhnwkmn 0:97a4f8cc534c 76 sqstd_fclose(_handle);
jhnwkmn 0:97a4f8cc534c 77 _handle = NULL;
jhnwkmn 0:97a4f8cc534c 78 _owns = false;
jhnwkmn 0:97a4f8cc534c 79 }
jhnwkmn 0:97a4f8cc534c 80 }
jhnwkmn 0:97a4f8cc534c 81 SQInteger Read(void *buffer,SQInteger size) {
jhnwkmn 0:97a4f8cc534c 82 return sqstd_fread(buffer,1,size,_handle);
jhnwkmn 0:97a4f8cc534c 83 }
jhnwkmn 0:97a4f8cc534c 84 SQInteger Write(void *buffer,SQInteger size) {
jhnwkmn 0:97a4f8cc534c 85 return sqstd_fwrite(buffer,1,size,_handle);
jhnwkmn 0:97a4f8cc534c 86 }
jhnwkmn 0:97a4f8cc534c 87 SQInteger Flush() {
jhnwkmn 0:97a4f8cc534c 88 return sqstd_fflush(_handle);
jhnwkmn 0:97a4f8cc534c 89 }
jhnwkmn 0:97a4f8cc534c 90 SQInteger Tell() {
jhnwkmn 0:97a4f8cc534c 91 return sqstd_ftell(_handle);
jhnwkmn 0:97a4f8cc534c 92 }
jhnwkmn 0:97a4f8cc534c 93 SQInteger Len() {
jhnwkmn 0:97a4f8cc534c 94 SQInteger prevpos=Tell();
jhnwkmn 0:97a4f8cc534c 95 Seek(0,SQ_SEEK_END);
jhnwkmn 0:97a4f8cc534c 96 SQInteger size=Tell();
jhnwkmn 0:97a4f8cc534c 97 Seek(prevpos,SQ_SEEK_SET);
jhnwkmn 0:97a4f8cc534c 98 return size;
jhnwkmn 0:97a4f8cc534c 99 }
jhnwkmn 0:97a4f8cc534c 100 SQInteger Seek(SQInteger offset, SQInteger origin) {
jhnwkmn 0:97a4f8cc534c 101 return sqstd_fseek(_handle,offset,origin);
jhnwkmn 0:97a4f8cc534c 102 }
jhnwkmn 0:97a4f8cc534c 103 bool IsValid() { return _handle?true:false; }
jhnwkmn 0:97a4f8cc534c 104 bool EOS() { return Tell()==Len()?true:false;}
jhnwkmn 0:97a4f8cc534c 105 SQFILE GetHandle() {return _handle;}
jhnwkmn 0:97a4f8cc534c 106 private:
jhnwkmn 0:97a4f8cc534c 107 SQFILE _handle;
jhnwkmn 0:97a4f8cc534c 108 bool _owns;
jhnwkmn 0:97a4f8cc534c 109 };
jhnwkmn 0:97a4f8cc534c 110
jhnwkmn 0:97a4f8cc534c 111 static SQInteger _file__typeof(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 112 {
jhnwkmn 0:97a4f8cc534c 113 sq_pushstring(v,_SC("file"),-1);
jhnwkmn 0:97a4f8cc534c 114 return 1;
jhnwkmn 0:97a4f8cc534c 115 }
jhnwkmn 0:97a4f8cc534c 116
jhnwkmn 0:97a4f8cc534c 117 static SQInteger _file_releasehook(SQUserPointer p, SQInteger size)
jhnwkmn 0:97a4f8cc534c 118 {
jhnwkmn 0:97a4f8cc534c 119 SQFile *self = (SQFile*)p;
jhnwkmn 0:97a4f8cc534c 120 self->~SQFile();
jhnwkmn 0:97a4f8cc534c 121 sq_free(self,sizeof(SQFile));
jhnwkmn 0:97a4f8cc534c 122 return 1;
jhnwkmn 0:97a4f8cc534c 123 }
jhnwkmn 0:97a4f8cc534c 124
jhnwkmn 0:97a4f8cc534c 125 static SQInteger _file_constructor(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 126 {
jhnwkmn 0:97a4f8cc534c 127 const SQChar *filename,*mode;
jhnwkmn 0:97a4f8cc534c 128 bool owns = true;
jhnwkmn 0:97a4f8cc534c 129 SQFile *f;
jhnwkmn 0:97a4f8cc534c 130 SQFILE newf;
jhnwkmn 0:97a4f8cc534c 131 if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) {
jhnwkmn 0:97a4f8cc534c 132 sq_getstring(v, 2, &filename);
jhnwkmn 0:97a4f8cc534c 133 sq_getstring(v, 3, &mode);
jhnwkmn 0:97a4f8cc534c 134 newf = sqstd_fopen(filename, mode);
jhnwkmn 0:97a4f8cc534c 135 if(!newf) return sq_throwerror(v, _SC("cannot open file"));
jhnwkmn 0:97a4f8cc534c 136 } else if(sq_gettype(v,2) == OT_USERPOINTER) {
jhnwkmn 0:97a4f8cc534c 137 owns = !(sq_gettype(v,3) == OT_NULL);
jhnwkmn 0:97a4f8cc534c 138 sq_getuserpointer(v,2,&newf);
jhnwkmn 0:97a4f8cc534c 139 } else {
jhnwkmn 0:97a4f8cc534c 140 return sq_throwerror(v,_SC("wrong parameter"));
jhnwkmn 0:97a4f8cc534c 141 }
jhnwkmn 0:97a4f8cc534c 142
jhnwkmn 0:97a4f8cc534c 143 f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns);
jhnwkmn 0:97a4f8cc534c 144 if(SQ_FAILED(sq_setinstanceup(v,1,f))) {
jhnwkmn 0:97a4f8cc534c 145 f->~SQFile();
jhnwkmn 0:97a4f8cc534c 146 sq_free(f,sizeof(SQFile));
jhnwkmn 0:97a4f8cc534c 147 return sq_throwerror(v, _SC("cannot create blob with negative size"));
jhnwkmn 0:97a4f8cc534c 148 }
jhnwkmn 0:97a4f8cc534c 149 sq_setreleasehook(v,1,_file_releasehook);
jhnwkmn 0:97a4f8cc534c 150 return 0;
jhnwkmn 0:97a4f8cc534c 151 }
jhnwkmn 0:97a4f8cc534c 152
jhnwkmn 0:97a4f8cc534c 153 static SQInteger _file_close(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 154 {
jhnwkmn 0:97a4f8cc534c 155 SQFile *self = NULL;
jhnwkmn 0:97a4f8cc534c 156 if(SQ_SUCCEEDED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_FILE_TYPE_TAG))
jhnwkmn 0:97a4f8cc534c 157 && self != NULL)
jhnwkmn 0:97a4f8cc534c 158 {
jhnwkmn 0:97a4f8cc534c 159 self->Close();
jhnwkmn 0:97a4f8cc534c 160 }
jhnwkmn 0:97a4f8cc534c 161 return 0;
jhnwkmn 0:97a4f8cc534c 162 }
jhnwkmn 0:97a4f8cc534c 163
jhnwkmn 0:97a4f8cc534c 164 //bindings
jhnwkmn 0:97a4f8cc534c 165 #define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck}
jhnwkmn 0:97a4f8cc534c 166 static SQRegFunction _file_methods[] = {
jhnwkmn 0:97a4f8cc534c 167 _DECL_FILE_FUNC(constructor,3,_SC("x")),
jhnwkmn 0:97a4f8cc534c 168 _DECL_FILE_FUNC(_typeof,1,_SC("x")),
jhnwkmn 0:97a4f8cc534c 169 _DECL_FILE_FUNC(close,1,_SC("x")),
jhnwkmn 0:97a4f8cc534c 170 {0,0,0,0},
jhnwkmn 0:97a4f8cc534c 171 };
jhnwkmn 0:97a4f8cc534c 172
jhnwkmn 0:97a4f8cc534c 173
jhnwkmn 0:97a4f8cc534c 174
jhnwkmn 0:97a4f8cc534c 175 SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own)
jhnwkmn 0:97a4f8cc534c 176 {
jhnwkmn 0:97a4f8cc534c 177 SQInteger top = sq_gettop(v);
jhnwkmn 0:97a4f8cc534c 178 sq_pushregistrytable(v);
jhnwkmn 0:97a4f8cc534c 179 sq_pushstring(v,_SC("std_file"),-1);
jhnwkmn 0:97a4f8cc534c 180 if(SQ_SUCCEEDED(sq_get(v,-2))) {
jhnwkmn 0:97a4f8cc534c 181 sq_remove(v,-2); //removes the registry
jhnwkmn 0:97a4f8cc534c 182 sq_pushroottable(v); // push the this
jhnwkmn 0:97a4f8cc534c 183 sq_pushuserpointer(v,file); //file
jhnwkmn 0:97a4f8cc534c 184 if(own){
jhnwkmn 0:97a4f8cc534c 185 sq_pushinteger(v,1); //true
jhnwkmn 0:97a4f8cc534c 186 }
jhnwkmn 0:97a4f8cc534c 187 else{
jhnwkmn 0:97a4f8cc534c 188 sq_pushnull(v); //false
jhnwkmn 0:97a4f8cc534c 189 }
jhnwkmn 0:97a4f8cc534c 190 if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) {
jhnwkmn 0:97a4f8cc534c 191 sq_remove(v,-2);
jhnwkmn 0:97a4f8cc534c 192 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 193 }
jhnwkmn 0:97a4f8cc534c 194 }
jhnwkmn 0:97a4f8cc534c 195 sq_settop(v,top);
jhnwkmn 0:97a4f8cc534c 196 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 197 }
jhnwkmn 0:97a4f8cc534c 198
jhnwkmn 0:97a4f8cc534c 199 SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file)
jhnwkmn 0:97a4f8cc534c 200 {
jhnwkmn 0:97a4f8cc534c 201 SQFile *fileobj = NULL;
jhnwkmn 0:97a4f8cc534c 202 if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) {
jhnwkmn 0:97a4f8cc534c 203 *file = fileobj->GetHandle();
jhnwkmn 0:97a4f8cc534c 204 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 205 }
jhnwkmn 0:97a4f8cc534c 206 return sq_throwerror(v,_SC("not a file"));
jhnwkmn 0:97a4f8cc534c 207 }
jhnwkmn 0:97a4f8cc534c 208
jhnwkmn 0:97a4f8cc534c 209
jhnwkmn 0:97a4f8cc534c 210
jhnwkmn 0:97a4f8cc534c 211 static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file)
jhnwkmn 0:97a4f8cc534c 212 {
jhnwkmn 0:97a4f8cc534c 213 SQInteger ret;
jhnwkmn 0:97a4f8cc534c 214 char c;
jhnwkmn 0:97a4f8cc534c 215 if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
jhnwkmn 0:97a4f8cc534c 216 return c;
jhnwkmn 0:97a4f8cc534c 217 return 0;
jhnwkmn 0:97a4f8cc534c 218 }
jhnwkmn 0:97a4f8cc534c 219
jhnwkmn 0:97a4f8cc534c 220 #ifdef SQUNICODE
jhnwkmn 0:97a4f8cc534c 221 static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file)
jhnwkmn 0:97a4f8cc534c 222 {
jhnwkmn 0:97a4f8cc534c 223 #define READ() \
jhnwkmn 0:97a4f8cc534c 224 if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \
jhnwkmn 0:97a4f8cc534c 225 return 0;
jhnwkmn 0:97a4f8cc534c 226
jhnwkmn 0:97a4f8cc534c 227 static const SQInteger utf8_lengths[16] =
jhnwkmn 0:97a4f8cc534c 228 {
jhnwkmn 0:97a4f8cc534c 229 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */
jhnwkmn 0:97a4f8cc534c 230 0,0,0,0, /* 1000 to 1011 : not valid */
jhnwkmn 0:97a4f8cc534c 231 2,2, /* 1100, 1101 : 2 bytes */
jhnwkmn 0:97a4f8cc534c 232 3, /* 1110 : 3 bytes */
jhnwkmn 0:97a4f8cc534c 233 4 /* 1111 :4 bytes */
jhnwkmn 0:97a4f8cc534c 234 };
jhnwkmn 0:97a4f8cc534c 235 static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07};
jhnwkmn 0:97a4f8cc534c 236 unsigned char inchar;
jhnwkmn 0:97a4f8cc534c 237 SQInteger c = 0;
jhnwkmn 0:97a4f8cc534c 238 READ();
jhnwkmn 0:97a4f8cc534c 239 c = inchar;
jhnwkmn 0:97a4f8cc534c 240 //
jhnwkmn 0:97a4f8cc534c 241 if(c >= 0x80) {
jhnwkmn 0:97a4f8cc534c 242 SQInteger tmp;
jhnwkmn 0:97a4f8cc534c 243 SQInteger codelen = utf8_lengths[c>>4];
jhnwkmn 0:97a4f8cc534c 244 if(codelen == 0)
jhnwkmn 0:97a4f8cc534c 245 return 0;
jhnwkmn 0:97a4f8cc534c 246 //"invalid UTF-8 stream";
jhnwkmn 0:97a4f8cc534c 247 tmp = c&byte_masks[codelen];
jhnwkmn 0:97a4f8cc534c 248 for(SQInteger n = 0; n < codelen-1; n++) {
jhnwkmn 0:97a4f8cc534c 249 tmp<<=6;
jhnwkmn 0:97a4f8cc534c 250 READ();
jhnwkmn 0:97a4f8cc534c 251 tmp |= inchar & 0x3F;
jhnwkmn 0:97a4f8cc534c 252 }
jhnwkmn 0:97a4f8cc534c 253 c = tmp;
jhnwkmn 0:97a4f8cc534c 254 }
jhnwkmn 0:97a4f8cc534c 255 return c;
jhnwkmn 0:97a4f8cc534c 256 }
jhnwkmn 0:97a4f8cc534c 257 #endif
jhnwkmn 0:97a4f8cc534c 258
jhnwkmn 0:97a4f8cc534c 259 static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file)
jhnwkmn 0:97a4f8cc534c 260 {
jhnwkmn 0:97a4f8cc534c 261 SQInteger ret;
jhnwkmn 0:97a4f8cc534c 262 wchar_t c;
jhnwkmn 0:97a4f8cc534c 263 if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) )
jhnwkmn 0:97a4f8cc534c 264 return (SQChar)c;
jhnwkmn 0:97a4f8cc534c 265 return 0;
jhnwkmn 0:97a4f8cc534c 266 }
jhnwkmn 0:97a4f8cc534c 267
jhnwkmn 0:97a4f8cc534c 268 static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file)
jhnwkmn 0:97a4f8cc534c 269 {
jhnwkmn 0:97a4f8cc534c 270 SQInteger ret;
jhnwkmn 0:97a4f8cc534c 271 unsigned short c;
jhnwkmn 0:97a4f8cc534c 272 if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) {
jhnwkmn 0:97a4f8cc534c 273 c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00);
jhnwkmn 0:97a4f8cc534c 274 return (SQChar)c;
jhnwkmn 0:97a4f8cc534c 275 }
jhnwkmn 0:97a4f8cc534c 276 return 0;
jhnwkmn 0:97a4f8cc534c 277 }
jhnwkmn 0:97a4f8cc534c 278
jhnwkmn 0:97a4f8cc534c 279 SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size)
jhnwkmn 0:97a4f8cc534c 280 {
jhnwkmn 0:97a4f8cc534c 281 SQInteger ret;
jhnwkmn 0:97a4f8cc534c 282 if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret;
jhnwkmn 0:97a4f8cc534c 283 return -1;
jhnwkmn 0:97a4f8cc534c 284 }
jhnwkmn 0:97a4f8cc534c 285
jhnwkmn 0:97a4f8cc534c 286 SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size)
jhnwkmn 0:97a4f8cc534c 287 {
jhnwkmn 0:97a4f8cc534c 288 return sqstd_fwrite(p,1,size,(SQFILE)file);
jhnwkmn 0:97a4f8cc534c 289 }
jhnwkmn 0:97a4f8cc534c 290
jhnwkmn 0:97a4f8cc534c 291 SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror)
jhnwkmn 0:97a4f8cc534c 292 {
jhnwkmn 0:97a4f8cc534c 293 SQFILE file = sqstd_fopen(filename,_SC("rb"));
jhnwkmn 0:97a4f8cc534c 294 SQInteger ret;
jhnwkmn 0:97a4f8cc534c 295 unsigned short us;
jhnwkmn 0:97a4f8cc534c 296 unsigned char uc;
jhnwkmn 0:97a4f8cc534c 297 SQLEXREADFUNC func = _io_file_lexfeed_PLAIN;
jhnwkmn 0:97a4f8cc534c 298 if(file){
jhnwkmn 0:97a4f8cc534c 299 ret = sqstd_fread(&us,1,2,file);
jhnwkmn 0:97a4f8cc534c 300 if(ret != 2) {
jhnwkmn 0:97a4f8cc534c 301 //probably an empty file
jhnwkmn 0:97a4f8cc534c 302 us = 0;
jhnwkmn 0:97a4f8cc534c 303 }
jhnwkmn 0:97a4f8cc534c 304 if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE
jhnwkmn 0:97a4f8cc534c 305 sqstd_fseek(file,0,SQ_SEEK_SET);
jhnwkmn 0:97a4f8cc534c 306 if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) {
jhnwkmn 0:97a4f8cc534c 307 sqstd_fclose(file);
jhnwkmn 0:97a4f8cc534c 308 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 309 }
jhnwkmn 0:97a4f8cc534c 310 }
jhnwkmn 0:97a4f8cc534c 311 else { //SCRIPT
jhnwkmn 0:97a4f8cc534c 312 switch(us)
jhnwkmn 0:97a4f8cc534c 313 {
jhnwkmn 0:97a4f8cc534c 314 //gotta swap the next 2 lines on BIG endian machines
jhnwkmn 0:97a4f8cc534c 315 case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian;
jhnwkmn 0:97a4f8cc534c 316 case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian;
jhnwkmn 0:97a4f8cc534c 317 case 0xBBEF:
jhnwkmn 0:97a4f8cc534c 318 if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) {
jhnwkmn 0:97a4f8cc534c 319 sqstd_fclose(file);
jhnwkmn 0:97a4f8cc534c 320 return sq_throwerror(v,_SC("io error"));
jhnwkmn 0:97a4f8cc534c 321 }
jhnwkmn 0:97a4f8cc534c 322 if(uc != 0xBF) {
jhnwkmn 0:97a4f8cc534c 323 sqstd_fclose(file);
jhnwkmn 0:97a4f8cc534c 324 return sq_throwerror(v,_SC("Unrecognozed ecoding"));
jhnwkmn 0:97a4f8cc534c 325 }
jhnwkmn 0:97a4f8cc534c 326 #ifdef SQUNICODE
jhnwkmn 0:97a4f8cc534c 327 func = _io_file_lexfeed_UTF8;
jhnwkmn 0:97a4f8cc534c 328 #else
jhnwkmn 0:97a4f8cc534c 329 func = _io_file_lexfeed_PLAIN;
jhnwkmn 0:97a4f8cc534c 330 #endif
jhnwkmn 0:97a4f8cc534c 331 break;//UTF-8 ;
jhnwkmn 0:97a4f8cc534c 332 default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii
jhnwkmn 0:97a4f8cc534c 333 }
jhnwkmn 0:97a4f8cc534c 334
jhnwkmn 0:97a4f8cc534c 335 if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){
jhnwkmn 0:97a4f8cc534c 336 sqstd_fclose(file);
jhnwkmn 0:97a4f8cc534c 337 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 338 }
jhnwkmn 0:97a4f8cc534c 339 }
jhnwkmn 0:97a4f8cc534c 340 sqstd_fclose(file);
jhnwkmn 0:97a4f8cc534c 341 return SQ_ERROR;
jhnwkmn 0:97a4f8cc534c 342 }
jhnwkmn 0:97a4f8cc534c 343 return sq_throwerror(v,_SC("cannot open the file"));
jhnwkmn 0:97a4f8cc534c 344 }
jhnwkmn 0:97a4f8cc534c 345
jhnwkmn 0:97a4f8cc534c 346 SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror)
jhnwkmn 0:97a4f8cc534c 347 {
jhnwkmn 0:97a4f8cc534c 348 if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) {
jhnwkmn 0:97a4f8cc534c 349 sq_push(v,-2);
jhnwkmn 0:97a4f8cc534c 350 if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) {
jhnwkmn 0:97a4f8cc534c 351 sq_remove(v,retval?-2:-1); //removes the closure
jhnwkmn 0:97a4f8cc534c 352 return 1;
jhnwkmn 0:97a4f8cc534c 353 }
jhnwkmn 0:97a4f8cc534c 354 sq_pop(v,1); //removes the closure
jhnwkmn 0:97a4f8cc534c 355 }
jhnwkmn 0:97a4f8cc534c 356 return SQ_ERROR;
jhnwkmn 0:97a4f8cc534c 357 }
jhnwkmn 0:97a4f8cc534c 358
jhnwkmn 0:97a4f8cc534c 359 SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename)
jhnwkmn 0:97a4f8cc534c 360 {
jhnwkmn 0:97a4f8cc534c 361 SQFILE file = sqstd_fopen(filename,_SC("wb+"));
jhnwkmn 0:97a4f8cc534c 362 if(!file) return sq_throwerror(v,_SC("cannot open the file"));
jhnwkmn 0:97a4f8cc534c 363 if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) {
jhnwkmn 0:97a4f8cc534c 364 sqstd_fclose(file);
jhnwkmn 0:97a4f8cc534c 365 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 366 }
jhnwkmn 0:97a4f8cc534c 367 sqstd_fclose(file);
jhnwkmn 0:97a4f8cc534c 368 return SQ_ERROR; //forward the error
jhnwkmn 0:97a4f8cc534c 369 }
jhnwkmn 0:97a4f8cc534c 370
jhnwkmn 0:97a4f8cc534c 371 SQInteger _g_io_loadfile(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 372 {
jhnwkmn 0:97a4f8cc534c 373 const SQChar *filename;
jhnwkmn 0:97a4f8cc534c 374 SQBool printerror = SQFalse;
jhnwkmn 0:97a4f8cc534c 375 sq_getstring(v,2,&filename);
jhnwkmn 0:97a4f8cc534c 376 if(sq_gettop(v) >= 3) {
jhnwkmn 0:97a4f8cc534c 377 sq_getbool(v,3,&printerror);
jhnwkmn 0:97a4f8cc534c 378 }
jhnwkmn 0:97a4f8cc534c 379 if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror)))
jhnwkmn 0:97a4f8cc534c 380 return 1;
jhnwkmn 0:97a4f8cc534c 381 return SQ_ERROR; //propagates the error
jhnwkmn 0:97a4f8cc534c 382 }
jhnwkmn 0:97a4f8cc534c 383
jhnwkmn 0:97a4f8cc534c 384 SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 385 {
jhnwkmn 0:97a4f8cc534c 386 const SQChar *filename;
jhnwkmn 0:97a4f8cc534c 387 sq_getstring(v,2,&filename);
jhnwkmn 0:97a4f8cc534c 388 if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename)))
jhnwkmn 0:97a4f8cc534c 389 return 1;
jhnwkmn 0:97a4f8cc534c 390 return SQ_ERROR; //propagates the error
jhnwkmn 0:97a4f8cc534c 391 }
jhnwkmn 0:97a4f8cc534c 392
jhnwkmn 0:97a4f8cc534c 393 SQInteger _g_io_dofile(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 394 {
jhnwkmn 0:97a4f8cc534c 395 const SQChar *filename;
jhnwkmn 0:97a4f8cc534c 396 SQBool printerror = SQFalse;
jhnwkmn 0:97a4f8cc534c 397 sq_getstring(v,2,&filename);
jhnwkmn 0:97a4f8cc534c 398 if(sq_gettop(v) >= 3) {
jhnwkmn 0:97a4f8cc534c 399 sq_getbool(v,3,&printerror);
jhnwkmn 0:97a4f8cc534c 400 }
jhnwkmn 0:97a4f8cc534c 401 sq_push(v,1); //repush the this
jhnwkmn 0:97a4f8cc534c 402 if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror)))
jhnwkmn 0:97a4f8cc534c 403 return 1;
jhnwkmn 0:97a4f8cc534c 404 return SQ_ERROR; //propagates the error
jhnwkmn 0:97a4f8cc534c 405 }
jhnwkmn 0:97a4f8cc534c 406
jhnwkmn 0:97a4f8cc534c 407 #define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck}
jhnwkmn 0:97a4f8cc534c 408 static SQRegFunction iolib_funcs[]={
jhnwkmn 0:97a4f8cc534c 409 _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")),
jhnwkmn 0:97a4f8cc534c 410 _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")),
jhnwkmn 0:97a4f8cc534c 411 _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")),
jhnwkmn 0:97a4f8cc534c 412 {0,0}
jhnwkmn 0:97a4f8cc534c 413 };
jhnwkmn 0:97a4f8cc534c 414
jhnwkmn 0:97a4f8cc534c 415 SQRESULT sqstd_register_iolib(HSQUIRRELVM v)
jhnwkmn 0:97a4f8cc534c 416 {
jhnwkmn 0:97a4f8cc534c 417 SQInteger top = sq_gettop(v);
jhnwkmn 0:97a4f8cc534c 418 //create delegate
jhnwkmn 0:97a4f8cc534c 419 declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs);
jhnwkmn 0:97a4f8cc534c 420 sq_pushstring(v,_SC("stdout"),-1);
jhnwkmn 0:97a4f8cc534c 421 sqstd_createfile(v,stdout,SQFalse);
jhnwkmn 0:97a4f8cc534c 422 sq_newslot(v,-3,SQFalse);
jhnwkmn 0:97a4f8cc534c 423 sq_pushstring(v,_SC("stdin"),-1);
jhnwkmn 0:97a4f8cc534c 424 sqstd_createfile(v,stdin,SQFalse);
jhnwkmn 0:97a4f8cc534c 425 sq_newslot(v,-3,SQFalse);
jhnwkmn 0:97a4f8cc534c 426 sq_pushstring(v,_SC("stderr"),-1);
jhnwkmn 0:97a4f8cc534c 427 sqstd_createfile(v,stderr,SQFalse);
jhnwkmn 0:97a4f8cc534c 428 sq_newslot(v,-3,SQFalse);
jhnwkmn 0:97a4f8cc534c 429 sq_settop(v,top);
jhnwkmn 0:97a4f8cc534c 430 return SQ_OK;
jhnwkmn 0:97a4f8cc534c 431 }