aboutsummaryrefslogtreecommitdiff
path: root/src/lib_io.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_io.c')
-rw-r--r--src/lib_io.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/src/lib_io.c b/src/lib_io.c
index 0f369ab2..12fe0427 100644
--- a/src/lib_io.c
+++ b/src/lib_io.c
@@ -19,8 +19,10 @@
19#include "lj_obj.h" 19#include "lj_obj.h"
20#include "lj_gc.h" 20#include "lj_gc.h"
21#include "lj_err.h" 21#include "lj_err.h"
22#include "lj_buf.h"
22#include "lj_str.h" 23#include "lj_str.h"
23#include "lj_state.h" 24#include "lj_state.h"
25#include "lj_strfmt.h"
24#include "lj_ff.h" 26#include "lj_ff.h"
25#include "lj_lib.h" 27#include "lj_lib.h"
26#include "lj_strscan.h" 28#include "lj_strscan.h"
@@ -85,7 +87,7 @@ static IOFileUD *io_file_open(lua_State *L, const char *mode)
85 IOFileUD *iof = io_file_new(L); 87 IOFileUD *iof = io_file_new(L);
86 iof->fp = fopen(fname, mode); 88 iof->fp = fopen(fname, mode);
87 if (iof->fp == NULL) 89 if (iof->fp == NULL)
88 luaL_argerror(L, 1, lj_str_pushf(L, "%s: %s", fname, strerror(errno))); 90 luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: %s", fname, strerror(errno)));
89 return iof; 91 return iof;
90} 92}
91 93
@@ -98,11 +100,8 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
98 int stat = -1; 100 int stat = -1;
99#if LJ_TARGET_POSIX 101#if LJ_TARGET_POSIX
100 stat = pclose(iof->fp); 102 stat = pclose(iof->fp);
101#elif LJ_TARGET_WINDOWS 103#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP
102 stat = _pclose(iof->fp); 104 stat = _pclose(iof->fp);
103#else
104 lua_assert(0);
105 return 0;
106#endif 105#endif
107#if LJ_52 106#if LJ_52
108 iof->fp = NULL; 107 iof->fp = NULL;
@@ -111,7 +110,8 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
111 ok = (stat != -1); 110 ok = (stat != -1);
112#endif 111#endif
113 } else { 112 } else {
114 lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF); 113 lj_assertL((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF,
114 "close of unknown FILE* type");
115 setnilV(L->top++); 115 setnilV(L->top++);
116 lua_pushliteral(L, "cannot close standard file"); 116 lua_pushliteral(L, "cannot close standard file");
117 return 2; 117 return 2;
@@ -127,8 +127,9 @@ static int io_file_readnum(lua_State *L, FILE *fp)
127 lua_Number d; 127 lua_Number d;
128 if (fscanf(fp, LUA_NUMBER_SCAN, &d) == 1) { 128 if (fscanf(fp, LUA_NUMBER_SCAN, &d) == 1) {
129 if (LJ_DUALNUM) { 129 if (LJ_DUALNUM) {
130 int32_t i = lj_num2int(d); 130 int64_t i64;
131 if (d == (lua_Number)i && !tvismzero((cTValue *)&d)) { 131 int32_t i;
132 if (lj_num2int_check(d, i64, i) && !tvismzero((cTValue *)&d)) {
132 setintV(L->top++, i); 133 setintV(L->top++, i);
133 return 1; 134 return 1;
134 } 135 }
@@ -146,7 +147,7 @@ static int io_file_readline(lua_State *L, FILE *fp, MSize chop)
146 MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0; 147 MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0;
147 char *buf; 148 char *buf;
148 for (;;) { 149 for (;;) {
149 buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 150 buf = lj_buf_tmp(L, m);
150 if (fgets(buf+n, m-n, fp) == NULL) break; 151 if (fgets(buf+n, m-n, fp) == NULL) break;
151 n += (MSize)strlen(buf+n); 152 n += (MSize)strlen(buf+n);
152 ok |= n; 153 ok |= n;
@@ -162,7 +163,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
162{ 163{
163 MSize m, n; 164 MSize m, n;
164 for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) { 165 for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) {
165 char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 166 char *buf = lj_buf_tmp(L, m);
166 n += (MSize)fread(buf+n, 1, m-n, fp); 167 n += (MSize)fread(buf+n, 1, m-n, fp);
167 if (n != m) { 168 if (n != m) {
168 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n)); 169 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
@@ -175,7 +176,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
175static int io_file_readlen(lua_State *L, FILE *fp, MSize m) 176static int io_file_readlen(lua_State *L, FILE *fp, MSize m)
176{ 177{
177 if (m) { 178 if (m) {
178 char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 179 char *buf = lj_buf_tmp(L, m);
179 MSize n = (MSize)fread(buf, 1, m, fp); 180 MSize n = (MSize)fread(buf, 1, m, fp);
180 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n)); 181 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
181 lj_gc_check(L); 182 lj_gc_check(L);
@@ -203,13 +204,12 @@ static int io_file_read(lua_State *L, IOFileUD *iof, int start)
203 for (n = start; nargs-- && ok; n++) { 204 for (n = start; nargs-- && ok; n++) {
204 if (tvisstr(L->base+n)) { 205 if (tvisstr(L->base+n)) {
205 const char *p = strVdata(L->base+n); 206 const char *p = strVdata(L->base+n);
206 if (p[0] != '*') 207 if (p[0] == '*') p++;
207 lj_err_arg(L, n+1, LJ_ERR_INVOPT); 208 if (p[0] == 'n')
208 if (p[1] == 'n')
209 ok = io_file_readnum(L, fp); 209 ok = io_file_readnum(L, fp);
210 else if ((p[1] & ~0x20) == 'L') 210 else if ((p[0] & ~0x20) == 'L')
211 ok = io_file_readline(L, fp, (p[1] == 'l')); 211 ok = io_file_readline(L, fp, (p[0] == 'l'));
212 else if (p[1] == 'a') 212 else if (p[0] == 'a')
213 io_file_readall(L, fp); 213 io_file_readall(L, fp);
214 else 214 else
215 lj_err_arg(L, n+1, LJ_ERR_INVFMT); 215 lj_err_arg(L, n+1, LJ_ERR_INVFMT);
@@ -233,19 +233,11 @@ static int io_file_write(lua_State *L, IOFileUD *iof, int start)
233 cTValue *tv; 233 cTValue *tv;
234 int status = 1; 234 int status = 1;
235 for (tv = L->base+start; tv < L->top; tv++) { 235 for (tv = L->base+start; tv < L->top; tv++) {
236 if (tvisstr(tv)) { 236 MSize len;
237 MSize len = strV(tv)->len; 237 const char *p = lj_strfmt_wstrnum(L, tv, &len);
238 status = status && (fwrite(strVdata(tv), 1, len, fp) == len); 238 if (!p)
239 } else if (tvisint(tv)) {
240 char buf[LJ_STR_INTBUF];
241 char *p = lj_str_bufint(buf, intV(tv));
242 size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
243 status = status && (fwrite(p, 1, len, fp) == len);
244 } else if (tvisnum(tv)) {
245 status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
246 } else {
247 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); 239 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
248 } 240 status = status && (fwrite(p, 1, len, fp) == len);
249 } 241 }
250 if (LJ_52 && status) { 242 if (LJ_52 && status) {
251 L->top = L->base+1; 243 L->top = L->base+1;
@@ -320,6 +312,14 @@ LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0)
320 return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL); 312 return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
321} 313}
322 314
315#if LJ_32 && defined(__ANDROID__) && __ANDROID_API__ < 24
316/* The Android NDK is such an unmatched marvel of engineering. */
317extern int fseeko32(FILE *, long int, int) __asm__("fseeko");
318extern long int ftello32(FILE *) __asm__("ftello");
319#define fseeko(fp, pos, whence) (fseeko32((fp), (pos), (whence)))
320#define ftello(fp) (ftello32((fp)))
321#endif
322
323LJLIB_CF(io_method_seek) 323LJLIB_CF(io_method_seek)
324{ 324{
325 FILE *fp = io_tofile(L)->fp; 325 FILE *fp = io_tofile(L)->fp;
@@ -336,7 +336,7 @@ LJLIB_CF(io_method_seek)
336 if (tvisint(o)) 336 if (tvisint(o))
337 ofs = (int64_t)intV(o); 337 ofs = (int64_t)intV(o);
338 else if (tvisnum(o)) 338 else if (tvisnum(o))
339 ofs = (int64_t)numV(o); 339 ofs = lj_num2i64(numV(o));
340 else if (!tvisnil(o)) 340 else if (!tvisnil(o))
341 lj_err_argt(L, 3, LUA_TNUMBER); 341 lj_err_argt(L, 3, LUA_TNUMBER);
342 } 342 }
@@ -421,7 +421,7 @@ LJLIB_CF(io_open)
421 421
422LJLIB_CF(io_popen) 422LJLIB_CF(io_popen)
423{ 423{
424#if LJ_TARGET_POSIX || LJ_TARGET_WINDOWS 424#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP)
425 const char *fname = strdata(lj_lib_checkstr(L, 1)); 425 const char *fname = strdata(lj_lib_checkstr(L, 1));
426 GCstr *s = lj_lib_optstr(L, 2); 426 GCstr *s = lj_lib_optstr(L, 2);
427 const char *mode = s ? strdata(s) : "r"; 427 const char *mode = s ? strdata(s) : "r";
@@ -442,7 +442,7 @@ LJLIB_CF(io_popen)
442LJLIB_CF(io_tmpfile) 442LJLIB_CF(io_tmpfile)
443{ 443{
444 IOFileUD *iof = io_file_new(L); 444 IOFileUD *iof = io_file_new(L);
445#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PSVITA 445#if LJ_TARGET_PS3 || LJ_TARGET_PS4 || LJ_TARGET_PS5 || LJ_TARGET_PSVITA || LJ_TARGET_NX
446 iof->fp = NULL; errno = ENOSYS; 446 iof->fp = NULL; errno = ENOSYS;
447#else 447#else
448 iof->fp = tmpfile(); 448 iof->fp = tmpfile();