xref: /netbsd-src/tests/usr.bin/indent/lsym_lparen_or_lbracket.c (revision e914aa7b64febc5304e99be7f921a14dbe6ae4db)
1 /* $NetBSD: lsym_lparen_or_lbracket.c,v 1.20 2025/01/03 23:37:18 rillig Exp $ */
2 
3 /*
4  * Tests for the token lsym_lparen_or_lbracket, which represents a '(' or '['
5  * in these contexts:
6  *
7  * In a type name, '(' constructs a function type.
8  *
9  * In an expression, '(' starts an inner expression to override the usual
10  * operator precedence.
11  *
12  * In a function call expression, '(' marks the beginning of the function
13  * arguments.
14  *
15  * In a 'sizeof' expression, '(' is required if the argument is a type name.
16  *
17  * In an expression, '(' followed by a type name starts a cast expression or
18  * a compound literal.
19  *
20  * In a type declaration, '(' marks the beginning of the function parameters.
21  *
22  * After one of the keywords 'for', 'if', 'switch' or 'while', the controlling
23  * expression must be enclosed in '(' and ')'; see lsym_for.c, lsym_if.c,
24  * lsym_switch.c, lsym_while.c.
25  *
26  * In a declaration, '[' derives an array type.
27  *
28  * In an expression, '[' starts an array subscript.
29  */
30 
31 /* The '(' in a type name derives a function type. */
32 //indent input
33 typedef void signal_handler(int);
34 void (*signal(void (*)(int)))(int);
35 //indent end
36 
37 //indent run
38 typedef void signal_handler(int);
39 void		(*signal(void (*)(int)))(int);
40 //indent end
41 
42 
43 //indent input
44 #define macro(arg) ((arg) + 1)
45 //indent end
46 
47 //indent run-equals-input -di0
48 
49 
50 /*
51  * The '(' in an expression overrides operator precedence.  In multi-line
52  * expressions, the continuation lines are aligned on the parentheses.
53  */
54 //indent input
55 int nested = (
56 	(
57 		(
58 			(
59 				1 + 4
60 			)
61 		)
62 	)
63 );
64 //indent end
65 
66 //indent run
67 int		nested = (
68 			  (
69 			   (
70 			    (
71 			     1 + 4
72 			     )
73 			    )
74 			   )
75 );
76 //indent end
77 
78 
79 /* The '(' in a function call expression starts the argument list. */
80 //indent input
81 int var = macro_call ( arg1,  arg2  ,arg3);
82 //indent end
83 
84 //indent run
85 int		var = macro_call(arg1, arg2, arg3);
86 //indent end
87 
88 
89 /*
90  * The '(' in a sizeof expression is required for type names and optional for
91  * expressions.
92  */
93 //indent input
94 size_t sizeof_typename = sizeof ( int );
95 size_t sizeof_expr = sizeof ( 12345 ) ;
96 //indent end
97 
98 //indent run
99 size_t		sizeof_typename = sizeof(int);
100 size_t		sizeof_expr = sizeof(12345);
101 //indent end
102 
103 
104 /* The '[' in a type name derives an array type. */
105 //indent input
106 int array_of_numbers[100];
107 //indent end
108 
109 //indent run
110 int		array_of_numbers[100];
111 //indent end
112 
113 
114 /* The '[' in an expression accesses an array element. */
115 //indent input
116 int second_prime = &primes[1];
117 //indent end
118 
119 //indent run
120 int		second_prime = &primes[1];
121 //indent end
122 
123 
124 //indent input
125 void
126 function(void)
127 {
128 	/* Type casts */
129 	a = (int)b;
130 	a = (struct tag)b;
131 	/* TODO: The '(int)' is not a type cast, it is a prototype list. */
132 	a = (int (*)(int))fn;
133 
134 	/* Not type casts */
135 	a = sizeof(int) * 2;
136 	a = sizeof(5) * 2;
137 	a = offsetof(struct stat, st_mtime);
138 
139 	/* Grouping subexpressions */
140 	a = ((((b + c)))) * d;
141 }
142 //indent end
143 
144 //indent run-equals-input
145 
146 
147 //indent input
148 int zero = (((((((((((((((((((0)))))))))))))))))));
149 int many = ((((((((((((((((((((((((((((((((0))))))))))))))))))))))))))))))));
150 //indent end
151 
152 //indent run-equals-input -di0
153 
154 
155 //indent input
156 void (*action)(void);
157 //indent end
158 
159 //indent run-equals-input -di0
160 
161 
162 //indent input
163 void
164 function(void)
165 {
166     other_function();
167     other_function("first", 2, "last argument"[4]);
168 
169     if (false)(void)x;
170     if (false)(func)(arg);
171     if (false)(cond)?123:456;
172 
173     /* C99 compound literal */
174     origin = (struct point){0,0};
175 
176     /* GCC statement expression */
177     /* expr = ({if(expr)debug();expr;}); */
178 /* $ XXX: Generates 'error: Standard Input:36: Unbalanced parentheses'. */
179 }
180 //indent end
181 
182 //indent run
183 void
184 function(void)
185 {
186 	other_function();
187 	other_function("first", 2, "last argument"[4]);
188 
189 	if (false)
190 		(void)x;
191 	if (false)
192 		(func)(arg);
193 	if (false)
194 		(cond) ? 123 : 456;
195 
196 	/* C99 compound literal */
197 	origin = (struct point){0, 0};
198 
199 	/* GCC statement expression */
200 	/* expr = ({if(expr)debug();expr;}); */
201 }
202 //indent end
203 
204 
205 /*
206  * Test a few variants of C99 compound expressions, as the '{' and '}' must not
207  * be treated as block delimiters.
208  */
209 //indent input
210 {
211 	return (struct point){0, 0};
212 	return (struct point){
213 		0, 0
214 	};
215 	return (struct point){.x = 0, .y = 0};
216 	return (struct point){
217 		.x = 0,
218 		.y = 0,
219 	};
220 }
221 //indent end
222 
223 //indent run-equals-input
224 
225 
226 /*
227  * C99 designator initializers are the rare situation where there is a space
228  * before a '['.
229  */
230 //indent input
231 int array[] = {
232 	1, 2, [2] = 3, [3] = 4,
233 };
234 //indent end
235 
236 //indent run-equals-input -di0
237 
238 
239 /*
240  * Test want_blank_before_lparen for all possible token types.
241  */
242 //indent input
243 void cover_want_blank_before_lparen(void)
244 {
245 	/* ps.prev_lsym can never be 'newline'. */
246 	int newline =
247 	(3);
248 
249 	int lparen_or_lbracket = a[(3)];
250 	int rparen_or_rbracket = a[3](5);
251 	+(unary_op);
252 	3 + (binary_op);
253 	a++(postfix_op);	/* unlikely to be seen in practice */
254 	cond ? (question) : (5);
255 	switch (expr) {
256 	case (case_label):;
257 	}
258 	a ? 3 : (colon);
259 	(semicolon) = 3;
260 	int lbrace[] = {(3)};
261 	int rbrace_in_decl = {{3}(4)};	/* syntax error */
262 	{}
263 	(rbrace_in_stmt)();
264 	ident(3);
265 	int(decl);
266 	a++, (comma)();
267 	int comment = /* comment */ (3);	/* comment is skipped */
268 	switch (expr) {}
269 #define preprocessing
270 	(preprocessing)();
271 	(lsym_form_feed)();
272 	for(;;);
273 	do(lsym_do)=3;while(0);
274 	if(cond);else(lsym_else)();
275 	do(lsym_do);while(0);
276 	str.(member);		/* syntax error */
277 	L("string_prefix");		/* impossible */
278 	static (int)storage_class;	/* syntax error */
279 	funcname(3);
280 	typedef (type_def) new_type;
281 	// $ TODO: is keyword_struct_union_enum possible?
282 	struct (keyword_struct_union_enum);	/* syntax error */
283 }
284 //indent end
285 
286 //indent run -ldi0
287 void
288 cover_want_blank_before_lparen(void)
289 {
290 	/* ps.prev_lsym can never be 'newline'. */
291 	int newline =
292 		(3);
293 
294 	int lparen_or_lbracket = a[(3)];
295 	int rparen_or_rbracket = a[3](5);
296 	+(unary_op);
297 	3 + (binary_op);
298 	a++(postfix_op);	/* unlikely to be seen in practice */
299 	cond ? (question) : (5);
300 	switch (expr) {
301 	case (case_label): ;
302 	}
303 	a ? 3 : (colon);
304 	(semicolon) = 3;
305 	int lbrace[] = {(3)};
306 	int rbrace_in_decl = {{3} (4)};	/* syntax error */
307 	{
308 	}
309 	(rbrace_in_stmt)();
310 	ident(3);
311 	int (decl);
312 	a++, (comma)();
313 	int comment = /* comment */ (3);	/* comment is skipped */
314 	switch (expr) {
315 	}
316 #define preprocessing
317 	(preprocessing)();
318 	(lsym_form_feed)();
319 	for (;;)
320 		;
321 	do
322 		(lsym_do) = 3;
323 	while (0);
324 	if (cond)
325 		;
326 	else
327 		(lsym_else)();
328 	do
329 		(lsym_do);
330 	while (0);
331 	str.(member);		/* syntax error */
332 	L("string_prefix");	/* impossible */
333 	static (int)storage_class;	/* syntax error */
334 	funcname(3);
335 	typedef (type_def) new_type;
336 	struct (keyword_struct_union_enum);	/* syntax error */
337 }
338 //indent end
339 
340 /* See t_errors.sh, test case 'compound_literal'. */
341 
342 
343 /*
344  * Ensure that a designated initializer after a comma is not indented further
345  * than necessary, as in most other contexts, there is no space before a '['.
346  */
347 //indent input
348 int arr[] = {
349 ['0'] = 1,
350 ['1'] = 2,
351 };
352 //indent end
353 
354 //indent run -di0
355 int arr[] = {
356 	['0'] = 1,
357 	['1'] = 2,
358 };
359 //indent end
360 
361 
362 /* In an initializer, a '(' does not start a function definition. */
363 //indent input
364 {
365 type var = {
366 .CONCAT(a, b)
367 = init,
368 };
369 }
370 
371 //indent end
372 
373 //indent run
374 {
375 	type		var = {
376 		.CONCAT(a, b)
377 		= init,
378 	};
379 }
380 //indent end
381