diff options
Diffstat (limited to 'src/lib_io.c')
-rw-r--r-- | src/lib_io.c | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/src/lib_io.c b/src/lib_io.c index d5786e5d..a3278ab2 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) | |||
174 | static int io_file_readlen(lua_State *L, FILE *fp, MSize m) | 174 | static 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); |
@@ -202,13 +202,12 @@ static int io_file_read(lua_State *L, IOFileUD *iof, int start) | |||
202 | for (n = start; nargs-- && ok; n++) { | 202 | for (n = start; nargs-- && ok; n++) { |
203 | if (tvisstr(L->base+n)) { | 203 | if (tvisstr(L->base+n)) { |
204 | const char *p = strVdata(L->base+n); | 204 | const char *p = strVdata(L->base+n); |
205 | if (p[0] != '*') | 205 | if (p[0] == '*') p++; |
206 | lj_err_arg(L, n+1, LJ_ERR_INVOPT); | 206 | if (p[0] == 'n') |
207 | if (p[1] == 'n') | ||
208 | ok = io_file_readnum(L, fp); | 207 | ok = io_file_readnum(L, fp); |
209 | else if ((p[1] & ~0x20) == 'L') | 208 | else if ((p[0] & ~0x20) == 'L') |
210 | ok = io_file_readline(L, fp, (p[1] == 'l')); | 209 | ok = io_file_readline(L, fp, (p[0] == 'l')); |
211 | else if (p[1] == 'a') | 210 | else if (p[0] == 'a') |
212 | io_file_readall(L, fp); | 211 | io_file_readall(L, fp); |
213 | else | 212 | else |
214 | lj_err_arg(L, n+1, LJ_ERR_INVFMT); | 213 | lj_err_arg(L, n+1, LJ_ERR_INVFMT); |
@@ -232,19 +231,11 @@ static int io_file_write(lua_State *L, IOFileUD *iof, int start) | |||
232 | cTValue *tv; | 231 | cTValue *tv; |
233 | int status = 1; | 232 | int status = 1; |
234 | for (tv = L->base+start; tv < L->top; tv++) { | 233 | for (tv = L->base+start; tv < L->top; tv++) { |
235 | if (tvisstr(tv)) { | 234 | MSize len; |
236 | MSize len = strV(tv)->len; | 235 | const char *p = lj_strfmt_wstrnum(L, tv, &len); |
237 | status = status && (fwrite(strVdata(tv), 1, len, fp) == len); | 236 | if (!p) |
238 | } else if (tvisint(tv)) { | ||
239 | char buf[LJ_STR_INTBUF]; | ||
240 | char *p = lj_str_bufint(buf, intV(tv)); | ||
241 | size_t len = (size_t)(buf+LJ_STR_INTBUF-p); | ||
242 | status = status && (fwrite(p, 1, len, fp) == len); | ||
243 | } else if (tvisnum(tv)) { | ||
244 | status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0); | ||
245 | } else { | ||
246 | lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); | 237 | lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); |
247 | } | 238 | status = status && (fwrite(p, 1, len, fp) == len); |
248 | } | 239 | } |
249 | if (LJ_52 && status) { | 240 | if (LJ_52 && status) { |
250 | L->top = L->base+1; | 241 | L->top = L->base+1; |
@@ -319,6 +310,14 @@ LJLIB_CF(io_method_flush) LJLIB_REC(io_flush 0) | |||
319 | return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL); | 310 | return luaL_fileresult(L, fflush(io_tofile(L)->fp) == 0, NULL); |
320 | } | 311 | } |
321 | 312 | ||
313 | #if LJ_32 && defined(__ANDROID__) && __ANDROID_API__ < 24 | ||
314 | /* The Android NDK is such an unmatched marvel of engineering. */ | ||
315 | extern int fseeko32(FILE *, long int, int) __asm__("fseeko"); | ||
316 | extern long int ftello32(FILE *) __asm__("ftello"); | ||
317 | #define fseeko(fp, pos, whence) (fseeko32((fp), (pos), (whence))) | ||
318 | #define ftello(fp) (ftello32((fp))) | ||
319 | #endif | ||
320 | |||
322 | LJLIB_CF(io_method_seek) | 321 | LJLIB_CF(io_method_seek) |
323 | { | 322 | { |
324 | FILE *fp = io_tofile(L)->fp; | 323 | FILE *fp = io_tofile(L)->fp; |
@@ -419,7 +418,7 @@ LJLIB_CF(io_open) | |||
419 | 418 | ||
420 | LJLIB_CF(io_popen) | 419 | LJLIB_CF(io_popen) |
421 | { | 420 | { |
422 | #if LJ_TARGET_POSIX || LJ_TARGET_WINDOWS | 421 | #if LJ_TARGET_POSIX || (LJ_TARGET_WINDOWS && !LJ_TARGET_XBOXONE && !LJ_TARGET_UWP) |
423 | const char *fname = strdata(lj_lib_checkstr(L, 1)); | 422 | const char *fname = strdata(lj_lib_checkstr(L, 1)); |
424 | GCstr *s = lj_lib_optstr(L, 2); | 423 | GCstr *s = lj_lib_optstr(L, 2); |
425 | const char *mode = s ? strdata(s) : "r"; | 424 | const char *mode = s ? strdata(s) : "r"; |