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 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 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