diff options
| author | ruki <[email protected]> | 2019-07-05 22:43:42 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2019-07-05 22:11:19 +0800 |
| commit | 55581bb68f44a6e17eba9cefd4f05868e802498b (patch) | |
| tree | f3e78c18903b3d9394be621d0d59558c11c53a95 /core/src | |
| parent | cf8ff12bc05fde4cb94344d1ca1bce31a4778527 (diff) | |
use stdfile
Diffstat (limited to 'core/src')
| m--------- | core/src/tbox/tbox | 0 | ||||
| -rw-r--r-- | core/src/xmake/io/file.h | 94 | ||||
| -rw-r--r-- | core/src/xmake/io/file___len.c | 15 | ||||
| -rw-r--r-- | core/src/xmake/io/file___tostring.c | 5 | ||||
| -rw-r--r-- | core/src/xmake/io/file_close___gc.c | 35 | ||||
| -rw-r--r-- | core/src/xmake/io/file_flush.c | 25 | ||||
| -rw-r--r-- | core/src/xmake/io/file_isatty.c | 21 | ||||
| -rw-r--r-- | core/src/xmake/io/file_path.c | 20 | ||||
| -rw-r--r-- | core/src/xmake/io/file_read.c | 110 | ||||
| -rw-r--r-- | core/src/xmake/io/file_seek.c | 18 | ||||
| -rw-r--r-- | core/src/xmake/io/file_write.c | 115 | ||||
| -rw-r--r-- | core/src/xmake/io/open.c | 114 | ||||
| -rw-r--r-- | core/src/xmake/io/std.c | 24 | ||||
| -rw-r--r-- | core/src/xmake/sandbox/interactive.c | 15 |
14 files changed, 262 insertions, 349 deletions
diff --git a/core/src/tbox/tbox b/core/src/tbox/tbox -Subproject 3cbefcb387542a9b3e0bb42f4e601fc937379a5 +Subproject 2b232556e6440b370442f954f19c598676c374f diff --git a/core/src/xmake/io/file.h b/core/src/xmake/io/file.h index c177999c3..23ff11d46 100644 --- a/core/src/xmake/io/file.h +++ b/core/src/xmake/io/file.h @@ -27,6 +27,42 @@ #include "prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// + * macros + */ +#define xm_io_file_is_file(file) ((file)->type == XM_IO_FILE_TYPE_FILE) +#define xm_io_file_is_std(file) ((file)->type != XM_IO_FILE_TYPE_FILE) + +#define xm_io_file_is_closed_file(file) ((file)->type == XM_IO_FILE_TYPE_FILE && !((file)->file_ref)) +#define xm_io_file_is_closed_std(file) ((file)->type != XM_IO_FILE_TYPE_FILE && !((file)->file_ref)) + +#define xm_io_file_is_tty(file) (!!((file)->type & XM_IO_FILE_FLAG_TTY)) +#define xm_io_file_is_closed(file) (xm_io_file_is_closed_file(file) || xm_io_file_is_closed_std(file)) + +#define xm_io_file_udata "XM_IO_FILE*" + +#define xm_io_file_return_success() \ + do \ + { \ + return 1; \ + } while (0) + +#define xm_io_file_return_error(lua, file, reason) \ + do \ + { \ + lua_pushnil(lua); \ + lua_pushfstring(lua, "error: %s (%s)", reason, file->name); \ + return 2; \ + } while (0) + +#define xm_io_file_return_error_closed(lua) \ + do \ + { \ + lua_pushnil(lua); \ + lua_pushliteral(lua, "error: file has been closed"); \ + return 2; \ + } while (0) + +/* ////////////////////////////////////////////////////////////////////////////////////// * types */ typedef enum __xm_io_file_type_e @@ -38,10 +74,12 @@ typedef enum __xm_io_file_type_e XM_IO_FILE_TYPE_STDERR = 3, XM_IO_FILE_FLAG_TTY = 0x10, //!< mark tty std stream + } xm_io_file_type_e; -// use negetive numbers for this enum, its a extension for tb_charset_type_e -// before adding new values, make sure they have not conflicts with values in tb_charset_type_e +/* use negetive numbers for this enum, its a extension for tb_charset_type_e + * before adding new values, make sure they have not conflicts with values in tb_charset_type_e + */ typedef enum __xm_io_file_encoding_e { XM_IO_FILE_ENCODING_BINARY = -1, @@ -55,8 +93,8 @@ typedef struct __xm_io_file { union { - tb_file_ref_t file_ref; // valid if type == XM_IO_FILE_TYPE_FILE - FILE* std_ref; // valid otherwise + tb_file_ref_t file_ref; // valid if type == XM_IO_FILE_TYPE_FILE + tb_stdfile_ref_t std_ref; // valid otherwise }; tb_size_t mode; // tb_file_mode_t @@ -67,60 +105,30 @@ typedef struct __xm_io_file } xm_io_file; /* ////////////////////////////////////////////////////////////////////////////////////// - * macros - */ -#define xm_io_file_is_file(fileref) (fileref->type == XM_IO_FILE_TYPE_FILE) -#define xm_io_file_is_std(fileref) (fileref->type != XM_IO_FILE_TYPE_FILE) - -#define xm_io_file_is_closed_file(fileref) (fileref->type == XM_IO_FILE_TYPE_FILE && !(fileref->file_ref)) -#define xm_io_file_is_closed_std(fileref) (fileref->type != XM_IO_FILE_TYPE_FILE && !(fileref->file_ref)) - -#define xm_io_file_is_tty(fileref) (!!(fileref->type & XM_IO_FILE_FLAG_TTY)) -#define xm_io_file_is_closed(fileref) (xm_io_file_is_closed_file(fileref) || xm_io_file_is_closed_std(fileref)) - -#define xm_io_file_udata "XM_IO_FILE*" - -#define xm_io_file_success() \ - do \ - { \ - return 1; \ - } while (0) - -#define xm_io_file_error(lua, file, reason) \ - do \ - { \ - lua_pushnil(lua); \ - lua_pushfstring(lua, "error: %s (%s)", reason, file->name); \ - return 2; \ - } while (0) - -#define xm_io_file_error_closed(lua) \ - do \ - { \ - lua_pushnil(lua); \ - lua_pushliteral(lua, "error: file has been closed"); \ - return 2; \ - } while (0) - -/* ////////////////////////////////////////////////////////////////////////////////////// * interfaces */ -static inline xm_io_file* xm_io_newfile(lua_State* lua) +static __tb_inline__ xm_io_file* xm_io_newfile(lua_State* lua) { + // check tb_assert_and_check_return_val(lua, tb_null); + // new file xm_io_file* file = (xm_io_file*)lua_newuserdata(lua, sizeof(xm_io_file)); - tb_assert(file); + tb_assert_and_check_return_val(file, tb_null); + + // init file luaL_getmetatable(lua, xm_io_file_udata); lua_setmetatable(lua, -2); tb_memset(file, 0, sizeof(xm_io_file)); return file; } -static inline xm_io_file* xm_io_getfile(lua_State* lua) +static __tb_inline__ xm_io_file* xm_io_getfile(lua_State* lua) { + // check tb_assert_and_check_return_val(lua, tb_null); + // get file xm_io_file* file = (xm_io_file*)luaL_checkudata(lua, 1, xm_io_file_udata); tb_assert(file); return file; diff --git a/core/src/xmake/io/file___len.c b/core/src/xmake/io/file___len.c index 0e81a94a0..5f86f9cfd 100644 --- a/core/src/xmake/io/file___len.c +++ b/core/src/xmake/io/file___len.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file___len" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file___len" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -35,8 +35,7 @@ * implementation */ -/* - * #file +/* get file length, #file */ tb_int_t xm_io_file___len(lua_State* lua) { @@ -45,12 +44,12 @@ tb_int_t xm_io_file___len(lua_State* lua) xm_io_file* file = xm_io_getfile(lua); if (xm_io_file_is_closed(file)) - xm_io_file_error_closed(lua); + xm_io_file_return_error_closed(lua); else if (xm_io_file_is_file(file)) { + tb_assert(file->file_ref); lua_pushnumber(lua, (lua_Number)tb_file_size(file->file_ref)); - xm_io_file_success(); + xm_io_file_return_success(); } - else - xm_io_file_error(lua, file, "getting file size for this file is invalid"); + else xm_io_file_return_error(lua, file, "getting file size for this file is invalid"); } diff --git a/core/src/xmake/io/file___tostring.c b/core/src/xmake/io/file___tostring.c index 28817ad62..8290d358a 100644 --- a/core/src/xmake/io/file___tostring.c +++ b/core/src/xmake/io/file___tostring.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file___tostring" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file___tostring" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -43,6 +43,7 @@ tb_int_t xm_io_file___tostring(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); + // get file name as string xm_io_file* file = xm_io_getfile(lua); lua_pushstring(lua, file->name); return 1; diff --git a/core/src/xmake/io/file_close___gc.c b/core/src/xmake/io/file_close___gc.c index cb7e0bb79..d13099cd2 100644 --- a/core/src/xmake/io/file_close___gc.c +++ b/core/src/xmake/io/file_close___gc.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file_close___gc" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file_close___gc" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -46,33 +46,34 @@ static tb_int_t xm_io_file_close_impl(lua_State* lua, tb_bool_t allow_closed_fil if (allow_closed_file) { lua_pushboolean(lua, tb_true); - xm_io_file_success(); - }else - xm_io_file_error_closed(lua); + xm_io_file_return_success(); + } + else xm_io_file_return_error_closed(lua); } if (xm_io_file_is_file(file)) { - if (!tb_file_exit(file->file_ref)) xm_io_file_error(lua, file, "failed to close file"); + // close file + tb_assert(file->file_ref); + if (!tb_file_exit(file->file_ref)) + xm_io_file_return_error(lua, file, "failed to close file"); file->file_ref = tb_null; + + // free file path if (file->path) { tb_free(file->path); file->path = tb_null; } + + // mark this file as closed tb_strlcpy(file->name, "file: (closed file)", tb_arrayn(file->name)); lua_pushboolean(lua, tb_true); - xm_io_file_success(); + xm_io_file_return_success(); } else { - // should we support close std files? - - // if (fclose(file->std_ref)) xm_io_file_error(lua, file, "failed to close file"); - // file->std_ref = tb_null; - // file->path = tb_null; - // tb_strcpy(file->name, "file: (closed file)"); lua_pushboolean(lua, tb_true); - xm_io_file_success(); + xm_io_file_return_success(); } } @@ -85,9 +86,6 @@ static tb_int_t xm_io_file_close_impl(lua_State* lua, tb_bool_t allow_closed_fil */ tb_int_t xm_io_file_close(lua_State* lua) { - // check - tb_assert_and_check_return_val(lua, 0); - return xm_io_file_close_impl(lua, tb_false); } @@ -96,8 +94,5 @@ tb_int_t xm_io_file_close(lua_State* lua) */ tb_int_t xm_io_file___gc(lua_State* lua) { - // check - tb_assert_and_check_return_val(lua, 0); - return xm_io_file_close_impl(lua, tb_true); } diff --git a/core/src/xmake/io/file_flush.c b/core/src/xmake/io/file_flush.c index a5295bf90..ef0cee39c 100644 --- a/core/src/xmake/io/file_flush.c +++ b/core/src/xmake/io/file_flush.c @@ -22,23 +22,22 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file_flush" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file_flush" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ #include "file.h" #include "prefix.h" -#include <stdio.h> /* ////////////////////////////////////////////////////////////////////////////////////// - * implementation + * private implementation */ static tb_bool_t xm_io_std_flush_impl(xm_io_file* file) { tb_assert_and_check_return_val(xm_io_file_is_std(file) && !xm_io_file_is_closed(file), tb_false); - return !fflush(file->std_ref); + return (file->std_ref != tb_stdfile_input())? tb_stdfile_flush(file->std_ref) : tb_false; } static tb_bool_t xm_io_file_flush_impl(xm_io_file* file) @@ -59,11 +58,17 @@ tb_int_t xm_io_file_flush(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); + // file has been closed? xm_io_file* file = xm_io_getfile(lua); - if (xm_io_file_is_closed(file)) xm_io_file_error_closed(lua); + if (xm_io_file_is_closed(file)) + xm_io_file_return_error_closed(lua); - tb_bool_t succeed = xm_io_file_is_file(file) ? xm_io_file_flush_impl(file) : xm_io_std_flush_impl(file); - if (!succeed) xm_io_file_error(lua, file, "failed to flush file"); - lua_pushboolean(lua, tb_true); - xm_io_file_success(); + // flush file + tb_bool_t ok = xm_io_file_is_file(file) ? xm_io_file_flush_impl(file) : xm_io_std_flush_impl(file); + if (ok) + { + lua_pushboolean(lua, tb_true); + xm_io_file_return_success(); + } + else xm_io_file_return_error(lua, file, "failed to flush file"); } diff --git a/core/src/xmake/io/file_isatty.c b/core/src/xmake/io/file_isatty.c index 0d89078d6..e09ea9b13 100644 --- a/core/src/xmake/io/file_isatty.c +++ b/core/src/xmake/io/file_isatty.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file_isatty" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file_isatty" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -42,19 +42,8 @@ tb_int_t xm_io_file_isatty(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); - // get file pointer - xm_io_file* fp = xm_io_getfile(lua); - - if (xm_io_file_is_file(fp)) - { - lua_pushboolean(lua, tb_false); - // ok - return 1; - } - tb_bool_t istty = xm_io_file_is_tty(fp); - // return answer - lua_pushboolean(lua, istty); - - // ok + // is tty? + xm_io_file* file = xm_io_getfile(lua); + lua_pushboolean(lua, xm_io_file_is_tty(file)); return 1; } diff --git a/core/src/xmake/io/file_path.c b/core/src/xmake/io/file_path.c index 8c84fbbc0..92ecfa3c5 100644 --- a/core/src/xmake/io/file_path.c +++ b/core/src/xmake/io/file_path.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file_path" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file_path" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -42,10 +42,14 @@ tb_int_t xm_io_file_path(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); - // get file pointer - xm_io_file* fp = xm_io_getfile(lua); - if (xm_io_file_is_closed(fp)) xm_io_file_error_closed(lua); - lua_pushstring(lua, fp->path); - // ok - return 1; + // this file has been closed? + xm_io_file* file = xm_io_getfile(lua); + if (xm_io_file_is_closed(file)) + xm_io_file_return_error_closed(lua); + else + { + // return file path + lua_pushstring(lua, file->path); + return 1; + } } diff --git a/core/src/xmake/io/file_read.c b/core/src/xmake/io/file_read.c index e9f8829d7..307cf30ae 100644 --- a/core/src/xmake/io/file_read.c +++ b/core/src/xmake/io/file_read.c @@ -379,7 +379,7 @@ static tb_int_t xm_io_file_read_all(lua_State* lua, xm_io_file* file, tb_char_t case PL_FAIL: default: luaL_pushresult(buf); - xm_io_file_error(lua, file, "failed to readline"); + xm_io_file_return_error(lua, file, "failed to readline"); break; } } @@ -406,7 +406,7 @@ static tb_int_t xm_io_file_read_line(lua_State* lua, xm_io_file* file, tb_char_t case PL_FAIL: default: luaL_pushresult(buf); - xm_io_file_error(lua, file, "failed to readline"); + xm_io_file_return_error(lua, file, "failed to readline"); break; } } @@ -419,13 +419,13 @@ static tb_int_t xm_io_file_read_n(lua_State* lua, xm_io_file* file, tb_char_t co // check continuation if (*continuation != '\0') - xm_io_file_error(lua, file, "continuation is not supported for read number of bytes"); + xm_io_file_return_error(lua, file, "continuation is not supported for read number of bytes"); // check encoding tb_size_t charset = file->encoding; tb_bool_t binary = charset == XM_IO_FILE_ENCODING_BINARY || charset == XM_IO_FILE_ENCODING_UNKNOWN; if (!binary) - xm_io_file_error(lua, file, "read number of bytes only allows binary file, reopen with 'rb' and try again"); + xm_io_file_return_error(lua, file, "read number of bytes only allows binary file, reopen with 'rb' and try again"); if (n == 0) { @@ -466,25 +466,10 @@ static tb_size_t xm_io_file_std_buffer_pushline(luaL_Buffer* buf, xm_io_file* fi tb_char_t strbuf[8192]; tb_size_t buflen = 0; tb_size_t result = PL_FAIL; -#ifdef TB_CONFIG_OS_WINDOWS - DWORD len = 0; - tb_wchar_t readbuf[2730]; - tb_assert(file->std_ref == stdin); - if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), readbuf, tb_arrayn(readbuf) - 1, &len, tb_null) && len < tb_arrayn(readbuf)) - { - readbuf[len] = L'\0'; - buflen = xm_wcstoutf8(strbuf, readbuf, tb_arrayn(strbuf) - 1); - } -#else - if (fgets(strbuf, (tb_int_t)tb_arrayn(strbuf) - 1, file->std_ref)) - { + if (tb_stdfile_gets(file->std_ref, strbuf, tb_arrayn(strbuf) - 1)) buflen = tb_strlen(strbuf); - } -#endif else - { return PL_EOF; - } tb_size_t conlen = tb_strlen(continuation); if (buflen > 0 && strbuf[buflen - 1] != '\n') @@ -535,7 +520,7 @@ static tb_int_t xm_io_file_std_read_line(lua_State* lua, xm_io_file* file, tb_ch case PL_FAIL: default: luaL_pushresult(buf); - xm_io_file_error(lua, file, "failed to readline"); + xm_io_file_return_error(lua, file, "failed to readline"); break; } } @@ -564,7 +549,7 @@ static tb_int_t xm_io_file_std_read_all(lua_State* lua, xm_io_file* file, tb_cha case PL_FAIL: default: luaL_pushresult(buf); - xm_io_file_error(lua, file, "failed to readline"); + xm_io_file_return_error(lua, file, "failed to readline"); break; } } @@ -577,52 +562,32 @@ static tb_int_t xm_io_file_std_read_n(lua_State* lua, xm_io_file* file, tb_char_ // check continuation if (*continuation != '\0') - xm_io_file_error(lua, file, "continuation is not supported for std streams"); + xm_io_file_return_error(lua, file, "continuation is not supported for std streams"); + // io.read(0) if (n == 0) { -#ifdef TB_CONFIG_OS_WINDOWS - wint_t c = getwc(file->std_ref); - ungetwc(c, file->std_ref); - if (c == WEOF) -#else - int c = getc(file->std_ref); - ungetc(c, file->std_ref); - if (c == EOF) -#endif + tb_char_t ch; + if (!tb_stdfile_peek(file->std_ref, &ch)) lua_pushnil(lua); else lua_pushliteral(lua, ""); return 1; } -#ifdef TB_CONFIG_OS_WINDOWS - tb_buffer_t readbuf, transbuf; - tb_bool_t rok = tb_buffer_init(&readbuf); - tb_bool_t tok = tb_buffer_init(&transbuf); - tb_assert_and_check_return_val(rok && tok, 0); - tb_wchar_t* readbuf_ptr = (tb_wchar_t*)tb_buffer_resize(&readbuf, (tb_size_t)((n + 1) * sizeof(tb_wchar_t))); - tb_assert(readbuf_ptr); - tb_size_t readcount = fread(readbuf_ptr, sizeof(tb_wchar_t), n, file->std_ref); - readbuf_ptr[readcount] = L'\0'; // add null termination for tb_wcstombs - tb_char_t* transbuf_ptr = (tb_char_t*)tb_buffer_resize(&transbuf, (tb_size_t)(n * 3)); - tb_assert(transbuf_ptr); - - tb_size_t transcount = tb_wcstombs(transbuf_ptr, readbuf_ptr, (tb_size_t)(n * 3)); - tb_buffer_exit(&readbuf); - lua_pushlstring(lua, transbuf_ptr, transcount); - tb_buffer_exit(&transbuf); -#else + // io.read(n) tb_buffer_t buf; - tb_bool_t ok = tb_buffer_init(&buf); - tb_assert_and_check_return_val(ok, 0); - tb_char_t* buf_ptr = (tb_char_t*)tb_buffer_resize(&buf, (tb_size_t)n); - tb_assert(buf_ptr); + if (tb_buffer_init(&buf)) + { + tb_byte_t* buf_ptr = tb_buffer_resize(&buf, (tb_size_t)n); + tb_assert(buf_ptr); - tb_size_t readcount = fread(buf_ptr, sizeof(tb_byte_t), (tb_size_t)n, file->std_ref); - lua_pushlstring(lua, buf_ptr, readcount); - tb_buffer_exit(&buf); -#endif + if (tb_stdfile_read(file->std_ref, buf_ptr, (tb_size_t)n)) + lua_pushlstring(lua, (tb_char_t const*)buf_ptr, (size_t)n); + else lua_pushnil(lua); + tb_buffer_exit(&buf); + } + else lua_pushnil(lua); return 1; } @@ -633,28 +598,15 @@ static tb_int_t xm_io_file_std_read_num(lua_State* lua, xm_io_file* file, tb_cha // check continuation if (*continuation != '\0') - xm_io_file_error(lua, file, "continuation is not supported for std streams"); + xm_io_file_return_error(lua, file, "continuation is not supported for std streams"); -#ifdef TB_CONFIG_OS_WINDOWS - DWORD len = 0; - tb_char_t strbuf[512]; - tb_wchar_t readbuf[128]; - tb_assert(file->std_ref == stdin); - if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), readbuf, tb_arrayn(readbuf) - 1, &len, tb_null) && len < tb_arrayn(readbuf)) + // read number + tb_char_t strbuf[512]; + if (tb_stdfile_gets(file->std_ref, strbuf, tb_arrayn(strbuf))) { - readbuf[len] = L'\0'; - xm_wcstoutf8(strbuf, readbuf, tb_arrayn(strbuf) - 1); lua_pushnumber(lua, tb_s10tod(strbuf)); return 1; } -#else - tb_double_t d = 0; - if (fscanf(file->std_ref, "%lf", &d) == 1) - { - lua_pushnumber(lua, d); - return 1; - } -#endif else { lua_pushnil(lua); @@ -682,14 +634,14 @@ tb_int_t xm_io_file_read(lua_State* lua) if (lua_isnumber(lua, 2)) { count = (tb_long_t)lua_tointeger(lua, 2); - if (count < 0) xm_io_file_error(lua, file, "invalid read size, must be positive nubmber or 0"); + if (count < 0) xm_io_file_return_error(lua, file, "invalid read size, must be positive nubmber or 0"); } else if (*mode == '*') mode++; if (xm_io_file_is_file(file)) { - if (xm_io_file_is_closed_file(file)) xm_io_file_error_closed(lua); + if (xm_io_file_is_closed_file(file)) xm_io_file_return_error_closed(lua); if (file->encoding == XM_IO_FILE_ENCODING_UNKNOWN) { // detect encoding @@ -715,10 +667,10 @@ tb_int_t xm_io_file_read(lua_State* lua) { case 'a': return xm_io_file_read_all(lua, file, continuation); case 'L': return xm_io_file_read_line(lua, file, continuation, tb_true); - case 'n': xm_io_file_error(lua, file, "read number is not implemented"); + case 'n': xm_io_file_return_error(lua, file, "read number is not implemented"); case 'l': return xm_io_file_read_line(lua, file, continuation, tb_false); default: - xm_io_file_error(lua, file, "unknonwn read mode"); + xm_io_file_return_error(lua, file, "unknonwn read mode"); return 0; } } @@ -730,7 +682,7 @@ tb_int_t xm_io_file_read(lua_State* lua) case 'n': return xm_io_file_std_read_num(lua, file, continuation); case 'l': return xm_io_file_std_read_line(lua, file, continuation, tb_false); default: - xm_io_file_error(lua, file, "unknonwn read mode"); + xm_io_file_return_error(lua, file, "unknonwn read mode"); return 0; } } diff --git a/core/src/xmake/io/file_seek.c b/core/src/xmake/io/file_seek.c index 5dd963138..8c970086e 100644 --- a/core/src/xmake/io/file_seek.c +++ b/core/src/xmake/io/file_seek.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file_seek" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file_seek" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -47,9 +47,12 @@ tb_int_t xm_io_file_seek(lua_State* lua) tb_char_t const* whence = luaL_optstring(lua, 2, "cur"); tb_hong_t offset = (tb_hong_t)luaL_optnumber(lua, 3, 0); tb_assert_and_check_return_val(file && whence, 0); + if (xm_io_file_is_file(file)) { - if (xm_io_file_is_closed_file(file)) xm_io_file_error_closed(lua); + if (xm_io_file_is_closed_file(file)) + xm_io_file_return_error_closed(lua); + tb_size_t mode = TB_FILE_SEEK_CUR; switch (*whence) { @@ -59,13 +62,12 @@ tb_int_t xm_io_file_seek(lua_State* lua) case 'e': // "end" mode = TB_FILE_SEEK_END; break; + default: + break; } offset = tb_file_seek(file->file_ref, offset, mode); lua_pushnumber(lua, (lua_Number)offset); - xm_io_file_success(); - } - else - { - xm_io_file_error(lua, file, "seek is not supported on this file"); + xm_io_file_return_success(); } + else xm_io_file_return_error(lua, file, "seek is not supported on this file"); } diff --git a/core/src/xmake/io/file_write.c b/core/src/xmake/io/file_write.c index 0a055324f..53b05daa6 100644 --- a/core/src/xmake/io/file_write.c +++ b/core/src/xmake/io/file_write.c @@ -22,100 +22,57 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "file_write" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "file_write" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes */ #include "prefix.h" -#ifdef TB_CONFIG_OS_WINDOWS -# include "../winos/ansi.h" -# include <io.h> -#else -# include <unistd.h> -#endif #include "file.h" /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ -static tb_void_t direct_write(xm_io_file* file, tb_char_t const* data, tb_size_t size) +static tb_void_t xm_io_file_write_direct(xm_io_file* file, tb_char_t const* data, tb_size_t size) { + // check tb_assert(file && data && xm_io_file_is_file(file) && !xm_io_file_is_closed(file)); + // write data to file tb_file_writ(file->file_ref, (tb_byte_t const*)data, size); } -static tb_void_t transcode_write(xm_io_file* file, tb_char_t const* data, tb_size_t size) +static tb_void_t xm_io_file_write_transcode(xm_io_file* file, tb_char_t const* data, tb_size_t size) { + // check tb_assert(file && data && xm_io_file_is_file(file) && !xm_io_file_is_closed(file)); tb_buffer_t buf; - tb_bool_t ok = tb_buffer_init(&buf); - tb_assert_and_check_return(ok); - tb_byte_t* buf_ptr = tb_buffer_resize(&buf, (size + 1) * 2); - tb_assert(buf_ptr); - tb_long_t buf_size = tb_charset_conv_cstr(TB_CHARSET_TYPE_UTF8, file->encoding, data, buf_ptr, size * 2); - if (buf_size > 0) tb_file_writ(file->file_ref, buf_ptr, (tb_size_t)buf_size); - tb_buffer_exit(&buf); - return; + if (tb_buffer_init(&buf)) + { + tb_byte_t* buf_ptr = tb_buffer_resize(&buf, (size + 1) << 1); + tb_assert(buf_ptr); + + tb_long_t buf_size = tb_charset_conv_cstr(TB_CHARSET_TYPE_UTF8, file->encoding, data, buf_ptr, size << 1); + if (buf_size > 0) + tb_file_writ(file->file_ref, buf_ptr, (tb_size_t)buf_size); + + tb_buffer_exit(&buf); + } } -static tb_void_t std_write(xm_io_file* file, tb_char_t const* data, tb_size_t size) +static tb_void_t xm_io_file_write_std(xm_io_file* file, tb_char_t const* data, tb_size_t size) { + // check tb_assert(file && data && xm_io_file_is_std(file) && !xm_io_file_is_closed(file)); + // check type tb_size_t type = (file->type & ~XM_IO_FILE_FLAG_TTY); tb_check_return(type != XM_IO_FILE_TYPE_STDIN); -#ifdef TB_CONFIG_OS_WINDOWS - HANDLE handle = INVALID_HANDLE_VALUE; - switch (type) - { - case XM_IO_FILE_TYPE_STDOUT: handle = GetStdHandle(STD_OUTPUT_HANDLE); break; - case XM_IO_FILE_TYPE_STDERR: handle = GetStdHandle(STD_ERROR_HANDLE); break; - } - tb_assert_and_check_return(handle != INVALID_HANDLE_VALUE); - - // write string to stdout - tb_size_t writ = 0; - - // write to the stdout - DWORD real = 0; - tb_buffer_t wbuf; - tb_bool_t ok = tb_buffer_init(&wbuf); - tb_assert_and_check_return(ok); - if (xm_io_file_is_tty(file)) - { - // write to console - tb_wchar_t* wdata = (tb_wchar_t*)tb_buffer_resize(&wbuf, (size + 1) * 2); - tb_assert(wdata); - tb_size_t wsize = tb_mbstowcs(wdata, data, size); - while (writ < wsize) - { - if (!WriteConsoleW(handle, wdata + writ, (DWORD)(wsize - writ), &real, tb_null)) break; - // update writted size - writ += (tb_size_t)real; - } - } - else - { - // write to redirected file - tb_char_t* wdata = (tb_char_t*)tb_buffer_resize(&wbuf, (size + 1) * 4); - tb_assert(wdata); - tb_size_t wsize = xm_utf8tombs(wdata, data, size * 4, GetConsoleOutputCP()); - while (writ < wsize) - { - if (!WriteFile(handle, wdata + writ, (DWORD)(wsize - writ), &real, tb_null)) break; - // update writted size - writ += (tb_size_t)real; - } - } - tb_buffer_exit(&wbuf); -#else - fwrite(data, sizeof(tb_char_t), size, file->std_ref); -#endif + // write data to stdout/stderr + tb_stdfile_writ(file->std_ref, (tb_byte_t const*)data, size); } /* @@ -126,33 +83,37 @@ tb_int_t xm_io_file_write(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); + // get file xm_io_file* file = xm_io_getfile(lua); tb_int_t narg = lua_gettop(lua); - if (xm_io_file_is_closed(file)) xm_io_file_error_closed(lua); + // this file has been closed? + if (xm_io_file_is_closed(file)) + xm_io_file_return_error_closed(lua); if (narg > 1) { // set to utf-8 if not specified - if (file->encoding == XM_IO_FILE_ENCODING_UNKNOWN) file->encoding = TB_CHARSET_TYPE_UTF8; - tb_bool_t direct = file->encoding == TB_CHARSET_TYPE_UTF8 || file->encoding == XM_IO_FILE_ENCODING_BINARY; + if (file->encoding == XM_IO_FILE_ENCODING_UNKNOWN) + file->encoding = TB_CHARSET_TYPE_UTF8; + tb_bool_t is_direct = file->encoding == TB_CHARSET_TYPE_UTF8 || file->encoding == XM_IO_FILE_ENCODING_BINARY; for (tb_int_t i = 2; i <= narg; i++) { - size_t datasize; + size_t datasize = 0; tb_char_t const* data = luaL_checklstring(lua, i, &datasize); - if (!datasize) continue; - tb_assert(data); + tb_check_continue(datasize); + tb_assert_and_check_break(data); if (xm_io_file_is_std(file)) - std_write(file, data, (tb_size_t)datasize); - else if (direct) - direct_write(file, data, (tb_size_t)datasize); + xm_io_file_write_std(file, data, (tb_size_t)datasize); + else if (is_direct) + xm_io_file_write_direct(file, data, (tb_size_t)datasize); else - transcode_write(file, data, (tb_size_t)datasize); + xm_io_file_write_transcode(file, data, (tb_size_t)datasize); } } lua_settop(lua, 1); - xm_io_file_success(); + xm_io_file_return_success(); } diff --git a/core/src/xmake/io/open.c b/core/src/xmake/io/open.c index 09311decd..9cdbdbfc7 100644 --- a/core/src/xmake/io/open.c +++ b/core/src/xmake/io/open.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "open" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "open" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -36,71 +36,77 @@ */ /* - * io.open(path, mode) + * io.open(path, modestr) */ tb_int_t xm_io_open(lua_State* lua) { + // check tb_assert_and_check_return_val(lua, 0); + // get file path and mode tb_char_t const* path = luaL_checkstring(lua, 1); - tb_char_t const* mode = luaL_optstring(lua, 2, "r"); + tb_char_t const* modestr = luaL_optstring(lua, 2, "r"); + tb_assert_and_check_return_val(path && modestr, 0); - tb_assert_and_check_return_val(path && mode, 0); - - tb_size_t tb_mode = TB_FILE_MODE_RW; - switch (mode[0]) + // get file mode value + tb_size_t mode = TB_FILE_MODE_RW; + switch (modestr[0]) { - case 'w': tb_mode |= TB_FILE_MODE_CREAT | TB_FILE_MODE_TRUNC; break; - case 'a': tb_mode |= TB_FILE_MODE_APPEND | TB_FILE_MODE_CREAT; break; + case 'w': mode |= TB_FILE_MODE_CREAT | TB_FILE_MODE_TRUNC; break; + case 'a': mode |= TB_FILE_MODE_APPEND | TB_FILE_MODE_CREAT; break; default: break; } - tb_bool_t update = !!tb_strchr(mode, '+'); - tb_char_t full[TB_PATH_MAXN] = {0}; - path = tb_path_absolute(path, full, TB_PATH_MAXN); - tb_file_ref_t file = tb_file_init(path, tb_mode); - tb_size_t pathlen = tb_strlen(path); - tb_char_t* savedfull = tb_malloc_cstr(pathlen + 1); - tb_assert(savedfull); - tb_strcpy(savedfull, path); - - if (file) - { - tb_size_t enc = XM_IO_FILE_ENCODING_UNKNOWN; - if (mode[1] == 'b' || (update && mode[2] == 'b')) - enc = XM_IO_FILE_ENCODING_BINARY; - else if (tb_strstr(mode, "utf8") || tb_strstr(mode, "utf-8")) - enc = TB_CHARSET_TYPE_UTF8; - else if (tb_strstr(mode, "utf16le") || tb_strstr(mode, "utf-16le")) - enc = TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_LE; - else if (tb_strstr(mode, "utf16be") || tb_strstr(mode, "utf-16be")) - enc = TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_BE; - else if (tb_strstr(mode, "utf16") || tb_strstr(mode, "utf-16")) - enc = TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_NE; - xm_io_file* xm_file = xm_io_newfile(lua); - xm_file->file_ref = file; - xm_file->mode = tb_mode; - xm_file->type = XM_IO_FILE_TYPE_FILE; - xm_file->encoding = enc; - xm_file->path = savedfull; - tb_strlcpy(xm_file->name, "file: ", tb_arrayn(xm_file->name)); - if (pathlen < tb_arrayn(xm_file->name) - tb_arrayn("file: ")) - { - tb_strcat(xm_file->name, full); - } - else - { - tb_strcat(xm_file->name, "..."); - tb_strcat(xm_file->name, - full + (pathlen - tb_arrayn(xm_file->name) + tb_arrayn("file: ") + tb_arrayn("..."))); - } - return 1; - } - else + // open file + tb_file_ref_t file = tb_file_init(path, mode); + if (!file) { - if (savedfull) tb_free(savedfull); lua_pushnil(lua); lua_pushliteral(lua, "failed to open file."); return 2; } -}
\ No newline at end of file + + // get file encoding + tb_bool_t update = !!tb_strchr(modestr, '+'); + tb_size_t encoding = XM_IO_FILE_ENCODING_UNKNOWN; + if (modestr[1] == 'b' || (update && modestr[2] == 'b')) + encoding = XM_IO_FILE_ENCODING_BINARY; + else if (tb_strstr(modestr, "utf8") || tb_strstr(modestr, "utf-8")) + encoding = TB_CHARSET_TYPE_UTF8; + else if (tb_strstr(modestr, "utf16le") || tb_strstr(modestr, "utf-16le")) + encoding = TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_LE; + else if (tb_strstr(modestr, "utf16be") || tb_strstr(modestr, "utf-16be")) + encoding = TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_BE; + else if (tb_strstr(modestr, "utf16") || tb_strstr(modestr, "utf-16")) + encoding = TB_CHARSET_TYPE_UTF16 | TB_CHARSET_TYPE_NE; + + // get absolute file path + tb_char_t full[TB_PATH_MAXN] = {0}; + path = tb_path_absolute(path, full, TB_PATH_MAXN); + tb_assert_and_check_return_val(path, 0); + + // new file + xm_io_file* xm_file = xm_io_newfile(lua); + xm_file->file_ref = file; + xm_file->mode = mode; + xm_file->type = XM_IO_FILE_TYPE_FILE; + xm_file->encoding = encoding; + + // save file path + tb_size_t pathlen = tb_strlen(path); + xm_file->path = tb_malloc_cstr(pathlen + 1); + if (xm_file->path) + tb_strncpy(xm_file->path, path, pathlen); + + // save file name + tb_size_t name_maxn = tb_arrayn(xm_file->name); + tb_strlcpy(xm_file->name, "file: ", name_maxn); + if (pathlen < name_maxn - tb_arrayn("file: ")) + tb_strlcat(xm_file->name, full, name_maxn); + else + { + tb_strlcat(xm_file->name, "...", name_maxn); + tb_strlcat(xm_file->name, full + (pathlen - name_maxn + tb_arrayn("file: ") + tb_arrayn("...")), name_maxn); + } + return 1; +} diff --git a/core/src/xmake/io/std.c b/core/src/xmake/io/std.c index d232e0eb2..33b6e0a93 100644 --- a/core/src/xmake/io/std.c +++ b/core/src/xmake/io/std.c @@ -22,8 +22,8 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * trace */ -#define TB_TRACE_MODULE_NAME "io_std" -#define TB_TRACE_MODULE_DEBUG (0) +#define TB_TRACE_MODULE_NAME "io_std" +#define TB_TRACE_MODULE_DEBUG (0) /* ////////////////////////////////////////////////////////////////////////////////////// * includes @@ -40,9 +40,9 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ -static tb_size_t xm_isatty(tb_size_t type) +static tb_size_t xm_io_std_isatty(tb_size_t type) { - tb_bool_t answer; + tb_bool_t answer = tb_false; #ifdef TB_CONFIG_OS_WINDOWS DWORD mode; HANDLE console_handle; @@ -62,7 +62,6 @@ static tb_size_t xm_isatty(tb_size_t type) } #endif - // return answer if (answer) type |= XM_IO_FILE_FLAG_TTY; return type; } @@ -74,20 +73,20 @@ static tb_void_t xm_io_std_init(lua_State* lua, tb_size_t type) tb_char_t const* name = tb_null; tb_char_t const* path = tb_null; - FILE* fp = tb_null; + tb_stdfile_ref_t fp = tb_null; switch (type) { case XM_IO_FILE_TYPE_STDIN: name = "stdin"; - fp = stdin; + fp = tb_stdfile_input(); break; case XM_IO_FILE_TYPE_STDOUT: name = "stdout"; - fp = stdout; + fp = tb_stdfile_output(); break; case XM_IO_FILE_TYPE_STDERR: name = "stderr"; - fp = stderr; + fp = tb_stdfile_error(); break; } #ifdef TB_CONFIG_OS_WINDOWS @@ -102,10 +101,14 @@ static tb_void_t xm_io_std_init(lua_State* lua, tb_size_t type) #endif tb_assert_and_check_return(name && path && fp); + // new file xm_io_file* file = xm_io_newfile(lua); + tb_assert_and_check_return(file); lua_setfield(lua, -2, name); + + // init file file->encoding = TB_CHARSET_TYPE_UTF8; - file->type = xm_isatty(type); + file->type = xm_io_std_isatty(type); file->path = path; file->std_ref = fp; tb_char_t const* info = xm_io_file_is_tty(file) ? "" : " redirected"; @@ -117,6 +120,7 @@ tb_int_t xm_io_std(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); + // init io.stdin, io.stdout and io.stderr lua_getglobal(lua, "io"); xm_io_std_init(lua, XM_IO_FILE_TYPE_STDIN); xm_io_std_init(lua, XM_IO_FILE_TYPE_STDOUT); diff --git a/core/src/xmake/sandbox/interactive.c b/core/src/xmake/sandbox/interactive.c index fa31b6cd1..75f36d947 100644 --- a/core/src/xmake/sandbox/interactive.c +++ b/core/src/xmake/sandbox/interactive.c @@ -174,22 +174,9 @@ static tb_size_t xm_sandbox_readline(tb_char_t* data, tb_size_t maxn, tb_char_t tb_printf(prompt); tb_print_sync(); -# ifdef TB_CONFIG_OS_WINDOWS // get input buffer - DWORD len = 0; - tb_wchar_t buf[LUA_PROMPT_BUFSIZE]; - if (ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), buf, (DWORD)tb_min(maxn / 3, tb_arrayn(buf)), &len, tb_null) && len < tb_arrayn(buf)) - { - buf[len] = L'\0'; - xm_wcstoutf8(data, buf, maxn); + if (tb_stdfile_gets(tb_stdfile_input(), data, maxn)) return tb_strlen(data); - } -# else - if (fgets(data, (tb_int_t)maxn, stdin)) - { - return tb_strlen(data); - } -# endif #endif // no more input |
