From 5a720f711e38ee8e474482f24d086f8a0deabe5c Mon Sep 17 00:00:00 2001
From: Mats Kindahl <mats@kindahl.net>
Date: Wed, 1 Jan 2025 14:15:51 +0100
Subject: [PATCH 3/7] Add meson build for coccicheck

This commit adds a run target `coccicheck` to meson build files.

Since ninja does not accept parameters the same way make does, there are three
run targets defined---"coccicheck-patch", "coccicheck-report", and
"coccicheck-context"---that you can use to generate a patch, get a report, and
get the context respectively. For example, to patch the tree from the "build"
subdirectory created by the meson run:

    ninja coccicheck-patch | patch -d .. -p1
---
 meson.build               | 30 ++++++++++++++++++++++++++++++
 meson_options.txt         |  7 ++++++-
 src/makefiles/meson.build |  6 ++++++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/meson.build b/meson.build
index d71c7c8267e..53543c6c50a 100644
--- a/meson.build
+++ b/meson.build
@@ -350,6 +350,7 @@ missing = find_program('config/missing', native: true)
 cp = find_program('cp', required: false, native: true)
 xmllint_bin = find_program(get_option('XMLLINT'), native: true, required: false)
 xsltproc_bin = find_program(get_option('XSLTPROC'), native: true, required: false)
+spatch = find_program(get_option('SPATCH'), native: true, required: false)
 
 bison_flags = []
 if bison.found()
@@ -1722,6 +1723,34 @@ else
 endif
 
 
+###############################################################
+# Option: Coccinelle checks
+###############################################################
+
+coccicheck_opt = get_option('coccicheck')
+coccicheck_dep = not_found_dep
+if not coccicheck_opt.disabled()
+  if spatch.found()
+    coccicheck_dep = declare_dependency()
+  elif coccicheck_opt.enabled()
+    error('missing required tools (spatch needed) for Coccinelle checks')
+  endif
+endif
+
+if coccicheck_opt.enabled()
+    coccicheck_modes = ['context', 'report', 'patch']
+    foreach mode : coccicheck_modes
+      run_target('coccicheck-' + mode,
+		 command: [python, files('src/tools/coccicheck.py'),
+			   '--mode', mode,
+			   '--spatch', spatch,
+			   '--patchdir', '@SOURCE_ROOT@',
+			   '@SOURCE_ROOT@/cocci/**/*.cocci',
+			   '@SOURCE_ROOT@/src',
+			   '@SOURCE_ROOT@/contrib',
+			  ])
+    endforeach
+endif
 
 ###############################################################
 # Compiler tests
@@ -3948,6 +3977,7 @@ summary(
   {
     'bison': '@0@ @1@'.format(bison.full_path(), bison_version),
     'dtrace': dtrace,
+    'spatch': spatch,
     'flex': '@0@ @1@'.format(flex.full_path(), flex_version),
   },
   section: 'Programs',
diff --git a/meson_options.txt b/meson_options.txt
index 06bf5627d3c..f9f1b919667 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -43,6 +43,9 @@ option('cassert', type: 'boolean', value: false,
 option('tap_tests', type: 'feature', value: 'auto',
   description: 'Enable TAP tests')
 
+option('coccicheck', type: 'feature', value: 'auto',
+       description: 'Enable Coccinelle checks')
+
 option('injection_points', type: 'boolean', value: false,
   description: 'Enable injection points')
 
@@ -52,7 +55,6 @@ option('PG_TEST_EXTRA', type: 'string', value: '',
 option('PG_GIT_REVISION', type: 'string', value: 'HEAD',
   description: 'git revision to be packaged by pgdist target')
 
-
 # Compilation options
 
 option('extra_include_dirs', type: 'array', value: [],
@@ -201,6 +203,9 @@ option('PYTHON', type: 'array', value: ['python3', 'python'],
 option('SED', type: 'string', value: 'gsed',
   description: 'Path to sed binary')
 
+option('SPATCH', type: 'string', value: 'spatch',
+  description: 'Path to spatch binary, used for SmPL patches')
+
 option('STRIP', type: 'string', value: 'strip',
   description: 'Path to strip binary, used for PGXS emulation')
 
diff --git a/src/makefiles/meson.build b/src/makefiles/meson.build
index 0def244c901..35616f524f2 100644
--- a/src/makefiles/meson.build
+++ b/src/makefiles/meson.build
@@ -57,6 +57,7 @@ pgxs_kv = {
   'enable_injection_points': get_option('injection_points') ? 'yes' : 'no',
   'enable_tap_tests': tap_tests_enabled ? 'yes' : 'no',
   'enable_debug': get_option('debug') ? 'yes' : 'no',
+  'enable_coccicheck': spatch.found() ? 'yes' : 'no',
   'enable_coverage': 'no',
   'enable_dtrace': dtrace.found() ? 'yes' : 'no',
 
@@ -149,6 +150,7 @@ pgxs_bins = {
   'TAR': tar,
   'ZSTD': program_zstd,
   'DTRACE': dtrace,
+  'SPATCH': spatch,
 }
 
 pgxs_empty = [
@@ -164,6 +166,10 @@ pgxs_empty = [
   'DBTOEPUB',
   'FOP',
 
+  # Coccinelle is not supported by pgxs
+  'SPATCH',
+  'SPFLAGS',
+  
   # supporting coverage for pgxs-in-meson build doesn't seem worth it
   'GENHTML',
   'LCOV',
-- 
2.43.0

