summaryrefslogtreecommitdiff
path: root/source/luametatex/source/luarest/lmtiolibext.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/luarest/lmtiolibext.c')
-rw-r--r--source/luametatex/source/luarest/lmtiolibext.c1608
1 files changed, 1608 insertions, 0 deletions
diff --git a/source/luametatex/source/luarest/lmtiolibext.c b/source/luametatex/source/luarest/lmtiolibext.c
new file mode 100644
index 000000000..319eb40c6
--- /dev/null
+++ b/source/luametatex/source/luarest/lmtiolibext.c
@@ -0,0 +1,1608 @@
+/*
+ See license.txt in the root of this project.
+*/
+
+/*tex
+
+ Lua doesn't have cardinals so basically we could stick to integers and accept that we have a
+ limited range.
+
+*/
+
+# include "luametatex.h"
+
+# ifdef _WIN32
+
+ # define lua_popen(L,c,m) ((void)L, _popen(c,m))
+ # define lua_pclose(L,file) ((void)L, _pclose(file))
+
+# else
+
+ # define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
+ # define lua_pclose(L,file) ((void)L, pclose(file))
+
+# endif
+
+/* Mojca: we need to sort this out! */
+
+# ifdef LUA_USE_POSIX
+
+ # define l_fseek(f,o,w) fseeko(f,o,w)
+ # define l_ftell(f) ftello(f)
+ # define l_seeknum off_t
+
+# elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) && defined(_MSC_VER) && (_MSC_VER >= 1400)
+
+ # define l_fseek(f,o,w) _fseeki64(f,o,w)
+ # define l_ftell(f) _ftelli64(f)
+ # define l_seeknum __int64
+
+# elif defined(__MINGW32__)
+
+ # define l_fseek(f,o,w) fseeko64(f,o,w)
+ # define l_ftell(f) ftello64(f)
+ # define l_seeknum int64_t
+
+# else
+
+ # define l_fseek(f,o,w) fseek(f,o,w)
+ # define l_ftell(f) ftell(f)
+ # define l_seeknum long
+
+# endif
+
+# define uchar(c) ((unsigned char)(c))
+
+/*tex
+
+ A few helpers to avoid reading numbers as strings. For now we put them in their own namespace.
+ We also have a few helpers that can make \IO\ functions \TEX\ friendly.
+
+*/
+
+static int fiolib_readcardinal1(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else {
+ lua_pushinteger(L, a);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readcardinal1(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if (p >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p]);
+ lua_pushinteger(L, a);
+ }
+ return 1;
+}
+
+static int fiolib_readcardinal2(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ if (b == EOF) {
+ lua_pushnil(L);
+ } else {
+ /* (a<<8) | b */
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_readcardinal2_le(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer b = getc(f);
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else {
+ /* (a<<8) | b */
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readcardinal2(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 1) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p]);
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ return 1;
+}
+
+static int siolib_readcardinal2_le(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 1) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer a = uchar(s[p]);
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ return 1;
+}
+
+static int fiolib_readcardinal3(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ if (c == EOF) {
+ lua_pushnil(L);
+ } else {
+ /* (a<<16) | (b<<8) | c */
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_readcardinal3_le(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer c = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else {
+ /* (a<<16) | (b<<8) | c */
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readcardinal3(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 2) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p]);
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ return 1;
+}
+
+static int siolib_readcardinal3_le(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 2) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer a = uchar(s[p]);
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ return 1;
+}
+
+static int fiolib_readcardinal4(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ lua_Integer d = getc(f);
+ if (d == EOF) {
+ lua_pushnil(L);
+ } else {
+ /* (a<<24) | (b<<16) | (c<<8) | d */
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_readcardinal4_le(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer d = getc(f);
+ lua_Integer c = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else {
+ /* (a<<24) | (b<<16) | (c<<8) | d */
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readcardinal4(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 3) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer d = uchar(s[p]);
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ return 1;
+}
+
+static int siolib_readcardinal4_le(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 3) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer d = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer a = uchar(s[p]);
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ return 1;
+}
+
+static int fiolib_readcardinaltable(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ lua_Integer m = lua_tointeger(L, 3);
+ lua_createtable(L, (int) n, 0);
+ switch (m) {
+ case 1:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ break;
+ } else {
+ lua_pushinteger(L, a);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 2:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ if (b == EOF) {
+ break;
+ } else {
+ /* (a<<8) | b */
+ lua_pushinteger(L, 0x100 * a + b);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 3:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ if (c == EOF) {
+ break;
+ } else {
+ /* (a<<16) | (b<<8) | c */
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 4:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ lua_Integer d = getc(f);
+ if (d == EOF) {
+ break;
+ } else {
+ /* (a<<24) | (b<<16) | (c<<8) | d */
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readcardinaltable(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer n = lua_tointeger(L, 3);
+ lua_Integer m = lua_tointeger(L, 4);
+ lua_Integer l = (lua_Integer) ls;
+ lua_createtable(L, (int) n, 0);
+ switch (m) {
+ case 1:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if (p >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_pushinteger(L, a);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 2:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if ((p + 1) >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_pushinteger(L, 0x100 * a + b);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 3:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if ((p + 2) >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 4:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if ((p + 3) >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer d = uchar(s[p++]);
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static int fiolib_readinteger1(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, a - 0x100);
+ } else {
+ lua_pushinteger(L, a);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readinteger1(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if (p >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, a - 0x100);
+ } else {
+ lua_pushinteger(L, a);
+ }
+ }
+ return 1;
+}
+
+static int fiolib_readinteger2(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ if (b == EOF) {
+ lua_pushnil(L);
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x100 * a + b - 0x10000);
+ } else {
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_readinteger2_le(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer b = getc(f);
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x100 * a + b - 0x10000);
+ } else {
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readinteger2(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 1) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x100 * a + b - 0x10000);
+ } else {
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ }
+ return 1;
+}
+
+static int siolib_readinteger2_le(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 1) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer a = uchar(s[p]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x100 * a + b - 0x10000);
+ } else {
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ }
+ return 1;
+}
+
+static int fiolib_readinteger3(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ if (c == EOF) {
+ lua_pushnil(L);
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c - 0x1000000);
+ } else {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_readinteger3_le(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer c = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c - 0x1000000);
+ } else {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readinteger3(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 2) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c - 0x1000000);
+ } else {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ }
+ return 1;
+}
+
+static int siolib_readinteger3_le(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 2) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer a = uchar(s[p]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c - 0x1000000);
+ } else {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ }
+ return 1;
+}
+
+static int fiolib_readinteger4(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ lua_Integer d = getc(f);
+ if (d == EOF) {
+ lua_pushnil(L);
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000);
+ } else {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_readinteger4_le(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer d = getc(f);
+ lua_Integer c = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ lua_pushnil(L);
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000);
+ } else {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readinteger4(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 3) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer d = uchar(s[p]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000);
+ } else {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ }
+ return 1;
+}
+
+static int siolib_readinteger4_le(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 3) >= l) {
+ lua_pushnil(L);
+ } else {
+ lua_Integer d = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer a = uchar(s[p]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000);
+ } else {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ }
+ return 1;
+}
+
+static int fiolib_readintegertable(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ lua_Integer m = lua_tointeger(L, 3);
+ lua_createtable(L, (int) n, 0);
+ switch (m) {
+ case 1:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ break;
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, a - 0x100);
+ } else {
+ lua_pushinteger(L, a);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ break;
+ case 2:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ if (b == EOF) {
+ break;
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x100 * a + b - 0x10000);
+ } else {
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ break;
+ case 3:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ if (c == EOF) {
+ break;
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c - 0x1000000);
+ } else {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ break;
+ case 4:
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ lua_Integer b = getc(f);
+ lua_Integer c = getc(f);
+ lua_Integer d = getc(f);
+ if (d == EOF) {
+ break;
+ } else if (a >= 0x80) {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000);
+ } else {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ break;
+ default:
+ break;
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readintegertable(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer n = lua_tointeger(L, 3);
+ lua_Integer m = lua_tointeger(L, 4);
+ lua_Integer l = (lua_Integer) ls;
+ lua_createtable(L, (int) n, 0);
+ switch (m) {
+ case 1:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if (p >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, a - 0x100);
+ } else {
+ lua_pushinteger(L, a);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 2:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if ((p + 1) >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x100 * a + b - 0x10000);
+ } else {
+ lua_pushinteger(L, 0x100 * a + b);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 3:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if ((p + 2) >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c - 0x1000000);
+ } else {
+ lua_pushinteger(L, 0x10000 * a + 0x100 * b + c);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ case 4:
+ for (lua_Integer i = 1; i <= n; i++) {
+ if ((p + 3) >= l) {
+ break;
+ } else {
+ lua_Integer a = uchar(s[p++]);
+ lua_Integer b = uchar(s[p++]);
+ lua_Integer c = uchar(s[p++]);
+ lua_Integer d = uchar(s[p++]);
+ if (a >= 0x80) {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000);
+ } else {
+ lua_pushinteger(L, 0x1000000 * a + 0x10000 * b + 0x100 * c + d);
+ }
+ lua_rawseti(L, -2, i);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+/* from ff */
+
+static int fiolib_readfixed2(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ int a = getc(f);
+ int b = getc(f);
+ if (b == EOF) {
+ lua_pushnil(L);
+ } else {
+ int n = 0x100 * a + b; /* really an int because we shift */
+ lua_pushnumber(L, (double) ((n>>8) + ((n&0xff)/256.0)));
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readfixed2(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 3) >= l) {
+ lua_pushnil(L);
+ } else {
+ int a = uchar(s[p++]);
+ int b = uchar(s[p]);
+ int n = 0x100 * a + b; /* really an int because we shift */
+ lua_pushnumber(L, (double) ((n>>8) + ((n&0xff)/256.0)));
+ }
+ return 1;
+}
+
+static int fiolib_readfixed4(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ int a = getc(f);
+ int b = getc(f);
+ int c = getc(f);
+ int d = getc(f);
+ if (d == EOF) {
+ lua_pushnil(L);
+ } else {
+ int n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d; /* really an int because we shift */
+ lua_pushnumber(L, (double) ((n>>16) + ((n&0xffff)/65536.0)));
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readfixed4(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 3) >= l) {
+ lua_pushnil(L);
+ } else {
+ int a = uchar(s[p++]);
+ int b = uchar(s[p++]);
+ int c = uchar(s[p++]);
+ int d = uchar(s[p]);
+ int n = 0x1000000 * a + 0x10000 * b + 0x100 * c + d; /* really an int because we shift */
+ lua_pushnumber(L, (double) ((n>>16) + ((n&0xffff)/65536.0)));
+ }
+ return 1;
+}
+
+static int fiolib_read2dot14(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ int a = getc(f);
+ int b = getc(f);
+ if (b == EOF) {
+ lua_pushnil(L);
+ } else {
+ int n = 0x100 * a + b; /* really an int because we shift */
+ /* from ff */
+ lua_pushnumber(L, (double) (((n<<16)>>(16+14)) + ((n&0x3fff)/16384.0)));
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_read2dot14(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if ((p + 1) >= l) {
+ lua_pushnil(L);
+ } else {
+ int a = uchar(s[p++]);
+ int b = uchar(s[p]);
+ int n = 0x100 * a + b; /* really an int because we shift */
+ lua_pushnumber(L, (double) (((n<<16)>>(16+14)) + ((n&0x3fff)/16384.0)));
+ }
+ return 1;
+}
+
+static int fiolib_getposition(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ long p = ftell(f);
+ if (p < 0) {
+ lua_pushnil(L);
+ } else {
+ lua_pushinteger(L, p);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_setposition(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ long p = lmt_tolong(L, 2);
+ p = fseek(f, p, SEEK_SET);
+ if (p < 0) {
+ lua_pushnil(L);
+ } else {
+ lua_pushinteger(L, p);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_skipposition(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ long p = lmt_tolong(L, 2);
+ p = fseek(f, ftell(f) + p, SEEK_SET);
+ if (p < 0) {
+ lua_pushnil(L);
+ } else {
+ lua_pushinteger(L, p);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int fiolib_readbytetable(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ lua_createtable(L, (int) n, 0);
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ break;
+ } else {
+ /*
+ lua_pushinteger(L, i);
+ lua_pushinteger(L, a);
+ lua_rawset(L, -3);
+ */
+ lua_pushinteger(L, a);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readbytetable(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer n = lua_tointeger(L, 3);
+ lua_Integer l = (lua_Integer) ls;
+ if (p >= l) {
+ lua_pushnil(L);
+ } else {
+ if (p + n >= l) {
+ n = l - p ;
+ }
+ lua_createtable(L, (int) n, 0);
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = uchar(s[p++]);
+ lua_pushinteger(L, a);
+ lua_rawseti(L, -2, i);
+ }
+ }
+ return 1;
+}
+
+static int fiolib_readbytes(lua_State *L) {
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = getc(f);
+ if (a == EOF) {
+ return (int) (i - 1);
+ } else {
+ lua_pushinteger(L, a);
+ }
+ }
+ return (int) n;
+ } else {
+ return 0;
+ }
+}
+
+static int siolib_readbytes(lua_State *L) {
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer n = lua_tointeger(L, 3);
+ lua_Integer l = (lua_Integer) ls;
+ if (p >= l) {
+ return 0;
+ } else {
+ if (p + n >= l) {
+ n = l - p ;
+ }
+ lua_createtable(L, (int) n, 0);
+ for (lua_Integer i = 1; i <= n; i++) {
+ lua_Integer a = uchar(s[p++]);
+ lua_pushinteger(L, a);
+ }
+ return (int) n;
+ }
+}
+
+static int fiolib_readcline(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ luaL_Buffer buf;
+ int c;
+ int n = 0;
+ luaL_buffinit(L, &buf);
+ do {
+ char *b = luaL_prepbuffer(&buf);
+ int i = 0;
+ while (i < LUAL_BUFFERSIZE) {
+ c = fgetc(f);
+ if (c == '\n') {
+ goto GOOD;
+ } else if (c == '\r') {
+ c = fgetc(f);
+ if (c != EOF && c != '\n') {
+ ungetc((int) c, f);
+ }
+ goto GOOD;
+ } else {
+ n++;
+ b[i++] = (char) c;
+ }
+ }
+ } while (c != EOF);
+ goto BAD;
+ GOOD:
+ if (n > 0) {
+ luaL_addsize(&buf, n);
+ luaL_pushresult(&buf);
+ } else {
+ lua_pushnil(L);
+ }
+ lua_pushinteger(L, ftell(f));
+ return 2;
+ }
+ BAD:
+ lua_pushnil(L);
+ return 1;
+}
+
+
+static int siolib_readcline(lua_State *L)
+{
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if (p < l) {
+ lua_Integer i = p;
+ int n = 0;
+ while (p < l) {
+ int c = uchar(s[p++]);
+ if (c == '\n') {
+ goto GOOD;
+ } else if (c == '\r') {
+ if (p < l) {
+ c = uchar(s[p++]);
+ if (c != EOF && c != '\n') {
+ --p;
+ }
+ }
+ goto GOOD;
+ } else {
+ n++;
+ }
+ }
+ goto BAD;
+ GOOD:
+ if (n > 0) {
+ lua_pushlstring(L, &s[i], n);
+ lua_pushinteger(L, p);
+ return 2;
+ }
+ }
+ BAD:
+ lua_pushnil(L);
+ lua_pushinteger(L, p + 1);
+ return 2;
+}
+
+static int fiolib_readcstring(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ luaL_Buffer buf;
+ int c;
+ int n = 0;
+ luaL_buffinit(L, &buf);
+ do {
+ char *b = luaL_prepbuffer(&buf);
+ int i = 0;
+ while (i < LUAL_BUFFERSIZE) {
+ c = fgetc(f);
+ if (c == '\0') {
+ goto GOOD;
+ } else {
+ n++;
+ b[i++] = (char) c;
+ }
+ }
+ } while (c != EOF);
+ goto BAD;
+ GOOD:
+ if (n > 0) {
+ luaL_addsize(&buf, n);
+ luaL_pushresult(&buf);
+ } else {
+ lua_pushliteral(L,"");
+ }
+ lua_pushinteger(L, ftell(f));
+ return 2;
+ }
+ BAD:
+ lua_pushnil(L);
+ return 1;
+}
+
+static int siolib_readcstring(lua_State *L)
+{
+ size_t ls = 0;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ lua_Integer p = luaL_checkinteger(L, 2) - 1;
+ lua_Integer l = (lua_Integer) ls;
+ if (p < l) {
+ lua_Integer i = p;
+ int n = 0;
+ while (p < l) {
+ int c = uchar(s[p++]);
+ if (c == '\0') {
+ goto GOOD;
+ } else {
+ n++;
+ }
+ };
+ goto BAD;
+ GOOD:
+ if (n > 0) {
+ lua_pushlstring(L, &s[i], n);
+ } else {
+ lua_pushliteral(L,"");
+ }
+ lua_pushinteger(L, p + 1);
+ return 2;
+ }
+ BAD:
+ lua_pushnil(L);
+ lua_pushinteger(L, p + 1);
+ return 2;
+}
+
+/* will be completed */
+
+static int fiolib_writecardinal1(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ putc(n & 0xFF, f);
+ }
+ return 0;
+}
+
+static int siolib_tocardinal1(lua_State *L)
+{
+ lua_Integer n = lua_tointeger(L, 1);
+ char buffer[1] = { n & 0xFF };
+ lua_pushlstring(L, buffer, 1);
+ return 1;
+}
+
+static int fiolib_writecardinal2(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ putc((n >> 8) & 0xFF, f);
+ putc( n & 0xFF, f);
+ }
+ return 0;
+}
+
+static int siolib_tocardinal2(lua_State *L)
+{
+ lua_Integer n = lua_tointeger(L, 1);
+ char buffer[2] = { (n >> 8) & 0xFF, n & 0xFF };
+ lua_pushlstring(L, buffer, 2);
+ return 1;
+}
+
+static int fiolib_writecardinal2_le(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ putc( n & 0xFF, f);
+ putc((n >> 8) & 0xFF, f);
+ }
+ return 0;
+}
+
+static int siolib_tocardinal2_le(lua_State *L)
+{
+ lua_Integer n = lua_tointeger(L, 1);
+ char buffer[2] = { n & 0xFF, (n >> 8) & 0xFF };
+ lua_pushlstring(L, buffer, 2);
+ return 1;
+}
+
+static int fiolib_writecardinal3(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ putc((n >> 16) & 0xFF, f);
+ putc((n >> 8) & 0xFF, f);
+ putc( n & 0xFF, f);
+ }
+ return 0;
+}
+
+static int siolib_tocardinal3(lua_State *L)
+{
+ lua_Integer n = lua_tointeger(L, 1);
+ char buffer[3] = { (n >> 16) & 0xFF, (n >> 8) & 0xFF, n & 0xFF };
+ lua_pushlstring(L, buffer, 3);
+ return 1;
+}
+
+
+static int fiolib_writecardinal3_le(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ putc( n & 0xFF, f);
+ putc((n >> 8) & 0xFF, f);
+ putc((n >> 16) & 0xFF, f);
+ }
+ return 0;
+}
+
+static int siolib_tocardinal3_le(lua_State *L)
+{
+ lua_Integer n = lua_tointeger(L, 1);
+ char buffer[3] = { n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF };
+ lua_pushlstring(L, buffer, 3);
+ return 1;
+}
+
+static int fiolib_writecardinal4(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ putc((n >> 24) & 0xFF, f);
+ putc((n >> 16) & 0xFF, f);
+ putc((n >> 8) & 0xFF, f);
+ putc( n & 0xFF, f);
+ }
+ return 0;
+}
+
+static int siolib_tocardinal4(lua_State *L)
+{
+ lua_Integer n = lua_tointeger(L, 1);
+ char buffer[4] = { (n >> 24) & 0xFF, (n >> 16) & 0xFF, (n >> 8) & 0xFF, n & 0xFF };
+ lua_pushlstring(L, buffer, 4);
+ return 1;
+}
+
+static int fiolib_writecardinal4_le(lua_State *L)
+{
+ FILE *f = lmt_valid_file(L);
+ if (f) {
+ lua_Integer n = lua_tointeger(L, 2);
+ putc( n & 0xFF, f);
+ putc((n >> 8) & 0xFF, f);
+ putc((n >> 16) & 0xFF, f);
+ putc((n >> 24) & 0xFF, f);
+ }
+ return 0;
+}
+
+static int siolib_tocardinal4_le(lua_State *L)
+{
+ lua_Integer n = lua_tointeger(L, 1);
+ char buffer[4] = { n & 0xFF, (n >> 8) & 0xFF, (n >> 16) & 0xFF, (n >> 24) & 0xFF };
+ lua_pushlstring(L, buffer, 4);
+ return 1;
+}
+
+/* */
+
+static const luaL_Reg fiolib_function_list[] = {
+ /* helpers */
+
+ { "readcardinal1", fiolib_readcardinal1 },
+ { "readcardinal2", fiolib_readcardinal2 },
+ { "readcardinal3", fiolib_readcardinal3 },
+ { "readcardinal4", fiolib_readcardinal4 },
+
+ { "readcardinal1le", fiolib_readcardinal1 },
+ { "readcardinal2le", fiolib_readcardinal2_le },
+ { "readcardinal3le", fiolib_readcardinal3_le },
+ { "readcardinal4le", fiolib_readcardinal4_le },
+
+ { "readcardinaltable", fiolib_readcardinaltable },
+
+ { "readinteger1", fiolib_readinteger1 },
+ { "readinteger2", fiolib_readinteger2 },
+ { "readinteger3", fiolib_readinteger3 },
+ { "readinteger4", fiolib_readinteger4 },
+
+ { "readinteger1le", fiolib_readinteger1 },
+ { "readinteger2le", fiolib_readinteger2_le },
+ { "readinteger3le", fiolib_readinteger3_le },
+ { "readinteger4le", fiolib_readinteger4_le },
+
+ { "readintegertable", fiolib_readintegertable },
+
+ { "readfixed2", fiolib_readfixed2 },
+ { "readfixed4", fiolib_readfixed4 },
+
+ { "read2dot14", fiolib_read2dot14 },
+
+ { "setposition", fiolib_setposition },
+ { "getposition", fiolib_getposition },
+ { "skipposition", fiolib_skipposition },
+
+ { "readbytes", fiolib_readbytes },
+ { "readbytetable", fiolib_readbytetable },
+
+ { "readcline", fiolib_readcline },
+ { "readcstring", fiolib_readcstring },
+
+ { "writecardinal1", fiolib_writecardinal1 },
+ { "writecardinal2", fiolib_writecardinal2 },
+ { "writecardinal3", fiolib_writecardinal3 },
+ { "writecardinal4", fiolib_writecardinal4 },
+
+ { "writecardinal1le", fiolib_writecardinal1 },
+ { "writecardinal2le", fiolib_writecardinal2_le },
+ { "writecardinal3le", fiolib_writecardinal3_le },
+ { "writecardinal4le", fiolib_writecardinal4_le },
+
+ { NULL, NULL }
+};
+
+static const luaL_Reg siolib_function_list[] = {
+
+ { "readcardinal1", siolib_readcardinal1 },
+ { "readcardinal2", siolib_readcardinal2 },
+ { "readcardinal3", siolib_readcardinal3 },
+ { "readcardinal4", siolib_readcardinal4 },
+
+ { "readcardinal1le", siolib_readcardinal1 },
+ { "readcardinal2le", siolib_readcardinal2_le },
+ { "readcardinal3le", siolib_readcardinal3_le },
+ { "readcardinal4le", siolib_readcardinal4_le },
+
+ { "readcardinaltable", siolib_readcardinaltable },
+
+ { "readinteger1", siolib_readinteger1 },
+ { "readinteger2", siolib_readinteger2 },
+ { "readinteger3", siolib_readinteger3 },
+ { "readinteger4", siolib_readinteger4 },
+
+ { "readinteger1le", siolib_readinteger1 },
+ { "readinteger2le", siolib_readinteger2_le },
+ { "readinteger3le", siolib_readinteger3_le },
+ { "readinteger4le", siolib_readinteger4_le },
+
+ { "readintegertable", siolib_readintegertable },
+
+ { "readfixed2", siolib_readfixed2 },
+ { "readfixed4", siolib_readfixed4 },
+ { "read2dot14", siolib_read2dot14 },
+
+ { "readbytes", siolib_readbytes },
+ { "readbytetable", siolib_readbytetable },
+
+ { "readcline", siolib_readcline },
+ { "readcstring", siolib_readcstring },
+
+ { "tocardinal1", siolib_tocardinal1 },
+ { "tocardinal2", siolib_tocardinal2 },
+ { "tocardinal3", siolib_tocardinal3 },
+ { "tocardinal4", siolib_tocardinal4 },
+
+ { "tocardinal1le", siolib_tocardinal1 },
+ { "tocardinal2le", siolib_tocardinal2_le },
+ { "tocardinal3le", siolib_tocardinal3_le },
+ { "tocardinal4le", siolib_tocardinal4_le },
+
+ { NULL, NULL }
+};
+
+/*tex
+
+ The sio helpers might be handy at some point. Speed-wise there is no gain over file access
+ because with ssd and caching we basically operate in memory too. We keep them as complement to
+ the file ones. I did consider using an userdata object for the position etc but some simple
+ tests demonstrated that there is no real gain and the current ones permits to wrap up whatever
+ interface one likes.
+
+*/
+
+int luaopen_fio(lua_State *L) {
+ lua_newtable(L);
+ luaL_setfuncs(L, fiolib_function_list, 0);
+ return 1;
+}
+
+int luaopen_sio(lua_State *L) {
+ lua_newtable(L);
+ luaL_setfuncs(L, siolib_function_list, 0);
+ return 1;
+}
+
+/* We patch a function in the standard |io| library. */
+
+/*tex
+
+ The following code overloads the |io.open| function to deal with so called wide characters on
+ windows.
+
+*/
+
+# if _WIN32
+
+# define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
+
+ static int l_checkmode(const char *mode) {
+ return (
+ *mode != '\0'
+ && strchr("rwa", *(mode++))
+ && (*mode != '+' || ((void)(++mode), 1))
+ && (strspn(mode, "b") == strlen(mode))
+ );
+ }
+
+ typedef luaL_Stream LStream;
+
+ static LStream *newprefile(lua_State *L) {
+ LStream *p = (LStream *)lua_newuserdatauv(L, sizeof(LStream), 0);
+ p->closef = NULL;
+ luaL_setmetatable(L, LUA_FILEHANDLE);
+ return p;
+ }
+
+ static int io_fclose(lua_State *L) {
+ LStream *p = tolstream(L);
+ int res = fclose(p->f);
+ return luaL_fileresult(L, (res == 0), NULL);
+ }
+
+ static LStream *newfile(lua_State *L) {
+ /*tex Watch out: lua 5.4 has different closers. */
+ LStream *p = newprefile(L);
+ p->f = NULL;
+ p->closef = &io_fclose;
+ return p;
+ }
+
+ static int io_open(lua_State *L)
+ {
+ const char *filename = luaL_checkstring(L, 1);
+ const char *mode = luaL_optstring(L, 2, "r");
+ LStream *p = newfile(L);
+ const char *md = mode; /* to traverse/check mode */
+ luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
+ p->f = aux_utf8_fopen(filename, mode);
+ return (p->f) ? 1 : luaL_fileresult(L, 0, filename);
+ }
+
+ static int io_pclose(lua_State *L) {
+ LStream *p = tolstream(L);
+ return luaL_execresult(L, _pclose(p->f));
+ }
+
+ static int io_popen(lua_State *L)
+ {
+ const char *filename = luaL_checkstring(L, 1);
+ const char *mode = luaL_optstring(L, 2, "r");
+ LStream *p = newprefile(L);
+ p->f = aux_utf8_popen(filename, mode);
+ p->closef = &io_pclose;
+ return (p->f) ? 1 : luaL_fileresult(L, 0, filename);
+ }
+
+ int luaextend_io(lua_State *L)
+ {
+ lua_getglobal(L, "io");
+ lua_pushcfunction(L, io_open); lua_setfield(L, -2, "open");
+ lua_pushcfunction(L, io_popen); lua_setfield(L, -2, "popen");
+ lua_pop(L, 1);
+ /*tex
+ Larger doesn't work and limits to 512 but then no amount is okay as there's always more
+ to demand.
+ */
+ _setmaxstdio(2048);
+ return 1;
+ }
+
+# else
+
+ int luaextend_io(lua_State *L)
+ {
+ (void) L;
+ return 1;
+ }
+
+# endif