@@ -61,6 +61,7 @@ fn do_ctest() {
61
61
t if t. contains ( "wasi" ) => return test_wasi ( t) ,
62
62
t if t. contains ( "windows" ) => return test_windows ( t) ,
63
63
t if t. contains ( "vxworks" ) => return test_vxworks ( t) ,
64
+ t if t. contains ( "nto-qnx" ) => return test_neutrino ( t) ,
64
65
t => panic ! ( "unknown target {}" , t) ,
65
66
}
66
67
}
@@ -2654,6 +2655,257 @@ fn test_emscripten(target: &str) {
2654
2655
cfg. generate ( "../src/lib.rs" , "main.rs" ) ;
2655
2656
}
2656
2657
2658
+ fn test_neutrino ( target : & str ) {
2659
+ assert ! ( target. contains( "nto-qnx" ) ) ;
2660
+
2661
+ let mut cfg = ctest_cfg ( ) ;
2662
+
2663
+ headers ! { cfg:
2664
+ "ctype.h" ,
2665
+ "dirent.h" ,
2666
+ "dlfcn.h" ,
2667
+ "sys/elf.h" ,
2668
+ "fcntl.h" ,
2669
+ "glob.h" ,
2670
+ "grp.h" ,
2671
+ "iconv.h" ,
2672
+ "ifaddrs.h" ,
2673
+ "limits.h" ,
2674
+ "sys/link.h" ,
2675
+ "locale.h" ,
2676
+ "sys/malloc.h" ,
2677
+ "rcheck/malloc.h" ,
2678
+ "malloc.h" ,
2679
+ "mqueue.h" ,
2680
+ "net/if.h" ,
2681
+ "net/if_arp.h" ,
2682
+ "net/route.h" ,
2683
+ "netdb.h" ,
2684
+ "netinet/in.h" ,
2685
+ "netinet/ip.h" ,
2686
+ "netinet/tcp.h" ,
2687
+ "netinet/udp.h" ,
2688
+ "netinet/ip_var.h" ,
2689
+ "sys/poll.h" ,
2690
+ "pthread.h" ,
2691
+ "pwd.h" ,
2692
+ "regex.h" ,
2693
+ "resolv.h" ,
2694
+ "sys/sched.h" ,
2695
+ "sched.h" ,
2696
+ "semaphore.h" ,
2697
+ "shadow.h" ,
2698
+ "signal.h" ,
2699
+ "spawn.h" ,
2700
+ "stddef.h" ,
2701
+ "stdint.h" ,
2702
+ "stdio.h" ,
2703
+ "stdlib.h" ,
2704
+ "string.h" ,
2705
+ "sys/sysctl.h" ,
2706
+ "sys/file.h" ,
2707
+ "sys/inotify.h" ,
2708
+ "sys/ioctl.h" ,
2709
+ "sys/ipc.h" ,
2710
+ "sys/mman.h" ,
2711
+ "sys/mount.h" ,
2712
+ "sys/msg.h" ,
2713
+ "sys/resource.h" ,
2714
+ "sys/sem.h" ,
2715
+ "sys/socket.h" ,
2716
+ "sys/stat.h" ,
2717
+ "sys/statvfs.h" ,
2718
+ "sys/swap.h" ,
2719
+ "sys/termio.h" ,
2720
+ "sys/time.h" ,
2721
+ "sys/times.h" ,
2722
+ "sys/types.h" ,
2723
+ "sys/uio.h" ,
2724
+ "sys/un.h" ,
2725
+ "sys/utsname.h" ,
2726
+ "sys/wait.h" ,
2727
+ "syslog.h" ,
2728
+ "termios.h" ,
2729
+ "time.h" ,
2730
+ "sys/time.h" ,
2731
+ "ucontext.h" ,
2732
+ "unistd.h" ,
2733
+ "utime.h" ,
2734
+ "utmp.h" ,
2735
+ "wchar.h" ,
2736
+ "aio.h" ,
2737
+ "nl_types.h" ,
2738
+ "langinfo.h" ,
2739
+ "unix.h" ,
2740
+ "nbutil.h" ,
2741
+ "aio.h" ,
2742
+ "net/bpf.h" ,
2743
+ "net/if_dl.h" ,
2744
+ "sys/syspage.h" ,
2745
+
2746
+ // TODO: The following header file doesn't appear as part of the default headers
2747
+ // found in a standard installation of Neutrino 7.1 SDP. The structures/
2748
+ // functions dependent on it are currently commented out.
2749
+ //"sys/asyncmsg.h",
2750
+ }
2751
+
2752
+ // Create and include a header file containing
2753
+ // items which are not included in any official
2754
+ // header file.
2755
+ let internal_header = "internal.h" ;
2756
+ let out_dir = env:: var ( "OUT_DIR" ) . unwrap ( ) ;
2757
+ cfg. header ( internal_header) ;
2758
+ cfg. include ( & out_dir) ;
2759
+ std:: fs:: write (
2760
+ out_dir. to_owned ( ) + "/" + internal_header,
2761
+ "#ifndef __internal_h__
2762
+ #define __internal_h__
2763
+ void __my_thread_exit(const void **);
2764
+ #endif" ,
2765
+ )
2766
+ . unwrap ( ) ;
2767
+
2768
+ cfg. type_name ( move |ty, is_struct, is_union| {
2769
+ match ty {
2770
+ // Just pass all these through, no need for a "struct" prefix
2771
+ "FILE" | "fd_set" | "Dl_info" | "DIR" | "Elf32_Phdr" | "Elf64_Phdr" | "Elf32_Shdr"
2772
+ | "Elf64_Shdr" | "Elf32_Sym" | "Elf64_Sym" | "Elf32_Ehdr" | "Elf64_Ehdr"
2773
+ | "Elf32_Chdr" | "Elf64_Chdr" | "aarch64_qreg_t" | "syspage_entry_info"
2774
+ | "syspage_array_info" => ty. to_string ( ) ,
2775
+
2776
+ "Ioctl" => "int" . to_string ( ) ,
2777
+
2778
+ t if is_union => format ! ( "union {}" , t) ,
2779
+
2780
+ t if t. ends_with ( "_t" ) => t. to_string ( ) ,
2781
+
2782
+ // put `struct` in front of all structs:.
2783
+ t if is_struct => format ! ( "struct {}" , t) ,
2784
+
2785
+ t => t. to_string ( ) ,
2786
+ }
2787
+ } ) ;
2788
+
2789
+ cfg. field_name ( move |_struct_, field| match field {
2790
+ "type_" => "type" . to_string ( ) ,
2791
+
2792
+ s => s. to_string ( ) ,
2793
+ } ) ;
2794
+
2795
+ cfg. volatile_item ( |i| {
2796
+ use ctest:: VolatileItemKind :: * ;
2797
+ match i {
2798
+ // The following fields are volatie but since we cannot express that in
2799
+ // Rust types, we have to explicitly tell the checker about it here:
2800
+ StructField ( ref n, ref f) if n == "aiocb" && f == "aio_buf" => true ,
2801
+ StructField ( ref n, ref f) if n == "qtime_entry" && f == "nsec_tod_adjust" => true ,
2802
+ StructField ( ref n, ref f) if n == "qtime_entry" && f == "nsec" => true ,
2803
+ StructField ( ref n, ref f) if n == "qtime_entry" && f == "nsec_stable" => true ,
2804
+ StructField ( ref n, ref f) if n == "intrspin" && f == "value" => true ,
2805
+ _ => false ,
2806
+ }
2807
+ } ) ;
2808
+
2809
+ cfg. skip_type ( move |ty| {
2810
+ match ty {
2811
+ // FIXME: `sighandler_t` type is incorrect, see:
2812
+ // https://github.com/rust-lang/libc/issues/1359
2813
+ "sighandler_t" => true ,
2814
+
2815
+ // Does not exist in Neutrino
2816
+ "locale_t" => true ,
2817
+
2818
+ _ => false ,
2819
+ }
2820
+ } ) ;
2821
+
2822
+ cfg. skip_struct ( move |ty| {
2823
+ if ty. starts_with ( "__c_anonymous_" ) {
2824
+ return true ;
2825
+ }
2826
+ match ty {
2827
+ "Elf64_Phdr" | "Elf32_Phdr" => true ,
2828
+
2829
+ // FIXME: This is actually a union, not a struct
2830
+ "sigval" => true ,
2831
+
2832
+ // union
2833
+ "_channel_connect_attr" => true ,
2834
+
2835
+ _ => false ,
2836
+ }
2837
+ } ) ;
2838
+
2839
+ cfg. skip_const ( move |name| {
2840
+ match name {
2841
+ // These signal "functions" are actually integer values that are casted to a fn ptr
2842
+ // This causes the compiler to err because of "illegal cast of int to ptr".
2843
+ "SIG_DFL" => true ,
2844
+ "SIG_IGN" => true ,
2845
+ "SIG_ERR" => true ,
2846
+
2847
+ _ => false ,
2848
+ }
2849
+ } ) ;
2850
+
2851
+ cfg. skip_fn ( move |name| {
2852
+ // skip those that are manually verified
2853
+ match name {
2854
+ // FIXME: https://github.com/rust-lang/libc/issues/1272
2855
+ "execv" | "execve" | "execvp" | "execvpe" => true ,
2856
+
2857
+ // wrong signature
2858
+ "signal" => true ,
2859
+
2860
+ // wrong signature of callback ptr
2861
+ "__cxa_atexit" => true ,
2862
+
2863
+ // FIXME: Our API is unsound. The Rust API allows aliasing
2864
+ // pointers, but the C API requires pointers not to alias.
2865
+ // We should probably be at least using `&`/`&mut` here, see:
2866
+ // https://github.com/gnzlbg/ctest/issues/68
2867
+ "lio_listio" => true ,
2868
+
2869
+ // 2 fields are actually unions which we're simply representing
2870
+ // as structures.
2871
+ "ChannelConnectAttr" => true ,
2872
+
2873
+ // fields contains unions
2874
+ "SignalKillSigval" => true ,
2875
+ "SignalKillSigval_r" => true ,
2876
+
2877
+ // Not defined in any headers. Defined to work around a
2878
+ // stack unwinding bug.
2879
+ "__my_thread_exit" => true ,
2880
+
2881
+ _ => false ,
2882
+ }
2883
+ } ) ;
2884
+
2885
+ cfg. skip_field_type ( move |struct_, field| {
2886
+ // sigval is actually a union, but we pretend it's a struct
2887
+ struct_ == "sigevent" && field == "sigev_value" ||
2888
+ // Anonymous structures
2889
+ struct_ == "_idle_hook" && field == "time"
2890
+ } ) ;
2891
+
2892
+ cfg. skip_field ( move |struct_, field| {
2893
+ ( struct_ == "__sched_param" && field == "reserved" ) ||
2894
+ ( struct_ == "sched_param" && field == "reserved" ) ||
2895
+ ( struct_ == "sigevent" && field == "__sigev_un1" ) || // union
2896
+ ( struct_ == "sigevent" && field == "__sigev_un2" ) || // union
2897
+ // sighandler_t type is super weird
2898
+ ( struct_ == "sigaction" && field == "sa_sigaction" ) ||
2899
+ // does not exist
2900
+ ( struct_ == "syspage_entry" && field == "__reserved" ) ||
2901
+ false // keep me for smaller diffs when something is added above
2902
+ } ) ;
2903
+
2904
+ cfg. skip_static ( move |name| ( name == "__dso_handle" ) ) ;
2905
+
2906
+ cfg. generate ( "../src/lib.rs" , "main.rs" ) ;
2907
+ }
2908
+
2657
2909
fn test_vxworks ( target : & str ) {
2658
2910
assert ! ( target. contains( "vxworks" ) ) ;
2659
2911
0 commit comments