192f3ab15Sopenharmony_ci#![allow(unused_macros)]
292f3ab15Sopenharmony_ci
392f3ab15Sopenharmony_ci// vendored from the cfg-if crate to avoid breaking ctest
492f3ab15Sopenharmony_cimacro_rules! cfg_if {
592f3ab15Sopenharmony_ci    // match if/else chains with a final `else`
692f3ab15Sopenharmony_ci    ($(
792f3ab15Sopenharmony_ci        if #[cfg($($meta:meta),*)] { $($it:item)* }
892f3ab15Sopenharmony_ci    ) else * else {
992f3ab15Sopenharmony_ci        $($it2:item)*
1092f3ab15Sopenharmony_ci    }) => {
1192f3ab15Sopenharmony_ci        cfg_if! {
1292f3ab15Sopenharmony_ci            @__items
1392f3ab15Sopenharmony_ci            () ;
1492f3ab15Sopenharmony_ci            $( ( ($($meta),*) ($($it)*) ), )*
1592f3ab15Sopenharmony_ci            ( () ($($it2)*) ),
1692f3ab15Sopenharmony_ci        }
1792f3ab15Sopenharmony_ci    };
1892f3ab15Sopenharmony_ci
1992f3ab15Sopenharmony_ci    // match if/else chains lacking a final `else`
2092f3ab15Sopenharmony_ci    (
2192f3ab15Sopenharmony_ci        if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
2292f3ab15Sopenharmony_ci        $(
2392f3ab15Sopenharmony_ci            else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
2492f3ab15Sopenharmony_ci        )*
2592f3ab15Sopenharmony_ci    ) => {
2692f3ab15Sopenharmony_ci        cfg_if! {
2792f3ab15Sopenharmony_ci            @__items
2892f3ab15Sopenharmony_ci            () ;
2992f3ab15Sopenharmony_ci            ( ($($i_met),*) ($($i_it)*) ),
3092f3ab15Sopenharmony_ci            $( ( ($($e_met),*) ($($e_it)*) ), )*
3192f3ab15Sopenharmony_ci            ( () () ),
3292f3ab15Sopenharmony_ci        }
3392f3ab15Sopenharmony_ci    };
3492f3ab15Sopenharmony_ci
3592f3ab15Sopenharmony_ci    // Internal and recursive macro to emit all the items
3692f3ab15Sopenharmony_ci    //
3792f3ab15Sopenharmony_ci    // Collects all the negated cfgs in a list at the beginning and after the
3892f3ab15Sopenharmony_ci    // semicolon is all the remaining items
3992f3ab15Sopenharmony_ci    (@__items ($($not:meta,)*) ; ) => {};
4092f3ab15Sopenharmony_ci    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => {
4192f3ab15Sopenharmony_ci        // Emit all items within one block, applying an appropriate #[cfg]. The
4292f3ab15Sopenharmony_ci        // #[cfg] will require all `$m` matchers specified and must also negate
4392f3ab15Sopenharmony_ci        // all previous matchers.
4492f3ab15Sopenharmony_ci        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
4592f3ab15Sopenharmony_ci
4692f3ab15Sopenharmony_ci        // Recurse to emit all other items in `$rest`, and when we do so add all
4792f3ab15Sopenharmony_ci        // our `$m` matchers to the list of `$not` matchers as future emissions
4892f3ab15Sopenharmony_ci        // will have to negate everything we just matched as well.
4992f3ab15Sopenharmony_ci        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
5092f3ab15Sopenharmony_ci    };
5192f3ab15Sopenharmony_ci
5292f3ab15Sopenharmony_ci    // Internal macro to Apply a cfg attribute to a list of items
5392f3ab15Sopenharmony_ci    (@__apply $m:meta, $($it:item)*) => {
5492f3ab15Sopenharmony_ci        $(#[$m] $it)*
5592f3ab15Sopenharmony_ci    };
5692f3ab15Sopenharmony_ci}
5792f3ab15Sopenharmony_ci
5892f3ab15Sopenharmony_cimacro_rules! stack {
5992f3ab15Sopenharmony_ci    ($t:ident) => {
6092f3ab15Sopenharmony_ci        cfg_if! {
6192f3ab15Sopenharmony_ci            if #[cfg(ossl110)] {
6292f3ab15Sopenharmony_ci                pub enum $t {}
6392f3ab15Sopenharmony_ci            } else {
6492f3ab15Sopenharmony_ci                #[repr(C)]
6592f3ab15Sopenharmony_ci                pub struct $t {
6692f3ab15Sopenharmony_ci                    pub stack: $crate::_STACK,
6792f3ab15Sopenharmony_ci                }
6892f3ab15Sopenharmony_ci            }
6992f3ab15Sopenharmony_ci        }
7092f3ab15Sopenharmony_ci    };
7192f3ab15Sopenharmony_ci}
7292f3ab15Sopenharmony_ci
7392f3ab15Sopenharmony_ci// openssl changes `*mut` to `*const` in certain parameters in certain versions;
7492f3ab15Sopenharmony_ci// in C this is ABI and (mostly) API compatible.
7592f3ab15Sopenharmony_ci//
7692f3ab15Sopenharmony_ci// We need to handle this explicitly, and this macro helps annotate which
7792f3ab15Sopenharmony_ci// parameter got converted in which version.
7892f3ab15Sopenharmony_ci//
7992f3ab15Sopenharmony_ci// Input is:
8092f3ab15Sopenharmony_ci//    extern "C" {
8192f3ab15Sopenharmony_ci//        #[attributes...]
8292f3ab15Sopenharmony_ci//        pub fn name(args) -> rettype; // `-> rettype` optional
8392f3ab15Sopenharmony_ci//        // more functions...
8492f3ab15Sopenharmony_ci//    }
8592f3ab15Sopenharmony_ci//
8692f3ab15Sopenharmony_ci// This macro replaces `#[const_ptr_if(...)]` in types with `*const` or `*mut`
8792f3ab15Sopenharmony_ci// (depending on the inner cfg flags)
8892f3ab15Sopenharmony_ci//
8992f3ab15Sopenharmony_ci// Walks through all argument and return types, but only finds inner types of
9092f3ab15Sopenharmony_ci// `*const` and `*mut`; doesn't walk arrays or generics.
9192f3ab15Sopenharmony_ci//
9292f3ab15Sopenharmony_ci// NOTE: can't abstract `pub` as `$fn_vis:vis`, as ctest macro handling doesn't
9392f3ab15Sopenharmony_ci// support it (old syntax crate). But we really only need `pub` anyway.
9492f3ab15Sopenharmony_ci//
9592f3ab15Sopenharmony_ci// NOTE: ctest seams to simply ignore macros it can't expand (whatever the
9692f3ab15Sopenharmony_ci// reason)
9792f3ab15Sopenharmony_cimacro_rules! const_ptr_api {
9892f3ab15Sopenharmony_ci    // ----------------------------------------------------------------
9992f3ab15Sopenharmony_ci    // (partialarg): partial argument, waiting for "final" argument type
10092f3ab15Sopenharmony_ci    // MAGIC PART 1: hande conditional const ptr in argument type
10192f3ab15Sopenharmony_ci    ( (partialarg)
10292f3ab15Sopenharmony_ci        { $(#[$fn_attr:meta])* pub fn $fn_name:ident }
10392f3ab15Sopenharmony_ci        $args_packed:tt
10492f3ab15Sopenharmony_ci        [ $($part_arg:tt)* ]
10592f3ab15Sopenharmony_ci        [ #[const_ptr_if( $($cfg:tt)* )] $($arg_rem:tt)* ]
10692f3ab15Sopenharmony_ci        $ret_packed:tt
10792f3ab15Sopenharmony_ci    ) => {
10892f3ab15Sopenharmony_ci        const_ptr_api!( (partialarg) { #[cfg($($cfg)*)]      $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_arg)* *const ] [ $($arg_rem)* ] $ret_packed );
10992f3ab15Sopenharmony_ci        const_ptr_api!( (partialarg) { #[cfg(not($($cfg)*))] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_arg)* *mut   ] [ $($arg_rem)* ] $ret_packed );
11092f3ab15Sopenharmony_ci    };
11192f3ab15Sopenharmony_ci    // continue partial argument with `*mut` pointer (might need special const handling in inner type)
11292f3ab15Sopenharmony_ci    ( (partialarg)
11392f3ab15Sopenharmony_ci        $def_packed:tt
11492f3ab15Sopenharmony_ci        $args_packed:tt
11592f3ab15Sopenharmony_ci        [ $($part_arg:tt)* ]
11692f3ab15Sopenharmony_ci        [ *mut $($arg_rem:tt)* ]
11792f3ab15Sopenharmony_ci        $ret_packed:tt
11892f3ab15Sopenharmony_ci    ) => {
11992f3ab15Sopenharmony_ci        const_ptr_api!( (partialarg) $def_packed $args_packed [ $($part_arg)* *mut ] [ $($arg_rem)* ] $ret_packed );
12092f3ab15Sopenharmony_ci    };
12192f3ab15Sopenharmony_ci    // continue partial argument with `*const` pointer (might need special const handling in inner type)
12292f3ab15Sopenharmony_ci    ( (partialarg)
12392f3ab15Sopenharmony_ci        $def_packed:tt
12492f3ab15Sopenharmony_ci        $args_packed:tt
12592f3ab15Sopenharmony_ci        [ $($part_arg:tt)* ]
12692f3ab15Sopenharmony_ci        [ *const $($arg_rem:tt)* ]
12792f3ab15Sopenharmony_ci        $ret_packed:tt
12892f3ab15Sopenharmony_ci    ) => {
12992f3ab15Sopenharmony_ci        const_ptr_api!( (partialarg) $def_packed $args_packed [ $($part_arg)* *const ] [ $($arg_rem)* ] $ret_packed );
13092f3ab15Sopenharmony_ci    };
13192f3ab15Sopenharmony_ci    // finish partial argument with trailing comma
13292f3ab15Sopenharmony_ci    ( (partialarg)
13392f3ab15Sopenharmony_ci        $def_packed:tt
13492f3ab15Sopenharmony_ci        { $($args_tt:tt)* }
13592f3ab15Sopenharmony_ci        [ $($part_arg:tt)* ]
13692f3ab15Sopenharmony_ci        [ $arg_ty:ty, $($arg_rem:tt)* ]
13792f3ab15Sopenharmony_ci        $ret_packed:tt
13892f3ab15Sopenharmony_ci    ) => {
13992f3ab15Sopenharmony_ci        const_ptr_api!( (parseargs) $def_packed { $($args_tt)* { $($part_arg)* $arg_ty } } [ $($arg_rem)* ] $ret_packed );
14092f3ab15Sopenharmony_ci    };
14192f3ab15Sopenharmony_ci    // finish final partial argument (no trailing comma)
14292f3ab15Sopenharmony_ci    ( (partialarg)
14392f3ab15Sopenharmony_ci        $def_packed:tt
14492f3ab15Sopenharmony_ci        { $($args_tt:tt)* }
14592f3ab15Sopenharmony_ci        [ $($part_arg:tt)* ]
14692f3ab15Sopenharmony_ci        [ $arg_ty:ty ]
14792f3ab15Sopenharmony_ci        $ret_packed:tt
14892f3ab15Sopenharmony_ci    ) => {
14992f3ab15Sopenharmony_ci        const_ptr_api!( (parseargs) $def_packed { $($args_tt)* { $($part_arg)* $arg_ty } } [ ] $ret_packed );
15092f3ab15Sopenharmony_ci    };
15192f3ab15Sopenharmony_ci
15292f3ab15Sopenharmony_ci    // ----------------------------------------------------------------
15392f3ab15Sopenharmony_ci    // (parseargs): parsing arguments
15492f3ab15Sopenharmony_ci    // start next argument
15592f3ab15Sopenharmony_ci    ( (parseargs)
15692f3ab15Sopenharmony_ci        $def_packed:tt
15792f3ab15Sopenharmony_ci        $args_packed:tt
15892f3ab15Sopenharmony_ci        [ $arg_name:ident : $($arg_rem:tt)* ]
15992f3ab15Sopenharmony_ci        $ret_packed:tt
16092f3ab15Sopenharmony_ci    ) => {
16192f3ab15Sopenharmony_ci        const_ptr_api!( (partialarg) $def_packed $args_packed [ $arg_name: ] [ $($arg_rem)* ] $ret_packed );
16292f3ab15Sopenharmony_ci    };
16392f3ab15Sopenharmony_ci    // end of arguments, there is a return type; start parsing it
16492f3ab15Sopenharmony_ci    ( (parseargs)
16592f3ab15Sopenharmony_ci        $def_packed:tt
16692f3ab15Sopenharmony_ci        $args_packed:tt
16792f3ab15Sopenharmony_ci        [ ]
16892f3ab15Sopenharmony_ci        [ -> $($rem:tt)* ]
16992f3ab15Sopenharmony_ci    ) => {
17092f3ab15Sopenharmony_ci        const_ptr_api!( (partialret) $def_packed $args_packed [] [ $($rem)* ] );
17192f3ab15Sopenharmony_ci    };
17292f3ab15Sopenharmony_ci    // end of arguments, no return type
17392f3ab15Sopenharmony_ci    ( (parseargs)
17492f3ab15Sopenharmony_ci        $def_packed:tt
17592f3ab15Sopenharmony_ci        $args_packed:tt
17692f3ab15Sopenharmony_ci        [ ]
17792f3ab15Sopenharmony_ci        [ ]
17892f3ab15Sopenharmony_ci    ) => {
17992f3ab15Sopenharmony_ci        const_ptr_api!( (generate) $def_packed $args_packed { () } );
18092f3ab15Sopenharmony_ci    };
18192f3ab15Sopenharmony_ci
18292f3ab15Sopenharmony_ci    // ----------------------------------------------------------------
18392f3ab15Sopenharmony_ci    // (partialret): have partial return type, waiting for final return type
18492f3ab15Sopenharmony_ci    // MAGIC PART 2: hande conditional const ptr in return type
18592f3ab15Sopenharmony_ci    ( (partialret)
18692f3ab15Sopenharmony_ci        { $(#[$fn_attr:meta])* pub fn $fn_name:ident }
18792f3ab15Sopenharmony_ci        $args_packed:tt
18892f3ab15Sopenharmony_ci        [ $($part_ret:tt)* ]
18992f3ab15Sopenharmony_ci        [ #[const_ptr_if( $($cfg:tt)* )] $($rem:tt)* ]
19092f3ab15Sopenharmony_ci    ) => {
19192f3ab15Sopenharmony_ci        const_ptr_api!( (partialret) { #[cfg($($cfg)*)]      $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_ret)* *const ] [ $($rem)* ] );
19292f3ab15Sopenharmony_ci        const_ptr_api!( (partialret) { #[cfg(not($($cfg)*))] $(#[$fn_attr])* pub fn $fn_name } $args_packed [ $($part_ret)* *mut   ] [ $($rem)* ] );
19392f3ab15Sopenharmony_ci    };
19492f3ab15Sopenharmony_ci    // `* mut` part in return type; continue parsing to find inner conditional const ptr
19592f3ab15Sopenharmony_ci    ( (partialret)
19692f3ab15Sopenharmony_ci        $def_packed:tt
19792f3ab15Sopenharmony_ci        $args_packed:tt
19892f3ab15Sopenharmony_ci        [ $($part_ret:tt)* ]
19992f3ab15Sopenharmony_ci        [ *mut $($rem:tt)* ]
20092f3ab15Sopenharmony_ci    ) => {
20192f3ab15Sopenharmony_ci        const_ptr_api!( (partialret) $def_packed $args_packed [ $($part_ret)* *mut ] [ $($rem)* ] );
20292f3ab15Sopenharmony_ci    };
20392f3ab15Sopenharmony_ci    // `* const` part in return type; continue parsing to find inner conditional const ptr
20492f3ab15Sopenharmony_ci    ( (partialret)
20592f3ab15Sopenharmony_ci        $def_packed:tt
20692f3ab15Sopenharmony_ci        $args_packed:tt
20792f3ab15Sopenharmony_ci        [ $($part_ret:tt)* ]
20892f3ab15Sopenharmony_ci        [ *const $($rem:tt)* ]
20992f3ab15Sopenharmony_ci    ) => {
21092f3ab15Sopenharmony_ci        const_ptr_api!( (partialret) $def_packed $args_packed [ $($part_ret)* *const ] [ $($rem)* ] );
21192f3ab15Sopenharmony_ci    };
21292f3ab15Sopenharmony_ci    // final part of return type
21392f3ab15Sopenharmony_ci    ( (partialret)
21492f3ab15Sopenharmony_ci        $def_packed:tt
21592f3ab15Sopenharmony_ci        $args_packed:tt
21692f3ab15Sopenharmony_ci        [ $($part_ret:tt)* ]
21792f3ab15Sopenharmony_ci        [ $ret_ty:ty ]
21892f3ab15Sopenharmony_ci    ) => {
21992f3ab15Sopenharmony_ci        const_ptr_api!( (generate) $def_packed $args_packed { $($part_ret)* $ret_ty } );
22092f3ab15Sopenharmony_ci    };
22192f3ab15Sopenharmony_ci
22292f3ab15Sopenharmony_ci    // ----------------------------------------------------------------
22392f3ab15Sopenharmony_ci    // generate
22492f3ab15Sopenharmony_ci    ( (generate)
22592f3ab15Sopenharmony_ci        { $(#[$fn_attr:meta])* pub fn $fn_name:ident }
22692f3ab15Sopenharmony_ci        { $({ $arg_name:ident: $($arg_ty:tt)* })* }
22792f3ab15Sopenharmony_ci        { $ret_ty:ty }
22892f3ab15Sopenharmony_ci    ) => {
22992f3ab15Sopenharmony_ci        extern "C" {
23092f3ab15Sopenharmony_ci            $(#[$fn_attr])*
23192f3ab15Sopenharmony_ci            pub fn $fn_name( $(
23292f3ab15Sopenharmony_ci                $arg_name: $($arg_ty)*
23392f3ab15Sopenharmony_ci            ),* ) -> $ret_ty;
23492f3ab15Sopenharmony_ci        }
23592f3ab15Sopenharmony_ci    };
23692f3ab15Sopenharmony_ci
23792f3ab15Sopenharmony_ci    // ----------------------------------------------------------------
23892f3ab15Sopenharmony_ci    // (fn): gather tokens for return type until ";"
23992f3ab15Sopenharmony_ci    // found end; start parsing current function, and parse remaining functions
24092f3ab15Sopenharmony_ci    ( (fn)
24192f3ab15Sopenharmony_ci        $def_packed:tt
24292f3ab15Sopenharmony_ci        $arg_tts_packed:tt
24392f3ab15Sopenharmony_ci        $ret_packed:tt
24492f3ab15Sopenharmony_ci        [ ; $($rem:tt)* ]
24592f3ab15Sopenharmony_ci    ) => {
24692f3ab15Sopenharmony_ci        const_ptr_api!( (parseargs) $def_packed {} $arg_tts_packed $ret_packed );
24792f3ab15Sopenharmony_ci        const_ptr_api!( (extern) [ $($rem)* ] );
24892f3ab15Sopenharmony_ci    };
24992f3ab15Sopenharmony_ci    // not ";" - all other tokens are part of the return type.
25092f3ab15Sopenharmony_ci    // don't expand return type yet; otherwise we'd have to remember in which branch `rem` needs
25192f3ab15Sopenharmony_ci    // to be used to parse further functions.
25292f3ab15Sopenharmony_ci    ( (fn)
25392f3ab15Sopenharmony_ci        $def_packed:tt
25492f3ab15Sopenharmony_ci        $arg_tts_packed:tt
25592f3ab15Sopenharmony_ci        [ $($ret_tt:tt)* ]
25692f3ab15Sopenharmony_ci        [ $tt:tt $($rem:tt)* ]
25792f3ab15Sopenharmony_ci    ) => {
25892f3ab15Sopenharmony_ci        const_ptr_api!( (fn) $def_packed $arg_tts_packed [ $($ret_tt)* $tt ] [ $($rem)* ] );
25992f3ab15Sopenharmony_ci    };
26092f3ab15Sopenharmony_ci
26192f3ab15Sopenharmony_ci    // ----------------------------------------------------------------
26292f3ab15Sopenharmony_ci    // (extern): in extern block, find next function
26392f3ab15Sopenharmony_ci    // try to split into functions as fast as possible to reduce recursion depth
26492f3ab15Sopenharmony_ci    ( (extern) [
26592f3ab15Sopenharmony_ci        $(#[$fn_attr:meta])*
26692f3ab15Sopenharmony_ci        pub fn $fn_name:ident( $($arg_rem:tt)* ) $($rem:tt)*
26792f3ab15Sopenharmony_ci    ] ) => {
26892f3ab15Sopenharmony_ci        const_ptr_api!( (fn)
26992f3ab15Sopenharmony_ci            { $(#[$fn_attr])* pub fn $fn_name } [ $($arg_rem)* ] [] [ $($rem)* ]
27092f3ab15Sopenharmony_ci        );
27192f3ab15Sopenharmony_ci    };
27292f3ab15Sopenharmony_ci    // end of extern block
27392f3ab15Sopenharmony_ci    ( (extern) [] ) => {};
27492f3ab15Sopenharmony_ci
27592f3ab15Sopenharmony_ci    // ----------------------------------------------------------------
27692f3ab15Sopenharmony_ci    // macro start; find extern block
27792f3ab15Sopenharmony_ci    ( extern "C" { $($rem:tt)* } ) => {
27892f3ab15Sopenharmony_ci        const_ptr_api!( (extern) [ $($rem)* ] );
27992f3ab15Sopenharmony_ci    };
28092f3ab15Sopenharmony_ci}
281