summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2019-07-05 22:43:42 +0800
committerruki <[email protected]>2019-07-05 22:11:19 +0800
commit55581bb68f44a6e17eba9cefd4f05868e802498b (patch)
treef3e78c18903b3d9394be621d0d59558c11c53a95 /core/src
parentcf8ff12bc05fde4cb94344d1ca1bce31a4778527 (diff)
use stdfile
Diffstat (limited to 'core/src')
m---------core/src/tbox/tbox0
-rw-r--r--core/src/xmake/io/file.h94
-rw-r--r--core/src/xmake/io/file___len.c15
-rw-r--r--core/src/xmake/io/file___tostring.c5
-rw-r--r--core/src/xmake/io/file_close___gc.c35
-rw-r--r--core/src/xmake/io/file_flush.c25
-rw-r--r--core/src/xmake/io/file_isatty.c21
-rw-r--r--core/src/xmake/io/file_path.c20
-rw-r--r--core/src/xmake/io/file_read.c110
-rw-r--r--core/src/xmake/io/file_seek.c18
-rw-r--r--core/src/xmake/io/file_write.c115
-rw-r--r--core/src/xmake/io/open.c114
-rw-r--r--core/src/xmake/io/std.c24
-rw-r--r--core/src/xmake/sandbox/interactive.c15
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