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.c55
1 files changed, 27 insertions, 28 deletions
diff --git a/src/lib_io.c b/src/lib_io.c
index f13cf048..c889a6b0 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 28
@@ -84,7 +86,7 @@ static IOFileUD *io_file_open(lua_State *L, const char *mode)
84 IOFileUD *iof = io_file_new(L); 86 IOFileUD *iof = io_file_new(L);
85 iof->fp = fopen(fname, mode); 87 iof->fp = fopen(fname, mode);
86 if (iof->fp == NULL) 88 if (iof->fp == NULL)
87 luaL_argerror(L, 1, lj_str_pushf(L, "%s: %s", fname, strerror(errno))); 89 luaL_argerror(L, 1, lj_strfmt_pushf(L, "%s: %s", fname, strerror(errno)));
88 return iof; 90 return iof;
89} 91}
90 92
@@ -97,11 +99,8 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
97 int stat = -1; 99 int stat = -1;
98#if LJ_TARGET_POSIX 100#if LJ_TARGET_POSIX
99 stat = pclose(iof->fp); 101 stat = pclose(iof->fp);
100#elif LJ_TARGET_WINDOWS 102#elif LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP
101 stat = _pclose(iof->fp); 103 stat = _pclose(iof->fp);
102#else
103 lua_assert(0);
104 return 0;
105#endif 104#endif
106#if LJ_52 105#if LJ_52
107 iof->fp = NULL; 106 iof->fp = NULL;
@@ -110,7 +109,8 @@ static int io_file_close(lua_State *L, IOFileUD *iof)
110 ok = (stat != -1); 109 ok = (stat != -1);
111#endif 110#endif
112 } else { 111 } else {
113 lua_assert((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF); 112 lj_assertL((iof->type & IOFILE_TYPE_MASK) == IOFILE_TYPE_STDF,
113 "close of unknown FILE* type");
114 setnilV(L->top++); 114 setnilV(L->top++);
115 lua_pushliteral(L, "cannot close standard file"); 115 lua_pushliteral(L, "cannot close standard file");
116 return 2; 116 return 2;
@@ -145,7 +145,7 @@ static int io_file_readline(lua_State *L, FILE *fp, MSize chop)
145 MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0; 145 MSize m = LUAL_BUFFERSIZE, n = 0, ok = 0;
146 char *buf; 146 char *buf;
147 for (;;) { 147 for (;;) {
148 buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 148 buf = lj_buf_tmp(L, m);
149 if (fgets(buf+n, m-n, fp) == NULL) break; 149 if (fgets(buf+n, m-n, fp) == NULL) break;
150 n += (MSize)strlen(buf+n); 150 n += (MSize)strlen(buf+n);
151 ok |= n; 151 ok |= n;
@@ -161,7 +161,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
161{ 161{
162 MSize m, n; 162 MSize m, n;
163 for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) { 163 for (m = LUAL_BUFFERSIZE, n = 0; ; m += m) {
164 char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 164 char *buf = lj_buf_tmp(L, m);
165 n += (MSize)fread(buf+n, 1, m-n, fp); 165 n += (MSize)fread(buf+n, 1, m-n, fp);
166 if (n != m) { 166 if (n != m) {
167 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n)); 167 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
@@ -174,7 +174,7 @@ static void io_file_readall(lua_State *L, FILE *fp)
174static int io_file_readlen(lua_State *L, FILE *fp, MSize m) 174static int io_file_readlen(lua_State *L, FILE *fp, MSize m)
175{ 175{
176 if (m) { 176 if (m) {
177 char *buf = lj_str_needbuf(L, &G(L)->tmpbuf, m); 177 char *buf = lj_buf_tmp(L, m);
178 MSize n = (MSize)fread(buf, 1, m, fp); 178 MSize n = (MSize)fread(buf, 1, m, fp);
179 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n)); 179 setstrV(L, L->top++, lj_str_new(L, buf, (size_t)n));
180 lj_gc_check(L); 180 lj_gc_check(L);
@@ -201,13 +201,12 @@ static int io_file_read(lua_State *L, FILE *fp, int start)
201 for (n = start; nargs-- && ok; n++) { 201 for (n = start; nargs-- && ok; n++) {
202 if (tvisstr(L->base+n)) { 202 if (tvisstr(L->base+n)) {
203 const char *p = strVdata(L->base+n); 203 const char *p = strVdata(L->base+n);
204 if (p[0] != '*') 204 if (p[0] == '*') p++;
205 lj_err_arg(L, n+1, LJ_ERR_INVOPT); 205 if (p[0] == 'n')
206 if (p[1] == 'n')
207 ok = io_file_readnum(L, fp); 206 ok = io_file_readnum(L, fp);
208 else if ((p[1] & ~0x20) == 'L') 207 else if ((p[0] & ~0x20) == 'L')
209 ok = io_file_readline(L, fp, (p[1] == 'l')); 208 ok = io_file_readline(L, fp, (p[0] == 'l'));
210 else if (p[1] == 'a') 209 else if (p[0] == 'a')
211 io_file_readall(L, fp); 210 io_file_readall(L, fp);
212 else 211 else
213 lj_err_arg(L, n+1, LJ_ERR_INVFMT); 212 lj_err_arg(L, n+1, LJ_ERR_INVFMT);
@@ -230,19 +229,11 @@ static int io_file_write(lua_State *L, FILE *fp, int start)
230 cTValue *tv; 229 cTValue *tv;
231 int status = 1; 230 int status = 1;
232 for (tv = L->base+start; tv < L->top; tv++) { 231 for (tv = L->base+start; tv < L->top; tv++) {
233 if (tvisstr(tv)) { 232 MSize len;
234 MSize len = strV(tv)->len; 233 const char *p = lj_strfmt_wstrnum(L, tv, &len);
235 status = status && (fwrite(strVdata(tv), 1, len, fp) == len); 234 if (!p)
236 } else if (tvisint(tv)) {
237 char buf[LJ_STR_INTBUF];
238 char *p = lj_str_bufint(buf, intV(tv));
239 size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
240 status = status && (fwrite(p, 1, len, fp) == len);
241 } else if (tvisnum(tv)) {
242 status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
243 } else {
244 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); 235 lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
245 } 236 status = status && (fwrite(p, 1, len, fp) == len);
246 } 237 }
247 if (LJ_52 && status) { 238 if (LJ_52 && status) {
248 L->top = L->base+1; 239 L->top = L->base+1;
@@ -313,6 +304,14 @@ LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0)
313 return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL); 304 return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL);
314} 305}
315 306
307#if LJ_32 && defined(__ANDROID__) && __ANDROID_API__ < 24
308/* The Android NDK is such an unmatched marvel of engineering. */
309extern int fseeko32(FILE *, long int, int) __asm__("fseeko");
310extern long int ftello32(FILE *) __asm__("ftello");
311#define fseeko(fp, pos, whence) (fseeko32((fp), (pos), (whence)))
312#define ftello(fp) (ftello32((fp)))
313#endif
314
316LJLIB_CF(io_method_seek) 315LJLIB_CF(io_method_seek)
317{ 316{
318 FILE *fp = io_tofile(L)->fp; 317 FILE *fp = io_tofile(L)->fp;
@@ -413,7 +412,7 @@ LJLIB_CF(io_open)
413 412
414LJLIB_CF(io_popen) 413LJLIB_CF(io_popen)
415{ 414{
416#if LJ_TARGET_POSIX || LJ_TARGET_WINDOWS 415#if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP)
417 const char *fname = strdata(lj_lib_checkstr(L, 1)); 416 const char *fname = strdata(lj_lib_checkstr(L, 1));
418 GCstr *s = lj_lib_optstr(L, 2); 417 GCstr *s = lj_lib_optstr(L, 2);
419 const char *mode = s ? strdata(s) : "r"; 418 const char *mode = s ? strdata(s) : "r";