xref: /netbsd-src/tests/usr.bin/indent/lsym_tag.c (revision 65e3242c1e7ce8e4fda93bdaae8c93d7270ffe07)
1 /* $NetBSD: lsym_tag.c,v 1.10 2023/06/17 22:09:24 rillig Exp $ */
2 
3 /*
4  * Tests for the token lsym_tag, which represents one of the keywords
5  * 'struct', 'union' or 'enum' that declare, define or use a tagged type.
6  */
7 
8 /* TODO: Add systematic tests for 'struct'. */
9 /* TODO: Add systematic tests for 'union'. */
10 /* TODO: Add systematic tests for 'enum'. */
11 
12 
13 //indent input
14 int
indent_enum_constants(void)15 indent_enum_constants(void)
16 {
17 	enum color {
18 		red,
19 		green
20 	};
21 	enum color	colors[] = {
22 		red,
23 		red,
24 		red,
25 	};
26 	/*
27 	 * Ensure that the token sequence 'enum type {' only matches if there
28 	 * are no other tokens in between, to prevent statement continuations
29 	 * from being indented like enum constant declarations.
30 	 *
31 	 * See https://gnats.netbsd.org/55453.
32 	 */
33 	if (colors[0] == (enum color)1) {
34 		return 1
35 		  + 2
36 		  + 3;
37 	}
38 	return 0;
39 }
40 //indent end
41 
42 //indent run-equals-input -ci2
43 
44 
45 //indent input
46 struct stat {
47 	mode_t		st_mode;
48 };
49 
50 union variant {
51 	enum {
52 	}		tag;
53 	int		v_int;
54 	long		v_long;
55 	bool		v_bool;
56 	void	       *v_pointer;
57 };
58 //indent end
59 
60 //indent run-equals-input
61 
62 
63 /* See FreeBSD r303485. */
64 //indent input
65 int f(struct x *a);
66 
67 void
t(void)68 t(void)
69 {
70 	static const struct {
71 		int	a;
72 		int	b;
73 	} c[] = {
74 		{ D, E },
75 		{ F, G }
76 	};
77 }
78 
u(struct x a)79 void u(struct x a) {
80 	int b;
81 	struct y c = (struct y *)&a;
82 }
83 //indent end
84 
85 //indent run
86 int		f(struct x *a);
87 
88 void
t(void)89 t(void)
90 {
91 	static const struct {
92 		int		a;
93 		int		b;
94 	}		c[] = {
95 		{D, E},
96 		{F, G}
97 	};
98 }
99 
100 void
u(struct x a)101 u(struct x a)
102 {
103 	int		b;
104 	struct y	c = (struct y *)&a;
105 }
106 //indent end
107 
108 
109 /* Comment between 'struct' and the tag name; doesn't occur in practice. */
110 //indent input
111 struct   /* comment */   tag var;
112 //indent end
113 
114 //indent run -di0
115 struct /* comment */ tag var;
116 //indent end
117 
118 
119 /*
120  * Ensure that the names of struct members are all indented the same.
121  * Before 2023-05-15, the indentation depended on their type name.
122  */
123 //indent input
124 struct outer {
125 	enum {
126 		untagged_constant,
127 	} untagged_member,
128 	  second_untagged_member;
129 	enum tag_name {
130 		tagged_constant,
131 	} tagged_member,
132 	  second_tagged_member;
133 };
134 //indent end
135 
136 //indent run-equals-input -di0
137 
138 
139 /*
140  * The initializer of an enum constant needs to be indented like any other
141  * initializer, especially the continuation lines.
142  */
143 //indent input
144 enum multi_line {
145 	ml1 = 1
146 	    + 2
147 	    + offsetof(struct s, member)
148 	    + 3,
149 	ml2 = 1
150 	    + 2
151 	    + offsetof(struct s, member)
152 	    + 3,
153 };
154 //indent end
155 
156 //indent run-equals-input -ci4
157 
158 //indent run-equals-input -ci4 -nlp
159 
160 
161 /*
162  * When 'typedef' or a tag is followed by a name, that name marks a type and a
163  * following '*' marks a pointer type.
164  */
165 //indent input
166 {
167 	// $ Syntactically invalid but shows that '*' is not multiplication.
168 	a = struct x * y;
169 	a = (struct x * y)z;
170 }
171 //indent end
172 
173 //indent run
174 {
175 	// $ Everything before the '*' is treated as a declaration.
176 	a = struct x   *y;
177 	a = (struct x *y)z;
178 }
179 //indent end
180