Coccinelle release 1.0.0-rc12
[bpt/coccinelle.git] / setup / cocci.m4
diff --git a/setup/cocci.m4 b/setup/cocci.m4
new file mode 100644 (file)
index 0000000..74fc281
--- /dev/null
@@ -0,0 +1,322 @@
+dnl
+dnl  autoconf helper macros for coccinelle
+dnl
+
+
+dnl  check if the ocaml version is recent enough
+dnl    $1: the variable to assign
+dnl    $2: version to test against
+AC_DEFUN([AC_CHECK_OCAMLVERSION],
+[dnl
+  AS_UNSET([versioncheck])
+  AC_MSG_CHECKING([that the OCaml version is at least $2])
+  AS_VERSION_COMPARE([$OCAMLVERSION],[$2],[versioncheck=no],[versioncheck=yes],[versioncheck=yes])
+  AC_MSG_RESULT([$versioncheck])
+  AC_SUBST([$1], [$versioncheck])
+])
+
+
+dnl  using ocamlfind to store into $1 the location where
+dnl  a package $2 resides.
+AC_DEFUN([AC_COCCI_OCAMLPKGDIR],
+[dnl
+  AC_SUBST(AS_TR_SH([PATH_$1]),[`$OCAMLFIND query $1 2>/dev/null`])
+])
+
+
+dnl  stores the result of checking for the
+dnl  ocaml package given as $2 in the
+dnl  variable given as $1
+AC_DEFUN([AC_COCCI_OCAMLPKG],
+[dnl
+  AC_CHECK_OCAML_PKG([$1])
+  AS_IF([test "x$[]AS_TR_SH([OCAML_PKG_$1])" != xno],[AC_COCCI_OCAMLPKGDIR([$1])])
+])
+
+dnl  requires that the ocaml package is installed.
+dnl  it is assumed that this package is part of the
+dnl  ocaml installation.
+AC_DEFUN([AC_REQ_COCCI_STDPKG],
+[dnl
+  AC_COCCI_OCAMLPKG([$1])
+  AS_IF([test "x$[]AS_TR_SH([OCAML_PKG_$1])" = xno],
+  [dnl
+    AC_MSG_ERROR([package $1 is required. It should be part of your ocaml installation.])
+  ])
+])
+
+
+dnl  defines the COCCI_OCAML_EXTERNAL variable to point to the directory
+dnl  with extra ocaml packages
+AC_DEFUN([AC_COCCI_SET_EXTERNAL_DIR],
+[dnl
+  AC_ARG_VAR(COCCI_OCAML_EXTERNAL, [path to extra ocaml packages (default: $1)])
+  AC_SUBST([COCCI_OCAML_EXTERNAL],["$1"])
+  AC_MSG_NOTICE([coccinelle may use external ocaml libraries in $COCCI_OCAML_EXTERNAL])
+])
+
+
+dnl  handle optional packages for which coccinelle may have
+dnl  local versions.
+dnl
+dnl  Note: this macro sets additional variables for use with
+dnl  'Makefile.config'.
+dnl
+dnl  variables:
+dnl    enable_$1: either 'yes', 'local', or 'no'
+AC_DEFUN([AC_CHECK_COCCI_EXTPKG],
+[dnl
+  AC_MSG_NOTICE([configuring package $1])
+  AC_ARG_ENABLE([$1], AS_HELP_STRING([--enable-$1], [enable global package $1 (yes,no) (default: auto)]))
+
+  dnl  try and find a globally installed version
+  dnl  if not, enable_$1 will be "no"
+  AS_IF([test "x$[]AS_TR_SH([enable_$1])" != xno],
+  [dnl
+    AC_COCCI_OCAMLPKG([$1])
+    AC_SUBST(AS_TR_SH([GLOBAL_$1]),[$[]AS_TR_SH([OCAML_PKG_$1])])
+
+    AS_IF([test "x$[]AS_TR_SH([GLOBAL_$1])" != xno],
+    [dnl  when the package is available
+      AC_SUBST(AS_TR_SH([enable_$1]),[yes])
+    ],
+    [dnl  when the package is not available
+      AS_IF([test "x$[]AS_TR_SH([enable_$1])" = xyes],
+      [dnl  when explicitly requested the global version
+        AC_MSG_ERROR([OCaml package $1 is not available but requested explicitly])
+      ])
+      AC_SUBST(AS_TR_SH([enable_$1]),[no])
+    ])
+  ])
+
+  dnl  check for a local package
+  AS_IF([test "x$AS_TR_SH([enable_$1])" = xno],
+  [dnl
+    AS_UNSET([pkgdir])
+    pkgdir="$COCCI_OCAML_EXTERNAL/$1/"
+    AC_MSG_CHECKING([for a bundled substitute of $1])
+    AS_IF([test -d "$pkgdir"],
+    [dnl
+      AC_MSG_RESULT([yes])
+      AC_MSG_NOTICE([using bundled substitute for $1 in $pkgdir])
+      AC_SUBST(AS_TR_SH([enable_$1]), [local])
+      AC_SUBST(AS_TR_SH([PATH_$1]), ["$pkgdir"])
+    ],
+    [AC_MSG_RESULT([not available])])
+  ])
+
+  dnl  additional handling
+  AS_IF([test "x$[]AS_TR_SH([enable_$1])" != xno],
+  [dnl
+    AC_SUBST(AS_TR_SH([FEATURE_$1]),[1])
+    AC_SUBST(AS_TR_SH([FLAGS_$1]),['$([]AS_TR_SH([FLAGS_$1]))'])
+
+    dnl  distinguish global/local
+    AS_IF([test "x$[]AS_TR_SH([enable_$1])" = xlocal],
+    [dnl
+      AC_SUBST(AS_TR_SH([LOCALLIB_$1]),[1])
+      AC_SUBST(AS_TR_SH([MODULES_$1]),['$(AS_TR_SH([LOCAL_$1]))'])
+      AC_SUBST(AS_TR_SH([MODULESOPT_$1]),['$(AS_TR_SH([LOCALOPT_$1]))'])
+
+      dnl check if the local directory has a Makefile
+      AS_IF([test -f "$[]AS_TR_SH([PATH_$1])/Makefile"],
+      [dnl
+        AC_SUBST(AS_TR_SH([MAKE_$1]),[$[]AS_TR_SH([PATH_$1])])
+      ],
+      [dnl
+        AC_SUBST(AS_TR_SH([MAKE_$1]),[ ])
+      ])
+    ],
+    [dnl
+      AC_SUBST(AS_TR_SH([MODULES_$1]),['$(AS_TR_SH([GLOBAL_$1]))'])
+      AC_SUBST(AS_TR_SH([MODULESOPT_$1]),['$(AS_TR_SH([GLOBALOPT_$1]))'])
+    ])
+  ])
+])
+
+
+dnl  initializes the defaults substitutions for
+dnl  configuration variables of packages
+AC_DEFUN([AC_COCCI_INIT_PKG_EMPTY],
+[dnl
+  AC_SUBST(AS_TR_SH([FEATURE_$1]), [0])
+  AC_SUBST(AS_TR_SH([LOCALLIB_$1]), [0])
+  AC_SUBST(AS_TR_SH([FLAGS_$1]), [ ])
+  AC_SUBST(AS_TR_SH([MODULES_$1]), [ ])
+  AC_SUBST(AS_TR_SH([MODULESOPT_$1]), [ ])
+  AC_SUBST(AS_TR_SH([PATH_$1]), [ ])
+])
+
+
+dnl  version of AC_CHECK_COCCI_EXTPKG that fails with an
+dnl  error if the package could not be found and no local
+dnl  substitute is available.
+AC_DEFUN([AC_REQ_COCCI_EXTPKG],
+[dnl
+  AC_CHECK_COCCI_EXTPKG([$1])
+  AS_IF([test "x$[]AS_TR_SH([enable_$1])" = xno],
+  [dnl
+    AC_MSG_ERROR([OCaml package $1 is required. Please make sure it is available.])
+  ])
+])
+
+
+dnl  determine python version
+AC_ARG_VAR([PYVER], [python version])
+AC_DEFUN([AC_COCCI_PYVER],
+[dnl
+  AS_IF([test -z "$PYVER"],
+  [dnl  PYVER not set before, determine it
+    AC_COCCI_TOOL([PYTHON],[python],[])
+
+    AS_IF([test "x$PYTHON" = xno -a -n "$with_python" -a "x$with_python" != xyes],
+    [dnl  python interpreter not found, but perhaps it was a version
+      AC_MSG_NOTICE([$1 is not a found as tool, therefore interpreted as version])
+      AC_SUBST([PYVER],["$1"])
+    ])
+
+    AS_IF([test "x$PYTHON" != xno],
+    [dnl  python interpereter found
+      AC_MSG_CHECKING([python version])
+      PYVER=`$PYTHON -c "import sys; print(sys.version[[:3]])"`
+      AS_IF([test -n "$PYVER"],[AC_MSG_RESULT([$PYVER found])],[AC_MSG_RESULT([failed])])
+      AC_SUBST([PYVER])
+    ])
+  ],
+  [dnl  PYVER set before
+    AC_MSG_NOTICE([python version assumed to be $PYVER])
+  ])
+])
+
+
+dnl  determine version date (RTC format)
+AC_DEFUN([AC_COCCI_CONFVERSION],
+[dnl
+  AC_SUBST([CONFVERSION])
+  AC_MSG_NOTICE([determining version suffix])
+
+  AS_IF([test -z "$CONFVERSION" -a -d "./.git"],
+  [dnl  git administration found
+    AC_MSG_NOTICE([building a version from a git repository])
+    AC_PATH_TOOL([GIT],[git])
+    AS_IF([test -n "$GIT"],
+    [dnl  ask git
+      CONFVERSION=`$GIT log -1 --date-order --date=rfc --pretty="format:%cd"`
+    ])
+  ])
+
+  AS_IF([test -z "$CONFVERSION"],
+  [dnl  otherwise, take the current date
+    AC_PATH_TOOL([DATE],[date])
+    AS_IF([test -n "$DATE"],
+    [dnl
+      CONFVERSION=`$DATE "+%a, %d %b %Y %H:%M:%S %z"`
+    ])
+  ])
+
+  AS_IF([test -z "$CONFVERSION"],
+  [dnl  fallback
+    CONFVERSION=unknown
+  ])
+
+  AC_MSG_NOTICE([version suffix set to $CONFVERSION])
+])
+
+
+dnl  find a tool, with specialized macros for certain cases
+dnl  $1: name of the variable
+dnl  $2: name of the tool
+AC_DEFUN([AC_COCCI_FINDTOOL],
+[dnl
+  AS_IF([test "x$2" = xpkg-config -a "x$1" = xPKG_CONFIG],
+  [dnl  specialized macro for pkg-config (from pkg-config m4 macros)
+    PKG_PROG_PKG_CONFIG
+  ], [test "x$2" = xocamllex -a "x$1" = xOCAMLLEX],
+  [dnl  specialized macro for ocamllex (from ocaml.m4)
+    AC_PROG_OCAMLLEX
+  ], [test "x$2" = xocamlyacc -a "x$1" = xOCAMLYACC],
+  [dnl  specialized macro for ocamlyacc (from ocaml.m4)
+    AC_PROG_OCAMLYACC
+  ],
+  [dnl  generic macro
+    AC_PATH_TOOL([$1], [$2])
+  ])
+])
+
+dnl  find/override a particular tool
+dnl  $1: var name
+dnl  $2: prog name
+dnl  $3: path to substitute (or empty)
+AC_DEFUN([AC_COCCI_TOOL],
+[dnl
+  AC_ARG_VAR([$1], [path to $2])
+  AC_ARG_WITH([$2], [AS_HELP_STRING([--with-$2], [whether/which $2 to use (default: auto)])])
+  AC_SUBST([with_$1],["$with_[]AS_TR_SH([$2])"])
+
+  dnl  explicit tool or command given
+  AS_IF([test -n "$with_[]$1" -a "x$with_[]$1" != xno -a "x$with_[]$1" != xyes],
+  [dnl  custom $with_$1 given
+    AC_SUBST([$1], ["$with_[]$1"])
+  ])
+
+  dnl  searches for the tool (result either empty or 'no' if not found)
+  AS_IF([test "x$with_$1" != xno],
+  [dnl  find the tool
+    AC_COCCI_FINDTOOL([$1],[$2])
+  ])
+
+  AS_IF([test -z "[$]$1" -o "x[$]$1" = xno],
+  [dnl  command not found
+    AS_IF([test "x$with_$1" = xyes],
+    [dnl  abort if a command was given explicitly
+      AC_MSG_ERROR([--with=$2 is given explicitly but not found])
+    ])
+
+    AS_IF([test -n "$3"],
+    [dnl  try substitute
+      AC_MSG_NOTICE([$2 not found. Trying substitute $3.])
+      AC_SUBST([$1],["$3"])
+      AC_COCCI_FINDTOOL([$1],[$2])
+      AC_SUBST([SUBSTITUTED_$1], [yes])
+    ])
+  ])
+
+  dnl  $1 will always be defined at the exit of this macro
+  AS_IF([test -z "[$]$1"],[AC_SUBST([$1],[no])])
+])
+
+
+dnl  defines a $1_CMD with $1 if set to a tool, otherwise
+dnl  takes $2
+AC_DEFUN([AC_COCCI_RUNTIME_CMD],
+[dnl
+  AC_ARG_VAR([RUNTIME_$1_CMD], [path to $2])
+  AC_ARG_WITH([runtime-$2], [AS_HELP_STRING([--with-runtime-$2], [override the runtime cmd for $2])])
+  
+  AS_IF([test -z "$RUNTIME_$1_CMD"],
+  [dnl  variable not yet set
+    AS_IF([test "x$with_runtime_[]AS_TR_SH([$2])" = xno],
+    [dnl  with_runtime_$2 set to no: use configured with_$2
+      AC_SUBST([RUNTIME_$1_CMD],[$][$1])
+    ], [test -n "$with_runtime_[]AS_TR_SH([$2])" -a "x$with_runtime_[]AS_TR_SH([$2])" != xyes],
+    [dnl  explicit with_runtime_$2 parameter given: use that as default
+      AC_SUBST([RUNTIME_$1_CMD],["$with_runtime_[]AS_TR_SH([$2])"])
+    ],
+    [dnl  otherwise, use $2
+      AC_SUBST([RUNTIME_$1_CMD],["$2"])
+    ])
+  ])
+])
+
+
+AC_DEFUN([AC_COCCI_YESNO],
+[dnl
+  AC_PATH_TOOL([YES], [yes])
+  AS_IF([test -n "$YES" -a "x$YES" != xno],
+  [dnl
+    AC_SUBST([YES_N_CMD],["$YES n"])
+  ],
+  [dnl
+    AC_SUBST([YES_N_CMD],["echo -e 'n\nn'"])
+  ])
+])