Skip to content

Commit 8afac0b

Browse files
committed
refactor: no check some unwrap None situation and utf8 validity; use std to convert CStr.
see ubolonton/emacs-module-rs#58 see Emacs bug#74922 Personally trust Emacs, so I‘ll not verify again.
1 parent d390a5c commit 8afac0b

File tree

1 file changed

+22
-29
lines changed

1 file changed

+22
-29
lines changed

src/lib.rs

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
88
use icu_segmenter::WordSegmenter;
99
#[cfg(all(not(feature = "windows"), feature = "icu_segmenter"))]
1010
use itertools::Itertools;
11+
use std::ffi::CStr;
1112
use std::os::raw;
1213
use std::ptr;
1314
#[cfg(feature = "windows")]
@@ -36,11 +37,11 @@ pub static plugin_is_GPL_compatible: libc::c_int = 1;
3637
#[unsafe(no_mangle)]
3738
pub unsafe extern "C" fn emacs_module_init(runtime: *mut emacs_runtime) -> libc::c_int {
3839
unsafe {
39-
let env = (*runtime).get_environment.unwrap()(runtime);
40+
let env = (*runtime).get_environment.unwrap_unchecked()(runtime);
4041

41-
let intern = (*env).intern.unwrap();
42-
let funcall = (*env).funcall.unwrap();
43-
let make_function = (*env).make_function.unwrap();
42+
let intern = (*env).intern.unwrap_unchecked();
43+
let funcall = (*env).funcall.unwrap_unchecked();
44+
let make_function = (*env).make_function.unwrap_unchecked();
4445

4546
let Qfset = intern(env, c"fset".as_ptr());
4647

@@ -89,10 +90,10 @@ unsafe extern "C" fn Femt__do_split_helper(
8990
data: *mut raw::c_void,
9091
) -> emacs_value {
9192
unsafe {
92-
let intern = (*env).intern.unwrap();
93-
let funcall = (*env).funcall.unwrap();
94-
let make_integer = (*env).make_integer.unwrap();
95-
let copy_string_contents = (*env).copy_string_contents.unwrap();
93+
let intern = (*env).intern.unwrap_unchecked();
94+
let funcall = (*env).funcall.unwrap_unchecked();
95+
let make_integer = (*env).make_integer.unwrap_unchecked();
96+
let copy_string_contents = (*env).copy_string_contents.unwrap_unchecked();
9697

9798
let Qcons = intern(env, c"cons".as_ptr());
9899
let Qvector = intern(env, c"vector".as_ptr());
@@ -103,9 +104,10 @@ unsafe extern "C" fn Femt__do_split_helper(
103104
let is_ok =
104105
copy_string_contents(env, *args, buf.as_mut_ptr() as *mut raw::c_char, &mut len);
105106

106-
strip_trailing_zero_bytes(&mut buf);
107+
let param_u8 =
108+
std::str::from_utf8_unchecked(CStr::from_bytes_with_nul_unchecked(&buf).to_bytes());
109+
// let param_u8 = CStr::from_bytes_with_nul(&buf).unwrap().to_str().unwrap();
107110

108-
let param_u8 = String::from_utf8(buf).unwrap();
109111
#[cfg(feature = "windows")]
110112
let mut consCell = {
111113
let param_hstring = HSTRING::from(param_u8);
@@ -123,7 +125,7 @@ unsafe extern "C" fn Femt__do_split_helper(
123125
let mut consCell = {
124126
let segmenter_icu = WordSegmenter::new_auto();
125127
let segments = segmenter_icu
126-
.segment_str(&param_u8)
128+
.segment_str(param_u8)
127129
.tuple_windows()
128130
.map(|(i, j)| &param_u8[i..j]);
129131
let ss = segments.map(|s| s.chars().count());
@@ -156,11 +158,11 @@ unsafe extern "C" fn Femt__word_at_point_or_forward(
156158
data: *mut raw::c_void,
157159
) -> emacs_value {
158160
unsafe {
159-
let intern = (*env).intern.unwrap();
160-
let funcall = (*env).funcall.unwrap();
161-
let make_integer = (*env).make_integer.unwrap();
162-
let extract_integer = (*env).extract_integer.unwrap();
163-
let copy_string_contents = (*env).copy_string_contents.unwrap();
161+
let intern = (*env).intern.unwrap_unchecked();
162+
let funcall = (*env).funcall.unwrap_unchecked();
163+
let make_integer = (*env).make_integer.unwrap_unchecked();
164+
let extract_integer = (*env).extract_integer.unwrap_unchecked();
165+
let copy_string_contents = (*env).copy_string_contents.unwrap_unchecked();
164166

165167
let Qcons = intern(env, c"cons".as_ptr());
166168

@@ -170,11 +172,12 @@ unsafe extern "C" fn Femt__word_at_point_or_forward(
170172
let is_ok =
171173
copy_string_contents(env, *args, buf.as_mut_ptr() as *mut raw::c_char, &mut len);
172174

173-
strip_trailing_zero_bytes(&mut buf);
175+
let param_u8 =
176+
std::str::from_utf8_unchecked(CStr::from_bytes_with_nul_unchecked(&buf).to_bytes());
177+
// let param_u8 = CStr::from_bytes_with_nul(&buf).unwrap().to_str().unwrap();
174178

175179
let n = extract_integer(env, *args.offset(1));
176180

177-
let param_u8 = String::from_utf8(buf).unwrap();
178181
#[cfg(feature = "windows")]
179182
let (l, r) = {
180183
let param_hstring = HSTRING::from(param_u8);
@@ -192,7 +195,7 @@ unsafe extern "C" fn Femt__word_at_point_or_forward(
192195
// Sadly WordSegmenter does not provide a way to get the nth token
193196
let segmenter_icu = WordSegmenter::new_auto();
194197
let segments = segmenter_icu
195-
.segment_str(&param_u8)
198+
.segment_str(param_u8)
196199
.tuple_windows()
197200
.map(|(i, j)| &param_u8[i..j]);
198201
let mut ss = segments.map(|s| s.chars().count());
@@ -223,13 +226,3 @@ unsafe extern "C" fn Femt__word_at_point_or_forward(
223226
funcall(env, Qcons, 2, [l, r].as_mut_ptr())
224227
}
225228
}
226-
227-
// Thank you,
228-
// https://github.com/ubolonton/emacs-module-rs/blob/126241a79d171e8de43c7db248b277fac7f1a4e8/src/types/string.rs#L103C1-L109C2
229-
fn strip_trailing_zero_bytes(bytes: &mut Vec<u8>) {
230-
let mut len = bytes.len();
231-
while len > 0 && bytes[len - 1] == 0 {
232-
bytes.pop(); // strip trailing 0-byte(s)
233-
len -= 1;
234-
}
235-
}

0 commit comments

Comments
 (0)