From 996445a6a3820ddf99723e99c669c1877fd53166 Mon Sep 17 00:00:00 2001 From: jD91mZM2 Date: Fri, 22 Jun 2018 14:10:05 +0200 Subject: [PATCH 1/2] Add empty locale functions --- Cargo.lock | 9 +++++ Cargo.toml | 1 + include/bits/locale.h | 7 ++++ src/lib.rs | 1 + src/locale/Cargo.toml | 11 ++++++ src/locale/build.rs | 11 ++++++ src/locale/cbindgen.toml | 6 ++++ src/locale/src/lib.rs | 70 ++++++++++++++++++++++++++++++++++++ src/stdio/src/lib.rs | 1 - tests/.gitignore | 1 + tests/Makefile | 1 + tests/expected/locale.stderr | 0 tests/expected/locale.stdout | 1 + tests/locale.c | 13 +++++++ 14 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 include/bits/locale.h create mode 100644 src/locale/Cargo.toml create mode 100644 src/locale/build.rs create mode 100644 src/locale/cbindgen.toml create mode 100644 src/locale/src/lib.rs create mode 100644 tests/expected/locale.stderr create mode 100644 tests/expected/locale.stdout create mode 100644 tests/locale.c diff --git a/Cargo.lock b/Cargo.lock index f7cb6db3f3..860ade9b40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,6 +158,14 @@ name = "libc" version = "0.2.40" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "locale" +version = "0.1.0" +dependencies = [ + "cbindgen 0.5.2", + "platform 0.1.0", +] + [[package]] name = "log" version = "0.3.9" @@ -271,6 +279,7 @@ dependencies = [ "fenv 0.1.0", "float 0.1.0", "grp 0.1.0", + "locale 0.1.0", "netinet 0.1.0", "platform 0.1.0", "semaphore 0.1.0", diff --git a/Cargo.toml b/Cargo.toml index 109e7e2cc3..6b2b0fe0b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ fcntl = { path = "src/fcntl" } fenv = { path = "src/fenv" } float = { path = "src/float" } grp = { path = "src/grp" } +locale = { path = "src/locale" } netinet = { path = "src/netinet" } platform = { path = "src/platform" } semaphore = { path = "src/semaphore" } diff --git a/include/bits/locale.h b/include/bits/locale.h new file mode 100644 index 0000000000..ceb24b1ed2 --- /dev/null +++ b/include/bits/locale.h @@ -0,0 +1,7 @@ +#define LC_ALL 0 +#define LC_COLLATE 1 +#define LC_CTYPE 2 +#define LC_MESSAGES 3 +#define LC_MONETARY 4 +#define LC_NUMERIC 5 +#define LC_TIME 6 diff --git a/src/lib.rs b/src/lib.rs index 7d605429f9..61672efd88 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ pub extern crate fcntl; pub extern crate fenv; pub extern crate float; pub extern crate grp; +pub extern crate locale; pub extern crate netinet; pub extern crate semaphore; pub extern crate stdio; diff --git a/src/locale/Cargo.toml b/src/locale/Cargo.toml new file mode 100644 index 0000000000..1840ba8f90 --- /dev/null +++ b/src/locale/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "locale" +version = "0.1.0" +authors = ["Jeremy Soller "] +build = "build.rs" + +[build-dependencies] +cbindgen = { path = "../../cbindgen" } + +[dependencies] +platform = { path = "../platform" } diff --git a/src/locale/build.rs b/src/locale/build.rs new file mode 100644 index 0000000000..60404ed885 --- /dev/null +++ b/src/locale/build.rs @@ -0,0 +1,11 @@ +extern crate cbindgen; + +use std::{env, fs}; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"); + fs::create_dir_all("../../target/include").expect("failed to create include directory"); + cbindgen::generate(crate_dir) + .expect("failed to generate bindings") + .write_to_file("../../target/include/locale.h"); +} diff --git a/src/locale/cbindgen.toml b/src/locale/cbindgen.toml new file mode 100644 index 0000000000..1c865da186 --- /dev/null +++ b/src/locale/cbindgen.toml @@ -0,0 +1,6 @@ +include_guard = "_LOCALE_H" +trailer = "#include " +language = "C" + +[enum] +prefix_with_name = true diff --git a/src/locale/src/lib.rs b/src/locale/src/lib.rs new file mode 100644 index 0000000000..17e438e615 --- /dev/null +++ b/src/locale/src/lib.rs @@ -0,0 +1,70 @@ +//! locale implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/locale.h.html + +#![no_std] +#![feature(alloc)] + +extern crate platform; + +use core::ptr; +use platform::types::*; + +const EMPTY_PTR: *const c_char = "\0" as *const _ as *const c_char; + +#[repr(C)] +#[no_mangle] +pub struct lconv { + currency_symbol: *const c_char, + decimal_point: *const c_char, + frac_digits: c_char, + grouping: *const c_char, + int_curr_symbol: *const c_char, + int_frac_digits: c_char, + mon_decimal_point: *const c_char, + mon_grouping: *const c_char, + mon_thousands_sep: *const c_char, + negative_sign: *const c_char, + n_cs_precedes: c_char, + n_sep_by_space: c_char, + n_sign_posn: c_char, + positive_sign: *const c_char, + p_cs_precedes: c_char, + p_sep_by_space: c_char, + p_sign_posn: c_char, + thousands_sep: *const c_char, +} +unsafe impl Sync for lconv {} + +static CURRENT_LOCALE: lconv = lconv { + currency_symbol: EMPTY_PTR, + decimal_point: ".\0" as *const _ as *const c_char, + frac_digits: c_char::max_value(), + grouping: EMPTY_PTR, + int_curr_symbol: EMPTY_PTR, + int_frac_digits: c_char::max_value(), + mon_decimal_point: EMPTY_PTR, + mon_grouping: EMPTY_PTR, + mon_thousands_sep: EMPTY_PTR, + negative_sign: EMPTY_PTR, + n_cs_precedes: c_char::max_value(), + n_sep_by_space: c_char::max_value(), + n_sign_posn: c_char::max_value(), + positive_sign: EMPTY_PTR, + p_cs_precedes: c_char::max_value(), + p_sep_by_space: c_char::max_value(), + p_sign_posn: c_char::max_value(), + thousands_sep: EMPTY_PTR +}; + +#[no_mangle] +pub extern "C" fn localeconv() -> *const lconv { + &CURRENT_LOCALE as *const _ +} + +#[no_mangle] +pub extern "C" fn setlocale(_option: c_int, val: *const c_char) -> *const c_char { + if val.is_null() { + return "C\0".as_ptr() as *const c_char; + } + // TODO actually implement + ptr::null() +} diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs index bc142e252a..cec2032da6 100644 --- a/src/stdio/src/lib.rs +++ b/src/stdio/src/lib.rs @@ -2,7 +2,6 @@ #![no_std] #![feature(alloc)] -#![feature(global_allocator)] extern crate alloc; extern crate errno; diff --git a/tests/.gitignore b/tests/.gitignore index 38ccc035f8..b54e9691b4 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -17,6 +17,7 @@ /getid /getc_unget /link +/locale /math /mem /pipe diff --git a/tests/Makefile b/tests/Makefile index 6133738f75..f961369c7f 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -15,6 +15,7 @@ EXPECT_BINS=\ getid \ getc_unget \ link \ + locale \ math \ mem \ pipe \ diff --git a/tests/expected/locale.stderr b/tests/expected/locale.stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/expected/locale.stdout b/tests/expected/locale.stdout new file mode 100644 index 0000000000..5d516f2e6d --- /dev/null +++ b/tests/expected/locale.stdout @@ -0,0 +1 @@ +success! diff --git a/tests/locale.c b/tests/locale.c new file mode 100644 index 0000000000..eba2ecede1 --- /dev/null +++ b/tests/locale.c @@ -0,0 +1,13 @@ +#include +#include +#include + +int main() { + // TODO: Implement locale properly and test it here + const char* val = setlocale(LC_ALL, NULL); + if (strcmp(val, "C") == 0) { + puts("success!"); + } else { + printf("setlocale returned the wrong value: %s", val); + } +} From 0a3c8abe957e7ec8236dec162958ce79388ec520 Mon Sep 17 00:00:00 2001 From: jD91mZM2 Date: Fri, 22 Jun 2018 14:49:02 +0200 Subject: [PATCH 2/2] Fix setlocale return value --- src/locale/src/lib.rs | 8 +++++--- tests/locale.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/locale/src/lib.rs b/src/locale/src/lib.rs index 17e438e615..f71380b353 100644 --- a/src/locale/src/lib.rs +++ b/src/locale/src/lib.rs @@ -9,6 +9,7 @@ use core::ptr; use platform::types::*; const EMPTY_PTR: *const c_char = "\0" as *const _ as *const c_char; +static mut C_LOCALE: [c_char; 2] = [b'C' as c_char, 0]; #[repr(C)] #[no_mangle] @@ -61,10 +62,11 @@ pub extern "C" fn localeconv() -> *const lconv { } #[no_mangle] -pub extern "C" fn setlocale(_option: c_int, val: *const c_char) -> *const c_char { +pub unsafe extern "C" fn setlocale(_option: c_int, val: *const c_char) -> *mut c_char { if val.is_null() { - return "C\0".as_ptr() as *const c_char; + // Can't use string`` + return C_LOCALE.as_mut_ptr() as *mut c_char; } // TODO actually implement - ptr::null() + ptr::null_mut() } diff --git a/tests/locale.c b/tests/locale.c index eba2ecede1..9358bc5554 100644 --- a/tests/locale.c +++ b/tests/locale.c @@ -4,7 +4,7 @@ int main() { // TODO: Implement locale properly and test it here - const char* val = setlocale(LC_ALL, NULL); + char* val = setlocale(LC_ALL, NULL); if (strcmp(val, "C") == 0) { puts("success!"); } else {