From d4d808fcc81ba5e6e08dadca832da901ce0e2aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20W=C3=BCrl?= <bastiwuerl@gmail.com> Date: Sun, 11 Mar 2018 11:48:05 +0100 Subject: [PATCH] Add implementation for a64l --- Cargo.lock | 1 + src/stdlib/src/lib.rs | 25 +++++++++++++++++++++++-- tests/.gitignore | 1 + tests/Makefile | 1 + tests/stdlib/a64l.c | 22 ++++++++++++++++++++++ 5 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 tests/stdlib/a64l.c diff --git a/Cargo.lock b/Cargo.lock index b9ae70624..a0ced709f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -507,6 +507,7 @@ name = "string" version = "0.1.0" dependencies = [ "cbindgen 0.5.0", + "compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins.git)", "errno 0.1.0", "platform 0.1.0", "stdlib 0.1.0", diff --git a/src/stdlib/src/lib.rs b/src/stdlib/src/lib.rs index dea8dbd13..228f561da 100644 --- a/src/stdlib/src/lib.rs +++ b/src/stdlib/src/lib.rs @@ -23,8 +23,29 @@ pub const EXIT_SUCCESS: c_int = 0; static mut ATEXIT_FUNCS: [Option<extern "C" fn()>; 32] = [None; 32]; #[no_mangle] -pub extern "C" fn a64l(s: *const c_char) -> c_long { - unimplemented!(); +pub unsafe extern "C" fn a64l(s: *const c_char) -> c_long { + if s as isize == 0 { + return 0; + } + let mut l: c_long = 0; + for x in 0..7 { + let c = *((s as isize + x) as *const c_char); + if c == 0 { + // string is null terminated + return l; + } + // ASCII to base64 conversion: + let mut bits: c_long = if c < 58 { + (c - 46) as c_long // ./0123456789 + } else if c < 91 { + (c - 53) as c_long // A-Z + } else { + (c - 59) as c_long // a-z + }; + bits <<= 6 * x; + l |= bits; + } + return l; } #[no_mangle] diff --git a/tests/.gitignore b/tests/.gitignore index c5a743e74..d0bc0d66b 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -29,6 +29,7 @@ /setid /sprintf /stdlib/strtol +/stdlib/a64l /string/strncmp /string/strcspn /string/strchr diff --git a/tests/Makefile b/tests/Makefile index ea41ffa7a..8a626402c 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -24,6 +24,7 @@ BINS=\ sleep \ sprintf \ stdlib/strtol \ + stdlib/a64l \ string/strncmp \ string/strcspn \ string/strchr \ diff --git a/tests/stdlib/a64l.c b/tests/stdlib/a64l.c new file mode 100644 index 000000000..8036d9e3f --- /dev/null +++ b/tests/stdlib/a64l.c @@ -0,0 +1,22 @@ +#include <stdlib.h> +#include <stdio.h> + +int main(int argc, char* argv[]) { + char * s = "azAZ9."; // test boundaries + long l = a64l(s); + if (l != 194301926) { + printf("Invalid result: a64l(%s) = %ld\n", s, l); + return 1; + } + printf("Correct a64l: %s = %ld\n", s, l); + + + s = "azA"; // test null terminated string + l = a64l(s); + if (l != 53222) { + printf("Invalid result: a64l(%s) = %ld\n", s, l); + return 1; + } + printf("Correct a64l: %s = %ld\n", s, l); + return 0; +} -- GitLab