Home | History | Annotate | Line # | Download | only in indent
      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