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