diff --git a/src/stdlib/src/lib.rs b/src/stdlib/src/lib.rs index dea8dbd13a4b17def216925f39324048faca1c66..7813b9bdc953c45e9a8a8a173f130f6022c95d4a 100644 --- a/src/stdlib/src/lib.rs +++ b/src/stdlib/src/lib.rs @@ -23,8 +23,30 @@ 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.is_null() { + return 0; + } + let mut l: c_long = 0; + // a64l does not support more than 6 characters at once + for x in 0..6 { + let c = *s.offset(x); + 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 c5a743e74f6964efc7476545fcce4229e2653fc7..d0bc0d66b343fcc3e240bfbcf4eb4d1a286f25a5 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 ea41ffa7a2a7761ab75e4e116579d9ef4276f051..8a626402c063dec9558d912e76b33b1d0906d024 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 0000000000000000000000000000000000000000..8036d9e3fb0c85391effadde4986a17fc66d8bbc --- /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; +}