Skip to main content

luaur_vm/functions/
lua_l_checkoption.rs

1use crate::functions::lua_l_argerror_l::lua_l_argerror_l;
2use crate::functions::lua_l_checklstring::lua_l_checklstring;
3use crate::functions::lua_l_optlstring::lua_l_optlstring;
4use crate::functions::lua_pushfstring_l::lua_pushfstring_l;
5use crate::type_aliases::lua_state::lua_State;
6use core::ffi::c_char;
7use core::ffi::c_int;
8use core::ffi::CStr;
9
10#[no_mangle]
11pub unsafe fn luaL_checkoption(
12    L: *mut lua_State,
13    narg: c_int,
14    def: *const c_char,
15    lst: *const *const c_char,
16) -> c_int {
17    let name: *const c_char = if !def.is_null() {
18        lua_l_optlstring(L, narg, def, core::ptr::null_mut())
19    } else {
20        lua_l_checklstring(L, narg, core::ptr::null_mut())
21    };
22
23    let mut i: c_int = 0;
24    while !(*lst.add(i as usize)).is_null() {
25        let opt = *lst.add(i as usize);
26        if libc_strcmp(opt, name) == 0 {
27            return i;
28        }
29        i += 1;
30    }
31
32    let name_str = CStr::from_ptr(name).to_string_lossy();
33    let msg = lua_pushfstring_l(
34        L,
35        c"invalid option '%s'".as_ptr(),
36        format_args!("invalid option '{}'", name_str),
37    );
38    let msg_str = CStr::from_ptr(msg).to_string_lossy();
39    lua_l_argerror_l(L, narg, msg_str.as_ref())
40}
41
42#[allow(non_snake_case)]
43pub fn lua_l_checkoption(
44    L: *mut lua_State,
45    narg: c_int,
46    def: Option<&str>,
47    lst: *const *const c_char,
48) -> c_int {
49    unsafe {
50        let def_cstring =
51            def.map(|s| std::ffi::CString::new(s).expect("option default contains nul"));
52        let def_ptr = match def_cstring.as_ref() {
53            Some(s) => s.as_ptr(),
54            None => core::ptr::null(),
55        };
56        luaL_checkoption(L, narg, def_ptr, lst)
57    }
58}
59
60unsafe fn libc_strcmp(s1: *const c_char, s2: *const c_char) -> c_int {
61    let mut i = 0;
62    loop {
63        let c1 = *s1.add(i) as u8;
64        let c2 = *s2.add(i) as u8;
65        if c1 != c2 {
66            return if c1 < c2 { -1 } else { 1 };
67        }
68        if c1 == 0 {
69            return 0;
70        }
71        i += 1;
72    }
73}