Skip to content

Fix feature dependency #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.64.0 # clippy is too much of a moving target at the moment
toolchain: 1.75.0 # clippy is too much of a moving target at the moment
override: true
components: clippy
- uses: actions-rs/clippy-check@v1
Expand Down
18 changes: 18 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,20 @@ all = [
"strlen",
"strtol",
"strtoul",
"strtoll",
"strtoull",
"strtoimax",
"strtoumax",
"strstr",
"strchr",
"atoi",
"utoa",
"itoa",
"snprintf",
"isspace",
"isdigit",
"isalpha",
"isupper",
]
abs = []
strcmp = []
Expand All @@ -38,8 +47,17 @@ strncpy = []
strlen = []
strtol = []
strtoul = []
strtoll = []
strtoull = []
strtoimax = []
strtoumax = []
strstr = []
strchr = []
atoi = []
utoa = []
itoa = []
snprintf = []
isspace = []
isdigit = []
isalpha = []
isupper = []
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,21 @@ This crate basically came about so that the [nrfxlib](https://github.com/NordicP
* abs
* strol
* atoi
* isspace
* isdigit
* isalpha
* isupper
* strcmp
* strncmp
* strcpy
* strncpy
* strlen
* strtol
* strtoll
* strtoul
* strtoull
* strtoimax
* strtoumax
* strstr
* strchr
* snprintf
Expand Down
25 changes: 22 additions & 3 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
fn main() {
if cfg!(feature = "snprintf") {
// Build our snprintf substitute (which has to be C as Rust doesn't do varargs)
cc::Build::new()
let mut build = cc::Build::new();

build
.warnings(true)
.extra_warnings(true)
.flag("-std=c99")
.file("./src/snprintf.c")
.compile("clocal");
.file("./src/snprintf.c");

#[cfg(not(feature = "itoa"))]
{
build.define("itoa", "tinyrlibc_itoa");
}
#[cfg(not(feature = "utoa"))]
{
build.define("utoa", "tinyrlibc_utoa");
}
#[cfg(not(feature = "strtoul"))]
{
build.define("strtoul", "tinyrlibc_strtoul");
}

build.compile("clocal");
}

println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/snprintf.c");
}
9 changes: 2 additions & 7 deletions src/abs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@

use crate::CInt;

/// Calculates the integer absolute value
///
/// ```
/// use tinyrlibc::abs;
/// assert_eq!(abs(-2), 2);
/// ```
#[no_mangle]
/// Rust implementation of C library function `abs`
#[cfg_attr(feature = "abs", no_mangle)]
pub extern "C" fn abs(i: CInt) -> CInt {
i.abs()
}
Expand Down
27 changes: 0 additions & 27 deletions src/atoi.rs

This file was deleted.

67 changes: 67 additions & 0 deletions src/ctype.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! A tiny C library, written in Rust.
//!
//! See README.md for more details.
//!
//! This file is Copyright (c) Jonathan 'theJPster' Pallant 2019
//! Licensed under the Blue Oak Model Licence 1.0.0
//!
//! See each module for its respective licence.

/// `void`
pub type CVoid = ::core::ffi::c_void;

/// `long long int`
pub type CLongLong = ::core::ffi::c_longlong;

/// `unsigned long long int`
pub type CULongLong = ::core::ffi::c_ulonglong;

/// `intmax_t`
pub type CUIntMax = CULongLong;

/// `uintmax_t`
pub type CIntMax = CLongLong;

/// `long int`
pub type CLong = ::core::ffi::c_long;

/// `unsigned long int`
pub type CULong = ::core::ffi::c_ulong;

/// `int`
pub type CInt = ::core::ffi::c_int;

/// `unsigned int`
pub type CUInt = ::core::ffi::c_uint;

/// Represents an 8-bit `char`. Rust does not (and will never) support
/// platforms where `char` is not 8-bits long.
pub type CChar = u8;

/// This allows you to iterate a null-terminated string in a relatively simple
/// way.
pub struct CStringIter {
ptr: *const CChar,
idx: isize,
}

impl CStringIter {
/// Create a new iterator from a pointer to a null-terminated string. The
/// behaviour is undefined if the string is not null-terminated.
pub fn new(s: *const CChar) -> CStringIter {
CStringIter { ptr: s, idx: 0 }
}
}

impl core::iter::Iterator for CStringIter {
type Item = CChar;
fn next(&mut self) -> Option<Self::Item> {
let c = unsafe { *self.ptr.offset(self.idx) };
if c == 0 {
None
} else {
self.idx += 1;
Some(c)
}
}
}
6 changes: 4 additions & 2 deletions src/itoa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@

use crate::CChar;

#[no_mangle]
/// Formats the given value `i`, with the given radix, into the given buffer (of the given length).
///
/// No prefixes (like 0x or 0b) are generated. Only radix values in the range
/// 2..=16 are supported.
///
/// Returns the number of bytes written on success (not including the null),
/// or -1 if the buffer wasn't large enough.
#[cfg_attr(not(feature = "itoa"), export_name = "tinyrlibc_itoa")]
#[cfg_attr(feature = "itoa", no_mangle)]
pub unsafe extern "C" fn itoa(i: i64, s: *mut CChar, s_len: usize, radix: u8) -> i32 {
let (is_negative, pos_i) = if i < 0 {
(true, (-i) as u64)
Expand All @@ -31,14 +32,15 @@ pub unsafe extern "C" fn itoa(i: i64, s: *mut CChar, s_len: usize, radix: u8) ->
}
}

#[no_mangle]
/// Formats the given value `u`, with the given radix, into the given buffer (of the given length).
///
/// No prefixes (like 0x or 0b) are generated. Only radix values in the range
/// 2..=16 are supported. Negative numbers are not supported.
///
/// Returns the number of bytes written on success (not including the null),
/// or -1 if the buffer wasn't large enough.
#[cfg_attr(not(feature = "utoa"), export_name = "tinyrlibc_utoa")]
#[cfg_attr(feature = "utoa", no_mangle)]
pub unsafe extern "C" fn utoa(mut u: u64, s: *mut CChar, s_len: usize, radix: u8) -> i32 {
let buffer_slice = core::slice::from_raw_parts_mut(s, s_len);

Expand Down
99 changes: 25 additions & 74 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,123 +5,74 @@
//! This file is Copyright (c) Jonathan 'theJPster' Pallant 2019
//! Licensed under the Blue Oak Model Licence 1.0.0
//!
//! See each module for its respective licence.
//! See each module for its respective license.

#![cfg_attr(not(test), no_std)]
#![allow(clippy::missing_safety_doc)]

#[cfg(test)]
#[allow(unused_imports)]
use std as core;

#[cfg(feature = "abs")]
mod itoa;

mod abs;
#[cfg(feature = "abs")]
pub use self::abs::abs;

#[cfg(feature = "strcmp")]
mod strcmp;
#[cfg(feature = "strcmp")]
pub use self::strcmp::strcmp;

#[cfg(feature = "strncmp")]
mod strncmp;
#[cfg(feature = "strncmp")]
pub use self::strncmp::strncmp;

#[cfg(feature = "strcpy")]
mod strcpy;
#[cfg(feature = "strcpy")]
pub use self::strcpy::strcpy;

#[cfg(feature = "strncpy")]
mod strncpy;
#[cfg(feature = "strncpy")]
pub use self::strncpy::strncpy;

#[cfg(feature = "strlen")]
mod strlen;
#[cfg(feature = "strlen")]
pub use self::strlen::strlen;

#[cfg(feature = "strtol")]
mod strtol;
#[cfg(feature = "atoi")]
pub use self::strtol::atoi;
#[cfg(feature = "isalpha")]
pub use self::strtol::isalpha;
#[cfg(feature = "isdigit")]
pub use self::strtol::isdigit;
#[cfg(feature = "isspace")]
pub use self::strtol::isspace;
#[cfg(feature = "isupper")]
pub use self::strtol::isupper;
#[cfg(feature = "strtoimax")]
pub use self::strtol::strtoimax;
#[cfg(feature = "strtol")]
pub use self::strtol::strtol;

#[cfg(feature = "strtoll")]
pub use self::strtol::strtoll;
#[cfg(feature = "strtoul")]
mod strtoul;
#[cfg(feature = "strtoul")]
pub use self::strtoul::strtoul;
pub use self::strtol::strtoul;
#[cfg(feature = "strtoull")]
pub use self::strtol::strtoull;
#[cfg(feature = "strtoumax")]
pub use self::strtol::strtoumax;

#[cfg(feature = "strstr")]
mod strstr;
#[cfg(feature = "strstr")]
pub use self::strstr::strstr;

#[cfg(feature = "strchr")]
mod strchr;
#[cfg(feature = "strchr")]
pub use self::strchr::strchr;

#[cfg(feature = "atoi")]
mod atoi;
#[cfg(feature = "atoi")]
pub use self::atoi::atoi;

#[cfg(feature = "itoa")]
mod itoa;
#[cfg(feature = "itoa")]
pub use self::itoa::itoa;

#[cfg(feature = "snprintf")]
mod snprintf;

/// `long long int`
pub type CLongLong = ::core::ffi::c_longlong;

/// `unsigned long long int`
pub type CULongLong = ::core::ffi::c_ulonglong;

/// `long int`
pub type CLong = ::core::ffi::c_long;

/// `unsigned long int`
pub type CULong = ::core::ffi::c_ulong;

/// `int`
pub type CInt = ::core::ffi::c_int;

/// `unsigned int`
pub type CUInt = ::core::ffi::c_uint;

/// Represents an 8-bit `char`. Rust does not (and will never) support
/// platforms where `char` is not 8-bits long.
pub type CChar = u8;

/// This allows you to iterate a null-terminated string in a relatively simple
/// way.
pub struct CStringIter {
ptr: *const CChar,
idx: isize,
}

impl CStringIter {
/// Create a new iterator from a pointer to a null-terminated string. The
/// behaviour is undefined if the string is not null-terminated.
pub fn new(s: *const CChar) -> CStringIter {
CStringIter { ptr: s, idx: 0 }
}
}

impl core::iter::Iterator for CStringIter {
type Item = CChar;
fn next(&mut self) -> Option<Self::Item> {
let c = unsafe { *self.ptr.offset(self.idx) };
if c == 0 {
None
} else {
self.idx += 1;
Some(c)
}
}
}
mod ctype;
pub use self::ctype::*;
Loading