indent: fix handling of INDENT OFF/ON comments

Previously, the 'INDENT OFF' comments were interpreted when the newline
token from the line above the comment was processed, which was earlier
than could be reasonably expected.

The 'INDENT ON' comments were interpreted equally early, which led to
the situation that the 'INDENT OFF' comments were preserved literally
but the 'INDENT ON' comments weren't.
This commit is contained in:
rillig 2023-05-16 08:04:03 +00:00
parent c5af9e9a2f
commit c5b428c7c1
5 changed files with 59 additions and 76 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: indent_off_on.c,v 1.10 2023/05/14 17:53:38 rillig Exp $ */
/* $NetBSD: indent_off_on.c,v 1.11 2023/05/16 08:04:04 rillig Exp $ */
/*
* Tests for the comments 'INDENT OFF' and 'INDENT ON', which temporarily
@ -15,18 +15,12 @@
{}
//indent end
/*
* XXX: It is asymmetric that 'INDENT OFF' is kept as is, while 'INDENT ON'
* gets enclosed with spaces.
*/
//indent run
{
}
/* $ FIXME: This empty line must stay. */
/*INDENT OFF*/
/* $ FIXME: The empty line below must be above the 'OFF' comment. */
/* INDENT ON */
/*INDENT OFF*/
/*INDENT ON*/
{
}
@ -45,10 +39,9 @@
{
}
/*INDENT OFF*/
/* $ FIXME: The empty line below must be above the 'OFF' comment. */
/* INDENT ON */
/*INDENT OFF*/
/*INDENT ON*/
//indent end
@ -59,17 +52,11 @@
{}
//indent end
/*
* XXX: It is asymmetric that 'INDENT OFF' is indented, while 'INDENT ON'
* is aligned.
*/
//indent run
{
}
/* INDENT OFF */
/* $ FIXME: The empty line below must be removed. */
/* INDENT ON */
/* INDENT ON */
{
}
//indent end
@ -82,17 +69,11 @@
{}
//indent end
/*
* XXX: It is asymmetric that 'INDENT OFF' is indented, while 'INDENT ON'
* is aligned.
*/
//indent run
{
}
/* INDENT OFF */
/* $ FIXME: The empty line below must be removed. */
/* INDENT ON */
/* INDENT ON */
{
}
//indent end
@ -114,9 +95,7 @@ int decl ;
int decl;
/*INDENTOFF*/
int decl ;
/* $ FIXME: The empty line below must be removed. */
/* INDENTON */
/*INDENTON*/
int decl;
//indent end
@ -133,17 +112,11 @@ int decl ;
int decl ;
//indent end
/*
* XXX: It is asymmetric that 'INDENT OFF' is indented, while 'INDENT ON'
* is pushed to the start of the line.
*/
//indent run -di0
int decl;
/* INDENT OFF */
int decl ;
/* $ FIXME: The empty line below must be removed. */
/* INDENT ON */
/* INDENT ON */
int decl;
//indent end
@ -160,11 +133,7 @@ int format( void ) {{{
/*INDENT OFF*/
/* No formatting takes place here. */
int format( void ) {{{
/* $ XXX: Why is the INDENT ON comment indented? */
/* $ XXX: Why does the INDENT ON comment get spaces, but not the OFF comment? */
/* $ FIXME: The empty line below must be removed. */
/* INDENT ON */
/*INDENT ON*/
}
}
}
@ -197,19 +166,11 @@ void indent_still_on ( void ) ; /* due to the extra comment to the right */
//indent run
/* INDENT OFF */
void indent_off ( void ) ;
/* $ FIXME: The empty line below must be removed. */
/* $ XXX: The double space from the below comment got merged to a single */
/* $ XXX: space even though the comment might be regarded to be still in */
/* $ XXX: the OFF section. */
/* INDENT */
/* INDENT */
void indent_on(void);
/* INDENT OFF */
void indent_off ( void ) ;
/* $ FIXME: The empty line below must be removed. */
/* $ XXX: The below comment got moved from column 9 to column 1. */
/* INDENT ON */
/* INDENT ON */
void indent_on(void); /* the comment may be indented */
/* INDENT OFF */
void indent_off ( void ) ;
@ -217,8 +178,6 @@ void indent_off ( void ) ;
void indent_still_off ( void ) ; /* due to the word 'INDENTATION' */
/* INDENT ON * */
void indent_still_off ( void ) ; /* due to the extra '*' at the end */
/* $ FIXME: The empty line below must be removed. */
/* INDENT ON */
void indent_on(void);
/* INDENT: OFF */

View File

@ -1,4 +1,4 @@
/* $NetBSD: indent.c,v 1.286 2023/05/15 22:52:21 rillig Exp $ */
/* $NetBSD: indent.c,v 1.287 2023/05/16 08:04:03 rillig Exp $ */
/*-
* SPDX-License-Identifier: BSD-4-Clause
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: indent.c,v 1.286 2023/05/15 22:52:21 rillig Exp $");
__RCSID("$NetBSD: indent.c,v 1.287 2023/05/16 08:04:03 rillig Exp $");
#include <sys/param.h>
#include <err.h>
@ -85,7 +85,7 @@ bool break_comma;
float case_ind;
bool had_eof;
int line_no = 1;
bool inhibit_formatting;
enum indent_enabled indent_enabled;
static int ifdef_level;
static struct parser_state state_stack[5];
@ -118,6 +118,8 @@ buf_add_char(struct buffer *buf, char ch)
void
buf_add_chars(struct buffer *buf, const char *s, size_t len)
{
if (len == 0)
return;
if (len > buf->cap - buf->len)
buf_expand(buf, len);
memcpy(buf->mem + buf->len, s, len);
@ -327,6 +329,10 @@ process_eof(void)
{
if (lab.len > 0 || code.len > 0 || com.len > 0)
output_line();
if (indent_enabled != indent_on) {
indent_enabled = indent_last_off_line;
output_line();
}
if (ps.tos > 1) /* check for balanced braces */
diag(1, "Stuff missing from end of file");

View File

@ -1,4 +1,4 @@
/* $NetBSD: indent.h,v 1.143 2023/05/16 07:13:05 rillig Exp $ */
/* $NetBSD: indent.h,v 1.144 2023/05/16 08:04:03 rillig Exp $ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
@ -229,7 +229,11 @@ extern float case_ind; /* indentation level to be used for a "case
* n:" */
extern bool had_eof; /* whether input is exhausted */
extern int line_no; /* the current line number. */
extern bool inhibit_formatting; /* true if INDENT OFF is in effect */
extern enum indent_enabled {
indent_on,
indent_off,
indent_last_off_line,
} indent_enabled;
#define STACKSIZE 256
@ -412,9 +416,9 @@ char inp_peek(void);
char inp_lookahead(size_t);
void inp_skip(void);
char inp_next(void);
void clear_indent_off_text(void);
lexer_symbol lexi(void);
void lex_indent_comment(void);
void diag(int, const char *, ...) __printflike(2, 3);
void output_line(void);
void output_line_ff(void);

View File

@ -1,4 +1,4 @@
/* $NetBSD: io.c,v 1.172 2023/05/16 07:13:05 rillig Exp $ */
/* $NetBSD: io.c,v 1.173 2023/05/16 08:04:03 rillig Exp $ */
/*-
* SPDX-License-Identifier: BSD-4-Clause
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: io.c,v 1.172 2023/05/16 07:13:05 rillig Exp $");
__RCSID("$NetBSD: io.c,v 1.173 2023/05/16 08:04:03 rillig Exp $");
#include <stdio.h>
#include <string.h>
@ -50,6 +50,7 @@ __RCSID("$NetBSD: io.c,v 1.172 2023/05/16 07:13:05 rillig Exp $");
* current read position is inp.s, and the invariant inp.s < inp.e holds.
*/
static struct buffer inp;
static struct buffer indent_off_text;
static int paren_indent;
@ -103,7 +104,7 @@ inp_read_next_line(FILE *f)
for (;;) {
int ch = getc(f);
if (ch == EOF) {
if (!inhibit_formatting) {
if (indent_enabled == indent_on) {
buf_add_char(&inp, ' ');
buf_add_char(&inp, '\n');
}
@ -250,7 +251,7 @@ output_complete_line(char line_terminator)
output_char('\n');
}
if (!inhibit_formatting) {
if (indent_enabled == indent_on) {
if (ps.ind_level == 0)
ps.in_stmt_cont = false; /* this is a class A kludge */
@ -271,6 +272,12 @@ output_complete_line(char line_terminator)
output_char(line_terminator);
}
if (indent_enabled == indent_last_off_line) {
indent_enabled = indent_on;
output_range(indent_off_text.st, indent_off_text.len);
indent_off_text.len = 0;
}
ps.decl_on_line = ps.in_decl; /* for proper comment indentation */
ps.in_stmt_cont = ps.in_stmt_or_decl && !ps.in_decl;
ps.decl_indent_done = false;
@ -362,10 +369,14 @@ compute_label_indent(void)
void
inp_read_line(void)
{
if (indent_enabled == indent_on)
indent_off_text.len = 0;
buf_add_chars(&indent_off_text, inp.mem, inp.len);
inp_read_next_line(input);
lex_indent_comment();
if (inhibit_formatting)
output_range(inp.st, inp.len);
}
void
clear_indent_off_text(void)
{
indent_off_text.len = 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: lexi.c,v 1.193 2023/05/16 07:13:05 rillig Exp $ */
/* $NetBSD: lexi.c,v 1.194 2023/05/16 08:04:03 rillig Exp $ */
/*-
* SPDX-License-Identifier: BSD-4-Clause
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: lexi.c,v 1.193 2023/05/16 07:13:05 rillig Exp $");
__RCSID("$NetBSD: lexi.c,v 1.194 2023/05/16 08:04:03 rillig Exp $");
#include <stdlib.h>
#include <string.h>
@ -488,11 +488,9 @@ skip_string(const char **pp, const char *s)
return false;
}
void
static void
lex_indent_comment(void)
{
bool on;
const char *p = inp_line_start();
skip_blank(&p);
@ -502,11 +500,12 @@ lex_indent_comment(void)
if (!skip_string(&p, "INDENT"))
return;
enum indent_enabled enabled;
skip_blank(&p);
if (*p == '*' || skip_string(&p, "ON"))
on = true;
enabled = indent_last_off_line;
else if (skip_string(&p, "OFF"))
on = false;
enabled = indent_off;
else
return;
@ -517,7 +516,7 @@ lex_indent_comment(void)
if (lab.len > 0 || code.len > 0 || com.len > 0)
output_line();
inhibit_formatting = !on;
indent_enabled = enabled;
}
/* Reads the next token, placing it in the global variable "token". */
@ -654,6 +653,10 @@ lexi(void)
default:
if (token.mem[token.len - 1] == '/'
&& (inp_peek() == '*' || inp_peek() == '/')) {
enum indent_enabled prev = indent_enabled;
lex_indent_comment();
if (prev == indent_on && indent_enabled == indent_off)
clear_indent_off_text();
token_add_char(inp_next());
lsym = lsym_comment;
next_unary = ps.next_unary;