Skip to main content

luaur_vm/functions/
lua_l_findtable.rs

1use crate::enums::lua_type::lua_Type;
2use crate::functions::lua_createtable::lua_createtable;
3use crate::functions::lua_pushlstring::lua_pushlstring;
4use crate::functions::lua_pushvalue::lua_pushvalue;
5use crate::functions::lua_rawget::lua_rawget;
6use crate::functions::lua_remove::lua_remove;
7use crate::functions::lua_settable::lua_settable;
8use crate::functions::lua_type::lua_type;
9use crate::macros::lua_pop::lua_pop;
10use crate::type_aliases::lua_state::lua_State;
11use core::ffi::{c_char, c_int};
12
13/// `const char* luaL_findtable(lua_State* L, int idx, const char* fname, int szhint)`
14///
15/// C++ source: `VM/src/laux.cpp:330`
16#[no_mangle]
17pub unsafe fn luaL_findtable(
18    l: *mut lua_State,
19    idx: c_int,
20    mut fname: *const c_char,
21    szhint: c_int,
22) -> *const c_char {
23    extern "C" {
24        fn strchr(s: *const c_char, c: c_int) -> *mut c_char;
25        fn strlen(s: *const c_char) -> usize;
26    }
27
28    lua_pushvalue(l, idx);
29    loop {
30        let mut e = strchr(fname, '.' as c_int);
31        if e.is_null() {
32            e = fname.add(strlen(fname)) as *mut c_char;
33        }
34
35        let len = (e as *const c_char).offset_from(fname) as usize;
36        lua_pushlstring(l, fname, len);
37        lua_rawget(l, -2);
38
39        if lua_type(l, -1) == (lua_Type::LUA_TNIL as i32) {
40            lua_pop(l, 1); // remove this nil
41            let next_szhint = if *e == ('.' as c_char) { 1 } else { szhint };
42            lua_createtable(l, 0, next_szhint);
43            lua_pushlstring(l, fname, len);
44            lua_pushvalue(l, -2);
45            lua_settable(l, -4);
46        } else if lua_type(l, -1) != (lua_Type::LUA_TTABLE as i32) {
47            lua_pop(l, 2); // remove table and value
48            return fname;
49        }
50
51        lua_remove(l, -2); // remove previous table
52        fname = e.add(1) as *const c_char;
53
54        if *e != ('.' as c_char) {
55            break;
56        }
57    }
58
59    core::ptr::null()
60}