]> git.lizzy.rs Git - rust.git/commitdiff
tests: Simplify VaList run-make test
authorDan Robertson <dan@dlrobertson.com>
Fri, 30 Nov 2018 17:37:23 +0000 (17:37 +0000)
committerDan Robertson <dan@dlrobertson.com>
Fri, 30 Nov 2018 20:39:32 +0000 (20:39 +0000)
The va_list tests were too complex and were causing some spurious
test failures on Windows

src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs
src/test/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c

index d4cc4a0ed5e2b08ca27d439aa56b7840c4c19839..90ad6011526c1d41fdb99c0a8ec7683cb9a87563 100644 (file)
 
 use libc::{c_char, c_double, c_int, c_long, c_longlong};
 use std::ffi::VaList;
-use std::slice;
-use std::ffi::CStr;
+use std::ffi::{CString, CStr};
 
-#[repr(C)]
-#[derive(Clone, Copy, Debug)]
-pub enum AnswerType {
-    Double,
-    Long,
-    LongLong,
-    Int,
-    Byte,
-    CStr,
-    Skip,
+macro_rules! continue_if {
+    ($cond:expr) => {
+        if !($cond) {
+            return 0xff;
+        }
+    }
 }
 
-#[repr(C)]
-pub union AnswerData {
-    pub double: c_double,
-    pub long: c_long,
-    pub longlong: c_longlong,
-    pub int: c_int,
-    pub byte: c_char,
-    pub cstr: *const c_char,
-    pub skip_ty: AnswerType,
+unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool {
+    let cstr0 = CStr::from_ptr(ptr);
+    let cstr1 = CString::new(val).unwrap();
+    &*cstr1 == cstr0
 }
 
-#[repr(C)]
-pub struct Answer {
-    tag: AnswerType,
-    data: AnswerData,
+#[no_mangle]
+pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_longlong>() == 1);
+    continue_if!(ap.arg::<c_int>() == 2);
+    continue_if!(ap.arg::<c_longlong>() == 3);
+    0
 }
 
 #[no_mangle]
-pub unsafe fn compare_answers(answers: &[Answer], mut ap: VaList) -> usize {
-    for (i, answer) in answers.iter().enumerate() {
-        match answer {
-            Answer { tag: AnswerType::Double, data: AnswerData { double: d } } => {
-                let tmp = ap.arg::<c_double>();
-                if d.floor() != tmp.floor() {
-                    println!("Double: {} != {}", d, tmp);
-                    return i + 1;
-                }
-            }
-            Answer { tag: AnswerType::Long, data: AnswerData { long: l } } => {
-                let tmp =  ap.arg::<c_long>();
-                if *l != tmp {
-                    println!("Long: {} != {}", l, tmp);
-                    return i + 1;
-                }
-            }
-            Answer { tag: AnswerType::LongLong, data: AnswerData { longlong: l } } => {
-                let tmp =  ap.arg::<c_longlong>();
-                if *l != tmp {
-                    println!("Long Long: {} != {}", l, tmp);
-                    return i + 1;
-                }
-            }
-            Answer { tag: AnswerType::Int, data: AnswerData { int: n } } => {
-                let tmp = ap.arg::<c_int>();
-                if *n != tmp {
-                    println!("Int: {} != {}", n, tmp);
-                    return i + 1;
-                }
-            }
-            Answer { tag: AnswerType::Byte, data: AnswerData { byte: b } } => {
-                let tmp = ap.arg::<c_char>();
-                if *b != tmp {
-                    println!("Byte: {} != {}", b, tmp);
-                    return i + 1;
-                }
-            }
-            Answer { tag: AnswerType::CStr, data: AnswerData { cstr: c0 } } => {
-                let c1 = ap.arg::<*const c_char>();
-                let cstr0 = CStr::from_ptr(*c0);
-                let cstr1 = CStr::from_ptr(c1);
-                if cstr0 != cstr1 {
-                    println!("C String: {:?} != {:?}", cstr0, cstr1);
-                    return i + 1;
-                }
-            }
-            _ => {
-                println!("Unknown type!");
-                return i + 1;
-            }
-        }
-    }
-    return 0;
+pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_int>() == -1);
+    continue_if!(ap.arg::<c_char>() == 'A' as c_char);
+    continue_if!(ap.arg::<c_char>() == '4' as c_char);
+    continue_if!(ap.arg::<c_char>() == ';' as c_char);
+    continue_if!(ap.arg::<c_int>() == 0x32);
+    continue_if!(ap.arg::<c_int>() == 0x10000001);
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!"));
+    0
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn check_rust(argc: usize, answers: *const Answer, ap: VaList) -> usize {
-    let slice = slice::from_raw_parts(answers, argc);
-    compare_answers(slice, ap)
+pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_double>().floor() == 3.14f64.floor());
+    continue_if!(ap.arg::<c_long>() == 12);
+    continue_if!(ap.arg::<c_char>() == 'a' as c_char);
+    continue_if!(ap.arg::<c_double>().floor() == 6.18f64.floor());
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello"));
+    continue_if!(ap.arg::<c_int>() == 42);
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World"));
+    0
 }
 
 #[no_mangle]
-pub unsafe extern "C" fn check_rust_copy(argc: usize, answers: *const Answer,
-                                         mut ap: VaList) -> usize {
-    let slice = slice::from_raw_parts(answers, argc);
-    let mut skip_n = 0;
-    for (i, answer) in slice.iter().enumerate() {
-        match answer {
-            Answer { tag: AnswerType::Skip, data: AnswerData { skip_ty } } => {
-                match skip_ty {
-                    AnswerType::Double => { ap.arg::<c_double>(); }
-                    AnswerType::Long => { ap.arg::<c_long>(); }
-                    AnswerType::LongLong => { ap.arg::<c_longlong>(); }
-                    AnswerType::Int => { ap.arg::<c_int>(); }
-                    AnswerType::Byte => { ap.arg::<c_char>(); }
-                    AnswerType::CStr => { ap.arg::<*const c_char>(); }
-                    _ => { return i; }
-                };
-            }
-            _ => {
-                skip_n = i;
-                break;
-            }
+pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize {
+    continue_if!(ap.arg::<c_double>().floor() == 6.28f64.floor());
+    continue_if!(ap.arg::<c_int>() == 16);
+    continue_if!(ap.arg::<c_char>() == 'A' as c_char);
+    continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!"));
+    ap.copy(|mut ap| {
+        if compare_c_str(ap.arg::<*const c_char>(), "Correct") {
+            0
+        } else {
+            0xff
         }
-    }
-
-    ap.copy(|ap| {
-        compare_answers(&slice[skip_n..], ap)
     })
 }
index 80d9a48014203544ab7df4972dee5afc7e8d4abe..e9edf59d2c9c5cd86fd57f14e41d6763c9f7997d 100644 (file)
 #include <assert.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <stdio.h>
 
-typedef enum {
-    TAG_DOUBLE,
-    TAG_LONG,
-    TAG_LONGLONG,
-    TAG_INT,
-    TAG_BYTE,
-    TAG_CSTR,
-    TAG_SKIP,
-} tag;
+extern size_t check_list_0(va_list ap);
+extern size_t check_list_1(va_list ap);
+extern size_t check_list_2(va_list ap);
+extern size_t check_list_copy_0(va_list ap);
 
-typedef struct {
-    tag answer_type;
-    union {
-        double double_precision;
-        long num_long;
-        long long num_longlong;
-        int num_int;
-        int8_t byte;
-        char* cstr;
-        tag skip_ty;
-    } answer_data;
-} answer;
-
-#define MK_DOUBLE(n) \
-    { TAG_DOUBLE, { .double_precision = n } }
-#define MK_LONG(n) \
-    { TAG_LONG, { .num_long = n } }
-#define MK_LONGLONG(n) \
-    { TAG_LONGLONG, { .num_longlong = n } }
-#define MK_INT(n) \
-    { TAG_INT, { .num_int = n } }
-#define MK_BYTE(b) \
-    { TAG_BYTE, { .byte = b } }
-#define MK_CSTR(s) \
-    { TAG_CSTR, { .cstr = s } }
-#define MK_SKIP(ty) \
-    { TAG_SKIP, { .skip_ty = TAG_ ## ty } }
-
-extern size_t check_rust(size_t argc, const answer* answers, va_list ap);
-extern size_t check_rust_copy(size_t argc, const answer* answers, va_list ap);
-
-size_t test_check_rust(size_t argc, const answer* answers, ...) {
-    size_t ret = 0;
-    va_list ap;
-    va_start(ap, answers);
-    ret = check_rust(argc, answers, ap);
-    va_end(ap);
-    return ret;
-}
-
-size_t test_check_rust_copy(size_t argc, const answer* answers, ...) {
+int test_rust(size_t (*fn)(va_list), ...) {
     size_t ret = 0;
     va_list ap;
-    va_start(ap, answers);
-    ret = check_rust_copy(argc, answers, ap);
+    va_start(ap, fn);
+    ret = fn(ap);
     va_end(ap);
     return ret;
 }
 
 int main(int argc, char* argv[]) {
-    answer test_alignment0[] = {MK_LONGLONG(0x01LL), MK_INT(0x02), MK_LONGLONG(0x03LL)};
-    assert(test_check_rust(3, test_alignment0, 0x01LL, 0x02, 0x03LL) == 0);
+    assert(test_rust(check_list_0, 0x01LL, 0x02, 0x03LL) == 0);
 
-    answer test_alignment1[] = {MK_INT(-1), MK_BYTE('A'), MK_BYTE('4'), MK_BYTE(';'),
-                                MK_INT(0x32), MK_INT(0x10000001), MK_CSTR("Valid!")};
-    assert(test_check_rust(7, test_alignment1, -1, 'A', '4', ';', 0x32, 0x10000001,
-                           "Valid!") == 0);
+    assert(test_rust(check_list_1, -1, 'A', '4', ';', 0x32, 0x10000001, "Valid!") == 0);
 
-    answer basic_answers[] = {MK_DOUBLE(3.14), MK_LONG(12l), MK_BYTE('a'),
-                              MK_DOUBLE(6.28), MK_CSTR("Hello"), MK_INT(42),
-                              MK_CSTR("World")};
-    assert(test_check_rust(7, basic_answers, 3.14, 12l, 'a', 6.28, "Hello",
-                           42, "World") == 0);
+    assert(test_rust(check_list_2, 3.14, 12l, 'a', 6.28, "Hello", 42, "World") == 0);
 
-    answer copy_answers[] = { MK_SKIP(DOUBLE), MK_SKIP(INT), MK_SKIP(BYTE), MK_SKIP(CSTR),
-                              MK_CSTR("Correctly skipped and copied list") };
-    assert(test_check_rust_copy(5, copy_answers, 6.28, 16, 'A', "Skip Me!",
-                                "Correctly skipped and copied list") == 0);
+    assert(test_rust(check_list_copy_0, 6.28, 16, 'A', "Skip Me!", "Correct") == 0);
     return 0;
 }