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