luaur_vm/functions/
codepoint.rs1use crate::functions::lua_l_checklstring::lua_l_checklstring;
2use crate::functions::lua_l_checkstack::lua_l_checkstack;
3use crate::functions::lua_l_error_l::lua_l_error_l;
4use crate::functions::lua_l_optinteger::lua_l_optinteger;
5use crate::functions::lua_pushinteger::lua_pushinteger;
6use crate::functions::u_posrelat::u_posrelat;
7use crate::functions::utf_8_decode::utf_8_decode;
8use crate::macros::lua_l_argcheck::luaL_argcheck;
9use crate::type_aliases::lua_state::lua_State;
10use core::ffi::c_int;
11
12#[no_mangle]
13pub unsafe fn codepoint(L: *mut lua_State) -> c_int {
14 let mut len: usize = 0;
15 let mut s = lua_l_checklstring(L, 1, &mut len);
16
17 let posi = u_posrelat(lua_l_optinteger(L, 2, 1), len);
18 let pose = u_posrelat(lua_l_optinteger(L, 3, posi), len);
19
20 luaL_argcheck!(L, posi >= 1, 2, "out of range");
21 luaL_argcheck!(L, pose <= len as i32, 3, "out of range");
22
23 if posi > pose {
24 return 0; }
26
27 if (pose - posi) >= c_int::MAX as i32 {
28 lua_l_error_l(
29 L,
30 c"string slice too long".as_ptr(),
31 core::format_args!("string slice too long"),
32 );
33 }
34
35 let n = (pose - posi) + 1;
36 lua_l_checkstack(L, n, "string slice too long");
37
38 let mut n = 0;
39 let se = s.add(pose as usize);
40 s = s.add((posi - 1) as usize);
41
42 while s < se {
43 let mut code: i32 = 0;
44 s = utf_8_decode(s, &mut code);
45 if s.is_null() {
46 lua_l_error_l(
47 L,
48 c"invalid UTF-8 code".as_ptr(),
49 core::format_args!("invalid UTF-8 code"),
50 );
51 }
52 lua_pushinteger(L, code);
53 n += 1;
54 }
55
56 n
57}