Skip to main content

luaur_vm/functions/
lua_o_chunkid.rs

1use core::ffi::c_char;
2
3#[allow(non_snake_case)]
4pub unsafe fn lua_o_chunkid(
5    buf: *mut c_char,
6    buflen: usize,
7    source: *const c_char,
8    srclen: usize,
9) -> *mut c_char {
10    debug_assert!(!buf.is_null());
11    debug_assert!(!source.is_null());
12
13    if *source == b'=' as c_char {
14        if srclen <= buflen {
15            return source.add(1) as *mut c_char;
16        }
17        // truncate the part after '='
18        if buflen == 0 {
19            return buf;
20        }
21
22        let n = buflen.saturating_sub(1);
23        core::ptr::copy_nonoverlapping(source.add(1) as *const u8, buf as *mut u8, n);
24        *buf.add(buflen - 1) = b'\0' as c_char;
25    } else if *source == b'@' as c_char {
26        if srclen <= buflen {
27            return source.add(1) as *mut c_char;
28        }
29        // truncate the part after '@'
30        if buflen == 0 {
31            return buf;
32        }
33
34        // memcpy(buf, "...", 3);
35        core::ptr::copy_nonoverlapping(b"..." as *const u8, buf as *mut u8, 3);
36
37        // memcpy(buf + 3, source + srclen - (buflen - 4), buflen - 4);
38        let tail_len = buflen.saturating_sub(4);
39        let src_start = source.add(srclen.saturating_sub(tail_len));
40        core::ptr::copy_nonoverlapping(src_start as *const u8, buf.add(3) as *mut u8, tail_len);
41
42        *buf.add(buflen - 1) = b'\0' as c_char;
43    } else {
44        // buf = [string "string"]
45        let mut len = 0usize;
46
47        // strcspn(source, "\n\r"); // stop at first newline or carriage return
48        loop {
49            let ch = *source.add(len);
50            if ch == b'\n' as c_char || ch == b'\r' as c_char || ch == 0 {
51                break;
52            }
53            len += 1;
54        }
55
56        // buflen -= sizeof("[string \"...\"]");
57        // In the C++ source, this literal size (excluding NUL terminator) behaves like subtracting 15.
58        let mut inner_buflen = buflen.saturating_sub(15);
59        if len > inner_buflen {
60            len = inner_buflen;
61        }
62
63        // strcpy(buf, "[string \"");
64        let prefix_bytes = b"[string \"";
65        core::ptr::copy_nonoverlapping(prefix_bytes.as_ptr(), buf as *mut u8, prefix_bytes.len());
66
67        let source_end = *source.add(len);
68        if source_end != 0 {
69            // strncat(buf, source, len);
70            if len > 0 {
71                core::ptr::copy_nonoverlapping(
72                    source as *const u8,
73                    buf.add(prefix_bytes.len()) as *mut u8,
74                    len,
75                );
76            }
77            // strcat(buf, "...");
78            let ell = b"...";
79            core::ptr::copy_nonoverlapping(
80                ell.as_ptr(),
81                buf.add(prefix_bytes.len() + len) as *mut u8,
82                3,
83            );
84            // strcat(buf, "\"]");
85            let suffix = b"\"]";
86            core::ptr::copy_nonoverlapping(
87                suffix.as_ptr(),
88                buf.add(prefix_bytes.len() + len + 3) as *mut u8,
89                suffix.len(),
90            );
91            *buf.add(prefix_bytes.len() + len + 3 + suffix.len()) = b'\0' as c_char;
92        } else {
93            // strcat(buf, source);
94            if len > 0 {
95                core::ptr::copy_nonoverlapping(
96                    source as *const u8,
97                    buf.add(prefix_bytes.len()) as *mut u8,
98                    len,
99                );
100            }
101            // strcat(buf, "\"]");
102            let suffix = b"\"]";
103            core::ptr::copy_nonoverlapping(
104                suffix.as_ptr(),
105                buf.add(prefix_bytes.len() + len) as *mut u8,
106                suffix.len(),
107            );
108            *buf.add(prefix_bytes.len() + len + suffix.len()) = b'\0' as c_char;
109        }
110    }
111
112    buf
113}