xref: /netbsd-src/tests/usr.bin/indent/edge_cases.c (revision 65e3242c1e7ce8e4fda93bdaae8c93d7270ffe07)
1*65e3242cSrillig /* $NetBSD: edge_cases.c,v 1.4 2023/06/17 22:09:24 rillig Exp $ */
2b60cb68fSrillig 
3b60cb68fSrillig /*
4b60cb68fSrillig  * Tests for edge cases in the C programming language that indent does not
5b60cb68fSrillig  * support or in which cases indent behaves strangely.
6b60cb68fSrillig  */
7b60cb68fSrillig 
8b60cb68fSrillig /*
9b60cb68fSrillig  * Digraphs are replacements for the characters '[', '{' and '#', which are
109bf98238Srillig  * missing in some exotic restricted source character sets.  They are not used
119bf98238Srillig  * in practice, therefore indent doesn't need to support them.
12b60cb68fSrillig  *
13b60cb68fSrillig  * See C99 6.4.6
14b60cb68fSrillig  */
15b60cb68fSrillig //indent input
16b60cb68fSrillig void
digraphs(void)17b60cb68fSrillig digraphs(void)
18b60cb68fSrillig {
19b60cb68fSrillig 	/* same as 'array[subscript]' */
20b60cb68fSrillig 	number = array<:subscript:>;
21b60cb68fSrillig 
22b60cb68fSrillig 	/* same as '(int){ initializer }' */
23b60cb68fSrillig 	number = (int)<% initializer %>;
24b60cb68fSrillig }
25b60cb68fSrillig //indent end
26b60cb68fSrillig 
27b60cb68fSrillig //indent run
28b60cb68fSrillig void
digraphs(void)29b60cb68fSrillig digraphs(void)
30b60cb68fSrillig {
31b60cb68fSrillig 	/* same as 'array[subscript]' */
329bf98238Srillig // $ Indent interprets everything before the second ':' as a label name,
333540994aSrillig // $ indenting the "label" 2 levels to the left.
349bf98238Srillig // $
359bf98238Srillig // $ The space between 'array' and '<' comes from the binary operator '<'.
36b60cb68fSrillig number = array <:subscript: >;
37b60cb68fSrillig 
38b60cb68fSrillig 	/* same as '(int){ initializer }' */
399bf98238Srillig // $ The opening '<' and '%' are interpreted as unary operators.
409bf98238Srillig // $ The closing '%' and '>' are interpreted as a binary and unary operator.
41b60cb68fSrillig 	number = (int)<%initializer % >;
42b60cb68fSrillig }
43b60cb68fSrillig //indent end
44b60cb68fSrillig 
45b60cb68fSrillig /* TODO: test trigraphs, which are as unusual as digraphs */
46b60cb68fSrillig /* TODO: test digraphs and trigraphs in string literals, just for fun */
47*65e3242cSrillig 
48*65e3242cSrillig 
49*65e3242cSrillig /*
50*65e3242cSrillig  * The keywords 'break', 'continue', 'goto' and 'restrict' are ordinary words,
51*65e3242cSrillig  * they do not force a line break before.
52*65e3242cSrillig  */
53*65e3242cSrillig //indent input
54*65e3242cSrillig {
55*65e3242cSrillig 	Whether to break or not to break, that is the question;
56*65e3242cSrillig 
57*65e3242cSrillig 	The people goto the shopping mall;
58*65e3242cSrillig 
59*65e3242cSrillig 	Begin at the beginning, then continue until you come to the end;
60*65e3242cSrillig 	then stop;
61*65e3242cSrillig 
62*65e3242cSrillig 	Try to restrict yourself;
63*65e3242cSrillig }
64*65e3242cSrillig //indent end
65*65e3242cSrillig 
66*65e3242cSrillig //indent run-equals-input -di0
67*65e3242cSrillig 
68*65e3242cSrillig 
69*65e3242cSrillig /*
70*65e3242cSrillig  * Try a bit of Perl code, just for fun, taken from pkgsrc/pkgtools/pkglint4.
71*65e3242cSrillig  *
72*65e3242cSrillig  * It works surprisingly well.
73*65e3242cSrillig  */
74*65e3242cSrillig //indent input
75*65e3242cSrillig package PkgLint::Line;
76*65e3242cSrillig 
77*65e3242cSrillig use strict;
78*65e3242cSrillig use warnings;
79*65e3242cSrillig 
80*65e3242cSrillig BEGIN {
81*65e3242cSrillig 	import PkgLint::Util qw(
82*65e3242cSrillig 		false true
83*65e3242cSrillig 		assert
84*65e3242cSrillig 	);
85*65e3242cSrillig }
86*65e3242cSrillig 
87*65e3242cSrillig use enum qw(FNAME LINES TEXT PHYSLINES CHANGED BEFORE AFTER EXTRA);
88*65e3242cSrillig 
89*65e3242cSrillig sub new($$$$) {
90*65e3242cSrillig 	my ($class, $fname, $lines, $text, $physlines) = @_;
91*65e3242cSrillig 	my ($self) = ([$fname, $lines, $text, $physlines, false, [], [], {}]);
92*65e3242cSrillig 	bless($self, $class);
93*65e3242cSrillig 	return $self;
94*65e3242cSrillig }
95*65e3242cSrillig 
96*65e3242cSrillig sub fname($)		{ return shift()->[FNAME]; }
97*65e3242cSrillig 
98*65e3242cSrillig # querying, getting and setting the extra values.
99*65e3242cSrillig sub has($$) {
100*65e3242cSrillig 	my ($self, $name) = @_;
101*65e3242cSrillig 	return exists($self->[EXTRA]->{$name});
102*65e3242cSrillig }
103*65e3242cSrillig //indent end
104*65e3242cSrillig 
105*65e3242cSrillig //indent run -di0 -nfbs -npsl
106*65e3242cSrillig // $ Space after '::'.
107*65e3242cSrillig package PkgLint:: Line;
108*65e3242cSrillig 
109*65e3242cSrillig use strict;
110*65e3242cSrillig use warnings;
111*65e3242cSrillig 
112*65e3242cSrillig BEGIN {
113*65e3242cSrillig // $ Space after '::'.
114*65e3242cSrillig 	import PkgLint:: Util qw(
115*65e3242cSrillig 				 false true
116*65e3242cSrillig 				 assert
117*65e3242cSrillig 	);
118*65e3242cSrillig }
119*65e3242cSrillig 
120*65e3242cSrillig // $ Space between 'qw' and '('.
121*65e3242cSrillig use enum qw (FNAME LINES TEXT PHYSLINES CHANGED BEFORE AFTER EXTRA);
122*65e3242cSrillig 
123*65e3242cSrillig sub new($$$$) {
124*65e3242cSrillig // $ No space between 'my' and '('.
125*65e3242cSrillig 	my($class, $fname, $lines, $text, $physlines) = @_;
126*65e3242cSrillig 	my($self) = ([$fname, $lines, $text, $physlines, false, [], [], {
127*65e3242cSrillig // $ Line break between '{' and '}'.
128*65e3242cSrillig 	}
129*65e3242cSrillig // $ Line break between '}' and ']'.
130*65e3242cSrillig 	]);
131*65e3242cSrillig 	bless($self, $class);
132*65e3242cSrillig 	return $self;
133*65e3242cSrillig }
134*65e3242cSrillig 
135*65e3242cSrillig sub fname($) {
136*65e3242cSrillig 	return shift()->[FNAME];
137*65e3242cSrillig }
138*65e3242cSrillig 
139*65e3242cSrillig // $ Preprocessing lines are mostly preserved.
140*65e3242cSrillig # querying, getting and setting the extra values.
141*65e3242cSrillig sub has($$) {
142*65e3242cSrillig 	my($self, $name) = @_;
143*65e3242cSrillig 	return exists($self->[EXTRA]->{
144*65e3242cSrillig // $ Line breaks between '{', '$name', '}' and ');'.
145*65e3242cSrillig 		$name
146*65e3242cSrillig 	}
147*65e3242cSrillig 	);
148*65e3242cSrillig }
149*65e3242cSrillig // exit 1
150*65e3242cSrillig // error: Standard Input:17: Unbalanced parentheses
151*65e3242cSrillig // warning: Standard Input:17: Extra ']'
152*65e3242cSrillig // warning: Standard Input:17: Extra ')'
153*65e3242cSrillig // error: Standard Input:27: Unbalanced parentheses
154*65e3242cSrillig // warning: Standard Input:27: Extra ')'
155*65e3242cSrillig //indent end
156*65e3242cSrillig 
157*65e3242cSrillig 
158*65e3242cSrillig /*
159*65e3242cSrillig  * Try a piece of old-style JavaScript, just for fun, using '==' instead of the
160*65e3242cSrillig  * now recommended '==='.
161*65e3242cSrillig  */
162*65e3242cSrillig //indent input
163*65e3242cSrillig function join(delim, values)
164*65e3242cSrillig {
165*65e3242cSrillig 	if (values.length == 0)
166*65e3242cSrillig 		return '';
167*65e3242cSrillig 	if (values.length == 1)
168*65e3242cSrillig 		return values[0];
169*65e3242cSrillig 	var result = '';
170*65e3242cSrillig 	for (var i in values) {
171*65e3242cSrillig 		result += delim;
172*65e3242cSrillig 		result += values[i];
173*65e3242cSrillig 	}
174*65e3242cSrillig 	return result.substr(delim.length);
175*65e3242cSrillig }
176*65e3242cSrillig //indent end
177*65e3242cSrillig 
178*65e3242cSrillig //indent run-equals-input -di0 -npsl
179