From b8dfd896c2b5b1fd10d80f2701c12307e86e9eba Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Sun, 14 Jun 2020 14:41:23 +0200 Subject: [PATCH] Use a Rust implementation of string.x lib --- lvgl-sys/build.rs | 1 - lvgl-sys/src/lib.rs | 2 + lvgl-sys/src/string_impl.rs | 183 ++++++++++++++++++++++++++++++++++++ lvgl-sys/string.c | 83 ---------------- 4 files changed, 185 insertions(+), 84 deletions(-) create mode 100644 lvgl-sys/src/string_impl.rs delete mode 100644 lvgl-sys/string.c diff --git a/lvgl-sys/build.rs b/lvgl-sys/build.rs index 005a296..19c14ff 100644 --- a/lvgl-sys/build.rs +++ b/lvgl-sys/build.rs @@ -58,7 +58,6 @@ fn main() { cfg.define("LV_CONF_INCLUDE_SIMPLE", Some("1")) .include(&vendor_src) .include(&vendor) - .file("string.c") .warnings(false) .include(&lv_config_dir) .compile("lvgl"); diff --git a/lvgl-sys/src/lib.rs b/lvgl-sys/src/lib.rs index 6d0c9f7..3e79a69 100644 --- a/lvgl-sys/src/lib.rs +++ b/lvgl-sys/src/lib.rs @@ -11,6 +11,8 @@ pub fn _bindgen_raw_src() -> &'static str { include_str!(concat!(env!("OUT_DIR"), "/bindings.rs")) } +mod string_impl; + #[cfg(test)] mod tests { use super::*; diff --git a/lvgl-sys/src/string_impl.rs b/lvgl-sys/src/string_impl.rs new file mode 100644 index 0000000..156ae07 --- /dev/null +++ b/lvgl-sys/src/string_impl.rs @@ -0,0 +1,183 @@ +// MIT License +// +// Copyright (c) 2018 Redox OS +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +use core::{mem, ptr, slice, usize}; +use cty::*; + +#[no_mangle] +pub unsafe extern "C" fn strchr(mut s: *const c_char, c: c_int) -> *mut c_char { + let c = c as c_char; + while *s != 0 { + if *s == c { + return s as *mut c_char; + } + s = s.offset(1); + } + ptr::null_mut() +} + +#[no_mangle] +pub unsafe extern "C" fn strcmp(s1: *const c_char, s2: *const c_char) -> c_int { + strncmp(s1, s2, usize::MAX) +} + +#[no_mangle] +pub unsafe extern "C" fn strcoll(s1: *const c_char, s2: *const c_char) -> c_int { + // relibc has no locale stuff (yet) + strcmp(s1, s2) +} + +#[no_mangle] +pub unsafe extern "C" fn strcpy(dst: *mut c_char, src: *const c_char) -> *mut c_char { + let mut i = 0; + + loop { + let byte = *src.offset(i); + *dst.offset(i) = byte; + + if byte == 0 { + break; + } + + i += 1; + } + + dst +} + +#[no_mangle] +pub unsafe extern "C" fn strlen(s: *const c_char) -> size_t { + strnlen(s, usize::MAX) +} + +#[no_mangle] +pub unsafe extern "C" fn strnlen(s: *const c_char, size: size_t) -> size_t { + let mut i = 0; + while i < size { + if *s.add(i) == 0 { + break; + } + i += 1; + } + i as size_t +} + +#[no_mangle] +pub unsafe extern "C" fn strnlen_s(s: *const c_char, size: size_t) -> size_t { + if s.is_null() { + 0 + } else { + strnlen(s, size) + } +} + +#[no_mangle] +pub unsafe extern "C" fn strcat(s1: *mut c_char, s2: *const c_char) -> *mut c_char { + strncat(s1, s2, usize::MAX) +} + +#[no_mangle] +pub unsafe extern "C" fn strncat(s1: *mut c_char, s2: *const c_char, n: size_t) -> *mut c_char { + let len = strlen(s1 as *const c_char); + let mut i = 0; + while i < n { + let b = *s2.add(i); + if b == 0 { + break; + } + + *s1.add(len + i) = b; + i += 1; + } + *s1.add(len + i) = 0; + + s1 +} + +#[no_mangle] +pub unsafe extern "C" fn strncmp(s1: *const c_char, s2: *const c_char, n: size_t) -> c_int { + let s1 = core::slice::from_raw_parts(s1 as *const c_uchar, n); + let s2 = core::slice::from_raw_parts(s2 as *const c_uchar, n); + + for (&a, &b) in s1.iter().zip(s2.iter()) { + let val = (a as c_int) - (b as c_int); + if a != b || a == 0 { + return val; + } + } + + 0 +} + +#[no_mangle] +pub unsafe extern "C" fn strncpy(dst: *mut c_char, src: *const c_char, n: size_t) -> *mut c_char { + let mut i = 0; + + while *src.add(i) != 0 && i < n { + *dst.add(i) = *src.add(i); + i += 1; + } + + for i in i..n { + *dst.add(i) = 0; + } + + dst +} + +#[no_mangle] +pub unsafe extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char { + let len = strlen(s) as isize; + let c = c as i8; + let mut i = len - 1; + while i >= 0 { + if *s.offset(i) == c { + return s.offset(i) as *mut c_char; + } + i -= 1; + } + ptr::null_mut() +} + +unsafe fn inner_strstr( + mut haystack: *const c_char, + needle: *const c_char, + mask: c_char, +) -> *mut c_char { + while *haystack != 0 { + let mut i = 0; + loop { + if *needle.offset(i) == 0 { + // We reached the end of the needle, everything matches this far + return haystack as *mut c_char; + } + if *haystack.offset(i) & mask != *needle.offset(i) & mask { + break; + } + + i += 1; + } + + haystack = haystack.offset(1); + } + ptr::null_mut() +} diff --git a/lvgl-sys/string.c b/lvgl-sys/string.c deleted file mode 100644 index 1ed90d8..0000000 --- a/lvgl-sys/string.c +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * linux/lib/string.c - * - * Copyright (C) 1991, 1992 Linus Torvalds - */ - -#include - -size_t strspn(const char *s, const char *accept) -{ - const char *p; - const char *a; - size_t count = 0; - - for (p = s; *p != '\0'; ++p) { - for (a = accept; *a != '\0'; ++a) { - if (*p == *a) - break; - } - if (*a == '\0') - return count; - ++count; - } - return count; -} - -size_t strcspn(const char *s, const char *reject) -{ - const char *p; - const char *r; - size_t count = 0; - - for (p = s; *p != '\0'; ++p) { - for (r = reject; *r != '\0'; ++r) { - if (*p == *r) - return count; - } - ++count; - } - return count; -} - -size_t strlen(const char *s) -{ - const char *sc; - - for (sc = s; *sc != '\0'; ++sc) - /* nothing */; - return sc - s; -} - -char *strchr(const char *s, int c) -{ - for (; *s != (char)c; ++s) - if (*s == '\0') - return NULL; - return (char *)s; -} - -char *strcpy(char *dest, const char *src) -{ - char *tmp = dest; - - while ((*dest++ = *src++) != '\0') - /* nothing */; - return tmp; -} - -int strcmp(const char *cs, const char *ct) -{ - unsigned char c1, c2; - - while (1) { - c1 = *cs++; - c2 = *ct++; - if (c1 != c2) - return c1 < c2 ? -1 : 1; - if (!c1) - break; - } - return 0; -}