Home | History | Annotate | Line # | Download | only in indent
      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)();
    273 	for(;;);
    274 	do(lsym_do)=3;while(0);
    275 	if(cond);else(lsym_else)();
    276 	do(lsym_do);while(0);
    277 	str.(member);		/* syntax error */
    278 	L("string_prefix");		/* impossible */
    279 	static (int)storage_class;	/* syntax error */
    280 	funcname(3);
    281 	typedef (type_def) new_type;
    282 	// $ TODO: is keyword_struct_union_enum possible?
    283 	struct (keyword_struct_union_enum);	/* syntax error */
    284 }
    285 //indent end
    286 
    287 //indent run -ldi0
    288 void
    289 cover_want_blank_before_lparen(void)
    290 {
    291 	/* ps.prev_lsym can never be 'newline'. */
    292 	int newline =
    293 		(3);
    294 
    295 	int lparen_or_lbracket = a[(3)];
    296 	int rparen_or_rbracket = a[3](5);
    297 	+(unary_op);
    298 	3 + (binary_op);
    299 	a++(postfix_op);	/* unlikely to be seen in practice */
    300 	cond ? (question) : (5);
    301 	switch (expr) {
    302 	case (case_label): ;
    303 	}
    304 	a ? 3 : (colon);
    305 	(semicolon) = 3;
    306 	int lbrace[] = {(3)};
    307 	int rbrace_in_decl = {{3} (4)};	/* syntax error */
    308 	{
    309 	}
    310 	(rbrace_in_stmt)();
    311 	ident(3);
    312 	int (decl);
    313 	a++, (comma)();
    314 	int comment = /* comment */ (3);	/* comment is skipped */
    315 	switch (expr) {
    316 	}
    317 #define preprocessing
    318 	(preprocessing)();
    319 	(lsym_form_feed)();
    321 	for (;;)
    322 		;
    323 	do
    324 		(lsym_do) = 3;
    325 	while (0);
    326 	if (cond)
    327 		;
    328 	else
    329 		(lsym_else)();
    330 	do
    331 		(lsym_do);
    332 	while (0);
    333 	str.(member);		/* syntax error */
    334 	L("string_prefix");	/* impossible */
    335 	static (int)storage_class;	/* syntax error */
    336 	funcname(3);
    337 	typedef (type_def) new_type;
    338 	struct (keyword_struct_union_enum);	/* syntax error */
    339 }
    340 //indent end
    341 
    342 /* See t_errors.sh, test case 'compound_literal'. */
    343 
    344 
    345 /*
    346  * Ensure that a designated initializer after a comma is not indented further
    347  * than necessary, as in most other contexts, there is no space before a '['.
    348  */
    349 //indent input
    350 int arr[] = {
    351 ['0'] = 1,
    352 ['1'] = 2,
    353 };
    354 //indent end
    355 
    356 //indent run -di0
    357 int arr[] = {
    358 	['0'] = 1,
    359 	['1'] = 2,
    360 };
    361 //indent end
    362 
    363 
    364 /* In an initializer, a '(' does not start a function definition. */
    365 //indent input
    366 {
    367 type var = {
    368 .CONCAT(a, b)
    369 = init,
    370 };
    371 }
    372 
    373 //indent end
    374 
    375 //indent run
    376 {
    377 	type		var = {
    378 		.CONCAT(a, b)
    379 		= init,
    380 	};
    381 }
    382 //indent end
    383