luaur_vm/functions/
lua_l_checkoption.rs1use 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}