1*95820b53Srillig /* $NetBSD: lsym_preprocessing.c,v 1.15 2023/06/16 23:19:01 rillig Exp $ */ 29ae26de1Srillig 39ae26de1Srillig /* 49ae26de1Srillig * Tests for the token lsym_preprocessing, which represents a '#' that starts 59ae26de1Srillig * a preprocessing line. 69ae26de1Srillig * 7b60cb68fSrillig * #define 8b60cb68fSrillig * #ifdef 9b60cb68fSrillig * #include 10b60cb68fSrillig * #line 11b60cb68fSrillig * #pragma 12b60cb68fSrillig * 139ae26de1Srillig * The whole preprocessing line is processed separately from the main source 149ae26de1Srillig * code, without much tokenizing or parsing. 159ae26de1Srillig */ 169ae26de1Srillig 179ae26de1Srillig // TODO: test '#' in the middle of a non-preprocessing line 189ae26de1Srillig // TODO: test stringify '#' 199ae26de1Srillig // TODO: test token paste '##' 209ae26de1Srillig 2147306038Srillig //indent input 229ae26de1Srillig // TODO: add input 2347306038Srillig //indent end 249ae26de1Srillig 2547306038Srillig //indent run-equals-input 2695e11159Srillig 2795e11159Srillig 2895e11159Srillig /* 2995e11159Srillig * Whitespace in the following preprocessing directives is preserved. 3095e11159Srillig */ 3147306038Srillig //indent input 3295e11159Srillig #define space ' ' /* the 'define' is followed by a space */ 3395e11159Srillig #define tab '\t' /* the 'define' is followed by a tab */ 3495e11159Srillig #if 0 /* 3 spaces */ 3595e11159Srillig #elif 0 /* 2 tabs */ 3695e11159Srillig #elif 0 > 1 /* tabs between the tokens */ 3795e11159Srillig #endif 3847306038Srillig //indent end 3995e11159Srillig 4047306038Srillig //indent run-equals-input 4195e11159Srillig 4295e11159Srillig // TODO: #define unfinished_string "... 4395e11159Srillig // TODO: #define unfinished_char '... 4495e11159Srillig // TODO: # 123 "file.h" 4595e11159Srillig // TODO: backslash-newline 4695e11159Srillig // TODO: block comment 4795e11159Srillig // TODO: line comment 48b60cb68fSrillig 49b60cb68fSrillig 50b60cb68fSrillig //indent input 51b60cb68fSrillig #include <system-header.h> 52b60cb68fSrillig #include "local-header.h" 53b60cb68fSrillig //indent end 54b60cb68fSrillig 55b60cb68fSrillig //indent run-equals-input 56b60cb68fSrillig 57b60cb68fSrillig 58b60cb68fSrillig /* 59b60cb68fSrillig * Nested conditional compilation. 60b60cb68fSrillig */ 61b60cb68fSrillig //indent input 62b60cb68fSrillig #if 0 63b60cb68fSrillig #else 64b60cb68fSrillig #endif 65b60cb68fSrillig 66b60cb68fSrillig #if 0 /* if comment */ 67b60cb68fSrillig #else /* else comment */ 68b60cb68fSrillig #endif /* endif comment */ 69b60cb68fSrillig 70b60cb68fSrillig #if 0 /* outer if comment */ 71b60cb68fSrillig # if nested /* inner if comment */ 72b60cb68fSrillig # else /* inner else comment */ 73b60cb68fSrillig # endif /* inner endif comment */ 74b60cb68fSrillig #endif /* outer endif comment */ 75b60cb68fSrillig //indent end 76b60cb68fSrillig 7738caea9bSrillig //indent run-equals-input 78b60cb68fSrillig 79b60cb68fSrillig 80b60cb68fSrillig //indent input 81b60cb68fSrillig #define multi_line_definition /* first line 82b60cb68fSrillig * middle 83b60cb68fSrillig * final line 84b60cb68fSrillig */ actual_value 85b60cb68fSrillig //indent end 86b60cb68fSrillig 87b60cb68fSrillig //indent run-equals-input 88b60cb68fSrillig 89b60cb68fSrillig 90b60cb68fSrillig /* 91b60cb68fSrillig * Before indent.c 1.129 from 2021-10-08, indent mistakenly interpreted quotes 92b60cb68fSrillig * in comments as starting a string literal. The '"' in the comment started a 93b60cb68fSrillig * string, the next '"' finished the string, and the following '/' '*' was 94b60cb68fSrillig * interpreted as the beginning of a comment. This comment lasted until the 95b60cb68fSrillig * next '*' '/', which in this test is another preprocessor directive, solely 96b60cb68fSrillig * for symmetry. 97b60cb68fSrillig * 98b60cb68fSrillig * The effect was that the extra space after d2 was not formatted, as that 99b60cb68fSrillig * line was considered part of the comment. 100b60cb68fSrillig */ 101b60cb68fSrillig //indent input 102b60cb68fSrillig #define comment_in_string_literal "/* no comment " 103b60cb68fSrillig int this_is_an_ordinary_line_again; 104b60cb68fSrillig 105b60cb68fSrillig int d1 ; 106b60cb68fSrillig #define confuse_d /*"*/ "/*" 107b60cb68fSrillig int d2 ; 108b60cb68fSrillig #define resolve_d "*/" 109b60cb68fSrillig int d3 ; 110b60cb68fSrillig 111b60cb68fSrillig int s1 ; 112b60cb68fSrillig #define confuse_s /*'*/ '/*' 113b60cb68fSrillig int s2 ; 114b60cb68fSrillig #define resolve_s '*/' 115b60cb68fSrillig int s3 ; 116b60cb68fSrillig //indent end 117b60cb68fSrillig 118b60cb68fSrillig //indent run 119b60cb68fSrillig #define comment_in_string_literal "/* no comment " 120b60cb68fSrillig int this_is_an_ordinary_line_again; 121b60cb68fSrillig 122b60cb68fSrillig int d1; 123b60cb68fSrillig #define confuse_d /*"*/ "/*" 124b60cb68fSrillig int d2; 125b60cb68fSrillig #define resolve_d "*/" 126b60cb68fSrillig int d3; 127b60cb68fSrillig 128b60cb68fSrillig int s1; 129b60cb68fSrillig #define confuse_s /*'*/ '/*' 130b60cb68fSrillig int s2; 131b60cb68fSrillig #define resolve_s '*/' 132b60cb68fSrillig int s3; 133b60cb68fSrillig //indent end 134b60cb68fSrillig 135b60cb68fSrillig 136b60cb68fSrillig /* 137b60cb68fSrillig * A preprocessing directive inside an expression keeps the state about 138b60cb68fSrillig * whether the next operator is unary or binary. 139b60cb68fSrillig */ 140b60cb68fSrillig //indent input 141b60cb68fSrillig int binary_plus = 3 142b60cb68fSrillig #define intermediate 1 143b60cb68fSrillig +4; 144b60cb68fSrillig int unary_plus = 145b60cb68fSrillig #define intermediate 1 146b60cb68fSrillig + 4; 147b60cb68fSrillig //indent end 148b60cb68fSrillig 149b60cb68fSrillig //indent run 150b60cb68fSrillig int binary_plus = 3 151b60cb68fSrillig #define intermediate 1 152b60cb68fSrillig + 4; 153b60cb68fSrillig int unary_plus = 154b60cb68fSrillig #define intermediate 1 155b60cb68fSrillig +4; 156b60cb68fSrillig //indent end 157b60cb68fSrillig 158b60cb68fSrillig 159b60cb68fSrillig /* 160b60cb68fSrillig * Before io.c 1.135 from 2021-11-26, indent fixed malformed preprocessing 161b60cb68fSrillig * lines that had arguments even though they shouldn't. It is not the task of 162b60cb68fSrillig * an indenter to fix code, that's what a linter is for. 163b60cb68fSrillig */ 164b60cb68fSrillig //indent input 165b60cb68fSrillig #if 0 166b60cb68fSrillig #elif 1 167b60cb68fSrillig #else if 3 168b60cb68fSrillig #endif 0 169b60cb68fSrillig //indent end 170b60cb68fSrillig 171b60cb68fSrillig //indent run-equals-input 172b60cb68fSrillig 173b60cb68fSrillig 174b60cb68fSrillig /* 175b60cb68fSrillig * Existing comments are indented just like code comments. 176b60cb68fSrillig * 177b60cb68fSrillig * This means that the above wrong preprocessing lines (#else with argument) 178b60cb68fSrillig * need to be fed through indent twice until they become stable. Since 179b60cb68fSrillig * compilers issue warnings about these invalid lines, not much code still has 180b60cb68fSrillig * these, making this automatic fix an edge case. 181b60cb68fSrillig */ 182b60cb68fSrillig //indent input 183b60cb68fSrillig #if 0 /* comment */ 184b60cb68fSrillig #else /* comment */ 185b60cb68fSrillig #endif /* comment */ 186b60cb68fSrillig 187b60cb68fSrillig #if 0/* comment */ 188b60cb68fSrillig #else/* comment */ 189b60cb68fSrillig #endif/* comment */ 190b60cb68fSrillig //indent end 191b60cb68fSrillig 192d5678748Srillig //indent run-equals-input 1935300eef1Srillig 1945300eef1Srillig 1955300eef1Srillig /* 1965300eef1Srillig * Multi-line comments in preprocessing lines. 1975300eef1Srillig */ 1985300eef1Srillig //indent input 1995300eef1Srillig #define eol_comment // EOL 2005300eef1Srillig 201d5678748Srillig #define no_wrap_comment /* line 1 2025300eef1Srillig * line 2 2035300eef1Srillig * line 3 2045300eef1Srillig */ 2055300eef1Srillig 2065300eef1Srillig #define fixed_comment /*- line 1 2075300eef1Srillig * line 2 2085300eef1Srillig * line 3 2095300eef1Srillig */ 210bacb7fc4Srillig 211bacb7fc4Srillig #define two_comments /* 1 */ /* 2 */ /*3*/ 212bacb7fc4Srillig #define three_comments /* first */ /* second */ /*third*/ 2135300eef1Srillig //indent end 2145300eef1Srillig 215d5678748Srillig //indent run-equals-input 216bacb7fc4Srillig 217bacb7fc4Srillig 218bacb7fc4Srillig /* 219bacb7fc4Srillig * Do not touch multi-line macro definitions. 220bacb7fc4Srillig */ 221bacb7fc4Srillig //indent input 222bacb7fc4Srillig #define do_once(stmt) \ 223bacb7fc4Srillig do { \ 224bacb7fc4Srillig stmt; \ 225bacb7fc4Srillig } while (/* constant condition */ false) 226bacb7fc4Srillig //indent end 227bacb7fc4Srillig 228bacb7fc4Srillig //indent run-equals-input 22946afda16Srillig 23046afda16Srillig 23146afda16Srillig /* 23246afda16Srillig * The 'INDENT OFF' state is global, it does not depend on the preprocessing 23346afda16Srillig * directives, otherwise the declarations for 'on' and 'after' would be moved 23446afda16Srillig * to column 1. 23546afda16Srillig */ 23646afda16Srillig //indent input 23746afda16Srillig int first_line; 23846afda16Srillig int before; 23946afda16Srillig #if 0 24046afda16Srillig /*INDENT OFF*/ 24146afda16Srillig int off; 24246afda16Srillig #else 24346afda16Srillig int on; 24446afda16Srillig #endif 24546afda16Srillig int after; 24646afda16Srillig //indent end 24746afda16Srillig 24846afda16Srillig //indent run -di0 24946afda16Srillig int first_line; 25046afda16Srillig int before; 25146afda16Srillig #if 0 25246afda16Srillig /*INDENT OFF*/ 25346afda16Srillig int off; 25446afda16Srillig #else 25546afda16Srillig int on; 25646afda16Srillig #endif 25746afda16Srillig int after; 25846afda16Srillig //indent end 259d2103f1cSrillig 260d2103f1cSrillig 261d2103f1cSrillig /* 262d2103f1cSrillig * Before 2023-06-14, indent was limited to 5 levels of conditional compilation 263d2103f1cSrillig * directives. 264d2103f1cSrillig */ 265d2103f1cSrillig //indent input 266d2103f1cSrillig #if 1 267d2103f1cSrillig #if 2 268d2103f1cSrillig #if 3 269d2103f1cSrillig #if 4 270d2103f1cSrillig #if 5 271d2103f1cSrillig #if 6 272d2103f1cSrillig #endif 6 273d2103f1cSrillig #endif 5 274d2103f1cSrillig #endif 4 275d2103f1cSrillig #endif 3 276d2103f1cSrillig #endif 2 277d2103f1cSrillig #endif 1 278d2103f1cSrillig //indent end 279d2103f1cSrillig 280d2103f1cSrillig //indent run-equals-input 281d2103f1cSrillig 282d2103f1cSrillig 283d2103f1cSrillig /* 284d2103f1cSrillig * Unrecognized and unmatched preprocessing directives are preserved. 285d2103f1cSrillig */ 286d2103f1cSrillig //indent input 287d2103f1cSrillig #else 288d2103f1cSrillig #elif 0 289d2103f1cSrillig #elifdef var 290d2103f1cSrillig #endif 291d2103f1cSrillig 292d2103f1cSrillig #unknown 293d2103f1cSrillig # 3 "file.c" 294d2103f1cSrillig //indent end 295d2103f1cSrillig 296d2103f1cSrillig //indent run 297d2103f1cSrillig #else 298d2103f1cSrillig #elif 0 299d2103f1cSrillig #elifdef var 300d2103f1cSrillig #endif 301d2103f1cSrillig 302d2103f1cSrillig #unknown 303d2103f1cSrillig # 3 "file.c" 304*95820b53Srillig // exit 1 305*95820b53Srillig // error: Standard Input:1: Unmatched #else 306*95820b53Srillig // error: Standard Input:2: Unmatched #elif 307*95820b53Srillig // error: Standard Input:3: Unmatched #elifdef 308*95820b53Srillig // error: Standard Input:4: Unmatched #endif 309d2103f1cSrillig //indent end 310940b8500Srillig 311940b8500Srillig 312940b8500Srillig /* 313940b8500Srillig * The '#' can only occur at the beginning of a line, therefore indent does not 314940b8500Srillig * care when it occurs in the middle of a line. 315940b8500Srillig */ 316940b8500Srillig //indent input 317940b8500Srillig int no = #; 318940b8500Srillig //indent end 319940b8500Srillig 320940b8500Srillig //indent run -di0 321940b8500Srillig int no = 322940b8500Srillig #; 323940b8500Srillig //indent end 324940b8500Srillig 325940b8500Srillig 326940b8500Srillig /* 327940b8500Srillig * Preprocessing directives may be indented; indent moves them to the beginning 328940b8500Srillig * of a line. 329940b8500Srillig */ 330940b8500Srillig //indent input 331940b8500Srillig #if 0 332940b8500Srillig #if 1 \ 333940b8500Srillig || 2 334940b8500Srillig #endif 335940b8500Srillig #endif 336940b8500Srillig //indent end 337940b8500Srillig 338940b8500Srillig //indent run 339940b8500Srillig #if 0 340940b8500Srillig #if 1 \ 341940b8500Srillig || 2 342940b8500Srillig #endif 343940b8500Srillig #endif 344940b8500Srillig //indent end 345