lsym_preprocessing.c revision 1.15
11.15Srillig/* $NetBSD: lsym_preprocessing.c,v 1.15 2023/06/16 23:19:01 rillig Exp $ */ 21.1Srillig 31.1Srillig/* 41.1Srillig * Tests for the token lsym_preprocessing, which represents a '#' that starts 51.1Srillig * a preprocessing line. 61.1Srillig * 71.5Srillig * #define 81.5Srillig * #ifdef 91.5Srillig * #include 101.5Srillig * #line 111.5Srillig * #pragma 121.5Srillig * 131.1Srillig * The whole preprocessing line is processed separately from the main source 141.1Srillig * code, without much tokenizing or parsing. 151.1Srillig */ 161.1Srillig 171.1Srillig// TODO: test '#' in the middle of a non-preprocessing line 181.1Srillig// TODO: test stringify '#' 191.1Srillig// TODO: test token paste '##' 201.1Srillig 211.4Srillig//indent input 221.1Srillig// TODO: add input 231.4Srillig//indent end 241.1Srillig 251.4Srillig//indent run-equals-input 261.2Srillig 271.2Srillig 281.2Srillig/* 291.2Srillig * Whitespace in the following preprocessing directives is preserved. 301.2Srillig */ 311.4Srillig//indent input 321.2Srillig#define space ' ' /* the 'define' is followed by a space */ 331.2Srillig#define tab '\t' /* the 'define' is followed by a tab */ 341.2Srillig#if 0 /* 3 spaces */ 351.2Srillig#elif 0 /* 2 tabs */ 361.2Srillig#elif 0 > 1 /* tabs between the tokens */ 371.2Srillig#endif 381.4Srillig//indent end 391.2Srillig 401.4Srillig//indent run-equals-input 411.2Srillig 421.2Srillig// TODO: #define unfinished_string "... 431.2Srillig// TODO: #define unfinished_char '... 441.2Srillig// TODO: # 123 "file.h" 451.2Srillig// TODO: backslash-newline 461.2Srillig// TODO: block comment 471.2Srillig// TODO: line comment 481.5Srillig 491.5Srillig 501.5Srillig//indent input 511.5Srillig#include <system-header.h> 521.5Srillig#include "local-header.h" 531.5Srillig//indent end 541.5Srillig 551.5Srillig//indent run-equals-input 561.5Srillig 571.5Srillig 581.5Srillig/* 591.5Srillig * Nested conditional compilation. 601.5Srillig */ 611.5Srillig//indent input 621.5Srillig#if 0 631.5Srillig#else 641.5Srillig#endif 651.5Srillig 661.5Srillig#if 0 /* if comment */ 671.5Srillig#else /* else comment */ 681.5Srillig#endif /* endif comment */ 691.5Srillig 701.5Srillig#if 0 /* outer if comment */ 711.5Srillig# if nested /* inner if comment */ 721.5Srillig# else /* inner else comment */ 731.5Srillig# endif /* inner endif comment */ 741.5Srillig#endif /* outer endif comment */ 751.5Srillig//indent end 761.5Srillig 771.10Srillig//indent run-equals-input 781.5Srillig 791.5Srillig 801.5Srillig//indent input 811.5Srillig#define multi_line_definition /* first line 821.5Srillig * middle 831.5Srillig * final line 841.5Srillig */ actual_value 851.5Srillig//indent end 861.5Srillig 871.5Srillig//indent run-equals-input 881.5Srillig 891.5Srillig 901.5Srillig/* 911.5Srillig * Before indent.c 1.129 from 2021-10-08, indent mistakenly interpreted quotes 921.5Srillig * in comments as starting a string literal. The '"' in the comment started a 931.5Srillig * string, the next '"' finished the string, and the following '/' '*' was 941.5Srillig * interpreted as the beginning of a comment. This comment lasted until the 951.5Srillig * next '*' '/', which in this test is another preprocessor directive, solely 961.5Srillig * for symmetry. 971.5Srillig * 981.5Srillig * The effect was that the extra space after d2 was not formatted, as that 991.5Srillig * line was considered part of the comment. 1001.5Srillig */ 1011.5Srillig//indent input 1021.5Srillig#define comment_in_string_literal "/* no comment " 1031.5Srilligint this_is_an_ordinary_line_again; 1041.5Srillig 1051.5Srilligint d1 ; 1061.5Srillig#define confuse_d /*"*/ "/*" 1071.5Srilligint d2 ; 1081.5Srillig#define resolve_d "*/" 1091.5Srilligint d3 ; 1101.5Srillig 1111.5Srilligint s1 ; 1121.5Srillig#define confuse_s /*'*/ '/*' 1131.5Srilligint s2 ; 1141.5Srillig#define resolve_s '*/' 1151.5Srilligint s3 ; 1161.5Srillig//indent end 1171.5Srillig 1181.5Srillig//indent run 1191.5Srillig#define comment_in_string_literal "/* no comment " 1201.5Srilligint this_is_an_ordinary_line_again; 1211.5Srillig 1221.5Srilligint d1; 1231.5Srillig#define confuse_d /*"*/ "/*" 1241.5Srilligint d2; 1251.5Srillig#define resolve_d "*/" 1261.5Srilligint d3; 1271.5Srillig 1281.5Srilligint s1; 1291.5Srillig#define confuse_s /*'*/ '/*' 1301.5Srilligint s2; 1311.5Srillig#define resolve_s '*/' 1321.5Srilligint s3; 1331.5Srillig//indent end 1341.5Srillig 1351.5Srillig 1361.5Srillig/* 1371.5Srillig * A preprocessing directive inside an expression keeps the state about 1381.5Srillig * whether the next operator is unary or binary. 1391.5Srillig */ 1401.5Srillig//indent input 1411.5Srilligint binary_plus = 3 1421.5Srillig#define intermediate 1 1431.5Srillig +4; 1441.5Srilligint unary_plus = 1451.5Srillig#define intermediate 1 1461.5Srillig + 4; 1471.5Srillig//indent end 1481.5Srillig 1491.5Srillig//indent run 1501.5Srilligint binary_plus = 3 1511.5Srillig#define intermediate 1 1521.5Srillig+ 4; 1531.5Srilligint unary_plus = 1541.5Srillig#define intermediate 1 1551.5Srillig+4; 1561.5Srillig//indent end 1571.5Srillig 1581.5Srillig 1591.5Srillig/* 1601.5Srillig * Before io.c 1.135 from 2021-11-26, indent fixed malformed preprocessing 1611.5Srillig * lines that had arguments even though they shouldn't. It is not the task of 1621.5Srillig * an indenter to fix code, that's what a linter is for. 1631.5Srillig */ 1641.5Srillig//indent input 1651.5Srillig#if 0 1661.5Srillig#elif 1 1671.5Srillig#else if 3 1681.5Srillig#endif 0 1691.5Srillig//indent end 1701.5Srillig 1711.5Srillig//indent run-equals-input 1721.5Srillig 1731.5Srillig 1741.5Srillig/* 1751.5Srillig * Existing comments are indented just like code comments. 1761.5Srillig * 1771.5Srillig * This means that the above wrong preprocessing lines (#else with argument) 1781.5Srillig * need to be fed through indent twice until they become stable. Since 1791.5Srillig * compilers issue warnings about these invalid lines, not much code still has 1801.5Srillig * these, making this automatic fix an edge case. 1811.5Srillig */ 1821.5Srillig//indent input 1831.5Srillig#if 0 /* comment */ 1841.5Srillig#else /* comment */ 1851.5Srillig#endif /* comment */ 1861.5Srillig 1871.5Srillig#if 0/* comment */ 1881.5Srillig#else/* comment */ 1891.5Srillig#endif/* comment */ 1901.5Srillig//indent end 1911.5Srillig 1921.8Srillig//indent run-equals-input 1931.6Srillig 1941.6Srillig 1951.6Srillig/* 1961.6Srillig * Multi-line comments in preprocessing lines. 1971.6Srillig */ 1981.6Srillig//indent input 1991.6Srillig#define eol_comment // EOL 2001.6Srillig 2011.8Srillig#define no_wrap_comment /* line 1 2021.6Srillig * line 2 2031.6Srillig * line 3 2041.6Srillig */ 2051.6Srillig 2061.6Srillig#define fixed_comment /*- line 1 2071.6Srillig * line 2 2081.6Srillig * line 3 2091.6Srillig */ 2101.7Srillig 2111.7Srillig#define two_comments /* 1 */ /* 2 */ /*3*/ 2121.7Srillig#define three_comments /* first */ /* second */ /*third*/ 2131.6Srillig//indent end 2141.6Srillig 2151.8Srillig//indent run-equals-input 2161.7Srillig 2171.7Srillig 2181.7Srillig/* 2191.7Srillig * Do not touch multi-line macro definitions. 2201.7Srillig */ 2211.7Srillig//indent input 2221.7Srillig#define do_once(stmt) \ 2231.7Srilligdo { \ 2241.7Srillig stmt; \ 2251.7Srillig} while (/* constant condition */ false) 2261.6Srillig//indent end 2271.7Srillig 2281.7Srillig//indent run-equals-input 2291.9Srillig 2301.9Srillig 2311.9Srillig/* 2321.9Srillig * The 'INDENT OFF' state is global, it does not depend on the preprocessing 2331.9Srillig * directives, otherwise the declarations for 'on' and 'after' would be moved 2341.9Srillig * to column 1. 2351.9Srillig */ 2361.9Srillig//indent input 2371.9Srilligint first_line; 2381.9Srillig int before; 2391.9Srillig#if 0 2401.9Srillig/*INDENT OFF*/ 2411.9Srillig int off; 2421.9Srillig#else 2431.9Srillig int on; 2441.9Srillig#endif 2451.9Srillig int after; 2461.9Srillig//indent end 2471.9Srillig 2481.9Srillig//indent run -di0 2491.9Srilligint first_line; 2501.9Srilligint before; 2511.9Srillig#if 0 2521.9Srillig/*INDENT OFF*/ 2531.9Srillig int off; 2541.9Srillig#else 2551.9Srillig int on; 2561.9Srillig#endif 2571.9Srillig int after; 2581.9Srillig//indent end 2591.11Srillig 2601.11Srillig 2611.11Srillig/* 2621.11Srillig * Before 2023-06-14, indent was limited to 5 levels of conditional compilation 2631.11Srillig * directives. 2641.11Srillig */ 2651.11Srillig//indent input 2661.11Srillig#if 1 2671.11Srillig#if 2 2681.11Srillig#if 3 2691.11Srillig#if 4 2701.11Srillig#if 5 2711.11Srillig#if 6 2721.11Srillig#endif 6 2731.11Srillig#endif 5 2741.11Srillig#endif 4 2751.11Srillig#endif 3 2761.11Srillig#endif 2 2771.11Srillig#endif 1 2781.11Srillig//indent end 2791.11Srillig 2801.11Srillig//indent run-equals-input 2811.11Srillig 2821.11Srillig 2831.11Srillig/* 2841.11Srillig * Unrecognized and unmatched preprocessing directives are preserved. 2851.11Srillig */ 2861.11Srillig//indent input 2871.11Srillig#else 2881.11Srillig#elif 0 2891.11Srillig#elifdef var 2901.11Srillig#endif 2911.11Srillig 2921.11Srillig#unknown 2931.11Srillig# 3 "file.c" 2941.11Srillig//indent end 2951.11Srillig 2961.11Srillig//indent run 2971.11Srillig#else 2981.11Srillig#elif 0 2991.11Srillig#elifdef var 3001.11Srillig#endif 3011.11Srillig 3021.11Srillig#unknown 3031.11Srillig# 3 "file.c" 3041.15Srillig// exit 1 3051.15Srillig// error: Standard Input:1: Unmatched #else 3061.15Srillig// error: Standard Input:2: Unmatched #elif 3071.15Srillig// error: Standard Input:3: Unmatched #elifdef 3081.15Srillig// error: Standard Input:4: Unmatched #endif 3091.11Srillig//indent end 3101.14Srillig 3111.14Srillig 3121.14Srillig/* 3131.14Srillig * The '#' can only occur at the beginning of a line, therefore indent does not 3141.14Srillig * care when it occurs in the middle of a line. 3151.14Srillig */ 3161.14Srillig//indent input 3171.14Srilligint no = #; 3181.14Srillig//indent end 3191.14Srillig 3201.14Srillig//indent run -di0 3211.14Srilligint no = 3221.14Srillig#; 3231.14Srillig//indent end 3241.14Srillig 3251.14Srillig 3261.14Srillig/* 3271.14Srillig * Preprocessing directives may be indented; indent moves them to the beginning 3281.14Srillig * of a line. 3291.14Srillig */ 3301.14Srillig//indent input 3311.14Srillig#if 0 3321.14Srillig #if 1 \ 3331.14Srillig || 2 3341.14Srillig #endif 3351.14Srillig#endif 3361.14Srillig//indent end 3371.14Srillig 3381.14Srillig//indent run 3391.14Srillig#if 0 3401.14Srillig#if 1 \ 3411.14Srillig || 2 3421.14Srillig#endif 3431.14Srillig#endif 3441.14Srillig//indent end 345