lsym_preprocessing.c revision 1.7
1/* $NetBSD: lsym_preprocessing.c,v 1.7 2023/05/11 18:44:14 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
208#if 0				/* comment */
209#else				/* comment */
210#endif				/* comment */
211
212#if 0				/* comment */
213#else				/* comment */
214#endif				/* comment */
215//indent end
216
217
218/*
219 * Multi-line comments in preprocessing lines.
220 */
221//indent input
222#define eol_comment		// EOL
223
224#define wrap_comment		/* line 1
225				 * line 2
226				 * line 3
227				 */
228
229#define fixed_comment		/*- line 1
230				 * line 2
231				 * line 3
232				 */
233
234#define two_comments /* 1 */ /* 2 */ /*3*/
235#define three_comments		/* first */ /* second */ /*third*/
236//indent end
237
238//indent run
239#define eol_comment		// EOL
240
241#define wrap_comment		/* line 1 line 2 line 3 */
242
243/* $ FIXME: Keep the original indentation of the follow-up lines. */
244#define fixed_comment		/*- line 1
245								 * line 2
246								 * line 3
247								 */
248
249#define two_comments /* 1 */ /* 2 */	/* 3 */
250#define three_comments		/* first */ /* second */	/* third */
251//indent end
252
253
254/*
255 * Do not touch multi-line macro definitions.
256 */
257//indent input
258#define do_once(stmt)		\
259do {				\
260	stmt;			\
261} while (/* constant condition */ false)
262//indent end
263
264//indent run-equals-input
265