tests/indent: migrate token tests to other tests

In indent.h 1.49 from 2021-10-25, the enumeration token_type was split
into lexer_symbol and parser_symbol to more clearly express that these
tokens fall into completely different classes of usage patterns.
This commit is contained in:
rillig 2022-04-24 10:36:37 +00:00
parent 34f99f73c4
commit b60cb68fed
56 changed files with 2153 additions and 2328 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1197 2022/04/24 08:48:17 rillig Exp $
# $NetBSD: mi,v 1.1198 2022/04/24 10:36:37 rillig Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -4771,6 +4771,7 @@
./usr/tests/usr.bin/indent/declarations.0 tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/declarations.0.stderr tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/declarations.0.stdout tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/edge_cases.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/elsecomment.0 tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/elsecomment.0.pro tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/elsecomment.0.stdout tests-obsolete obsolete,atf
@ -4782,6 +4783,7 @@
./usr/tests/usr.bin/indent/fmt_decl.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/fmt_else_comment.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/fmt_expr.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/fmt_init.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/indent_off_on.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/indent_variables.0 tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/indent_variables.0.pro tests-obsolete obsolete,atf
@ -5253,44 +5255,44 @@
./usr/tests/usr.bin/indent/token-while_expr.0 tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token-while_expr.0.pro tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token-while_expr.0.stdout tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_binary_op.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_binary_op.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_case_label.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_colon.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_comma.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_comment.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_decl.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_do_stmt.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_end_of_file.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_for_exprs.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_form_feed.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_funcname.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_ident.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_comment.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_decl.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_do_stmt.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_end_of_file.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_for_exprs.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_form_feed.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_funcname.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_ident.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_if_expr.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_if_expr_stmt.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_if_expr_stmt_else.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_keyword_do.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_keyword_do_else.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_keyword_else.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_keyword_for_if_while.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_keyword_struct_union_enum.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_keyword_do.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_keyword_do_else.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_keyword_else.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_keyword_for_if_while.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_keyword_struct_union_enum.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_lbrace.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_lparen.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_newline.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_newline.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_period.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_postfix_op.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_preprocessing.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_postfix_op.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_preprocessing.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_question.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_rbrace.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_rparen.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_semicolon.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_stmt.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_stmt_list.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_storage_class.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_string_prefix.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_switch_expr.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_type_def.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_unary_op.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_while_expr.c tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/token_rparen.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_semicolon.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_stmt.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_stmt_list.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_storage_class.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_string_prefix.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_switch_expr.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_type_def.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_unary_op.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/token_while_expr.c tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/types_from_file.0 tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/types_from_file.0.list tests-obsolete obsolete,atf
./usr/tests/usr.bin/indent/types_from_file.0.pro tests-obsolete obsolete,atf

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.44 2022/04/24 09:04:12 rillig Exp $
# $NetBSD: Makefile,v 1.45 2022/04/24 10:36:37 rillig Exp $
.include <bsd.own.mk>
@ -8,10 +8,12 @@ TESTS_SH+= t_misc
TESTS_SH+= t_options
FILESDIR= ${TESTSDIR}
FILES+= edge_cases.c
FILES+= fmt_block.c
FILES+= fmt_decl.c
FILES+= fmt_else_comment.c
FILES+= fmt_expr.c
FILES+= fmt_init.c
FILES+= indent_off_on.c
FILES+= label.c
FILES+= lex_char.c
@ -110,33 +112,6 @@ FILES+= psym_stmt_list.c
FILES+= psym_switch_expr.c
FILES+= psym_while_expr.c
FILES+= t_options.awk
FILES+= token_binary_op.c
FILES+= token_comment.c
FILES+= token_decl.c
FILES+= token_do_stmt.c
FILES+= token_end_of_file.c
FILES+= token_for_exprs.c
FILES+= token_form_feed.c
FILES+= token_funcname.c
FILES+= token_ident.c
FILES+= token_keyword_do.c
FILES+= token_keyword_do_else.c
FILES+= token_keyword_else.c
FILES+= token_keyword_for_if_while.c
FILES+= token_keyword_struct_union_enum.c
FILES+= token_newline.c
FILES+= token_postfix_op.c
FILES+= token_preprocessing.c
FILES+= token_rparen.c
FILES+= token_semicolon.c
FILES+= token_stmt.c
FILES+= token_stmt_list.c
FILES+= token_storage_class.c
FILES+= token_string_prefix.c
FILES+= token_switch_expr.c
FILES+= token_type_def.c
FILES+= token_unary_op.c
FILES+= token_while_expr.c
add-test: .PHONY
@set -eu; \

View File

@ -0,0 +1,42 @@
/* $NetBSD: edge_cases.c,v 1.1 2022/04/24 10:36:37 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.
*
* 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]' */
// $ XXX: The indentation is completely wrong.
// $ XXX: The space between 'array' and '<' doesn't belong there.
number = array <:subscript:>;
/* same as '(int){ initializer }' */
// $ XXX: The space between '%' and '>' doesn't belong there.
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 */

View File

@ -1,4 +1,4 @@
/* $NetBSD: fmt_decl.c,v 1.35 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: fmt_decl.c,v 1.36 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for declarations of global variables, external functions, and local
@ -884,3 +884,24 @@ a(char *fe)
{
}
//indent end
/*
* Before NetBSD indent.c 1.178 from 2021-10-29, indent removed the blank
* before the '=', in the second and third of these function pointer
* declarations. This was because indent interpreted the prototype parameters
* 'int' and 'int, int' as type casts, which doesn't make sense at all. Fixing
* this properly requires large style changes since indent is based on simple
* heuristics all over. This didn't change in indent.c 1.178; instead, the
* rule for inserting a blank before a binary operator was changed to always
* insert a blank, except at the beginning of a line.
*/
//indent input
char *(*fn)() = NULL;
char *(*fn)(int) = NULL;
char *(*fn)(int, int) = NULL;
//indent end
/* XXX: The parameter '(int)' is wrongly interpreted as a type cast. */
/* XXX: The parameter '(int, int)' is wrongly interpreted as a type cast. */
//indent run-equals-input -di0

View File

@ -0,0 +1,39 @@
/* $NetBSD: fmt_init.c,v 1.1 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for variable initializations.
*/
//indent input
int global = { initializer };
int global = {
initializer
};
void
example(void)
{
int local = { initializer };
int local = {
initializer
};
}
//indent end
//indent run -di0
// $ XXX: The spaces around the initializer are gone.
int global = {initializer};
int global = {
initializer
};
void
example(void)
{
// $ XXX: The spaces around the initializer are gone.
int local = {initializer};
int local = {
initializer
};
}
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_binary_op.c,v 1.5 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_binary_op.c,v 1.6 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_binary_op, which represents a binary operator in
@ -74,3 +74,89 @@ int var = expr**ptr;
//indent run -di0
int var = expr * *ptr;
//indent end
/*
* When indent tokenizes some operators, it allows for
* arbitrary repetitions of the operator character, followed by an
* arbitrary amount of '='. This is used for operators like '&&' or
* '|||==='.
*
* Before 2021-03-07 22:11:01, the comment '//' was treated as an
* operator as well, and so was the comment '/////', leading to
* unexpected results.
*
* See lexi.c, lexi, "default:".
*/
//indent input
void
long_run_of_operators(void)
{
if (a &&&&&&& b)
return;
if (a |||=== b)
return;
}
//indent end
//indent run-equals-input
/*
* Long chains of '+' and '-' must be split into several operators as the
* lexer has to distinguish between '++' and '+' early. The following
* sequence is thus tokenized as:
*
* word "a"
* postfix_op "++"
* binary_op "++"
* unary_op "++"
* unary_op "+"
* word "b"
*
* See lexi.c, lexi, "case '+':".
*/
//indent input
void
joined_unary_and_binary_operators(void)
{
if (a +++++++ b)
return;
}
//indent end
//indent run
void
joined_unary_and_binary_operators(void)
{
if (a++ ++ ++ +b)
return;
}
//indent end
/*
* Ensure that the result of the indentation does not depend on whether a
* token from the input starts in column 1 or 9.
*
* See process_binary_op, ps.curr_col_1.
*/
//indent input
int col_1 //
= //
1;
int col_9 //
= //
9;
//indent end
//indent run
int col_1 //
= //
1;
int col_9 //
= //
9;
//indent end

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_do.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_do.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_do, which represents the keyword 'do' that starts
@ -12,7 +12,19 @@
*/
//indent input
// TODO: add input
void
function(void)
{
do stmt();while(cond);
}
//indent end
//indent run-equals-input
//indent run
void
function(void)
{
do
stmt();
while (cond);
}
//indent end

View File

@ -1,11 +1,16 @@
/* $NetBSD: lsym_eof.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_eof.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_eof, which represents the end of the input file.
*
* The end of a file typically occurs after a top-level declaration, or after
* a preprocessing directive. Everything else is a syntax error.
*/
//indent input
// TODO: add input
int decl;
//indent end
//indent run-equals-input
//indent run
int decl;
//indent end

View File

@ -1,12 +1,89 @@
/* $NetBSD: lsym_for.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_for.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_for, which represents the keyword 'for' that
* starts a 'for' loop.
*
* Most 'for' loops have 3 expressions in their head. Each of these
* expressions is optional though.
*
* When all 3 expressions are omitted, the 'for' loop is often called a
* 'forever' loop.
*/
//indent input
// TODO: add input
void
example(void)
{
for (;;)
break;
for (var = value;;)
break;
for (; cond;)
break;
for (;; i++)
break;
}
//indent end
//indent run-equals-input
//indent input
void
function(void)
{
for (int i = 0; i < 6; i++)
print_char("hello\n"[i]);
forever {
stmt();
}
}
//indent end
//indent run-equals-input
/*
* Indent can cope with various syntax errors, which may be caused by
* syntactic macros like 'forever' or 'foreach'.
*/
//indent input
#define forever for (;;)
#define foreach(list, it) for (it = list.first; it != NULL; it = it->next)
void
function(void)
{
forever
stmt();
forever {
stmt();
}
/* $ No space after 'foreach' since it looks like a function name. */
foreach(list, it)
println(it->data);
/* $ No space after 'foreach' since it looks like a function name. */
foreach(list, it) {
println(it->data);
}
}
//indent end
//indent run-equals-input
/*
* Another variant of a 'for' loop, seen in sys/arch/arm/apple/apple_intc.c.
*/
//indent input
{
for (CPU_INFO_FOREACH(cii, ci)) {
}
}
//indent end
//indent run-equals-input

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_form_feed.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_form_feed.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_form_feed, which represents a form feed, a special
@ -8,7 +8,41 @@
*/
//indent input
// TODO: add input
void function_1(void);
void function_2(void);
//indent end
//indent run-equals-input
//indent run -di0
void function_1(void);
/* $ XXX: The form feed is not preserved. */
/* $ XXX: Why 2 empty lines? */
void function_2(void);
//indent end
/*
* Test form feed after 'if (expr)', which is handled in search_stmt.
*/
//indent input
void function(void)
{
if (expr)
/* <-- form feed */
{
}
}
//indent end
//indent run
void
function(void)
{
if (expr) {
/* $ XXX: The form feed has disappeared. */
/* <-- form feed */
}
}
//indent end

View File

@ -1,15 +1,23 @@
/* $NetBSD: lsym_funcname.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_funcname.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_funcname, which is an identifier that is followed
* by an opening parenthesis.
*
* TODO: Document how lsym_funcname is handled differently from lsym_word.
*
* See also:
* lsym_word.c
*/
//indent input
// TODO: add input
void
function(void)
{
func();
(func)();
func(1, 2, 3);
}
//indent end
//indent run-equals-input

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_if.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_if.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_if, which represents the keyword 'if' that starts
@ -6,7 +6,18 @@
*/
//indent input
// TODO: add input
void
function(void)
{
if(cond)stmt();
}
//indent end
//indent run-equals-input
//indent run
void
function(void)
{
if (cond)
stmt();
}
//indent end

View File

@ -1,17 +1,34 @@
/* $NetBSD: lsym_newline.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_newline.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_newline, which represents a forced line break in
* the source code.
*
* Indent preserves most of the line breaks from the original code.
* A newline ends an end-of-line comment that has been started with '//'.
*
* When a line ends with a backslash immediately followed by '\n', these two
* characters are merged and continue the logical line (C11 5.1.1.2p1i2).
*
* In other contexts, a newline is an ordinary space character from a
* compiler's point of view. Indent preserves most line breaks though.
*
* See also:
* lsym_form_feed.c
*/
//indent input
// TODO: add input
int var=
1
+2
+3
+4;
//indent end
//indent run-equals-input
//indent run
int var =
1
+ 2
+ 3
+ 4;
//indent end

View File

@ -1,9 +1,15 @@
/* $NetBSD: lsym_preprocessing.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_preprocessing.c,v 1.5 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_preprocessing, which represents a '#' that starts
* a preprocessing line.
*
* #define
* #ifdef
* #include
* #line
* #pragma
*
* The whole preprocessing line is processed separately from the main source
* code, without much tokenizing or parsing.
*/
@ -39,3 +45,171 @@
// TODO: backslash-newline
// TODO: block comment
// TODO: line comment
//indent input
#include <system-header.h>
#include "local-header.h"
//indent end
//indent run-equals-input
/*
* Nested conditional compilation.
*/
//indent input
#if 0
#else
#endif
#if 0 /* if comment */
#else /* else comment */
#endif /* endif comment */
#if 0 /* outer if comment */
# if nested /* inner if comment */
# else /* inner else comment */
# endif /* inner endif comment */
#endif /* outer endif comment */
//indent end
//indent run
#if 0
#else
#endif
#if 0 /* if comment */
#else /* else comment */
#endif /* endif comment */
#if 0 /* outer if comment */
/* $ XXX: The indentation is removed, which can get confusing */
#if nested /* inner if comment */
#else /* inner else comment */
#endif /* inner endif comment */
#endif /* outer endif comment */
//indent end
//indent input
#define multi_line_definition /* first line
* middle
* final line
*/ actual_value
//indent end
//indent run-equals-input
/*
* Before indent.c 1.129 from 2021-10-08, indent mistakenly interpreted quotes
* in comments as starting a string literal. The '"' in the comment started a
* string, the next '"' finished the string, and the following '/' '*' was
* interpreted as the beginning of a comment. This comment lasted until the
* next '*' '/', which in this test is another preprocessor directive, solely
* for symmetry.
*
* The effect was that the extra space after d2 was not formatted, as that
* line was considered part of the comment.
*/
//indent input
#define comment_in_string_literal "/* no comment "
int this_is_an_ordinary_line_again;
int d1 ;
#define confuse_d /*"*/ "/*"
int d2 ;
#define resolve_d "*/"
int d3 ;
int s1 ;
#define confuse_s /*'*/ '/*'
int s2 ;
#define resolve_s '*/'
int s3 ;
//indent end
//indent run
#define comment_in_string_literal "/* no comment "
int this_is_an_ordinary_line_again;
int d1;
#define confuse_d /*"*/ "/*"
int d2;
#define resolve_d "*/"
int d3;
int s1;
#define confuse_s /*'*/ '/*'
int s2;
#define resolve_s '*/'
int s3;
//indent end
/*
* A preprocessing directive inside an expression keeps the state about
* whether the next operator is unary or binary.
*/
//indent input
int binary_plus = 3
#define intermediate 1
+4;
int unary_plus =
#define intermediate 1
+ 4;
//indent end
//indent run
int binary_plus = 3
#define intermediate 1
+ 4;
int unary_plus =
#define intermediate 1
+4;
//indent end
/*
* Before io.c 1.135 from 2021-11-26, indent fixed malformed preprocessing
* lines that had arguments even though they shouldn't. It is not the task of
* an indenter to fix code, that's what a linter is for.
*/
//indent input
#if 0
#elif 1
#else if 3
#endif 0
//indent end
//indent run-equals-input
/*
* Existing comments are indented just like code comments.
*
* This means that the above wrong preprocessing lines (#else with argument)
* need to be fed through indent twice until they become stable. Since
* compilers issue warnings about these invalid lines, not much code still has
* these, making this automatic fix an edge case.
*/
//indent input
#if 0 /* comment */
#else /* comment */
#endif /* comment */
#if 0/* comment */
#else/* comment */
#endif/* comment */
//indent end
//indent run
#if 0 /* comment */
#else /* comment */
#endif /* comment */
#if 0 /* comment */
#else /* comment */
#endif /* comment */
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_rparen_or_rbracket.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_rparen_or_rbracket.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_rparen_or_lbracket, which represents ')' or ']',
@ -9,7 +9,12 @@
*/
//indent input
// TODO: add input
int var = (3);
int cast = (int)3;
int cast = (int)(3);
int call = function(3);
int array[3] = {1, 2, 3};
int array[3] = {[2] = 3};
//indent end
//indent run-equals-input
//indent run-equals-input -di0

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_semicolon.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_semicolon.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_semicolon, which represents ';' in these contexts:
@ -12,7 +12,32 @@
*/
//indent input
// TODO: add input
struct {
int member;
} global_var;
//indent end
//indent run-equals-input
//indent run-equals-input -di0
//indent input
void
function(void)
{
for ( ; ; )
stmt();
for (;;)
stmt();
}
//indent end
//indent run
void
function(void)
{
for (;;)
stmt();
for (;;)
stmt();
}
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_storage_class.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_storage_class.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_storage_class, which represents a storage class as
@ -6,7 +6,9 @@
*/
//indent input
// TODO: add input
static int definition_with_internal_linkage;
extern int declaration_with_external_linkage;
int definition_with_external_linkage;
//indent end
//indent run-equals-input
//indent run-equals-input -di0

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_tag.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_tag.c,v 1.5 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_tag, which represents one of the keywords
@ -40,3 +40,77 @@ indent_enum_constants(void)
//indent end
//indent run-equals-input -ci2
//indent input
struct stat {
mode_t st_mode;
};
union variant {
enum {
} tag;
int v_int;
long v_long;
bool v_bool;
void *v_pointer;
};
//indent end
//indent run-equals-input
/* See FreeBSD r303485. */
//indent input
int f(struct x *a);
void
t(void)
{
static const struct {
int a;
int b;
} c[] = {
{ D, E },
{ F, G }
};
}
void u(struct x a) {
int b;
struct y c = (struct y *)&a;
}
//indent end
//indent run
int f(struct x *a);
void
t(void)
{
static const struct {
int a;
int b;
} c[] = {
{D, E},
{F, G}
};
}
void
u(struct x a)
{
int b;
struct y c = (struct y *)&a;
}
//indent end
/* Comment between 'struct' and the tag name; doesn't occur in practice. */
//indent input
struct /* comment */ tag var;
//indent end
//indent run -di0
struct /* comment */ tag var;
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_typedef.c,v 1.5 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_typedef.c,v 1.6 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_typedef, which represents the keyword 'typedef'
@ -48,3 +48,14 @@ enum {
EC2
} E;
//indent end
/*
* Contrary to declarations, type definitions are not affected by the option
* '-di'.
*/
//indent input
typedef int number;
//indent end
//indent run-equals-input

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_unary_op.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_unary_op.c,v 1.5 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_unary_op, which represents a unary operator.
@ -20,3 +20,37 @@ unary_operators(void)
//indent end
//indent run-equals-input
/*
* The unary operators '+' and '-' can occur in long chains. In these chains,
* adjacent '+' must not be merged to '++' since that would be a different
* token. The same applies to '&', but that case is irrelevant in practice
* since the address of an address cannot be taken.
*/
//indent input
int var=+3;
int mixed=+-+-+-+-+-+-+-+-+-+-+-+-+-3;
int count=~-~-~-~-~-~-~-~-~-~-~-~-~-3;
int same = + + + + + - - - - - 3;
//indent end
//indent run -di0
int var = +3;
int mixed = +-+-+-+-+-+-+-+-+-+-+-+-+-3;
int count = ~-~-~-~-~-~-~-~-~-~-~-~-~-3;
int same = + + + + +- - - - -3;
//indent end
/*
* A special kind of unary operator is '->', which additionally suppresses the
* next space.
*/
//indent input
int var = p -> member;
//indent end
//indent run -di0
int var = p->member;
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_while.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_while.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token 'lsym_while', which represents the keyword 'while' that
@ -6,7 +6,22 @@
*/
//indent input
// TODO: add input
void
function(void)
{
while(cond)stmt();
do stmt();while(cond);
}
//indent end
//indent run-equals-input
//indent run
void
function(void)
{
while (cond)
stmt();
do
stmt();
while (cond);
}
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: lsym_word.c,v 1.5 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: lsym_word.c,v 1.6 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the token lsym_word, which represents a constant, a string
@ -11,6 +11,8 @@
// TODO: Is '"string"(' syntactically valid in any context?
// TODO: Is '123(' syntactically valid in any context?
// TODO: Would the output of the above depend on -pcs/-npcs?
// TODO: Add more systematic tests.
// TODO: Completely cover each state transition in lex_number_state.
//indent input
// TODO: add input
@ -32,3 +34,114 @@ int var\
//indent run
int var + name = 4;
//indent end
//indent input
wchar_t wide_string[] = L"wide string";
//indent end
/*
* Regardless of the line length, the 'L' must never be separated from the
* string literal. Before lexi.c 1.167 from 2021-11-28, the 'L' was a
* separate token, which could have resulted in accidental spacing between the
* 'L' and the following "".
*/
//indent run-equals-input -di0
//indent run-equals-input -di0 -l25
//indent run-equals-input -di0 -l1
//indent input
wchar_t wide_char[] = L'w';
//indent end
//indent run-equals-input -di0
/* Binary number literals, a GCC extension that was added in C11. */
//indent input
#define b00101010 -1
void t(void) {
unsigned a[] = {0b00101010, 0x00005678, 02, 17U};
float x[] = {.7f, 0.7f};
unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL};
if (0 b00101010)
return;
/* $ '0r' is not a number base prefix, so the tokens are split. */
if (0r12345)
return;
}
//indent end
//indent run
#define b00101010 -1
void
t(void)
{
unsigned a[] = {0b00101010, 0x00005678, 02, 17U};
float x[] = {.7f, 0.7f};
unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL};
if (0 b00101010)
return;
if (0 r12345)
return;
}
//indent end
/* Floating point numbers. */
//indent input
void t(void) {
unsigned long x = 314UL;
double y[] = {0x1P+9F, 0.3, .1, 1.2f, 0xa.p01f, 3.14f, 2.L};
int z = 0b0101;
DO_NOTHING;
x._y = 5;
}
//indent end
//indent run
void
t(void)
{
unsigned long x = 314UL;
double y[] = {0x1P+9F, 0.3, .1, 1.2f, 0xa.p01f, 3.14f, 2.L};
int z = 0b0101;
DO_NOTHING;
x._y = 5;
}
//indent end
/*
* Test identifiers containing '$', which some compilers support as an
* extension to the C standard.
*/
//indent input
int $ = jQuery; // just kidding
const char SYS$LOGIN[]="$HOME";
//indent end
//indent run
int $ = jQuery; // just kidding
const char SYS$LOGIN[] = "$HOME";
//indent end
/*
* Test the tokenizer for number constants.
*
* When the tokenizer reads a character that makes a token invalid (such as
* '0x') but may later be extended to form a valid token (such as '0x123'),
* indent does not care about this invalid prefix and returns it nevertheless.
*/
//indent input
int unfinished_hex_prefix = 0x;
double unfinished_hex_float = 0x123p;
//indent end
//indent run-equals-input -di0

View File

@ -1,4 +1,4 @@
/* $NetBSD: psym_decl.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: psym_decl.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the parser symbol psym_decl, which represents a declaration.
@ -6,13 +6,33 @@
* Since C99, declarations and statements can be mixed in blocks.
*
* A label can be followed by a statement but not by a declaration.
*
* Indent distinguishes global and local declarations.
*
* Declarations can be for functions or for variables.
*/
// TODO: prove that psym_decl can only ever occur at the top of the stack.
// TODO: delete decl_level if the above is proven.
//indent input
// TODO: add input
int global_var;
int global_array = [1,2,3,4];
int global_array = [
1
,2,
3,
4,
];
//indent end
//indent run-equals-input
//indent run -di0
int global_var;
int global_array = [1, 2, 3, 4];
int global_array = [
1
,2,
3,
4,
];
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: psym_do.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: psym_do.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the parser symbol psym_do, which represents the state after
@ -6,7 +6,43 @@
*/
//indent input
// TODO: add input
void function(void) {
do stmt(); while (0);
do {} while (0);
}
//indent end
//indent run-equals-input
//indent run
void
function(void)
{
do
stmt();
while (0);
do {
} while (0);
}
//indent end
/*
* The keyword 'do' is followed by a statement, as opposed to 'while', which
* is followed by a parenthesized expression.
*/
//indent input
void
function(void)
{
do(var)--;while(var>0);
}
//indent end
//indent run
void
function(void)
{
do
(var)--;
while (var > 0);
}
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: psym_do_stmt.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: psym_do_stmt.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the parser symbol psym_do_stmt, which represents the state after
@ -7,7 +7,25 @@
*/
//indent input
// TODO: add input
void function(void) {
do stmt(); while (0);
do { stmt(); } while (0);
do /* comment */ stmt(); while (0);
}
//indent end
//indent run-equals-input
//indent run
void
function(void)
{
do
stmt();
while (0);
do {
stmt();
} while (0);
do /* comment */
stmt();
while (0);
}
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: psym_else.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: psym_else.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the parser symbol psym_else, which represents the keyword 'else'
@ -7,8 +7,67 @@
* This parser symbol never ends up on the stack itself.
*/
/*
* When parsing nested incomplete 'if' statements, the problem of the
* 'dangling else' occurs. It is resolved by binding the 'else' to the
* innermost incomplete 'if' statement.
*
* In 'parse', an if_expr_stmt is reduced to a simple statement, unless the
* next token is 'else'. The comment does not influence this since it never
* reaches 'parse'.
*/
//indent input
// TODO: add input
void
example(bool cond)
{
if (cond)
if (cond)
if (cond)
stmt();
else
stmt();
/* comment */
else
stmt();
}
//indent end
//indent run-equals-input
//indent run
void
example(bool cond)
{
if (cond)
if (cond)
if (cond)
stmt();
else
stmt();
/* comment */
else
stmt();
}
//indent end
/*
* The keyword 'else' is followed by an expression, as opposed to 'if', which
* is followed by a parenthesized expression.
*/
//indent input
void
function(void)
{
if(var>0)var=0;else(var=3);
}
//indent end
//indent run
void
function(void)
{
if (var > 0)
var = 0;
else
(var = 3);
}
//indent end

View File

@ -1,4 +1,4 @@
/* $NetBSD: psym_stmt.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: psym_stmt.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the parser symbol psym_stmt, which represents a statement on the
@ -8,7 +8,21 @@
*/
//indent input
// TODO: add input
#define unless(cond) if (!(cond))
void
function(void)
{
stmt();
stmt; /* probably some macro */
unless(cond)
stmt();
}
//indent end
/*
* There is no space after 'unless' since indent cannot know that it is a
* syntactic macro, especially not when its definition is in a header file.
*/
//indent run-equals-input

View File

@ -1,14 +1,47 @@
/* $NetBSD: psym_stmt_list.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/* $NetBSD: psym_stmt_list.c,v 1.4 2022/04/24 10:36:37 rillig Exp $ */
/*
* Tests for the parser symbol psym_stmt_list, which represents a list of
* statements.
*
* Since C99, in such a statement list, statements can be intermixed with
* declarations.
*
* TODO: explain why psym_stmt and psym_stmt_list are both necessary.
*/
//indent input
// TODO: add input
void
function(void)
{
stmt();
int var;
stmt();
{
stmt();
int var;
stmt();
}
}
//indent end
//indent run-equals-input
//indent run-equals-input -ldi0
//indent input
void
return_after_rbrace(void)
{
{}return;
}
//indent end
//indent run
void
return_after_rbrace(void)
{
{
// $ FIXME: The 'return' must go in a separate line.
} return;
}
//indent end

View File

@ -1,153 +0,0 @@
/* $NetBSD: token_binary_op.c,v 1.13 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for binary operators like '+', '&&' and several others.
*
* Several binary operators can be used as unary operators as well, or in
* other contexts. An example for such an operator is '*', which can be a
* multiplication, or pointer dereference, or pointer type declaration.
*/
/* TODO: split into separate tests */
/* See C99 6.4.6 */
//indent input
void
punctuators(void)
{
int braces = { initializer };
int period = structure.member;
int arrow = structure->member;
/* digraphs */
number = array<:subscript:>;
number = (int)<% initializer %>;
}
//indent end
//indent run -ldi0
void
punctuators(void)
{
/* $ XXX: The spaces around the initializer are gone. */
int braces = {initializer};
int period = structure.member;
int arrow = structure->member;
/* digraphs */
/* $ XXX: indent is confused by the digraphs for '[' and ']'. */
/* $ This probably doesn't matter since digraphs are not used in practice. */
number = array <:subscript:>;
number = (int)<%initializer % >;
}
//indent end
/* TODO: move digraphs into separate test */
/* TODO: test trigraphs, which are as unusual as digraphs */
/* TODO: test digraphs and trigraphs in string literals, just for fun */
/*
* When indent tokenizes some of the operators, it allows for
* arbitrary repetitions of the operator character, followed by an
* arbitrary amount of '='. This is used for operators like '&&' or
* '|||==='.
*
* Before 2021-03-07 22:11:01, the comment '//' was treated as an
* operator as well, and so was the comment '/////', leading to
* unexpected results.
*
* See lexi.c, lexi, "default:".
*/
//indent input
void
long_run_of_operators(void)
{
if (a &&&&&&& b)
return;
if (a |||=== b)
return;
}
//indent end
//indent run-equals-input
/*
* Long chains of '+' and '-' must be split into several operators as the
* lexer has to distinguish between '++' and '+' early. The following
* sequence is thus tokenized as:
*
* word "a"
* postfix_op "++"
* binary_op "++"
* unary_op "++"
* unary_op "+"
* word "b"
*
* See lexi.c, lexi, "case '+':".
*/
//indent input
void
joined_unary_and_binary_operators(void)
{
if (a +++++++ b)
return;
}
//indent end
//indent run
void
joined_unary_and_binary_operators(void)
{
if (a++ ++ ++ +b)
return;
}
//indent end
/*
* Before NetBSD indent.c 1.178 from 2021-10-29, indent removed the blank
* before the '=', in the second and third of these function pointer
* declarations. This was because indent interpreted the prototype parameters
* 'int' and 'int, int' as type casts, which doesn't make sense at all. Fixing
* this properly requires large style changes since indent is based on simple
* heuristics all over. This didn't change in indent.c 1.178; instead, the
* rule for inserting a blank before a binary operator was changed to always
* insert a blank, except at the beginning of a line.
*/
//indent input
char *(*fn)() = NULL;
char *(*fn)(int) = NULL;
char *(*fn)(int, int) = NULL;
//indent end
/* XXX: The parameter '(int)' is wrongly interpreted as a type cast. */
/* XXX: The parameter '(int, int)' is wrongly interpreted as a type cast. */
//indent run-equals-input -di0
/*
* Ensure that the result of the indentation does not depend on whether a
* token from the input starts in column 1 or 9.
*
* See process_binary_op, ps.curr_col_1.
*/
//indent input
int col_1 //
= //
1;
int col_9 //
= //
9;
//indent end
//indent run
int col_1 //
= //
1;
int col_9 //
= //
9;
//indent end

File diff suppressed because it is too large Load Diff

View File

@ -1,31 +0,0 @@
/* $NetBSD: token_decl.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for declarations.
*
* Indent distinguishes global and local declarations.
*
* Declarations can be for functions or for variables.
*/
//indent input
int global_var;
int global_array = [1,2,3,4];
int global_array = [
1
,2,
3,
4,
];
//indent end
//indent run -di0
int global_var;
int global_array = [1, 2, 3, 4];
int global_array = [
1
,2,
3,
4,
];
//indent end

View File

@ -1,29 +0,0 @@
/* $NetBSD: token_do_stmt.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for do-while statements.
*/
//indent input
void function(void) {
do stmt(); while (0);
do { stmt(); } while (0);
do /* comment */ stmt(); while (0);
}
//indent end
//indent run
void
function(void)
{
do
stmt();
while (0);
do {
stmt();
} while (0);
do /* comment */
stmt();
while (0);
}
//indent end

View File

@ -1,16 +0,0 @@
/* $NetBSD: token_end_of_file.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the end of a file.
*
* The end of a file typically occurs after a top-level declaration, or after
* a preprocessing directive. Everything else is a syntax error.
*/
//indent input
int decl;
//indent end
//indent run
int decl;
//indent end

View File

@ -1,70 +0,0 @@
/* $NetBSD: token_for_exprs.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/*
* Test for 'for' loops.
*
* Most 'for' loops have 3 expressions in their head. Each of these
* expressions is optional though.
*
* When all 3 expressions are omitted, the 'for' loop is often called a
* 'forever' loop.
*/
//indent input
void
function(void)
{
for (int i = 0; i < 6; i++)
print_char("hello\n"[i]);
forever {
stmt();
}
}
//indent end
//indent run-equals-input
/*
* Indent can cope with various syntax errors, which may be caused by
* syntactic macros like 'forever' or 'foreach'.
*/
//indent input
#define forever for (;;)
#define foreach(list, it) for (it = list.first; it != NULL; it = it->next)
void
function(void)
{
forever
stmt();
forever {
stmt();
}
/* $ No space after 'foreach' since it looks like a function name. */
foreach(list, it)
println(it->data);
/* $ No space after 'foreach' since it looks like a function name. */
foreach(list, it) {
println(it->data);
}
}
//indent end
//indent run-equals-input
/*
* Another variant of a 'for' loop, seen in sys/arch/arm/apple/apple_intc.c.
*/
//indent input
{
for (CPU_INFO_FOREACH(cii, ci)) {
}
}
//indent end
//indent run-equals-input

View File

@ -1,45 +0,0 @@
/* $NetBSD: token_form_feed.c,v 1.5 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for form feeds, which is a control character (C99 5.2.1p3).
*/
//indent input
void function_1(void);
void function_2(void);
//indent end
//indent run -di0
void function_1(void);
/* $ XXX: The form feed is not preserved. */
/* $ XXX: Why 2 empty lines? */
void function_2(void);
//indent end
/*
* Test form feed after 'if (expr)', which is handled in search_stmt.
*/
//indent input
void function(void)
{
if (expr)
/* <-- form feed */
{
}
}
//indent end
//indent run
void
function(void)
{
if (expr) {
/* $ XXX: The form feed has disappeared. */
/* <-- form feed */
}
}
//indent end

View File

@ -1,17 +0,0 @@
/* $NetBSD: token_funcname.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for function names.
*/
//indent input
void
function(void)
{
func();
(func)();
func(1, 2, 3);
}
//indent end
//indent run-equals-input

View File

@ -1,94 +0,0 @@
/* $NetBSD: token_ident.c,v 1.7 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for identifiers, numbers and string literals.
*/
/* TODO: Add more systematic tests. */
/* TODO: Completely cover each state transition in lex_number_state. */
/* Binary number literals, a GCC extension that was added in C11. */
//indent input
#define b00101010 -1
void t(void) {
unsigned a[] = {0b00101010, 0x00005678, 02, 17U};
float x[] = {.7f, 0.7f};
unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL};
if (0 b00101010)
return;
/* $ '0r' is not a number base prefix, so the tokens are split. */
if (0r12345)
return;
}
//indent end
//indent run
#define b00101010 -1
void
t(void)
{
unsigned a[] = {0b00101010, 0x00005678, 02, 17U};
float x[] = {.7f, 0.7f};
unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL};
if (0 b00101010)
return;
if (0 r12345)
return;
}
//indent end
/* Floating point numbers. */
//indent input
void t(void) {
unsigned long x = 314UL;
double y[] = {0x1P+9F, 0.3, .1, 1.2f, 0xa.p01f, 3.14f, 2.L};
int z = 0b0101;
DO_NOTHING;
x._y = 5;
}
//indent end
//indent run
void
t(void)
{
unsigned long x = 314UL;
double y[] = {0x1P+9F, 0.3, .1, 1.2f, 0xa.p01f, 3.14f, 2.L};
int z = 0b0101;
DO_NOTHING;
x._y = 5;
}
//indent end
/*
* Test identifiers containing '$', which some compilers support as an
* extension to the C standard.
*/
//indent input
int $ = jQuery; // just kidding
const char SYS$LOGIN[]="$HOME";
//indent end
//indent run
int $ = jQuery; // just kidding
const char SYS$LOGIN[] = "$HOME";
//indent end
/*
* Test the tokenizer for number constants.
*
* When the tokenizer reads a character that makes a token invalid (such as
* '0x') but may later be extended to form a valid token (such as '0x123'),
* indent does not care about this invalid prefix and returns it nevertheless.
*/
//indent input
int unfinished_hex_prefix = 0x;
double unfinished_hex_float = 0x123p;
//indent end
//indent run-equals-input -di0

View File

@ -1,24 +0,0 @@
/* $NetBSD: token_keyword_do.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keyword 'do' that begins a do-while statement.
*/
//indent input
void function(void) {
do stmt(); while (0);
do {} while (0);
}
//indent end
//indent run
void
function(void)
{
do
stmt();
while (0);
do {
} while (0);
}
//indent end

View File

@ -1,30 +0,0 @@
/* $NetBSD: token_keyword_do_else.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keyword 'do' or 'else'. These two keywords are followed by
* a space. In contrast to 'for', 'if' and 'while', the space is not
* followed by a parenthesized expression.
*/
//indent input
void
function(void)
{
do(var)--;while(var>0);
if(var>0)var=0;else(var=3);
}
//indent end
//indent run
void
function(void)
{
do
(var)--;
while (var > 0);
if (var > 0)
var = 0;
else
(var = 3);
}
//indent end

View File

@ -1,46 +0,0 @@
/* $NetBSD: token_keyword_else.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keyword 'else'.
*
* When parsing nested incomplete 'if' statements, the problem of the
* 'dangling else' occurs. It is resolved by binding the 'else' to the
* innermost incomplete 'if' statement.
*/
/*
* In 'parse', an if_expr_stmt is reduced to a simple statement, unless the
* next token is 'else'. The comment does not influence this since it never
* reaches 'parse'.
*/
//indent input
void
example(bool cond)
{
if (cond)
if (cond)
if (cond)
stmt();
else
stmt();
/* comment */
else
stmt();
}
//indent end
//indent run
void
example(bool cond)
{
if (cond)
if (cond)
if (cond)
stmt();
else
stmt();
/* comment */
else
stmt();
}
//indent end

View File

@ -1,35 +0,0 @@
/* $NetBSD: token_keyword_for_if_while.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keywords 'for', 'if' and 'while'. These keywords have in
* common that they are followed by a space and a parenthesized statement
* head. For 'if' and 'while', this head is a single expression. For 'for',
* the head is 0 to 3 expressions, separated by semicolons.
*/
//indent input
void
function(void)
{
if(cond)stmt();
while(cond)stmt();
for(;cond;)stmt();
do stmt();while(cond);
}
//indent end
//indent run
void
function(void)
{
if (cond)
stmt();
while (cond)
stmt();
for (; cond;)
stmt();
do
stmt();
while (cond);
}
//indent end

View File

@ -1,78 +0,0 @@
/* $NetBSD: token_keyword_struct_union_enum.c,v 1.5 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keywords 'struct', 'union' and 'enum'.
*/
//indent input
struct stat {
mode_t st_mode;
};
union variant {
enum {
} tag;
int v_int;
long v_long;
bool v_bool;
void *v_pointer;
};
//indent end
//indent run-equals-input
/* See FreeBSD r303485. */
//indent input
int f(struct x *a);
void
t(void)
{
static const struct {
int a;
int b;
} c[] = {
{ D, E },
{ F, G }
};
}
void u(struct x a) {
int b;
struct y c = (struct y *)&a;
}
//indent end
//indent run
int f(struct x *a);
void
t(void)
{
static const struct {
int a;
int b;
} c[] = {
{D, E},
{F, G}
};
}
void
u(struct x a)
{
int b;
struct y c = (struct y *)&a;
}
//indent end
/* Comment between 'struct' and the tag name; doesn't occur in practice. */
//indent input
struct /* comment */ tag var;
//indent end
//indent run -di0
struct /* comment */ tag var;
//indent end

View File

@ -1,29 +0,0 @@
/* $NetBSD: token_newline.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/*-
* Tests for the token '\n', which ends a line.
*
* A newline ends an end-of-line comment that has been started with '//'.
*
* When a line ends with a backslash immediately followed by '\n', these two
* characters are merged and continue the logical line (C11 5.1.1.2p1i2).
*
* In other contexts, a newline is an ordinary space character from a
* compiler's point of view. Indent preserves most line breaks though.
*/
//indent input
int var=
1
+2
+3
+4;
//indent end
//indent run
int var =
1
+ 2
+ 3
+ 4;
//indent end

View File

@ -1,18 +0,0 @@
/* $NetBSD: token_postfix_op.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the postfix increment and decrement operators '++' and '--'.
*/
//indent input
void
function(void)
{
counter++;
++counter; /* this is a prefix unary operator instead */
counter--;
--counter; /* this is a prefix unary operator instead */
}
//indent end
//indent run-equals-input

View File

@ -1,178 +0,0 @@
/* $NetBSD: token_preprocessing.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/*-
* Tests for indenting preprocessing directives:
*
* #define
* #ifdef
* #pragma
* #line
*/
//indent input
#include <system-header.h>
#include "local-header.h"
//indent end
//indent run-equals-input
/*
* Nested conditional compilation.
*/
//indent input
#if 0
#else
#endif
#if 0 /* if comment */
#else /* else comment */
#endif /* endif comment */
#if 0 /* outer if comment */
# if nested /* inner if comment */
# else /* inner else comment */
# endif /* inner endif comment */
#endif /* outer endif comment */
//indent end
//indent run
#if 0
#else
#endif
#if 0 /* if comment */
#else /* else comment */
#endif /* endif comment */
#if 0 /* outer if comment */
/* $ XXX: The indentation is removed, which can get confusing */
#if nested /* inner if comment */
#else /* inner else comment */
#endif /* inner endif comment */
#endif /* outer endif comment */
//indent end
//indent input
#define multi_line_definition /* first line
* middle
* final line
*/ actual_value
//indent end
//indent run-equals-input
/*
* Before indent.c 1.129 from 2021-10-08, indent mistakenly interpreted quotes
* in comments as starting a string literal. The '"' in the comment started a
* string, the next '"' finished the string, and the following '/' '*' was
* interpreted as the beginning of a comment. This comment lasted until the
* next '*' '/', which in this test is another preprocessor directive, solely
* for symmetry.
*
* The effect was that the extra space after d2 was not formatted, as that
* line was considered part of the comment.
*/
//indent input
#define comment_in_string_literal "/* no comment "
int this_is_an_ordinary_line_again;
int d1 ;
#define confuse_d /*"*/ "/*"
int d2 ;
#define resolve_d "*/"
int d3 ;
int s1 ;
#define confuse_s /*'*/ '/*'
int s2 ;
#define resolve_s '*/'
int s3 ;
//indent end
//indent run
#define comment_in_string_literal "/* no comment "
int this_is_an_ordinary_line_again;
int d1;
#define confuse_d /*"*/ "/*"
int d2;
#define resolve_d "*/"
int d3;
int s1;
#define confuse_s /*'*/ '/*'
int s2;
#define resolve_s '*/'
int s3;
//indent end
/*
* A preprocessing directive inside an expression keeps the state about
* whether the next operator is unary or binary.
*/
//indent input
int binary_plus = 3
#define intermediate 1
+4;
int unary_plus =
#define intermediate 1
+ 4;
//indent end
//indent run
int binary_plus = 3
#define intermediate 1
+ 4;
int unary_plus =
#define intermediate 1
+4;
//indent end
/*
* Before io.c 1.135 from 2021-11-26, indent fixed malformed preprocessing
* lines that had arguments even though they shouldn't. It is not the task of
* an indenter to fix code, that's what a linter is for.
*/
//indent input
#if 0
#elif 1
#else if 3
#endif 0
//indent end
//indent run-equals-input
/*
* Existing comments are indented just like code comments.
*
* This means that the above wrong preprocessing lines (#else with argument)
* need to be fed through indent twice until they become stable. Since
* compilers issue warnings about these invalid lines, not much code still has
* these, making this automatic fix an edge case.
*/
//indent input
#if 0 /* comment */
#else /* comment */
#endif /* comment */
#if 0/* comment */
#else/* comment */
#endif/* comment */
//indent end
//indent run
#if 0 /* comment */
#else /* comment */
#endif /* comment */
#if 0 /* comment */
#else /* comment */
#endif /* comment */
//indent end

View File

@ -1,17 +0,0 @@
/* $NetBSD: token_rparen.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the token ')', which ends the corresponding ')', as well as ']',
* which ends the corresponding ']'.
*/
//indent input
int var = (3);
int cast = (int)3;
int cast = (int)(3);
int call = function(3);
int array[3] = {1, 2, 3};
int array[3] = {[2] = 3};
//indent end
//indent run-equals-input -di0

View File

@ -1,42 +0,0 @@
/* $NetBSD: token_semicolon.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the token ';'.
*
* The ';' ends a declaration.
*
* The ';' ends a statement.
*
* The ';' separates the 3 expressions in the head of the 'for' loop.
*/
//indent input
struct {
int member;
} global_var;
//indent end
//indent run-equals-input -di0
//indent input
void
function(void)
{
for ( ; ; )
stmt();
for (;;)
stmt();
}
//indent end
//indent run
void
function(void)
{
for (;;)
stmt();
for (;;)
stmt();
}
//indent end

View File

@ -1,25 +0,0 @@
/* $NetBSD: token_stmt.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for statements.
*/
//indent input
#define unless(cond) if (!(cond))
void
function(void)
{
stmt();
stmt; /* probably some macro */
unless(cond)
stmt();
}
//indent end
/*
* There is no space after 'unless' since indent cannot know that it is a
* syntactic macro, especially not when its definition is in a header file.
*/
//indent run-equals-input

View File

@ -1,25 +0,0 @@
/* $NetBSD: token_stmt_list.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for lists of statements.
*
* Since C99, in such a statement list, statements can be intermixed with
* declarations in arbitrary ways.
*/
//indent input
void
function(void)
{
stmt();
int var;
stmt();
{
stmt();
int var;
stmt();
}
}
//indent end
//indent run-equals-input -ldi0

View File

@ -1,13 +0,0 @@
/* $NetBSD: token_storage_class.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for storage classes such as 'extern', 'static', but not 'typedef'.
*/
//indent input
static int var;
extern int var;
int var;
//indent end
//indent run-equals-input -di0

View File

@ -1,28 +0,0 @@
/* $NetBSD: token_string_prefix.c,v 1.5 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for strings of wide characters, which are prefixed with 'L'.
*
* See FreeBSD r309220.
*/
//indent input
wchar_t wide_string[] = L"wide string";
//indent end
/*
* Regardless of the line length, the 'L' must never be separated from the
* string literal.
*/
//indent run-equals-input -di0
//indent run-equals-input -di0 -l25
//indent run-equals-input -di0 -l1
//indent input
wchar_t wide_char[] = L'w';
//indent end
//indent run-equals-input -di0

View File

@ -1,16 +0,0 @@
/* $NetBSD: token_switch_expr.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keyword 'switch' followed by a parenthesized expression.
*/
//indent input
void
function(void)
{
switch (expr) {
}
}
//indent end
//indent run-equals-input

View File

@ -1,15 +0,0 @@
/* $NetBSD: token_type_def.c,v 1.3 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keyword 'typedef'.
*/
/*
* Contrary to declarations, type definitions are not affected by the option
* '-di'.
*/
//indent input
typedef int number;
//indent end
//indent run-equals-input

View File

@ -1,19 +0,0 @@
/* $NetBSD: token_unary_op.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for unary operators, such as '+', '-', '*', '&'.
*/
//indent input
int var=+3;
int mixed=+-+-+-+-+-+-+-+-+-+-+-+-+-3;
int count=~-~-~-~-~-~-~-~-~-~-~-~-~-3;
int same = + + + + + - - - - - 3;
//indent end
//indent run -di0
int var = +3;
int mixed = +-+-+-+-+-+-+-+-+-+-+-+-+-3;
int count = ~-~-~-~-~-~-~-~-~-~-~-~-~-3;
int same = + + + + +- - - - -3;
//indent end

View File

@ -1,29 +0,0 @@
/* $NetBSD: token_while_expr.c,v 1.4 2022/04/24 09:04:12 rillig Exp $ */
/*
* Tests for the keyword 'while', followed by a parenthesized expression.
*/
//indent input
int main(int argc,char**argv){int o;while((o=getopt(argc,argv,"x:"))!=-1)
switch(o){case'x':do{o++;}while(o<5);break;default:usage();}return 0;}
//indent end
//indent run
int
main(int argc, char **argv)
{
int o;
while ((o = getopt(argc, argv, "x:")) != -1)
switch (o) {
case 'x':
do {
o++;
} while (o < 5);
break;
default:
usage();
/* $ FIXME: The 'return' must be in a separate line. */
} return 0;
}
//indent end