summaryrefslogtreecommitdiffstats
path: root/coccinelle
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 13:00:47 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 13:00:47 +0000
commit2cb7e0aaedad73b076ea18c6900b0e86c5760d79 (patch)
treeda68ca54bb79f4080079bf0828acda937593a4e1 /coccinelle
parentInitial commit. (diff)
downloadsystemd-2cb7e0aaedad73b076ea18c6900b0e86c5760d79.tar.xz
systemd-2cb7e0aaedad73b076ea18c6900b0e86c5760d79.zip
Adding upstream version 247.3.upstream/247.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'coccinelle')
-rw-r--r--coccinelle/bool-cast.cocci12
-rw-r--r--coccinelle/close-above-stdio.cocci36
-rw-r--r--coccinelle/cmp.cocci28
-rw-r--r--coccinelle/const-strlen.disabled14
-rw-r--r--coccinelle/debug-logging.cocci16
-rw-r--r--coccinelle/div-round-up.cocci20
-rw-r--r--coccinelle/dup-fcntl.cocci7
-rw-r--r--coccinelle/empty-or-dash.cocci5
-rw-r--r--coccinelle/empty-or-root.cocci10
-rw-r--r--coccinelle/empty-to-null.cocci8
-rw-r--r--coccinelle/empty-to-root.cocci16
-rw-r--r--coccinelle/enotsup.cocci4
-rw-r--r--coccinelle/equals-null.cocci29
-rw-r--r--coccinelle/errno-check.cocci10
-rw-r--r--coccinelle/errno.cocci41
-rw-r--r--coccinelle/exit-0.cocci16
-rw-r--r--coccinelle/flags-set.cocci22
-rw-r--r--coccinelle/fopen-unlocked.cocci71
-rw-r--r--coccinelle/free_and_replace.cocci15
-rw-r--r--coccinelle/hashmap_free.cocci54
-rw-r--r--coccinelle/htonl.cocci20
-rw-r--r--coccinelle/in_set.cocci25
-rw-r--r--coccinelle/iovec-make.cocci29
-rw-r--r--coccinelle/isempty.cocci42
-rw-r--r--coccinelle/log-json.cocci8
-rw-r--r--coccinelle/macros.h231
-rw-r--r--coccinelle/malloc_multiply.cocci20
-rw-r--r--coccinelle/memzero.cocci38
-rw-r--r--coccinelle/mfree.cocci6
-rw-r--r--coccinelle/mfree_return.cocci8
-rw-r--r--coccinelle/no-if-assignments.cocci20
-rw-r--r--coccinelle/not_in_set.cocci23
-rw-r--r--coccinelle/o-ndelay.cocci4
-rw-r--r--coccinelle/reallocarray.cocci20
-rw-r--r--coccinelle/redundant-if.cocci54
-rwxr-xr-xcoccinelle/run-coccinelle.sh42
-rw-r--r--coccinelle/safe_close-no-if.cocci7
-rw-r--r--coccinelle/safe_close.cocci18
-rw-r--r--coccinelle/safe_closedir.cocci27
-rw-r--r--coccinelle/safe_fclose.cocci27
-rw-r--r--coccinelle/sd_event_source_disable_unref.cocci36
-rw-r--r--coccinelle/set_ensure_put.cocci18
-rw-r--r--coccinelle/strempty.cocci72
-rw-r--r--coccinelle/strjoin.cocci15
-rw-r--r--coccinelle/strjoina.cocci6
-rw-r--r--coccinelle/strv_free.cocci27
-rw-r--r--coccinelle/swap-two.cocci7
-rw-r--r--coccinelle/synthetic-errno.cocci48
-rw-r--r--coccinelle/take-fd.cocci21
-rw-r--r--coccinelle/take-ptr.cocci14
-rw-r--r--coccinelle/while-true.cocci12
-rw-r--r--coccinelle/xsprintf.cocci7
-rw-r--r--coccinelle/zz-drop-braces.cocci27
53 files changed, 1413 insertions, 0 deletions
diff --git a/coccinelle/bool-cast.cocci b/coccinelle/bool-cast.cocci
new file mode 100644
index 0000000..051ccb9
--- /dev/null
+++ b/coccinelle/bool-cast.cocci
@@ -0,0 +1,12 @@
+@@
+bool b;
+expression y;
+@@
+- b = !!(y);
++ b = y;
+@@
+bool b;
+expression y;
+@@
+- b = !!y;
++ b = y;
diff --git a/coccinelle/close-above-stdio.cocci b/coccinelle/close-above-stdio.cocci
new file mode 100644
index 0000000..44b3b1c
--- /dev/null
+++ b/coccinelle/close-above-stdio.cocci
@@ -0,0 +1,36 @@
+@@
+expression fd;
+@@
+- if (fd > 2)
+- safe_close(fd);
++ safe_close_above_stdio(fd);
+@@
+expression fd;
+@@
+- if (fd > 2)
+- fd = safe_close(fd);
++ fd = safe_close_above_stdio(fd);
+@@
+expression fd;
+@@
+- if (fd >= 3)
+- safe_close(fd);
++ safe_close_above_stdio(fd);
+@@
+expression fd;
+@@
+- if (fd >= 3)
+- fd = safe_close(fd);
++ fd = safe_close_above_stdio(fd);
+@@
+expression fd;
+@@
+- if (fd > STDERR_FILENO)
+- safe_close(fd);
++ safe_close_above_stdio(fd);
+@@
+expression fd;
+@@
+- if (fd > STDERR_FILENO)
+- fd = safe_close(fd);
++ fd = safe_close_above_stdio(fd);
diff --git a/coccinelle/cmp.cocci b/coccinelle/cmp.cocci
new file mode 100644
index 0000000..a34cbe5
--- /dev/null
+++ b/coccinelle/cmp.cocci
@@ -0,0 +1,28 @@
+@@
+expression x, y;
+@@
+- if (x < y)
+- return -1;
+- if (x > y)
+- return 1;
+- return 0;
++ return CMP(x, y);
+@@
+expression x, y;
+@@
+- if (x < y)
+- return -1;
+- else if (x > y)
+- return 1;
+- return 0;
++ return CMP(x, y);
+@@
+expression x, y;
+@@
+- if (x < y)
+- return -1;
+- else if (x > y)
+- return 1;
+- else
+- return 0;
++ return CMP(x, y);
diff --git a/coccinelle/const-strlen.disabled b/coccinelle/const-strlen.disabled
new file mode 100644
index 0000000..30a6e5a
--- /dev/null
+++ b/coccinelle/const-strlen.disabled
@@ -0,0 +1,14 @@
+@@
+constant s;
+@@
+(
+#define STRLEN
+&
+- sizeof(s)-1
++ STRLEN(s)
+)
+@@
+constant s;
+@@
+- strlen(s)
++ STRLEN(s)
diff --git a/coccinelle/debug-logging.cocci b/coccinelle/debug-logging.cocci
new file mode 100644
index 0000000..a679dab
--- /dev/null
+++ b/coccinelle/debug-logging.cocci
@@ -0,0 +1,16 @@
+@@
+@@
+(
+#define DEBUG_LOGGING
+&
+- _unlikely_(log_get_max_level() >= LOG_DEBUG)
++ DEBUG_LOGGING
+)
+@@
+@@
+(
+#define DEBUG_LOGGING
+&
+- log_get_max_level() >= LOG_DEBUG
++ DEBUG_LOGGING
+)
diff --git a/coccinelle/div-round-up.cocci b/coccinelle/div-round-up.cocci
new file mode 100644
index 0000000..a0c6df9
--- /dev/null
+++ b/coccinelle/div-round-up.cocci
@@ -0,0 +1,20 @@
+@@
+expression x, y;
+@@
+- ((x + y - 1) / y)
++ DIV_ROUND_UP(x, y)
+@@
+expression x, y;
+@@
+- ((x + (y - 1)) / y)
++ DIV_ROUND_UP(x, y)
+@@
+expression x, y;
+@@
+- (x + y - 1) / y
++ DIV_ROUND_UP(x, y)
+@@
+expression x, y;
+@@
+- (x + (y - 1)) / y
++ DIV_ROUND_UP(x, y)
diff --git a/coccinelle/dup-fcntl.cocci b/coccinelle/dup-fcntl.cocci
new file mode 100644
index 0000000..8b133b3
--- /dev/null
+++ b/coccinelle/dup-fcntl.cocci
@@ -0,0 +1,7 @@
+@@
+/* We want to stick with dup() in test-fd-util.c */
+position p : script:python() { p[0].file != "src/test/test-fd-util.c" };
+expression fd;
+@@
+- dup@p(fd)
++ fcntl(fd, F_DUPFD, 3)
diff --git a/coccinelle/empty-or-dash.cocci b/coccinelle/empty-or-dash.cocci
new file mode 100644
index 0000000..bebaead
--- /dev/null
+++ b/coccinelle/empty-or-dash.cocci
@@ -0,0 +1,5 @@
+@@
+expression s;
+@@
+- (isempty(s) || streq(s, "-"))
++ empty_or_dash(s)
diff --git a/coccinelle/empty-or-root.cocci b/coccinelle/empty-or-root.cocci
new file mode 100644
index 0000000..bf2f614
--- /dev/null
+++ b/coccinelle/empty-or-root.cocci
@@ -0,0 +1,10 @@
+@@
+expression s;
+@@
+- (isempty(s) || path_equal(s, "/"))
++ empty_or_root(s)
+@@
+expression s;
+@@
+- (!isempty(s) && !path_equal(s, "/"))
++ !empty_or_root(s)
diff --git a/coccinelle/empty-to-null.cocci b/coccinelle/empty-to-null.cocci
new file mode 100644
index 0000000..bc6c656
--- /dev/null
+++ b/coccinelle/empty-to-null.cocci
@@ -0,0 +1,8 @@
+@@
+/* Avoid running this transformation on the empty_to_null function itself */
+position p : script:python() { p[0].current_element != "empty_to_null" };
+expression s;
+@@
+
+- isempty@p(s) ? NULL : s
++ empty_to_null(s)
diff --git a/coccinelle/empty-to-root.cocci b/coccinelle/empty-to-root.cocci
new file mode 100644
index 0000000..3720497
--- /dev/null
+++ b/coccinelle/empty-to-root.cocci
@@ -0,0 +1,16 @@
+@@
+expression s;
+@@
+- if (empty_or_root(s))
+- s = "/";
++ s = empty_to_root(s);
+@@
+expression s;
+@@
+- (empty_or_root(s) ? "/" : s)
++ empty_to_root(s)
+@@
+expression s;
+@@
+- (s ? s : "/")
++ empty_to_root(s)
diff --git a/coccinelle/enotsup.cocci b/coccinelle/enotsup.cocci
new file mode 100644
index 0000000..c65734d
--- /dev/null
+++ b/coccinelle/enotsup.cocci
@@ -0,0 +1,4 @@
+@@
+@@
+- ENOTSUP
++ EOPNOTSUPP
diff --git a/coccinelle/equals-null.cocci b/coccinelle/equals-null.cocci
new file mode 100644
index 0000000..3fce0f4
--- /dev/null
+++ b/coccinelle/equals-null.cocci
@@ -0,0 +1,29 @@
+@@
+expression e;
+statement s;
+@@
+if (
+(
+!e
+|
+- e == NULL
++ !e
+)
+ )
+ {...}
+else s
+
+@@
+expression e;
+statement s;
+@@
+if (
+(
+e
+|
+- e != NULL
++ e
+)
+ )
+ {...}
+else s
diff --git a/coccinelle/errno-check.cocci b/coccinelle/errno-check.cocci
new file mode 100644
index 0000000..709cb4a
--- /dev/null
+++ b/coccinelle/errno-check.cocci
@@ -0,0 +1,10 @@
+@@
+constant c;
+@@
+(
+- errno == -c
++ errno == c
+|
+- errno != -c
++ errno != c
+)
diff --git a/coccinelle/errno.cocci b/coccinelle/errno.cocci
new file mode 100644
index 0000000..c928266
--- /dev/null
+++ b/coccinelle/errno.cocci
@@ -0,0 +1,41 @@
+@@
+identifier log_LEVEL_errno =~ "^log_(debug|info|notice|warning|error|emergency)_errno$";
+local idexpression r;
+expression e;
+@@
+- r = -e;
++ r =
+ log_LEVEL_errno(e, ...);
+@@
+identifier log_LEVEL_errno =~ "^log_(debug|info|notice|warning|error|emergency)_errno$";
+local idexpression r;
+expression e;
+@@
++ r =
+ log_LEVEL_errno(e, ...);
+- r = -e;
+@@
+identifier log_LEVEL_errno =~ "^log_(debug|info|notice|warning|error|emergency)_errno$";
+local idexpression r;
+expression e;
+@@
+- r =
++ return
+ log_LEVEL_errno(e, ...);
+- return r;
+@@
+identifier log_LEVEL_errno =~ "^log_(debug|info|notice|warning|error|emergency)_errno$";
+expression e;
+@@
++ return
+ log_LEVEL_errno(e, ...);
+- return -e;
+@@
+identifier log_LEVEL_errno =~ "^log_(debug|info|notice|warning|error|emergency)_errno$";
+expression list args;
+expression e;
+local idexpression r;
+@@
+- log_LEVEL_errno(e, args);
+- r = e;
++ r = log_LEVEL_errno(e, args);
diff --git a/coccinelle/exit-0.cocci b/coccinelle/exit-0.cocci
new file mode 100644
index 0000000..8b81600
--- /dev/null
+++ b/coccinelle/exit-0.cocci
@@ -0,0 +1,16 @@
+@@
+@@
+- exit(0);
++ exit(EXIT_SUCCESS);
+@@
+@@
+- _exit(0);
++ _exit(EXIT_SUCCESS);
+@@
+@@
+- exit(1);
++ exit(EXIT_FAILURE);
+@@
+@@
+- _exit(1);
++ _exit(EXIT_FAILURE);
diff --git a/coccinelle/flags-set.cocci b/coccinelle/flags-set.cocci
new file mode 100644
index 0000000..f6cc8ba
--- /dev/null
+++ b/coccinelle/flags-set.cocci
@@ -0,0 +1,22 @@
+@@
+/* Disable this transformation in cases where it doesn't make sense or
+ * where it makes the resulting expression more confusing
+ */
+position p : script:python() {
+ not (p[0].file == "src/shared/securebits-util.h" or
+ p[0].file == "src/core/manager.h" or
+ p[0].current_element == "log_set_max_level_realm" or
+ p[0].current_element == "unichar_is_valid")
+ };
+expression x, y;
+@@
+(
+- ((x@p) & (y)) == (y)
++ FLAGS_SET(x, y)
+|
+- (x@p & (y)) == (y)
++ FLAGS_SET(x, y)
+|
+- ((x@p) & y) == y
++ FLAGS_SET(x, y)
+)
diff --git a/coccinelle/fopen-unlocked.cocci b/coccinelle/fopen-unlocked.cocci
new file mode 100644
index 0000000..7870f8c
--- /dev/null
+++ b/coccinelle/fopen-unlocked.cocci
@@ -0,0 +1,71 @@
+@@
+expression f, path, options;
+@@
+- f = fopen(path, options);
+- if (!f)
+- return -errno;
+- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
++ r = fopen_unlocked(path, options, &f);
++ if (r < 0)
++ return r;
+@@
+expression f, path, options;
+@@
+- f = fopen(path, options);
+- if (!f) {
+- if (errno == ENOENT)
+- return -ESRCH;
+- return -errno;
+- }
+- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
++ r = fopen_unlocked(path, options, &f);
++ if (r == -ENOENT)
++ return -ESRCH;
++ if (r < 0)
++ return r;
+@@
+expression f, path, options;
+@@
+- f = fopen(path, options);
+- if (!f)
+- return errno == ENOENT ? -ESRCH : -errno;
+- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
++ r = fopen_unlocked(path, options, &f);
++ if (r == -ENOENT)
++ return -ESRCH;
++ if (r < 0)
++ return r;
+@@
+expression f, path, p;
+@@
+ r = fopen_temporary(path, &f, &p);
+ if (r < 0)
+ return ...;
+- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+@@
+expression f, g, path, p;
+@@
+ r = fopen_temporary_label(path, g, &f, &p);
+ if (r < 0)
+ return ...;
+- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+@@
+expression f, fd, options;
+@@
+- f = fdopen(fd, options);
++ r = fdopen_unlocked(fd, options, &f);
++ if (r < 0) {
+- if (!f) {
+ ...
+- return -errno;
++ return r;
+ }
+- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
+@@
+expression f, buf, sz;
+@@
+- f = open_memstream(&buf, &sz);
++ f = open_memstream_unlocked(&buf, &sz);
+ if (!f)
+ return ...;
+- (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
diff --git a/coccinelle/free_and_replace.cocci b/coccinelle/free_and_replace.cocci
new file mode 100644
index 0000000..9dcdbf4
--- /dev/null
+++ b/coccinelle/free_and_replace.cocci
@@ -0,0 +1,15 @@
+@@
+expression p, q;
+@@
+- free(p);
+- p = q;
+- q = NULL;
+- return 0;
++ return free_and_replace(p, q);
+@@
+expression p, q;
+@@
+- free(p);
+- p = q;
+- q = NULL;
++ free_and_replace(p, q);
diff --git a/coccinelle/hashmap_free.cocci b/coccinelle/hashmap_free.cocci
new file mode 100644
index 0000000..86b9542
--- /dev/null
+++ b/coccinelle/hashmap_free.cocci
@@ -0,0 +1,54 @@
+@@
+expression p;
+@@
+- set_free(p);
+- p = NULL;
++ p = set_free(p);
+@@
+expression p;
+@@
+- if (p)
+- set_free(p);
+- p = NULL;
++ p = set_free(p);
+@@
+expression p;
+@@
+- if (p) {
+- set_free(p);
+- p = NULL;
+- }
++ p = set_free(p);
+@@
+expression p;
+@@
+- if (p)
+- set_free(p);
++ set_free(p);
+@@
+expression p;
+@@
+- hashmap_free(p);
+- p = NULL;
++ p = hashmap_free(p);
+@@
+expression p;
+@@
+- if (p)
+- hashmap_free(p);
+- p = NULL;
++ p = hashmap_free(p);
+@@
+expression p;
+@@
+- if (p) {
+- hashmap_free(p);
+- p = NULL;
+- }
++ p = hashmap_free(p);
+@@
+expression p;
+@@
+- if (p)
+- hashmap_free(p);
++ hashmap_free(p);
diff --git a/coccinelle/htonl.cocci b/coccinelle/htonl.cocci
new file mode 100644
index 0000000..4e69bb7
--- /dev/null
+++ b/coccinelle/htonl.cocci
@@ -0,0 +1,20 @@
+@@
+expression s;
+@@
+- htonl(s)
++ htobe32(s)
+@@
+expression s;
+@@
+- htons(s)
++ htobe16(s)
+@@
+expression s;
+@@
+- ntohl(s)
++ be32toh(s)
+@@
+expression s;
+@@
+- ntohs(s)
++ be16toh(s)
diff --git a/coccinelle/in_set.cocci b/coccinelle/in_set.cocci
new file mode 100644
index 0000000..1c17c7d
--- /dev/null
+++ b/coccinelle/in_set.cocci
@@ -0,0 +1,25 @@
+/* Limit the number of expressions to 6 for performance reasons */
+@@
+expression e;
+/* Exclude JsonVariant * from the transformation, as it can't work with the
+ * current version of the IN_SET macro */
+typedef JsonVariant;
+type T != JsonVariant*;
+constant T n0, n1, n2, n3, n4, n5;
+@@
+(
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4 || e == n5
++ IN_SET(e, n0, n1, n2, n3, n4, n5)
+|
+- e == n0 || e == n1 || e == n2 || e == n3 || e == n4
++ IN_SET(e, n0, n1, n2, n3, n4)
+|
+- e == n0 || e == n1 || e == n2 || e == n3
++ IN_SET(e, n0, n1, n2, n3)
+|
+- e == n0 || e == n1 || e == n2
++ IN_SET(e, n0, n1, n2)
+|
+- e == n0 || e == n1
++ IN_SET(e, n0, n1)
+)
diff --git a/coccinelle/iovec-make.cocci b/coccinelle/iovec-make.cocci
new file mode 100644
index 0000000..7a0d4ce
--- /dev/null
+++ b/coccinelle/iovec-make.cocci
@@ -0,0 +1,29 @@
+@@
+expression x, y, p, l;
+@@
+- x[y].iov_base = p;
+- x[y].iov_len = l;
+- y++;
++ x[y++] = IOVEC_MAKE(p, l);
+@@
+expression x, p, l;
+@@
+- x.iov_base = p;
+- x.iov_len = l;
++ x = IOVEC_MAKE(p, l);
+@@
+expression x, p, l;
+@@
+- x->iov_base = p;
+- x->iov_len = l;
++ *x = IOVEC_MAKE(p, l);
+@@
+expression s;
+@@
+- IOVEC_MAKE(s, strlen(s));
++ IOVEC_MAKE_STRING(s);
+@@
+expression x, y, z;
+@@
+- x = (struct iovec) { .iov_base = y, .iov_len = z };
++ x = IOVEC_MAKE(y, z);
diff --git a/coccinelle/isempty.cocci b/coccinelle/isempty.cocci
new file mode 100644
index 0000000..e0a9f07
--- /dev/null
+++ b/coccinelle/isempty.cocci
@@ -0,0 +1,42 @@
+@@
+/* Disable this transformation for the test-string-util.c */
+position p : script:python() { p[0].file != "src/test/test-string-util.c" };
+expression s;
+@@
+(
+- strv_length@p(s) == 0
++ strv_isempty(s)
+|
+- strv_length@p(s) <= 0
++ strv_isempty(s)
+|
+- strv_length@p(s) > 0
++ !strv_isempty(s)
+|
+- strv_length@p(s) != 0
++ !strv_isempty(s)
+|
+- strlen@p(s) == 0
++ isempty(s)
+|
+- strlen@p(s) <= 0
++ isempty(s)
+|
+- strlen@p(s) > 0
++ !isempty(s)
+|
+- strlen@p(s) != 0
++ !isempty(s)
+|
+- strlen_ptr@p(s) == 0
++ isempty(s)
+|
+- strlen_ptr@p(s) <= 0
++ isempty(s)
+|
+- strlen_ptr@p(s) > 0
++ !isempty(s)
+|
+- strlen_ptr@p(s) != 0
++ !isempty(s)
+)
diff --git a/coccinelle/log-json.cocci b/coccinelle/log-json.cocci
new file mode 100644
index 0000000..3730fd6
--- /dev/null
+++ b/coccinelle/log-json.cocci
@@ -0,0 +1,8 @@
+@@
+expression e, v, flags;
+expression list args;
+@@
++ return
+- json_log(v, flags, 0, args);
++ json_log(v, flags, SYNTHETIC_ERRNO(e), args);
+- return -e;
diff --git a/coccinelle/macros.h b/coccinelle/macros.h
new file mode 100644
index 0000000..62177f0
--- /dev/null
+++ b/coccinelle/macros.h
@@ -0,0 +1,231 @@
+/* Collected macros from our systemd codebase to make the cocci semantic
+ * parser happy. Inspired by the original cocci macros file
+ * /usr/lib64/coccinelle/standard.h (including the YACFE_* symbols)
+ */
+
+// General
+#define PTR_TO_PID(x)
+
+// src/basic/macro.h
+#define _printf_(a, b) __attribute__((__format__(printf, a, b)))
+#define _alloc_(...) __attribute__((__alloc_size__(__VA_ARGS__)))
+#define _sentinel_ __attribute__((__sentinel__))
+#define _section_(x) __attribute__((__section__(x)))
+#define _used_ __attribute__((__used__))
+#define _unused_ __attribute__((__unused__))
+#define _destructor_ __attribute__((__destructor__))
+#define _pure_ __attribute__((__pure__))
+#define _const_ __attribute__((__const__))
+#define _deprecated_ __attribute__((__deprecated__))
+#define _packed_ __attribute__((__packed__))
+#define _malloc_ __attribute__((__malloc__))
+#define _weak_ __attribute__((__weak__))
+#define _likely_(x) (__builtin_expect(!!(x), 1))
+#define _unlikely_(x) (__builtin_expect(!!(x), 0))
+#define _public_ __attribute__((__visibility__("default")))
+#define _hidden_ __attribute__((__visibility__("hidden")))
+#define _weakref_(x) __attribute__((__weakref__(#x)))
+#define _align_(x) __attribute__((__aligned__(x)))
+#define _alignas_(x) __attribute__((__aligned__(__alignof(x))))
+#define _alignptr_ __attribute__((__aligned__(sizeof(void*))))
+#define _cleanup_(x) __attribute__((__cleanup__(x)))
+#define _fallthrough_
+#define _noreturn_ __attribute__((__noreturn__))
+#define thread_local __thread
+
+#define ELEMENTSOF(x) \
+ (__builtin_choose_expr( \
+ !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
+ sizeof(x)/sizeof((x)[0]), \
+ VOID_0))
+
+// src/basic/umask-util.h
+#define _cleanup_umask_
+#define RUN_WITH_UMASK(mask) \
+ for (_cleanup_umask_ mode_t _saved_umask_ = umask(mask) | S_IFMT; \
+ FLAGS_SET(_saved_umask_, S_IFMT); \
+ _saved_umask_ &= 0777)
+
+// src/basic/hashmap.h
+#define _IDX_ITERATOR_FIRST (UINT_MAX - 1)
+#define HASHMAP_FOREACH(e, h) YACFE_ITERATOR
+#define ORDERED_HASHMAP_FOREACH(e, h) YACFE_ITERATOR
+#define HASHMAP_FOREACH_KEY(e, k, h) YACFE_ITERATOR
+#define ORDERED_HASHMAP_FOREACH_KEY(e, k, h) YACFE_ITERATOR
+
+// src/basic/list.h
+#define LIST_HEAD(t,name) \
+ t *name
+#define LIST_FIELDS(t,name) \
+ t *name##_next, *name##_prev
+#define LIST_HEAD_INIT(head) \
+ do { \
+ (head) = NULL; \
+ } while (false)
+#define LIST_INIT(name,item) \
+ do { \
+ typeof(*(item)) *_item = (item); \
+ assert(_item); \
+ _item->name##_prev = _item->name##_next = NULL; \
+ } while (false)
+#define LIST_PREPEND(name,head,item) \
+ do { \
+ typeof(*(head)) **_head = &(head), *_item = (item); \
+ assert(_item); \
+ if ((_item->name##_next = *_head)) \
+ _item->name##_next->name##_prev = _item; \
+ _item->name##_prev = NULL; \
+ *_head = _item; \
+ } while (false)
+#define LIST_APPEND(name,head,item) \
+ do { \
+ typeof(*(head)) **_hhead = &(head), *_tail; \
+ LIST_FIND_TAIL(name, *_hhead, _tail); \
+ LIST_INSERT_AFTER(name, *_hhead, _tail, item); \
+ } while (false)
+#define LIST_REMOVE(name,head,item) \
+ do { \
+ typeof(*(head)) **_head = &(head), *_item = (item); \
+ assert(_item); \
+ if (_item->name##_next) \
+ _item->name##_next->name##_prev = _item->name##_prev; \
+ if (_item->name##_prev) \
+ _item->name##_prev->name##_next = _item->name##_next; \
+ else { \
+ assert(*_head == _item); \
+ *_head = _item->name##_next; \
+ } \
+ _item->name##_next = _item->name##_prev = NULL; \
+ } while (false)
+#define LIST_FIND_HEAD(name,item,head) \
+ do { \
+ typeof(*(item)) *_item = (item); \
+ if (!_item) \
+ (head) = NULL; \
+ else { \
+ while (_item->name##_prev) \
+ _item = _item->name##_prev; \
+ (head) = _item; \
+ } \
+ } while (false)
+#define LIST_FIND_TAIL(name,item,tail) \
+ do { \
+ typeof(*(item)) *_item = (item); \
+ if (!_item) \
+ (tail) = NULL; \
+ else { \
+ while (_item->name##_next) \
+ _item = _item->name##_next; \
+ (tail) = _item; \
+ } \
+ } while (false)
+#define LIST_INSERT_AFTER(name,head,a,b) \
+ do { \
+ typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
+ assert(_b); \
+ if (!_a) { \
+ if ((_b->name##_next = *_head)) \
+ _b->name##_next->name##_prev = _b; \
+ _b->name##_prev = NULL; \
+ *_head = _b; \
+ } else { \
+ if ((_b->name##_next = _a->name##_next)) \
+ _b->name##_next->name##_prev = _b; \
+ _b->name##_prev = _a; \
+ _a->name##_next = _b; \
+ } \
+ } while (false)
+#define LIST_INSERT_BEFORE(name,head,a,b) \
+ do { \
+ typeof(*(head)) **_head = &(head), *_a = (a), *_b = (b); \
+ assert(_b); \
+ if (!_a) { \
+ if (!*_head) { \
+ _b->name##_next = NULL; \
+ _b->name##_prev = NULL; \
+ *_head = _b; \
+ } else { \
+ typeof(*(head)) *_tail = (head); \
+ while (_tail->name##_next) \
+ _tail = _tail->name##_next; \
+ _b->name##_next = NULL; \
+ _b->name##_prev = _tail; \
+ _tail->name##_next = _b; \
+ } \
+ } else { \
+ if ((_b->name##_prev = _a->name##_prev)) \
+ _b->name##_prev->name##_next = _b; \
+ else \
+ *_head = _b; \
+ _b->name##_next = _a; \
+ _a->name##_prev = _b; \
+ } \
+ } while (false)
+
+#define LIST_JUST_US(name,item) \
+ (!(item)->name##_prev && !(item)->name##_next) \
+#define LIST_FOREACH(name,i,head) \
+ for ((i) = (head); (i); (i) = (i)->name##_next)
+#define LIST_FOREACH_SAFE(name,i,n,head) \
+ for ((i) = (head); (i) && (((n) = (i)->name##_next), 1); (i) = (n))
+#define LIST_FOREACH_BEFORE(name,i,p) \
+ for ((i) = (p)->name##_prev; (i); (i) = (i)->name##_prev)
+#define LIST_FOREACH_AFTER(name,i,p) \
+ for ((i) = (p)->name##_next; (i); (i) = (i)->name##_next)
+#define LIST_FOREACH_OTHERS(name,i,p) \
+ for (({ \
+ (i) = (p); \
+ while ((i) && (i)->name##_prev) \
+ (i) = (i)->name##_prev; \
+ if ((i) == (p)) \
+ (i) = (p)->name##_next; \
+ }); \
+ (i); \
+ (i) = (i)->name##_next == (p) ? (p)->name##_next : (i)->name##_next)
+#define LIST_LOOP_BUT_ONE(name,i,head,p) \
+ for ((i) = (p)->name##_next ? (p)->name##_next : (head); \
+ (i) != (p); \
+ (i) = (i)->name##_next ? (i)->name##_next : (head))
+
+#define LIST_IS_EMPTY(head) \
+ (!(head))
+#define LIST_JOIN(name,a,b) \
+ do { \
+ assert(b); \
+ if (!(a)) \
+ (a) = (b); \
+ else { \
+ typeof(*(a)) *_head = (b), *_tail; \
+ LIST_FIND_TAIL(name, (a), _tail); \
+ _tail->name##_next = _head; \
+ _head->name##_prev = _tail; \
+ } \
+ (b) = NULL; \
+ } while (false)
+
+// src/basic/strv.h
+#define STRV_FOREACH(s, l) YACFE_ITERATOR
+#define STRV_FOREACH_BACKWARDS(s, l) YACFE_ITERATOR
+#define STRV_FOREACH_PAIR(x, y, l) YACFE_ITERATOR
+
+// src/basic/socket-util.h
+#define CMSG_BUFFER_TYPE(size) \
+ union { \
+ struct cmsghdr cmsghdr; \
+ uint8_t buf[size]; \
+ uint8_t align_check[(size) >= CMSG_SPACE(0) && \
+ (size) == CMSG_ALIGN(size) ? 1 : -1]; \
+ }
+
+// src/libsystemd/sd-device/device-util.h
+#define FOREACH_DEVICE_PROPERTY(device, key, value) YACFE_ITERATOR
+#define FOREACH_DEVICE_TAG(device, tag) YACFE_ITERATOR
+#define FOREACH_DEVICE_CURRENT_TAG(device, tag) YACFE_ITERATOR
+#define FOREACH_DEVICE_SYSATTR(device, attr) YACFE_ITERATOR
+#define FOREACH_DEVICE_DEVLINK(device, devlink) YACFE_ITERATOR
+#define FOREACH_DEVICE(enumerator, device) YACFE_ITERATOR
+#define FOREACH_SUBSYSTEM(enumerator, device) YACFE_ITERATOR
+
+// src/basic/dirent-util.h
+#define FOREACH_DIRENT(de, d, on_error) YACFE_ITERATOR
+#define FOREACH_DIRENT_ALL(de, d, on_error) YACFE_ITERATOR
diff --git a/coccinelle/malloc_multiply.cocci b/coccinelle/malloc_multiply.cocci
new file mode 100644
index 0000000..3284edf
--- /dev/null
+++ b/coccinelle/malloc_multiply.cocci
@@ -0,0 +1,20 @@
+@@
+expression q, n, m;
+@@
+- q = malloc((n)*(m))
++ q = malloc_multiply(n, m)
+@@
+expression q, n, m;
+@@
+- q = malloc(n*(m))
++ q = malloc_multiply(n, m)
+@@
+expression q, n, m;
+@@
+- q = malloc((n)*m)
++ q = malloc_multiply(n, m)
+@@
+expression q, n, m;
+@@
+- q = malloc(n*m)
++ q = malloc_multiply(n, m)
diff --git a/coccinelle/memzero.cocci b/coccinelle/memzero.cocci
new file mode 100644
index 0000000..8198cc8
--- /dev/null
+++ b/coccinelle/memzero.cocci
@@ -0,0 +1,38 @@
+@@
+expression s;
+@@
+- memset(&s, 0, sizeof(s))
++ zero(s)
+@@
+expression s;
+@@
+- memset(s, 0, sizeof(*s))
++ zero(*s)
+@@
+expression s;
+@@
+- bzero(&s, sizeof(s))
++ zero(s)
+@@
+expression s;
+@@
+- bzero(s, sizeof(*s))
++ zero(*s)
+@@
+expression a, b;
+@@
+(
+#define memzero
+&
+- memset(a, 0, b)
++ memzero(a, b)
+)
+@@
+expression a, b;
+@@
+(
+#define memzero
+&
+- bzero(a, b)
++ memzero(a, b)
+)
diff --git a/coccinelle/mfree.cocci b/coccinelle/mfree.cocci
new file mode 100644
index 0000000..1389cd3
--- /dev/null
+++ b/coccinelle/mfree.cocci
@@ -0,0 +1,6 @@
+@@
+expression p;
+@@
+- free(p);
+- p = NULL;
++ p = mfree(p);
diff --git a/coccinelle/mfree_return.cocci b/coccinelle/mfree_return.cocci
new file mode 100644
index 0000000..15e6c7d
--- /dev/null
+++ b/coccinelle/mfree_return.cocci
@@ -0,0 +1,8 @@
+@@
+/* Avoid running this transformation on the mfree function itself */
+position p : script:python() { p[0].current_element != "mfree" };
+expression e;
+@@
+- free@p(e);
+- return NULL;
++ return mfree(e);
diff --git a/coccinelle/no-if-assignments.cocci b/coccinelle/no-if-assignments.cocci
new file mode 100644
index 0000000..9f63e90
--- /dev/null
+++ b/coccinelle/no-if-assignments.cocci
@@ -0,0 +1,20 @@
+@@
+expression p, q;
+identifier r;
+statement s;
+@@
+- if ((r = q) < p)
+- s
++ r = q;
++ if (r < p)
++ s
+@@
+expression p, q;
+identifier r;
+statement s;
+@@
+- if ((r = q) >= p)
+- s
++ r = q;
++ if (r >= p)
++ s
diff --git a/coccinelle/not_in_set.cocci b/coccinelle/not_in_set.cocci
new file mode 100644
index 0000000..3486cff
--- /dev/null
+++ b/coccinelle/not_in_set.cocci
@@ -0,0 +1,23 @@
+/* Limit the number of expressions to 6 for performance reasons */
+@@
+expression e;
+typedef JsonVariant;
+type T != JsonVariant*;
+constant T n0, n1, n2, n3, n4, n5;
+@@
+(
+- e != n0 && e != n1 && e != n2 && e != n3 && e != n4 && e != n5
++ !IN_SET(e, n0, n1, n2, n3, n4, n5)
+|
+- e != n0 && e != n1 && e != n2 && e != n3 && e != n4
++ !IN_SET(e, n0, n1, n2, n3, n4)
+|
+- e != n0 && e != n1 && e != n2 && e != n3
++ !IN_SET(e, n0, n1, n2, n3)
+|
+- e != n0 && e != n1 && e != n2
++ !IN_SET(e, n0, n1, n2)
+|
+- e != n0 && e != n1
++ !IN_SET(e, n0, n1)
+)
diff --git a/coccinelle/o-ndelay.cocci b/coccinelle/o-ndelay.cocci
new file mode 100644
index 0000000..669424a
--- /dev/null
+++ b/coccinelle/o-ndelay.cocci
@@ -0,0 +1,4 @@
+@@
+@@
+- O_NDELAY
++ O_NONBLOCK
diff --git a/coccinelle/reallocarray.cocci b/coccinelle/reallocarray.cocci
new file mode 100644
index 0000000..21fe9df
--- /dev/null
+++ b/coccinelle/reallocarray.cocci
@@ -0,0 +1,20 @@
+@@
+expression q, p, n, m;
+@@
+- q = realloc(p, (n)*(m))
++ q = reallocarray(p, n, m)
+@@
+expression q, p, n, m;
+@@
+- q = realloc(p, n*(m))
++ q = reallocarray(p, n, m)
+@@
+expression q, p, n, m;
+@@
+- q = realloc(p, (n)*m)
++ q = reallocarray(p, n, m)
+@@
+expression q, p, n, m;
+@@
+- q = realloc(p, n*m)
++ q = reallocarray(p, n, m)
diff --git a/coccinelle/redundant-if.cocci b/coccinelle/redundant-if.cocci
new file mode 100644
index 0000000..515e36e
--- /dev/null
+++ b/coccinelle/redundant-if.cocci
@@ -0,0 +1,54 @@
+@@
+expression r;
+@@
+- if (r < 0)
+- return r;
+- if (r == 0)
+- return 0;
++ if (r <= 0)
++ return r;
+@@
+expression r;
+@@
+- if (r == 0)
+- return 0;
+- if (r < 0)
+- return r;
++ if (r <= 0)
++ return r;
+@@
+expression r;
+@@
+- if (r < 0)
+- return r;
+- if (r == 0)
+- return r;
++ if (r <= 0)
++ return r;
+@@
+expression r;
+@@
+- if (r == 0)
+- return r;
+- if (r < 0)
+- return r;
++ if (r <= 0)
++ return r;
+@@
+expression r;
+@@
+- if (r < 0)
+- return r;
+- if (r > 0)
+- return r;
++ if (r != 0)
++ return r;
+@@
+expression r;
+@@
+- if (r > 0)
+- return r;
+- if (r < 0)
+- return r;
++ if (r != 0)
++ return r;
diff --git a/coccinelle/run-coccinelle.sh b/coccinelle/run-coccinelle.sh
new file mode 100755
index 0000000..871547a
--- /dev/null
+++ b/coccinelle/run-coccinelle.sh
@@ -0,0 +1,42 @@
+#!/bin/bash -e
+
+# Exclude following paths from the Coccinelle transformations
+EXCLUDED_PATHS=(
+ "src/boot/efi/*"
+ "src/shared/linux/*"
+ "src/basic/linux/*"
+ # Symlinked to test-bus-vtable-cc.cc, which causes issues with the IN_SET macro
+ "src/libsystemd/sd-bus/test-bus-vtable.c"
+)
+
+top="$(git rev-parse --show-toplevel)"
+args=
+
+# Create an array from files tracked by git...
+mapfile -t files < <(git ls-files ':/*.[ch]')
+# ...and filter everything that matches patterns from EXCLUDED_PATHS
+for excl in "${EXCLUDED_PATHS[@]}"; do
+ files=(${files[@]//$excl})
+done
+
+case "$1" in
+ -i)
+ args="$args --in-place"
+ shift
+ ;;
+esac
+
+if ! parallel -h >/dev/null; then
+ echo 'Please install GNU parallel (package "parallel")'
+ exit 1
+fi
+
+for SCRIPT in ${@-$top/coccinelle/*.cocci}; do
+ echo "--x-- Processing $SCRIPT --x--"
+ TMPFILE=`mktemp`
+ echo "+ spatch --sp-file $SCRIPT $args ..."
+ parallel --halt now,fail=1 --keep-order --noswap --max-args=20 \
+ spatch --macro-file="$top/coccinelle/macros.h" --sp-file $SCRIPT $args ::: "${files[@]}" \
+ 2>"$TMPFILE" || cat "$TMPFILE"
+ echo -e "--x-- Processed $SCRIPT --x--\n"
+done
diff --git a/coccinelle/safe_close-no-if.cocci b/coccinelle/safe_close-no-if.cocci
new file mode 100644
index 0000000..81c5678
--- /dev/null
+++ b/coccinelle/safe_close-no-if.cocci
@@ -0,0 +1,7 @@
+@@
+expression fd;
+@@
+- if (fd >= 0) {
+- fd = safe_close(fd);
+- }
++ fd = safe_close(fd);
diff --git a/coccinelle/safe_close.cocci b/coccinelle/safe_close.cocci
new file mode 100644
index 0000000..6fedd80
--- /dev/null
+++ b/coccinelle/safe_close.cocci
@@ -0,0 +1,18 @@
+@@
+expression fd;
+@@
+- close(fd);
+- fd = -1;
++ fd = safe_close(fd);
+@@
+expression fd;
+@@
+- close_nointr(fd);
+- fd = -1;
++ fd = safe_close(fd);
+@@
+expression fd;
+@@
+- safe_close(fd);
+- fd = -1;
++ fd = safe_close(fd);
diff --git a/coccinelle/safe_closedir.cocci b/coccinelle/safe_closedir.cocci
new file mode 100644
index 0000000..743ffd9
--- /dev/null
+++ b/coccinelle/safe_closedir.cocci
@@ -0,0 +1,27 @@
+@@
+expression p;
+@@
+- if (p) {
+- closedir(p);
+- p = NULL;
+- }
++ p = safe_closedir(p);
+@@
+expression p;
+@@
+- if (p)
+- closedir(p);
+- p = NULL;
++ p = safe_closedir(p);
+@@
+expression p;
+@@
+- closedir(p);
+- p = NULL;
++ p = safe_closedir(p);
+@@
+expression p;
+@@
+- if (p)
+- closedir(p);
++ safe_closedir(p);
diff --git a/coccinelle/safe_fclose.cocci b/coccinelle/safe_fclose.cocci
new file mode 100644
index 0000000..6961cd0
--- /dev/null
+++ b/coccinelle/safe_fclose.cocci
@@ -0,0 +1,27 @@
+@@
+expression p;
+@@
+- if (p) {
+- fclose(p);
+- p = NULL;
+- }
++ p = safe_fclose(p);
+@@
+expression p;
+@@
+- if (p)
+- fclose(p);
+- p = NULL;
++ p = safe_fclose(p);
+@@
+expression p;
+@@
+- fclose(p);
+- p = NULL;
++ p = safe_fclose(p);
+@@
+expression p;
+@@
+- if (p)
+- fclose(p);
++ safe_fclose(p);
diff --git a/coccinelle/sd_event_source_disable_unref.cocci b/coccinelle/sd_event_source_disable_unref.cocci
new file mode 100644
index 0000000..2763fef
--- /dev/null
+++ b/coccinelle/sd_event_source_disable_unref.cocci
@@ -0,0 +1,36 @@
+@@
+expression p;
+@@
+- if (p) {
+- (void) sd_event_source_set_enabled(p, SD_EVENT_OFF);
+- p = sd_event_source_unref(p);
+- }
++ p = sd_event_source_disable_unref(p);
+@@
+expression p;
+@@
+- if (p) {
+- sd_event_source_set_enabled(p, SD_EVENT_OFF);
+- sd_event_source_unref(p);
+- }
++ sd_event_source_disable_unref(p);
+@@
+expression p;
+@@
+- if (p) {
+- (void) sd_event_source_set_enabled(p, SD_EVENT_OFF);
+- sd_event_source_unref(p);
+- }
++ sd_event_source_disable_unref(p);
+@@
+expression p;
+@@
+- (void) sd_event_source_set_enabled(p, SD_EVENT_OFF);
+- sd_event_source_unref(p);
++ sd_event_source_disable_unref(p);
+@@
+expression p;
+@@
+- sd_event_source_set_enabled(p, SD_EVENT_OFF);
+- sd_event_source_unref(p);
++ sd_event_source_disable_unref(p);
diff --git a/coccinelle/set_ensure_put.cocci b/coccinelle/set_ensure_put.cocci
new file mode 100644
index 0000000..92d7970
--- /dev/null
+++ b/coccinelle/set_ensure_put.cocci
@@ -0,0 +1,18 @@
+@@
+local idexpression r;
+expression p, k, x;
+@@
+- r = set_ensure_allocated(&p, k);
+- if (r < 0)
+- return ...;
+- r = set_put(p, x);
++ r = set_ensure_put(&p, k, x);
+@@
+local idexpression r;
+expression p, k, x;
+@@
+- r = set_ensure_allocated(p, k);
+- if (r < 0)
+- return ...;
+- r = set_put(*p, x);
++ r = set_ensure_put(p, k, x);
diff --git a/coccinelle/strempty.cocci b/coccinelle/strempty.cocci
new file mode 100644
index 0000000..0868184
--- /dev/null
+++ b/coccinelle/strempty.cocci
@@ -0,0 +1,72 @@
+@@
+/* Avoid running this transformation on the strempty function itself and
+ * on the "make_expression" macro in src/libsystemd/sd-bus/bus-convenience.c.
+ * As Coccinelle's Location object doesn't support macro "detection", use
+ * a pretty horrifying combo of specifying a file and a special "something_else"
+ * position element, which is, apparently, the default value of
+ * "current_element" before it's set (according to the source code), thus
+ * matching any "top level" position, including macros. Let's hope we never
+ * introduce a function called "something_else"...
+ */
+position p : script:python() {
+ not (p[0].current_element == "strempty" or
+ (p[0].file == "src/libsystemd/sd-bus/bus-convenience.c" and
+ p[0].current_element == "something_else"))
+};
+expression s;
+@@
+(
+- s@p ?: ""
++ strempty(s)
+|
+- s@p ? s : ""
++ strempty(s)
+)
+
+@@
+position p : script:python() { p[0].current_element != "strempty" };
+expression s;
+@@
+- if (!s@p)
+- s = "";
++ s = strempty(s);
+
+@@
+position p : script:python() { p[0].current_element != "strnull" };
+expression s;
+@@
+(
+- s@p ?: "(null)"
++ strnull(s)
+|
+- s@p ? s : "(null)"
++ strnull(s)
+)
+
+@@
+position p : script:python() { p[0].current_element != "strnull" };
+expression s;
+@@
+- if (!s@p)
+- s = "(null)";
++ s = strnull(s);
+
+@@
+position p : script:python() { p[0].current_element != "strna" };
+expression s;
+@@
+(
+- s@p ?: "n/a"
++ strna(s)
+|
+- s@p ? s : "n/a"
++ strna(s)
+)
+
+@@
+position p : script:python() { p[0].current_element != "strna" };
+expression s;
+@@
+- if (!s@p)
+- s = "n/a";
++ s = strna(s);
diff --git a/coccinelle/strjoin.cocci b/coccinelle/strjoin.cocci
new file mode 100644
index 0000000..46f70c4
--- /dev/null
+++ b/coccinelle/strjoin.cocci
@@ -0,0 +1,15 @@
+@@
+position p : script:python() { p[0].current_element != "test_strjoin" };
+expression t;
+expression list args;
+@@
+(
+- strjoin@p(args, NULL);
++ strjoin(args);
+|
+- t = strjoin@p(args, NULL);
++ t = strjoin(args);
+|
+- return strjoin@p(args, NULL);
++ return strjoin(args);
+)
diff --git a/coccinelle/strjoina.cocci b/coccinelle/strjoina.cocci
new file mode 100644
index 0000000..a6236eb
--- /dev/null
+++ b/coccinelle/strjoina.cocci
@@ -0,0 +1,6 @@
+@@
+expression n, m;
+expression list s;
+@@
+- n = strjoina(m, s, NULL);
++ n = strjoina(m, s);
diff --git a/coccinelle/strv_free.cocci b/coccinelle/strv_free.cocci
new file mode 100644
index 0000000..0ad56f7
--- /dev/null
+++ b/coccinelle/strv_free.cocci
@@ -0,0 +1,27 @@
+@@
+expression p;
+@@
+- strv_free(p);
+- p = NULL;
++ p = strv_free(p);
+@@
+expression p;
+@@
+- if (p)
+- strv_free(p);
+- p = NULL;
++ p = strv_free(p);
+@@
+expression p;
+@@
+- if (p) {
+- strv_free(p);
+- p = NULL;
+- }
++ p = strv_free(p);
+@@
+expression p;
+@@
+- if (p)
+- strv_free(p);
++ strv_free(p);
diff --git a/coccinelle/swap-two.cocci b/coccinelle/swap-two.cocci
new file mode 100644
index 0000000..edf7d32
--- /dev/null
+++ b/coccinelle/swap-two.cocci
@@ -0,0 +1,7 @@
+@@
+expression x, y, z;
+@@
+- z = x;
+- x = y;
+- y = z;
++ SWAP_TWO(x, y);
diff --git a/coccinelle/synthetic-errno.cocci b/coccinelle/synthetic-errno.cocci
new file mode 100644
index 0000000..650c37e
--- /dev/null
+++ b/coccinelle/synthetic-errno.cocci
@@ -0,0 +1,48 @@
+@@
+expression e;
+expression list args;
+@@
+(
+/* Ignore one specific case in src/shared/bootspec.c where we want to stick
+ * with the log_debug() + return pattern */
+log_debug("Found no default boot entry :(");
+|
+- log_debug(args);
+- return -e;
++ return log_debug_errno(SYNTHETIC_ERRNO(e), args);
+)
+@@
+expression e;
+expression list args;
+@@
+- log_info(args);
+- return -e;
++ return log_info_errno(SYNTHETIC_ERRNO(e), args);
+@@
+expression e;
+expression list args;
+@@
+- log_notice(args);
+- return -e;
++ return log_notice_errno(SYNTHETIC_ERRNO(e), args);
+@@
+expression e;
+expression list args;
+@@
+- log_error(args);
+- return -e;
++ return log_error_errno(SYNTHETIC_ERRNO(e), args);
+@@
+expression e;
+expression list args;
+@@
+- log_emergency(args);
+- return -e;
++ return log_emergency_errno(SYNTHETIC_ERRNO(e), args);
+@@
+identifier log_LEVEL_errno =~ "^log_(debug|info|notice|warning|error|emergency)_errno$";
+identifier ERRNO =~ "^E[A-Z]+$";
+expression list args;
+@@
+- log_LEVEL_errno(ERRNO, args);
++ log_LEVEL_errno(SYNTHETIC_ERRNO(ERRNO), args);
diff --git a/coccinelle/take-fd.cocci b/coccinelle/take-fd.cocci
new file mode 100644
index 0000000..f7124e7
--- /dev/null
+++ b/coccinelle/take-fd.cocci
@@ -0,0 +1,21 @@
+@@
+local idexpression p;
+expression q;
+@@
+- p = q;
+- q = -1;
+- return p;
++ return TAKE_FD(q);
+
+/* The ideal solution would use 'local idexpression' to avoid matching errno,
+ * which is a global variable. However, 'idexpression' nor 'identifier'
+ * would match, for example, "x->fd", which is considered 'expression' in
+ * the SmPL grammar
+ */
+@@
+expression p != errno;
+expression q;
+@@
+- p = q;
+- q = -1;
++ p = TAKE_FD(q);
diff --git a/coccinelle/take-ptr.cocci b/coccinelle/take-ptr.cocci
new file mode 100644
index 0000000..0cebe81
--- /dev/null
+++ b/coccinelle/take-ptr.cocci
@@ -0,0 +1,14 @@
+@@
+local idexpression p;
+expression q;
+@@
+- p = q;
+- q = NULL;
+- return p;
++ return TAKE_PTR(q);
+@@
+expression p, q;
+@@
+- p = q;
+- q = NULL;
++ p = TAKE_PTR(q);
diff --git a/coccinelle/while-true.cocci b/coccinelle/while-true.cocci
new file mode 100644
index 0000000..c23fb11
--- /dev/null
+++ b/coccinelle/while-true.cocci
@@ -0,0 +1,12 @@
+@@
+statement s;
+@@
+- while (true)
++ for (;;)
+s
+@@
+statement s;
+@@
+- while (1)
++ for (;;)
+s
diff --git a/coccinelle/xsprintf.cocci b/coccinelle/xsprintf.cocci
new file mode 100644
index 0000000..660a35e
--- /dev/null
+++ b/coccinelle/xsprintf.cocci
@@ -0,0 +1,7 @@
+@@
+position p : script:python() { not p[0].file.startswith("man/") };
+expression e, fmt;
+expression list vaargs;
+@@
+- snprintf@p(e, sizeof(e), fmt, vaargs);
++ xsprintf(e, fmt, vaargs);
diff --git a/coccinelle/zz-drop-braces.cocci b/coccinelle/zz-drop-braces.cocci
new file mode 100644
index 0000000..34bf12f
--- /dev/null
+++ b/coccinelle/zz-drop-braces.cocci
@@ -0,0 +1,27 @@
+@@
+position p : script:python() { p[0].file != "src/journal/lookup3.c" };
+identifier id;
+expression e;
+@@
+if (...)
+- {
+(
+ id@p(...);
+|
+ e@p;
+)
+- }
+
+@@
+position p : script:python() { p[0].file != "src/journal/lookup3.c" };
+identifier id;
+expression e;
+@@
+if (...)
+- {
+(
+ return id@p(...);
+|
+ return e@p;
+)
+- }