diff --git a/Cargo.lock b/Cargo.lock index f7cb6db3f3134dbcde8579304590cc732a045106..860ade9b4021346ebaf1c832490b0cf42e414cad 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 109e7e2cc3db050da6c75fd4600a50846817a777..6b2b0fe0b24cd6d8c47d4c8758f1e49998bcaf26 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 0000000000000000000000000000000000000000..ceb24b1ed2eee8d1b56f2ba3e55e45612fd5bc94 --- /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 7d605429f983886fe5f9c5d276c6d38a711b6ed7..61672efd885670a409a56d5bcfd20b867586b715 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 0000000000000000000000000000000000000000..1840ba8f90555289ef8db8aaf5416b8c0f4d48aa --- /dev/null +++ b/src/locale/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "locale" +version = "0.1.0" +authors = ["Jeremy Soller <jackpot51@gmail.com>"] +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 0000000000000000000000000000000000000000..60404ed885663b630b4947bf861986b7231959ca --- /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 0000000000000000000000000000000000000000..1c865da186479bd23f76ac9b644f1bcfe752a62f --- /dev/null +++ b/src/locale/cbindgen.toml @@ -0,0 +1,6 @@ +include_guard = "_LOCALE_H" +trailer = "#include <bits/locale.h>" +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 0000000000000000000000000000000000000000..17e438e615fbf88835cb4599a8070d864f20b2a2 --- /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 bc142e252ae14ab02498d662641d9cc40c385822..cec2032da6e6b62dc9b9d049fb8123c5e0c64d14 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 38ccc035f869a97add4d0f0684cf579a1e145bae..b54e9691b4ba61a4fa8dd217c468b492d1a52660 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 6133738f75c6b719fff2ec074b2153284dc9bfa0..f961369c7f3cfff22862246b05eb52116ace28b3 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/expected/locale.stdout b/tests/expected/locale.stdout new file mode 100644 index 0000000000000000000000000000000000000000..5d516f2e6dcea9bc11c7d447c6c52eec5af0e7cf --- /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 0000000000000000000000000000000000000000..eba2ecede1d7ea8204ec9adae781ab27e7da5b8e --- /dev/null +++ b/tests/locale.c @@ -0,0 +1,13 @@ +#include <locale.h> +#include <stdio.h> +#include <string.h> + +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); + } +}