Переглянути джерело

Merge pull request #66 from w0xel/master

Add implementation for a64l
Jeremy Soller 7 роки тому
батько
коміт
1b1ff5c750
5 змінених файлів з 49 додано та 2 видалено
  1. 1 0
      Cargo.lock
  2. 24 2
      src/stdlib/src/lib.rs
  3. 1 0
      tests/.gitignore
  4. 1 0
      tests/Makefile
  5. 22 0
      tests/stdlib/a64l.c

+ 1 - 0
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",

+ 24 - 2
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]

+ 1 - 0
tests/.gitignore

@@ -29,6 +29,7 @@
 /setid
 /sprintf
 /stdlib/strtol
+/stdlib/a64l
 /string/strncmp
 /string/strcspn
 /string/strchr

+ 1 - 0
tests/Makefile

@@ -24,6 +24,7 @@ BINS=\
 	sleep \
 	sprintf \
 	stdlib/strtol \
+	stdlib/a64l \
 	string/strncmp \
 	string/strcspn \
 	string/strchr \

+ 22 - 0
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;
+}