diff options
Diffstat (limited to 'src/lib_io.c')
| -rw-r--r-- | src/lib_io.c | 64 |
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) | |||
| 175 | static int io_file_readlen(lua_State *L, FILE *fp, MSize m) | 176 | static 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. */ | ||
| 317 | extern int fseeko32(FILE *, long int, int) __asm__("fseeko"); | ||
| 318 | extern 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 | |||
| 323 | LJLIB_CF(io_method_seek) | 323 | LJLIB_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 | ||
| 422 | LJLIB_CF(io_popen) | 422 | LJLIB_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) | |||
| 442 | LJLIB_CF(io_tmpfile) | 442 | LJLIB_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(); |
