aboutsummaryrefslogtreecommitdiff
path: root/m4/mhd_check_func.m4
blob: 502a9b15b2b1e5f753a42974bf188dfa5f5d6ddc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# SYNOPSIS
#
#   MHD_CHECK_FUNC([FUNCTION_NAME],
#                  [INCLUDES=AC_INCLUDES_DEFAULT], [CHECK_CODE],
#                  [ACTION-IF-AVAILABLE], [ACTION-IF-NOT-AVAILABLE],
#                  [ADDITIONAL_LIBS])
#
# DESCRIPTION
#
#   This macro checks for presence of specific function by including
#   specified headers and compiling and linking CHECK_CODE.
#   This check both declaration and presence in library.
#   Unlike AC_CHECK_FUNCS macro, this macro do not produce false
#   negative result if function is declared with specific calling
#   conventions like __stdcall' or attribute like
#   __attribute__((__dllimport__)) and linker failed to build test
#   program if library contains function with calling conventions
#   different from declared. 
#   By using definition from provided headers, this macro ensures that
#   correct calling convention is used for detection.
#
#   Example usage:
#
#     MHD_CHECK_FUNC([memmem],
#                    [[#include <string.h>]],
#                    [const void *ptr = memmem("aa", 2, "a", 1); (void)ptr;],
#                    [var_use_memmem='yes'], [var_use_memmem='no'])
#
#   Defined cache variable used in check so if any test will not work
#   correctly on some platform, user may simply fix it by giving cache
#   variable in configure parameters, for example:
#
#     ./configure mhd_cv_func_memmem_have=no
#
#   This simplify building from source on exotic platforms as patching
#   of configure.ac is not required to change results of tests.
#
# LICENSE
#
#   Copyright (c) 2019-2023 Karlson2k (Evgeny Grin) <k2k@narod.ru>
#
#   Copying and distribution of this file, with or without modification, are
#   permitted in any medium without royalty provided the copyright notice
#   and this notice are preserved. This file is offered as-is, without any
#   warranty.

#serial 4

AC_DEFUN([MHD_CHECK_FUNC],[dnl
  AC_PREREQ([2.64])dnl for AS_VAR_IF, m4_ifblank, m4_ifnblank
  m4_ifblank(m4_translit([$1],[()],[  ]), [m4_fatal([First macro argument must not be empty])])dnl
  m4_ifblank([$3], [m4_fatal([Third macro argument must not be empty])])dnl
  m4_bmatch(m4_normalize([$1]), [\s],dnl
            [m4_fatal([First macro argument must not contain whitespaces])])dnl
  m4_if(m4_index([$3], m4_normalize(m4_translit([$1],[()],[  ]))), [-1], dnl
        [m4_fatal([CHECK_CODE parameter (third macro argument) does not contain ']m4_normalize([$1])[' token])])dnl
  AS_VAR_PUSHDEF([cv_Var], [mhd_cv_func_]m4_bpatsubst(_mhd_norm_expd(m4_translit([$1],[()],[  ])),[[^a-zA-Z0-9]],[_]))dnl
  dnl
  AC_CACHE_CHECK([for function $1], cv_Var,
    [dnl
      m4_ifnblank([$6],[dnl
        mhd_check_func_SAVE_LIBS="$LIBS"
        LIBS="$LIBS _mhd_norm_expd([$6])"
      ])dnl
      AC_LINK_IFELSE(
        [AC_LANG_SOURCE([
m4_default_nblank([$2],[AC_INCLUDES_DEFAULT])

int main(void)
{

  $3

  return 0;
}
          ])
        ],
        [AS_VAR_SET([cv_Var],["yes"])], [AS_VAR_SET([cv_Var],["no"])] ) 
      m4_ifnblank([$6],[dnl
        LIBS="${mhd_check_func_SAVE_LIBS}"
        AS_UNSET([mhd_check_func_SAVE_LIBS])
      ])dnl
    ])
  AS_VAR_IF([cv_Var], ["yes"],
            [AC_DEFINE([[HAVE_]]m4_bpatsubst(m4_toupper(_mhd_norm_expd(m4_translit([$1],[()],[  ]))),[[^A-Z0-9]],[_]),
                       [1], [Define to 1 if you have the ']_mhd_norm_expd(m4_translit([$1],[()],[  ]))[' function.])
            m4_n([$4])dnl
            ], [$5])
  AS_VAR_POPDEF([cv_Var])dnl
])