]> git.ipfire.org Git - thirdparty/systemd.git/blame - coccinelle/parsing_hacks.h
introduce FOREACH_ELEMENT
[thirdparty/systemd.git] / coccinelle / parsing_hacks.h
CommitLineData
b25d3b36
FS
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3/* FIXME
4 * - issues with parsing stuff like
cd4b16c0
FS
5 * - validchars = UPPERCASE_LETTERS DIGITS;
6 * - see: https://github.com/coccinelle/coccinelle/issues/341
7 * - keywords in macro invocations like FOREACH_DIRENT_ALL(de, d, return -errno)
8 * - see: https://github.com/coccinelle/coccinelle/issues/340
9 * - also see the FIXME in the TEST() stuff below
b25d3b36
FS
10 */
11
12/* This file contains parsing hacks for Coccinelle (spatch), to make it happy with some of our more complex
13 * macros - it is intended to be used with the --macro-file-builtins option for spatch.
14 *
15 * Coccinelle's macro support is somewhat limited and the parser trips over some of our more complex macros.
16 * In most cases this doesn't really matter, as the parsing errors are silently ignored, but there are
17 * special cases in which the parser incorrectly infers information that then causes issues in valid code
18 * later down the line.
19 *
a1ccd5ee 20 * Inspired by a similarly named file [0] from the Coccinelle sources, and the original builtin macros [1].
b25d3b36
FS
21 *
22 * [0] https://github.com/coccinelle/coccinelle/blob/master/parsing_c/parsing_hacks.ml
23 * [1] https://github.com/coccinelle/coccinelle/blob/master/standard.h
24 *
25 */
26
27/* Coccinelle really doesn't like our way of registering unit test cases, and incorrectly assumes that "id"
28 * from TEST(id) is the actual function identifier. This then causes name conflicts, since the unit tests
29 * are usually named after the functions they test.
30 *
31 * For example, a unit test for xsetxattr() is defined using TEST(xsetxattr), which eventually yields a
32 * procedure with following declaration:
33 *
34 * static const void test_xsetxattr(void);
35 *
36 * However, Coccinelle fails to parse the chain of macros behind TEST(x) and assumes the test function is
37 * named "xsetxattr", which then causes a name conflict when the actual "xsetxattr" function is called:
38 *
39 * (ONCE) SEMANTIC:parameter name omitted, but I continue
40 * Warning: PARSING: src/test/test-xattr-util.c:57: type defaults to 'int'; ...
41 * ERROR-RECOV: found sync '}' at line 127
42 * Parsing pass2: try again
43 * ERROR-RECOV: found sync '}' at line 127
44 * Parsing pass3: try again
45 * ERROR-RECOV: found sync '}' at line 127
46 * Parse error
47 * = File "src/test/test-xattr-util.c", line 101, column 12, charpos = 3152
48 * around = 'xsetxattr',
49 * whole content = r = xsetxattr(AT_FDCWD, x, "user.foo", "fullpath", SIZE_MAX, 0);
50 * Badcount: 40
51 *
52 * The easy way out here is to just provide a simplified version of the TEST(x) macro that pinpoints the most
53 * important detail - that the actual function name is prefixed with test_.
54 *
55 * FIXME: even with this Coccinelle still fails to process TEST(x) instances where x is a keyword, e.g.
56 * TEST(float), TEST(default), ...
57 */
58#define TEST(x, ...) static void test_##x(void)
59#define TEST_RET(x, ...) static int test_##x(void)
60
61/* Coccinelle doesn't know this keyword, so just drop it, since it's not important for any of our rules. */
62#define thread_local
63
cd4b16c0 64/* Coccinelle fails to parse these from the included headers, so let's just drop them. */
b25d3b36 65#define PAM_EXTERN
cd4b16c0 66#define STACK_OF(x)
b25d3b36
FS
67
68/* Mark a couple of iterator explicitly as iterators, otherwise Coccinelle gets a bit confused. Coccinelle
69 * can usually infer this information automagically, but in these specific cases it needs a bit of help. */
70#define FOREACH_ARRAY(i, array, num) YACFE_ITERATOR
64f7b296 71#define FOREACH_ELEMENT(i, array) YACFE_ITERATOR
b25d3b36
FS
72#define FOREACH_DIRENT_ALL(de, d, on_error) YACFE_ITERATOR
73#define FOREACH_STRING(x, y, ...) YACFE_ITERATOR
74#define HASHMAP_FOREACH(e, h) YACFE_ITERATOR
75#define LIST_FOREACH(name, i, head) YACFE_ITERATOR
76#define ORDERED_HASHMAP_FOREACH(e, h) YACFE_ITERATOR
77#define SET_FOREACH(e, s) YACFE_ITERATOR
cd4b16c0 78#define STRV_FOREACH_BACKWARDS YACFE_ITERATOR
b25d3b36
FS
79
80/* Coccinelle really doesn't like multiline macros that are not in the "usual" do { ... } while(0) format, so
81 * let's help it a little here by providing simplified one-line versions. */
82#define CMSG_BUFFER_TYPE(x) union { uint8_t align_check[(size) >= CMSG_SPACE(0) && (size) == CMSG_ALIGN(size) ? 1 : -1]; }
cd4b16c0 83#define SD_ID128_MAKE(...) ((const sd_id128) {})