lsym_preprocessing.c revision 1.8
1/* $NetBSD: lsym_preprocessing.c,v 1.8 2023/05/11 19:01:35 rillig Exp $ */ 2 3/* 4 * Tests for the token lsym_preprocessing, which represents a '#' that starts 5 * a preprocessing line. 6 * 7 * #define 8 * #ifdef 9 * #include 10 * #line 11 * #pragma 12 * 13 * The whole preprocessing line is processed separately from the main source 14 * code, without much tokenizing or parsing. 15 */ 16 17// TODO: test '#' in the middle of a non-preprocessing line 18// TODO: test stringify '#' 19// TODO: test token paste '##' 20 21//indent input 22// TODO: add input 23//indent end 24 25//indent run-equals-input 26 27 28/* 29 * Whitespace in the following preprocessing directives is preserved. 30 */ 31//indent input 32#define space ' ' /* the 'define' is followed by a space */ 33#define tab '\t' /* the 'define' is followed by a tab */ 34#if 0 /* 3 spaces */ 35#elif 0 /* 2 tabs */ 36#elif 0 > 1 /* tabs between the tokens */ 37#endif 38//indent end 39 40//indent run-equals-input 41 42// TODO: #define unfinished_string "... 43// TODO: #define unfinished_char '... 44// TODO: # 123 "file.h" 45// TODO: backslash-newline 46// TODO: block comment 47// TODO: line comment 48 49 50//indent input 51#include <system-header.h> 52#include "local-header.h" 53//indent end 54 55//indent run-equals-input 56 57 58/* 59 * Nested conditional compilation. 60 */ 61//indent input 62#if 0 63#else 64#endif 65 66#if 0 /* if comment */ 67#else /* else comment */ 68#endif /* endif comment */ 69 70#if 0 /* outer if comment */ 71# if nested /* inner if comment */ 72# else /* inner else comment */ 73# endif /* inner endif comment */ 74#endif /* outer endif comment */ 75//indent end 76 77//indent run 78#if 0 79#else 80#endif 81 82#if 0 /* if comment */ 83#else /* else comment */ 84#endif /* endif comment */ 85 86#if 0 /* outer if comment */ 87/* $ XXX: The indentation is removed, which can get confusing */ 88#if nested /* inner if comment */ 89#else /* inner else comment */ 90#endif /* inner endif comment */ 91#endif /* outer endif comment */ 92//indent end 93 94 95//indent input 96#define multi_line_definition /* first line 97 * middle 98 * final line 99 */ actual_value 100//indent end 101 102//indent run-equals-input 103 104 105/* 106 * Before indent.c 1.129 from 2021-10-08, indent mistakenly interpreted quotes 107 * in comments as starting a string literal. The '"' in the comment started a 108 * string, the next '"' finished the string, and the following '/' '*' was 109 * interpreted as the beginning of a comment. This comment lasted until the 110 * next '*' '/', which in this test is another preprocessor directive, solely 111 * for symmetry. 112 * 113 * The effect was that the extra space after d2 was not formatted, as that 114 * line was considered part of the comment. 115 */ 116//indent input 117#define comment_in_string_literal "/* no comment " 118int this_is_an_ordinary_line_again; 119 120int d1 ; 121#define confuse_d /*"*/ "/*" 122int d2 ; 123#define resolve_d "*/" 124int d3 ; 125 126int s1 ; 127#define confuse_s /*'*/ '/*' 128int s2 ; 129#define resolve_s '*/' 130int s3 ; 131//indent end 132 133//indent run 134#define comment_in_string_literal "/* no comment " 135int this_is_an_ordinary_line_again; 136 137int d1; 138#define confuse_d /*"*/ "/*" 139int d2; 140#define resolve_d "*/" 141int d3; 142 143int s1; 144#define confuse_s /*'*/ '/*' 145int s2; 146#define resolve_s '*/' 147int s3; 148//indent end 149 150 151/* 152 * A preprocessing directive inside an expression keeps the state about 153 * whether the next operator is unary or binary. 154 */ 155//indent input 156int binary_plus = 3 157#define intermediate 1 158 +4; 159int unary_plus = 160#define intermediate 1 161 + 4; 162//indent end 163 164//indent run 165int binary_plus = 3 166#define intermediate 1 167+ 4; 168int unary_plus = 169#define intermediate 1 170+4; 171//indent end 172 173 174/* 175 * Before io.c 1.135 from 2021-11-26, indent fixed malformed preprocessing 176 * lines that had arguments even though they shouldn't. It is not the task of 177 * an indenter to fix code, that's what a linter is for. 178 */ 179//indent input 180#if 0 181#elif 1 182#else if 3 183#endif 0 184//indent end 185 186//indent run-equals-input 187 188 189/* 190 * Existing comments are indented just like code comments. 191 * 192 * This means that the above wrong preprocessing lines (#else with argument) 193 * need to be fed through indent twice until they become stable. Since 194 * compilers issue warnings about these invalid lines, not much code still has 195 * these, making this automatic fix an edge case. 196 */ 197//indent input 198#if 0 /* comment */ 199#else /* comment */ 200#endif /* comment */ 201 202#if 0/* comment */ 203#else/* comment */ 204#endif/* comment */ 205//indent end 206 207//indent run-equals-input 208 209 210/* 211 * Multi-line comments in preprocessing lines. 212 */ 213//indent input 214#define eol_comment // EOL 215 216#define no_wrap_comment /* line 1 217 * line 2 218 * line 3 219 */ 220 221#define fixed_comment /*- line 1 222 * line 2 223 * line 3 224 */ 225 226#define two_comments /* 1 */ /* 2 */ /*3*/ 227#define three_comments /* first */ /* second */ /*third*/ 228//indent end 229 230//indent run-equals-input 231 232 233/* 234 * Do not touch multi-line macro definitions. 235 */ 236//indent input 237#define do_once(stmt) \ 238do { \ 239 stmt; \ 240} while (/* constant condition */ false) 241//indent end 242 243//indent run-equals-input 244