summaryrefslogtreecommitdiff
path: root/core/src/xmake/utf8/codes.c
diff options
context:
space:
mode:
authorruki <[email protected]>2026-01-20 23:11:30 +0800
committerruki <[email protected]>2026-01-20 23:11:30 +0800
commite0f8104c1a0e0e62a4c5f02fa7457f308b27e5dd (patch)
tree316cc92a602d7d4788fc15e5ed679b5b118ea08b /core/src/xmake/utf8/codes.c
parent766a7a86a7af89c58038500985c9d8ec441de25f (diff)
add utf8 module
Diffstat (limited to 'core/src/xmake/utf8/codes.c')
-rw-r--r--core/src/xmake/utf8/codes.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/core/src/xmake/utf8/codes.c b/core/src/xmake/utf8/codes.c
new file mode 100644
index 000000000..be6cf462a
--- /dev/null
+++ b/core/src/xmake/utf8/codes.c
@@ -0,0 +1,71 @@
+/*!A cross-platform build utility based on Lua
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (C) 2015-present, Xmake Open Source Community.
+ *
+ * @author ruki
+ * @file codes.c
+ *
+ */
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * includes
+ */
+#include "utf8.h"
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * private implementation
+ */
+
+static tb_int_t iter_aux (lua_State *lua, tb_bool_t strict) {
+ size_t len;
+ tb_char_t const* s = luaL_checklstring(lua, 1, &len);
+ lua_Unsigned n = (lua_Unsigned)lua_tointeger(lua, 2);
+ if (n < len) {
+ while (n < len && xm_utf8_iscontp(s + n)) n++; /* go to next character */
+ }
+ if (n >= len) /* (also handles original 'n' being negative) */
+ return 0; /* no more codepoints */
+ else {
+ xm_utf8_int_t code;
+ tb_char_t const* next = xm_utf8_decode(s + n, &code, strict);
+ if (next == NULL || xm_utf8_iscontp(next))
+ return luaL_error(lua, XM_UTF8_MSGInvalid);
+ lua_pushinteger(lua, n + 1);
+ lua_pushinteger(lua, code);
+ return 2;
+ }
+}
+
+static int iter_auxstrict (lua_State *lua) {
+ return iter_aux(lua, tb_true);
+}
+
+static int iter_auxlax (lua_State *lua) {
+ return iter_aux(lua, tb_false);
+}
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * implementation
+ */
+
+tb_int_t xm_utf8_codes(lua_State *lua) {
+ tb_bool_t lax = lua_toboolean(lua, 2);
+ tb_char_t const* s = luaL_checkstring(lua, 1);
+ luaL_argcheck(lua, !xm_utf8_iscontp(s), 1, XM_UTF8_MSGInvalid);
+ lua_pushcfunction(lua, lax ? iter_auxlax : iter_auxstrict);
+ lua_pushvalue(lua, 1);
+ lua_pushinteger(lua, 0);
+ return 3;
+}