]>
Commit | Line | Data |
---|---|---|
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) {}) |