luaur_vm/functions/
str_split.rs1use crate::functions::lua_createtable::lua_createtable;
2use crate::functions::lua_l_checklstring::lua_l_checklstring;
3use crate::functions::lua_l_optlstring::lua_l_optlstring;
4use crate::functions::lua_pushinteger::lua_pushinteger;
5use crate::functions::lua_pushlstring::lua_pushlstring;
6use crate::functions::lua_settable::lua_settable;
7use crate::type_aliases::lua_state::lua_State;
8use core::ffi::{c_char, c_int};
9
10#[no_mangle]
11pub unsafe fn str_split(l: *mut lua_State) -> c_int {
12 extern "C" {
13 fn memcmp(s1: *const core::ffi::c_void, s2: *const core::ffi::c_void, n: usize) -> c_int;
14 }
15
16 let mut haystack_len: usize = 0;
17 let haystack = lua_l_checklstring(l, 1, &mut haystack_len);
18 let mut needle_len: usize = 0;
19 let needle = lua_l_optlstring(l, 2, c",".as_ptr() as *const c_char, &mut needle_len);
20
21 let begin = haystack;
22 let end = haystack.add(haystack_len);
23 let mut span_start = begin;
24 let mut num_matches = 0;
25
26 lua_createtable(l, 0, 0);
27
28 let mut iter = begin;
29 if needle_len == 0 {
30 iter = iter.add(1);
31 }
32
33 while iter <= end.offset(-(needle_len as isize)) {
37 if memcmp(
40 iter as *const core::ffi::c_void,
41 needle as *const core::ffi::c_void,
42 needle_len,
43 ) == 0
44 {
45 num_matches += 1;
46 lua_pushinteger(l, num_matches);
47 lua_pushlstring(l, span_start, iter.offset_from(span_start) as usize);
48 lua_settable(l, -3);
49
50 span_start = iter.add(needle_len);
51 if needle_len > 0 {
52 iter = iter.add(needle_len - 1);
53 }
54 }
55 iter = iter.add(1);
56 }
57
58 if needle_len > 0 {
59 num_matches += 1;
60 lua_pushinteger(l, num_matches);
61 lua_pushlstring(l, span_start, end.offset_from(span_start) as usize);
62 lua_settable(l, -3);
63 }
64
65 1
66}