Upgrade indent(1)

Merge all the changes from the recent FreeBSD HEAD snapshot
into our local copy.

FreeBSD actively maintains this program in their sources and their
repository contains over 100 commits with changes.

Keep the delta between the FreeBSD and NetBSD versions to absolute
minimum, mostly RCS Id and compatiblity fixes.

Major chages in this import:

 - Added an option -ldi<N> to control indentation of local variable names.
 - Added option -P for loading user-provided files as profiles
 - Added -tsn for setting tabsize
 - Rename -nsac/-sac ("space after cast") to -ncs/-cs
 - Added option -fbs Enables (disables) splitting the function declaration and opening brace across two lines.
 - Respect SIMPLE_BACKUP_SUFFIX environment variable in indent(1)
 - Group global option variables into an options structure
 - Use bsearch() for looking up type keywords.
 - Don't produce unneeded space character in function declarators
 - Don't unnecessarily add a blank before a comment ends.
 - Don't ignore newlines after comments that follow braces.

Merge the FreeBSD intend(1) tests with our ATF framework.
All tests pass.

Upgrade prepared by Manikishan Ghantasala.
Final polishing by myself.
This commit is contained in:
kamil 2019-04-04 15:22:13 +00:00
parent d7a2bf8dd0
commit d6a1bc3f07
13 changed files with 3315 additions and 3601 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.809 2019/02/26 10:01:40 isaki Exp $
# $NetBSD: mi,v 1.810 2019/04/04 15:22:13 kamil Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -3822,6 +3822,54 @@
./usr/tests/usr.bin/id/t_groups tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/id/t_id tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/id/t_whoami tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/Atffile tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua
./usr/tests/usr.bin/indent/t_indent tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/binary.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/binary.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/comments.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/comments.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/comments.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/cs.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/cs.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/cs.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/declarations.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/declarations.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/elsecomment.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/elsecomment.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/elsecomment.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/f_decls.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/f_decls.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/float.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/float.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/label.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/label.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/label.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/list_head.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/list_head.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/ncs.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/ncs.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/ncs.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/offsetof.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/offsetof.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/parens.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/parens.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/parens.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/pcs.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/pcs.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/pcs.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/struct.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/struct.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/surplusbad.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/surplusbad.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/surplusbad.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/types_from_file.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/types_from_file.0.list tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/types_from_file.0.pro tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/types_from_file.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/wchar.0 tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/indent/wchar.0.stdout tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/infocmp tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/infocmp/Atffile tests-usr.bin-tests compattestfile,atf
./usr/tests/usr.bin/infocmp/Kyuafile tests-usr.bin-tests compattestfile,atf,kyua

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.26 2018/09/05 21:05:40 kre Exp $
# $NetBSD: Makefile,v 1.27 2019/04/04 15:22:13 kamil Exp $
#
.include <bsd.own.mk>
@ -6,7 +6,7 @@
TESTSDIR= ${TESTSBASE}/usr.bin
TESTS_SUBDIRS= awk basename bzip2 cc cmp config cut \
diff dirname find gdb grep gzip id \
diff dirname find gdb grep gzip id indent \
infocmp jot ld m4 make mixerctl mkdep nbperf netpgpverify \
pkill pr printf rump_server shmif_dumpbus sdiff \
sed sort tmux tr unifdef uniq vmstat xlint

View File

@ -1,7 +1,9 @@
# $NetBSD: Makefile,v 1.6 2006/10/08 17:52:28 peter Exp $
# $NetBSD: Makefile,v 1.7 2019/04/04 15:22:13 kamil Exp $
# from: @(#)Makefile 8.1 (Berkeley) 6/6/93
PROG= indent
SRCS= indent.c io.c lexi.c parse.c pr_comment.c args.c
COPTS.io.c += -Wno-error=format-nonliteral
.include <bsd.prog.mk>

View File

@ -45,7 +45,7 @@ version. David Willcox (the author) states that:
| Time passed. Some years later, indent showed up on one of the early
| emacs distributions.
|
| Later still, someone from UC Berlekey called the UofI and asked if
| Later still, someone from UC Berkeley called the UofI and asked if
| indent was in the public domain. They wanted to include it in their
| UNIX distributions, along with the emacs stuff. I was no longer at the
| UofI, but Rob Kolstad, who was, asked me about it. I told him I didn't
@ -67,7 +67,7 @@ version. David Willcox (the author) states that:
| Berkeley's copyright probably should only cover their changes, and I
| don't know their feelings about sending it out.
In any case, there appears to be noone at UofI to clarify/and change
In any case, there appears to be none at UofI to clarify/and change
that copyright, but I am confident (based on the statements of its
author) that the code, as it stands with its copyright, is
distributable, and will not cause any legal problems.

View File

@ -1,37 +1,11 @@
/* $NetBSD: args.c,v 1.13 2016/02/22 21:20:29 ginsbach Exp $ */
/* $NetBSD: args.c,v 1.14 2019/04/04 15:22:13 kamil Exp $ */
/*
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -63,14 +37,20 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: args.c,v 1.13 2016/02/22 21:20:29 ginsbach Exp $");
#if defined(__NetBSD__)
__RCSID("$NetBSD: args.c,v 1.14 2019/04/04 15:22:13 kamil Exp $");
#elif defined(__FreeBSD__)
__FBSDID("$FreeBSD: head/usr.bin/indent/args.c 336318 2018-07-15 21:04:21Z pstef $");
#endif
#endif
#endif /* not lint */
/*
* Argument scanning and profile reading code. Default parameters are set
@ -79,16 +59,19 @@ __RCSID("$NetBSD: args.c,v 1.13 2016/02/22 21:20:29 ginsbach Exp $");
#include <ctype.h>
#include <err.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
#include "indent.h"
#define INDENT_VERSION "2.0"
/* profile types */
#define PRO_SPECIAL 1 /* special case */
#define PRO_BOOL 2 /* boolean */
#define PRO_INT 3 /* integer */
#define PRO_FONT 4 /* troff font */
/* profile specials for booleans */
#define ON 1 /* turn it on */
@ -100,8 +83,15 @@ __RCSID("$NetBSD: args.c,v 1.13 2016/02/22 21:20:29 ginsbach Exp $");
#define STDIN 3 /* use stdin */
#define KEY 4 /* type (keyword) */
static void scan_profile(FILE *);
#define KEY_FILE 5 /* only used for args */
#define VERSION 6 /* only used for args */
const char *option_source = "?";
void add_typedefs_from_file(const char *str);
/*
* N.B.: because of the way the table here is scanned, options whose names are
* substrings of other options must occur later; that is, with -lp vs -l, -lp
@ -109,355 +99,264 @@ const char *option_source = "?";
* default value is the one actually assigned.
*/
struct pro {
const char *p_name; /* name, eg -bl, -cli */
int p_type; /* type (int, bool, special) */
int p_default; /* the default value (if int) */
int p_special; /* depends on type */
int *p_obj; /* the associated variable */
} pro[] = {
{
"T", PRO_SPECIAL, 0, KEY, 0
},
{
"bacc", PRO_BOOL, false, ON, &blanklines_around_conditional_compilation
},
{
"badp", PRO_BOOL, false, ON, &blanklines_after_declarations_at_proctop
},
{
"bad", PRO_BOOL, false, ON, &blanklines_after_declarations
},
{
"bap", PRO_BOOL, false, ON, &blanklines_after_procs
},
{
"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments
},
{
"bc", PRO_BOOL, true, OFF, &ps.leave_comma
},
{
"bl", PRO_BOOL, true, OFF, &btype_2
},
{
"br", PRO_BOOL, true, ON, &btype_2
},
{
"bs", PRO_BOOL, false, ON, &Bill_Shannon
},
{
"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline
},
{
"cd", PRO_INT, 0, 0, &ps.decl_com_ind
},
{
"ce", PRO_BOOL, true, ON, &cuddle_else
},
{
"ci", PRO_INT, 0, 0, &continuation_indent
},
{
"cli", PRO_SPECIAL, 0, CLI, 0
},
{
"c", PRO_INT, 33, 0, &ps.com_ind
},
{
"di", PRO_INT, 16, 0, &ps.decl_indent
},
{
"dj", PRO_BOOL, false, ON, &ps.ljust_decl
},
{
"d", PRO_INT, 0, 0, &ps.unindent_displace
},
{
"eei", PRO_BOOL, false, ON, &extra_expression_indent
},
{
"ei", PRO_BOOL, true, ON, &ps.else_if
},
{
"fbc", PRO_FONT, 0, 0, (int *) &blkcomf
},
{
"fbx", PRO_FONT, 0, 0, (int *) &boxcomf
},
{
"fb", PRO_FONT, 0, 0, (int *) &bodyf
},
{
"fc1", PRO_BOOL, true, ON, &format_col1_comments
},
{
"fc", PRO_FONT, 0, 0, (int *) &scomf
},
{
"fk", PRO_FONT, 0, 0, (int *) &keywordf
},
{
"fs", PRO_FONT, 0, 0, (int *) &stringf
},
{
"ip", PRO_BOOL, true, ON, &ps.indent_parameters
},
{
"i", PRO_INT, 8, 0, &ps.ind_size
},
{
"lc", PRO_INT, 0, 0, &block_comment_max_col
},
{
"lp", PRO_BOOL, true, ON, &lineup_to_parens
},
{
"l", PRO_INT, 78, 0, &max_col
},
{
"nbacc", PRO_BOOL, false, OFF, &blanklines_around_conditional_compilation
},
{
"nbadp", PRO_BOOL, false, OFF, &blanklines_after_declarations_at_proctop
},
{
"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations
},
{
"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs
},
{
"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments
},
{
"nbc", PRO_BOOL, true, ON, &ps.leave_comma
},
{
"nbs", PRO_BOOL, false, OFF, &Bill_Shannon
},
{
"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline
},
{
"nce", PRO_BOOL, true, OFF, &cuddle_else
},
{
"ndj", PRO_BOOL, false, OFF, &ps.ljust_decl
},
{
"neei", PRO_BOOL, false, OFF, &extra_expression_indent
},
{
"nei", PRO_BOOL, true, OFF, &ps.else_if
},
{
"nfc1", PRO_BOOL, true, OFF, &format_col1_comments
},
{
"nip", PRO_BOOL, true, OFF, &ps.indent_parameters
},
{
"nlp", PRO_BOOL, true, OFF, &lineup_to_parens
},
{
"npcs", PRO_BOOL, false, OFF, &proc_calls_space
},
{
"npro", PRO_SPECIAL, 0, IGN, 0
},
{
"npsl", PRO_BOOL, true, OFF, &procnames_start_line
},
{
"nps", PRO_BOOL, false, OFF, &pointer_as_binop
},
{
"nsc", PRO_BOOL, true, OFF, &star_comment_cont
},
{
"nut", PRO_BOOL, true, OFF, &use_tabs
},
{
"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines
},
{
"nv", PRO_BOOL, false, OFF, &verbose
},
{
"pcs", PRO_BOOL, false, ON, &proc_calls_space
},
{
"psl", PRO_BOOL, true, ON, &procnames_start_line
},
{
"ps", PRO_BOOL, false, ON, &pointer_as_binop
},
{
"sc", PRO_BOOL, true, ON, &star_comment_cont
},
{
"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines
},
{
"st", PRO_SPECIAL, 0, STDIN, 0
},
{
"troff", PRO_BOOL, false, ON, &troff
},
{
"ut", PRO_BOOL, true, ON, &use_tabs
},
{
"v", PRO_BOOL, false, ON, &verbose
},
/* whew! */
{
0, 0, 0, 0, 0
}
const char *p_name; /* name, e.g. -bl, -cli */
int p_type; /* type (int, bool, special) */
int p_default; /* the default value (if int) */
int p_special; /* depends on type */
int *p_obj; /* the associated variable */
} pro[] = {
{"T", PRO_SPECIAL, 0, KEY, 0},
{"U", PRO_SPECIAL, 0, KEY_FILE, 0},
{"-version", PRO_SPECIAL, 0, VERSION, 0},
{"P", PRO_SPECIAL, 0, IGN, 0},
{"bacc", PRO_BOOL, false, ON, &opt.blanklines_around_conditional_compilation},
{"badp", PRO_BOOL, false, ON, &opt.blanklines_after_declarations_at_proctop},
{"bad", PRO_BOOL, false, ON, &opt.blanklines_after_declarations},
{"bap", PRO_BOOL, false, ON, &opt.blanklines_after_procs},
{"bbb", PRO_BOOL, false, ON, &opt.blanklines_before_blockcomments},
{"bc", PRO_BOOL, true, OFF, &opt.leave_comma},
{"bl", PRO_BOOL, true, OFF, &opt.btype_2},
{"br", PRO_BOOL, true, ON, &opt.btype_2},
{"bs", PRO_BOOL, false, ON, &opt.Bill_Shannon},
{"cdb", PRO_BOOL, true, ON, &opt.comment_delimiter_on_blankline},
{"cd", PRO_INT, 0, 0, &opt.decl_com_ind},
{"ce", PRO_BOOL, true, ON, &opt.cuddle_else},
{"ci", PRO_INT, 0, 0, &opt.continuation_indent},
{"cli", PRO_SPECIAL, 0, CLI, 0},
{"cs", PRO_BOOL, false, ON, &opt.space_after_cast},
{"c", PRO_INT, 33, 0, &opt.com_ind},
{"di", PRO_INT, 16, 0, &opt.decl_indent},
{"dj", PRO_BOOL, false, ON, &opt.ljust_decl},
{"d", PRO_INT, 0, 0, &opt.unindent_displace},
{"eei", PRO_BOOL, false, ON, &opt.extra_expression_indent},
{"ei", PRO_BOOL, true, ON, &opt.else_if},
{"fbs", PRO_BOOL, true, ON, &opt.function_brace_split},
{"fc1", PRO_BOOL, true, ON, &opt.format_col1_comments},
{"fcb", PRO_BOOL, true, ON, &opt.format_block_comments},
{"ip", PRO_BOOL, true, ON, &opt.indent_parameters},
{"i", PRO_INT, 8, 0, &opt.ind_size},
{"lc", PRO_INT, 0, 0, &opt.block_comment_max_col},
{"ldi", PRO_INT, -1, 0, &opt.local_decl_indent},
{"lpl", PRO_BOOL, false, ON, &opt.lineup_to_parens_always},
{"lp", PRO_BOOL, true, ON, &opt.lineup_to_parens},
{"l", PRO_INT, 78, 0, &opt.max_col},
{"nbacc", PRO_BOOL, false, OFF, &opt.blanklines_around_conditional_compilation},
{"nbadp", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations_at_proctop},
{"nbad", PRO_BOOL, false, OFF, &opt.blanklines_after_declarations},
{"nbap", PRO_BOOL, false, OFF, &opt.blanklines_after_procs},
{"nbbb", PRO_BOOL, false, OFF, &opt.blanklines_before_blockcomments},
{"nbc", PRO_BOOL, true, ON, &opt.leave_comma},
{"nbs", PRO_BOOL, false, OFF, &opt.Bill_Shannon},
{"ncdb", PRO_BOOL, true, OFF, &opt.comment_delimiter_on_blankline},
{"nce", PRO_BOOL, true, OFF, &opt.cuddle_else},
{"ncs", PRO_BOOL, false, OFF, &opt.space_after_cast},
{"ndj", PRO_BOOL, false, OFF, &opt.ljust_decl},
{"neei", PRO_BOOL, false, OFF, &opt.extra_expression_indent},
{"nei", PRO_BOOL, true, OFF, &opt.else_if},
{"nfbs", PRO_BOOL, true, OFF, &opt.function_brace_split},
{"nfc1", PRO_BOOL, true, OFF, &opt.format_col1_comments},
{"nfcb", PRO_BOOL, true, OFF, &opt.format_block_comments},
{"nip", PRO_BOOL, true, OFF, &opt.indent_parameters},
{"nlpl", PRO_BOOL, false, OFF, &opt.lineup_to_parens_always},
{"nlp", PRO_BOOL, true, OFF, &opt.lineup_to_parens},
{"npcs", PRO_BOOL, false, OFF, &opt.proc_calls_space},
{"npro", PRO_SPECIAL, 0, IGN, 0},
{"npsl", PRO_BOOL, true, OFF, &opt.procnames_start_line},
{"nsc", PRO_BOOL, true, OFF, &opt.star_comment_cont},
{"nsob", PRO_BOOL, false, OFF, &opt.swallow_optional_blanklines},
{"nut", PRO_BOOL, true, OFF, &opt.use_tabs},
{"nv", PRO_BOOL, false, OFF, &opt.verbose},
{"pcs", PRO_BOOL, false, ON, &opt.proc_calls_space},
{"psl", PRO_BOOL, true, ON, &opt.procnames_start_line},
{"sc", PRO_BOOL, true, ON, &opt.star_comment_cont},
{"sob", PRO_BOOL, false, ON, &opt.swallow_optional_blanklines},
{"st", PRO_SPECIAL, 0, STDIN, 0},
{"ta", PRO_BOOL, false, ON, &opt.auto_typedefs},
{"ts", PRO_INT, 8, 0, &opt.tabsize},
{"ut", PRO_BOOL, true, ON, &opt.use_tabs},
{"v", PRO_BOOL, false, ON, &opt.verbose},
/* whew! */
{0, 0, 0, 0, 0}
};
/*
* set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
* given in these files.
*/
void
set_profile(void)
set_profile(const char *profile_name)
{
FILE *f;
char fname[BUFSIZ];
static char prof[] = ".indent.pro";
FILE *f;
char fname[PATH_MAX];
static char prof[] = ".indent.pro";
if (profile_name == NULL)
snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof);
if ((f = fopen(option_source = fname, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
if ((f = fopen(option_source = prof, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
option_source = "Command line";
else
snprintf(fname, sizeof(fname), "%s", profile_name + 2);
if ((f = fopen(option_source = fname, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
if ((f = fopen(option_source = prof, "r")) != NULL) {
scan_profile(f);
(void) fclose(f);
}
option_source = "Command line";
}
void
static void
scan_profile(FILE *f)
{
int i;
char *p;
char buf[BUFSIZ];
int comment, i;
char *p;
char buf[BUFSIZ];
while (1) {
for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
if (p != buf) {
*p++ = 0;
if (verbose)
printf("profile: %s\n", buf);
set_option(buf);
} else
if (i == EOF)
return;
while (1) {
p = buf;
comment = 0;
while ((i = getc(f)) != EOF) {
if (i == '*' && !comment && p > buf && p[-1] == '/') {
comment = p - buf;
*p++ = i;
} else if (i == '/' && comment && p > buf && p[-1] == '*') {
p = buf + comment - 1;
comment = 0;
} else if (isspace((unsigned char)i)) {
if (p > buf && !comment)
break;
} else {
*p++ = i;
}
}
if (p != buf) {
*p++ = 0;
if (opt.verbose)
printf("profile: %s\n", buf);
set_option(buf);
}
else if (i == EOF)
return;
}
}
const char *param_start;
int
static const char *
eqin(const char *s1, const char *s2)
{
while (*s1) {
if (*s1++ != *s2++)
return (false);
}
param_start = s2;
return (true);
while (*s1) {
if (*s1++ != *s2++)
return (NULL);
}
return (s2);
}
/*
* Set the defaults.
*/
void
set_defaults(void)
{
struct pro *p;
struct pro *p;
/*
* Because ps.case_indent is a float, we can't initialize it from the
* table:
*/
ps.case_indent = 0.0; /* -cli0.0 */
for (p = pro; p->p_name; p++)
if (p->p_type != PRO_SPECIAL && p->p_type != PRO_FONT)
*p->p_obj = p->p_default;
/*
* Because ps.case_indent is a float, we can't initialize it from the
* table:
*/
opt.case_indent = 0.0; /* -cli0.0 */
for (p = pro; p->p_name; p++)
if (p->p_type != PRO_SPECIAL)
*p->p_obj = p->p_default;
}
void
set_option(char *arg)
{
struct pro *p;
struct pro *p;
const char *param_start;
arg++; /* ignore leading "-" */
for (p = pro; p->p_name; p++)
if (*p->p_name == *arg && eqin(p->p_name, arg))
goto found;
errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1);
arg++; /* ignore leading "-" */
for (p = pro; p->p_name; p++)
if (*p->p_name == *arg && (param_start = eqin(p->p_name, arg)) != NULL)
goto found;
errx(1, "%s: unknown parameter \"%s\"", option_source, arg - 1);
found:
switch (p->p_type) {
switch (p->p_type) {
case PRO_SPECIAL:
switch (p->p_special) {
case PRO_SPECIAL:
switch (p->p_special) {
case IGN:
break;
case IGN:
break;
case CLI:
if (*param_start == 0)
goto need_param;
ps.case_indent = atof(param_start);
break;
case CLI:
if (*param_start == 0)
goto need_param;
opt.case_indent = atof(param_start);
break;
case STDIN:
if (input == 0)
input = stdin;
if (output == 0)
output = stdout;
break;
case STDIN:
if (input == NULL)
input = stdin;
if (output == NULL)
output = stdout;
break;
case KEY:
if (*param_start == 0)
goto need_param;
{
char *str;
case KEY:
if (*param_start == 0)
goto need_param;
add_typename(param_start);
break;
str = strdup(param_start);
addkey(str, 4);
}
break;
case KEY_FILE:
if (*param_start == 0)
goto need_param;
add_typedefs_from_file(param_start);
break;
default:
errx(1, "set_option: internal error: p_special %d",
p->p_special);
}
break;
case PRO_BOOL:
if (p->p_special == OFF)
*p->p_obj = false;
else
*p->p_obj = true;
break;
case PRO_INT:
if (!isdigit((unsigned char)*param_start)) {
need_param:
errx(1, "%s: ``%s'' requires a parameter",
option_source, arg - 1);
}
*p->p_obj = atoi(param_start);
break;
case PRO_FONT:
parsefont((struct fstate *) p->p_obj, param_start);
break;
case VERSION:
printf("FreeBSD indent %s\n", INDENT_VERSION);
exit(0);
default:
errx(1, "set_option: internal error: p_type %d", p->p_type);
errx(1, "set_option: internal error: p_special %d", p->p_special);
}
break;
case PRO_BOOL:
if (p->p_special == OFF)
*p->p_obj = false;
else
*p->p_obj = true;
break;
case PRO_INT:
if (!isdigit((unsigned char)*param_start)) {
need_param:
errx(1, "%s: ``%s'' requires a parameter", option_source, p->p_name);
}
*p->p_obj = atoi(param_start);
break;
default:
errx(1, "set_option: internal error: p_type %d", p->p_type);
}
}
void
add_typedefs_from_file(const char *str)
{
FILE *file;
char line[BUFSIZ];
if ((file = fopen(str, "r")) == NULL) {
fprintf(stderr, "indent: cannot open file %s\n", str);
exit(1);
}
while ((fgets(line, BUFSIZ, file)) != NULL) {
/* Remove trailing whitespace */
line[strcspn(line, " \t\n\r")] = '\0';
add_typename(line);
}
fclose(file);
}

View File

@ -1,7 +1,9 @@
.\" $NetBSD: indent.1,v 1.26 2016/02/25 14:55:56 wiz Exp $
.\" $NetBSD: indent.1,v 1.27 2019/04/04 15:22:13 kamil Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
.\" The Regents of the University of California. All rights reserved.
.\" Copyright (c) 1976 Board of Trustees of the University of Illinois.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@ -27,41 +29,10 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" Copyright (c) 1985 Sun Microsystems, Inc.
.\" Copyright (c) 1976 Board of Trustees of the University of Illinois.
.\" All rights reserved.
.\" @(#)indent.1 8.1 (Berkeley) 7/1/93
.\" $FreeBSD: head/usr.bin/indent/indent.1 334944 2018-06-11 05:35:57Z pstef $
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" from: @(#)indent.1 8.1 (Berkeley) 7/1/93
.\"
.Dd February 24, 2016
.Dd June 11, 2018
.Dt INDENT 1
.Os
.Sh NAME
@ -72,48 +43,71 @@
.Op Ar input-file Op Ar output-file
.Op Fl bacc | Fl nbacc
.Op Fl bad | Fl nbad
.Op Fl badp | Fl nbadp
.Op Fl bap | Fl nbap
.Op Fl bbb | Fl nbbb
.Op Fl \&bc | Fl nbc
.Op Fl \&bl
.Op Fl \&br
.Op Fl \&bl | Fl \&br
.Op Fl bs | Fl nbs
.Op Fl c Ns Ar n
.Op Fl \&cd Ns Ar n
.Bk -words
.Op Fl cdb | Fl ncdb
.Ek
.Op Fl \&ce | Fl nce
.Op Fl \&ci Ns Ar n
.Op Fl cli Ns Ar n
.Op Fl cs | Fl ncs
.Op Fl d Ns Ar n
.Op Fl \&di Ns Ar n
.Op Fl dj | Fl ndj
.Bk -words
.Op Fl ei | Fl nei
.Op Fl eei | Fl neei
.Ek
.Bk -words
.Op Fl fbs | Fl nfbs
.Op Fl fc1 | Fl nfc1
.Op Fl fcb | Fl nfcb
.Ek
.Op Fl i Ns Ar n
.Op Fl \&ip | Fl nip
.Op Fl l Ns Ar n
.Op Fl \&lc Ns Ar n
.Op Fl \&ldi Ns Ar n
.Op Fl \&lp | Fl nlp
.Op Fl \&lpl | Fl nlpl
.Op Fl npro
.Op Fl P Ns Ar file
.Op Fl pcs | Fl npcs
.Op Fl psl | Fl npsl
.Op Fl \&sc | Fl nsc
.Bk -words
.Op Fl sob | Fl nsob
.Ek
.Op Fl \&st
.Op Fl troff
.Op Fl \&ta
.Op Fl T Ns Ar typename
.Op Fl ts Ns Ar n
.Op Fl U Ns Ar file
.Op Fl ut | Fl nut
.Op Fl v | Fl \&nv
.Op Fl -version
.Sh DESCRIPTION
The
.Nm
is a
.Tn C
utility is a
.Em C
program formatter.
It reformats the
.Tn C
.Em C
program in the
.Ar input-file
according to the switches.
The switches which can be specified are described below.
They may appear before or after the file names.
The switches which can be
specified are described below.
They may appear before or after the file
names.
.Pp
.Sy NOTE :
If you only specify an
@ -129,20 +123,18 @@ If
is named
.Sq Pa /blah/blah/file ,
the backup file is named
.Pa file.BAK .
.Sq Pa file.BAK
by default. The extension used for the backup file may be overridden using the
.Ev SIMPLE_BACKUP_SUFFIX
environment variable.
.Pp
If
.Ar output-file
is specified,
.Nm
checks to make sure it is different from
checks to make sure that it is different from
.Ar input-file .
.Pp
If no
.Ar input-file
is specified
input is read from stdin and the formatted file is written to stdout.
.Pp
The options listed below control the formatting style imposed by
.Nm .
.Bl -tag -width Op
@ -154,7 +146,7 @@ compilation block.
For example, in front of every #ifdef and after every #endif.
Other blank lines surrounding such blocks will be swallowed.
Default:
.Fl nbacc .
.Fl nbacc .
.It Fl bad , nbad
If
.Fl bad
@ -162,6 +154,14 @@ is specified, a blank line is forced after every block of
declarations.
Default:
.Fl nbad .
.It Fl badp , nbadp
This is vaguely similar to
.Fl bad
except that it only applies to the first set of declarations
in a procedure (just after the first `{') and it causes a blank
line to be generated even if there are no declarations.
The default is
.Fl nbadp.
.It Fl bap , nbap
If
.Fl bap
@ -181,8 +181,8 @@ is specified, then a newline is forced after each comma in a declaration.
.Fl nbc
turns off this option.
Default:
.Fl \&bc .
.It Fl \&br , \&bl
.Fl \&nbc .
.It Fl \&bl , \&br
Specifying
.Fl \&bl
lines up compound statements like this:
@ -201,24 +201,21 @@ if (...) {
code
}
.Ed
.It Fl bs , Fl nbs
If
.Fl bs
is specified, a blank is forced after
.Ic sizeof .
Default:
.Fl nbs .
.It Fl bs , nbs
Whether a blank should always be inserted after sizeof.
The default is
.Fl nbs.
.It Fl c Ns Ar n
The column in which comments on code start.
Default:
.Fl c33 .
The default is 33.
.It Fl cd Ns Ar n
The column in which comments on declarations start.
The default
is for these comments to start in the same column as those on code.
.It Fl cdb , ncdb
Enables (disables) the placement of comment delimiters on blank lines.
With this option enabled, comments look like this:
With
this option enabled, comments look like this:
.Bd -literal -offset indent
/*
* this is a comment
@ -232,12 +229,12 @@ Rather than like this:
.Pp
This only affects block comments, not comments to the right of
code.
Default:
The default is
.Fl cdb .
.It Fl ce , nce
Enables (disables) forcing `else's to cuddle up to the immediately preceding
Enables (disables) forcing of `else's to cuddle up to the immediately preceding
`}'.
Default:
The default is
.Fl \&ce .
.It Fl \&ci Ns Ar n
Sets the continuation indent to be
@ -248,7 +245,8 @@ statement.
Parenthesized expressions have extra indentation added to
indicate the nesting, unless
.Fl \&lp
is in effect.
is in effect
or the continuation indent is exactly half of the main indent.
.Fl \&ci
defaults to the same value as
.Fl i .
@ -260,42 +258,51 @@ tab stops to the right of the containing
statement.
.Fl cli0.5
causes case labels to be indented half a tab stop.
Default:
The
default is
.Fl cli0 .
.It Fl cs , ncs
Control whether parenthesized type names in casts are followed by a space or
not.
The default is
.Fl ncs .
.It Fl d Ns Ar n
Controls the placement of comments which are not to the right of code.
Controls the placement of comments which are not to the
right of code.
For example,
.Fl \&d\&1
means that such comments are placed one indentation level to the left of code.
means that such comments are placed one indentation level to the
left of code.
Specifying the default
.Fl \&d\&0
lines up these comments with the code.
See the section on comment
indentation below.
.It Fl \&di Ns Ar n
Specifies the indentation, in character positions, from a declaration keyword
to the following identifier.
Default:
Specifies the indentation, in character positions,
of global variable names and all struct/union member names
relative to the beginning of their type declaration.
The default is
.Fl di16 .
.It Fl dj , ndj
.Fl \&dj
left justifies declarations.
.Fl ndj
indents declarations the same as code.
Default:
The default is
.Fl ndj .
.It Fl \&ei , nei
Enables (disables) special
.Ic else-if
processing.
If it's enabled, an
If it is enabled, an
.Ic if
following an
.Ic else
will have the same indentation as the preceding
.Ic \&if
statement.
Default:
The default is
.Fl ei .
.It Fl eei , neei
Enables (disables) extra indentation on continuation lines of
@ -305,41 +312,70 @@ and
.Ic while
statements.
These continuation lines will be indented one extra level.
Default:
The default is
.Fl neei .
.It Fl fbs , nfbs
Enables (disables) splitting the function declaration and opening brace
across two lines.
The default is
.Fl fbs .
.It Fl fc1 , nfc1
Enables (disables) the formatting of comments that start in column 1.
Often, comments whose leading `/' is in column 1 have been carefully
hand formatted by the programmer.
In such cases,
.Fl nfc1
should be used.
Default:
should be
used.
The default is
.Fl fc1 .
.It Fl fcb , nfcb
Enables (disables) the formatting of block comments (ones that begin
with `/*\\n').
Often, block comments have been not so carefully hand formatted by the
programmer, but reformatting that would just change the line breaks is not
wanted.
In such cases,
.Fl nfcb
should be used.
Block comments are then handled like box comments.
The default is
.Fl fcb .
.It Fl i Ns Ar n
The number of spaces for one indentation level.
Default:
.Fl i8 .
The number of columns for one indentation level.
The default is 8.
.It Fl \&ip , nip
Enables (disables) the indentation of parameter declarations from the left
margin.
Default:
The default is
.Fl \&ip .
.It Fl l Ns Ar n
Maximum length of an output line.
Default:
.Fl l78 .
The default is 78.
.It Fl lc Ns Ar n
Maximum length of an output line in a block comment.
The default is 0, which means to limit block comment lines in accordance with
.Fl l.
.It Fl \&ldi Ns Ar n
Specifies the indentation, in character positions,
of local variable names
relative to the beginning of their type declaration.
The default is for local variable names to be indented
by the same amount as global ones.
.It Fl \&lp , nlp
Lines up code surrounded by parenthesis in continuation lines.
If a line has a left parenthesis which is not closed on that line, then
continuation lines will be lined up to start at the character
position just after the left parenthesis.
Lines up code surrounded by parentheses in continuation lines.
With
.Fl \&lp ,
if a line
has a left paren which is not closed on that line, then continuation lines
will be lined up to start at the character position just after the left
paren.
For example, here is how a piece of continued code looks with
.Fl nlp
in effect:
.Bd -literal -offset indent
p1 = first_procedure(second_procedure(p2, p3),
\ \ third_procedure(p4,p5));
\ \ third_procedure(p4, p5));
.Ed
.Pp
With
@ -347,52 +383,73 @@ With
in effect (the default) the code looks somewhat clearer:
.Bd -literal -offset indent
p1\ =\ first_procedure(second_procedure(p2,\ p3),
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,p5));
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,\ p5));
.Ed
.Pp
Inserting two more newlines we get:
.Bd -literal -offset indent
p1\ =\ first_procedure(second_procedure(p2,
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p3),
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ third_procedure(p4,
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ p5));
.Ed
.It Fl \&lpl , nlpl
With
.Fl \&lpl ,
code surrounded by parentheses in continuation lines is lined up even if it
would extend past the right margin.
With
.Fl \&nlpl
(the default), such a line that would extend past the right margin is moved
left to keep it within the margin, if that does not require placing it to
the left of the prevailing indentation level.
These switches have no effect if
.Fl nlp
is selected.
.It Fl npro
Causes the profile files,
.Sq Pa ./.indent.pro
and
.Sq Pa ~/.indent.pro ,
to be ignored.
.It Fl P Ns Ar file
Read profile from
.Ar file .
.It Fl pcs , npcs
If true
.Pq Fl pcs
all procedure calls will have a space inserted between
the name and the `('.
Default:
The default is
.Fl npcs .
.It Fl psl , npsl
If true
.Pq Fl psl
the names of procedures being defined are placed in
column 1 \- their types, if any, will be left on the previous lines.
Default:
The
default is
.Fl psl .
.It Fl \&sc , nsc
Enables (disables) the placement of asterisks (`*'s) at the left edge of all
comments.
Default:
The default is
.Fl sc .
.It Fl sob , nsob
If
.Fl sob
is specified, indent will swallow optional blank lines.
You can use this to get rid of blank lines after declarations.
You can use this to
get rid of blank lines after declarations.
Default:
.Fl nsob .
.It Fl \&st
Causes
.Nm
to take its input from stdin, and put its output to stdout.
to take its input from stdin and put its output to stdout.
.It Fl ta
Automatically add all identifiers ending in "_t" to the list
of type keywords.
.It Fl T Ns Ar typename
Adds
.Ar typename
@ -404,30 +461,26 @@ You need to specify all the typenames that
appear in your program that are defined by
.Ic typedef
\- nothing will be
harmed if you miss a few, but the program won't be formatted as nicely as
harmed if you miss a few, but the program will not be formatted as nicely as
it should.
This sounds like a painful thing to have to do, but it's really
This sounds like a painful thing to have to do, but it is really
a symptom of a problem in C:
.Ic typedef
causes a syntactic change in the
language and
.Nm
can't find all
cannot find all
instances of
.Ic typedef .
.It Fl troff
Causes
.Nm
to format the program for processing by
.Xr troff 1 .
It will produce a fancy
listing in much the same spirit as
.Xr vgrind 1 .
If the output file is not specified, the default is standard output,
rather than formatting in place.
.It Fl ts Ns Ar n
Assumed distance between tab stops.
The default is 8.
.It Fl U Ns Ar file
Adds type names from
.Ar file
to the list of type keywords.
.It Fl ut , nut
Enables (disables) the use of tab characters in the output.
Tabs are assumed to be aligned on columns divisible by 8.
The default is
.Fl ut .
.It Fl v , \&nv
@ -439,8 +492,12 @@ When in verbose mode,
.Nm
reports when it splits one line of input into two or more lines of output,
and gives some size statistics at completion.
Default:
The default is
.Fl \&nv .
.It Fl -version
Causes
.Nm
to print its version number and exit.
.El
.Pp
You may set up your own `profile' of defaults to
@ -455,12 +512,16 @@ If
.Nm
is run and a profile file exists, then it is read to set up the program's
defaults.
Switches on the command line, though, always override profile switches.
Switches on the command line, though, always override profile
switches.
The switches should be separated by spaces, tabs or newlines.
.Pp
.Ss Comments
.Sq Em Box
.Em comments .
The
.Nm
utility
assumes that any comment with a dash or star immediately after the start of
comment (that is, `/*\-' or `/**') is a comment surrounded by a box of stars.
Each line of such a comment is left unchanged, except that its indentation
@ -469,8 +530,9 @@ of the comment.
.Pp
.Em Straight text .
All other comments are treated as straight text.
The
.Nm
fits as many words (separated by blanks, tabs, or newlines) on a
utility fits as many words (separated by blanks, tabs, or newlines) on a
line as possible.
Blank lines break paragraphs.
.Ss Comment indentation
@ -492,8 +554,10 @@ automatically extended in extreme cases.
In general,
.Nm
leaves preprocessor lines alone.
The only reformatting that it will do is to straighten up trailing comments.
It leaves embedded comments alone.
The only
reformatting that it will do is to straighten up trailing comments.
It
leaves embedded comments alone.
Conditional compilation
.Pq Ic #ifdef...#endif
is recognized and
@ -501,18 +565,21 @@ is recognized and
attempts to correctly
compensate for the syntactic peculiarities introduced.
.Ss C syntax
The
.Nm
understands a substantial amount about the syntax of C, but it
utility understands a substantial amount about the syntax of C, but it
has a `forgiving' parser.
It attempts to cope with the usual sorts of incomplete and misformed syntax.
It attempts to cope with the usual sorts of
incomplete and malformed syntax.
In particular, the use of macros like:
.Pp
.Dl #define forever for(;;)
.Pp
is handled properly.
.Sh ENVIRONMENT
The
.Nm
uses the
utility uses the
.Ev HOME
environment variable.
.Sh FILES
@ -528,15 +595,15 @@ The
command appeared in
.Bx 4.2 .
.Sh BUGS
The
.Nm
has even more switches than
utility has even more switches than
.Xr ls 1 .
.Pp
A common mistake that often causes grief is typing:
A common mistake is to try to indent all the
.Em C
programs in a directory by typing:
.Pp
.Dl indent *.c
.Pp
to the shell in an attempt to indent all the
.Tn C
programs in a directory.
This is probably a bug, not a feature.

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +1,11 @@
/* $NetBSD: indent_codes.h,v 1.5 2003/08/07 11:14:08 agc Exp $ */
/* $NetBSD: indent_codes.h,v 1.6 2019/04/04 15:22:13 kamil Exp $ */
/*
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -64,7 +36,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
* @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
* $FreeBSD: head/usr.bin/indent/indent_codes.h 334564 2018-06-03 16:21:15Z pstef $
*/
#define newline 1
@ -99,3 +72,8 @@
#define ifhead 30
#define elsehead 31
#define period 32
#define strpfx 33
#define storage 34
#define funcname 35
#define type_def 36
#define structure 37

View File

@ -1,39 +1,11 @@
/* $NetBSD: indent_globs.h,v 1.10 2014/09/04 04:06:07 mrg Exp $ */
/* $NetBSD: indent_globs.h,v 1.11 2019/04/04 15:22:13 kamil Exp $ */
/*
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_globs.h 8.1 (Berkeley) 6/6/93
*/
/*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -64,7 +36,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)indent_globs.h 8.1 (Berkeley) 6/6/93
* @(#)indent_globs.h 8.1 (Berkeley) 6/6/93
* $FreeBSD: head/usr.bin/indent/indent_globs.h 337651 2018-08-11 19:20:06Z pstef $
*/
#define BACKSLASH '\\'
@ -73,293 +46,276 @@
#define label_offset 2 /* number of levels a label is placed to left
* of code */
#define tabsize 8 /* the size of a tab */
#define tabmask 0177770 /* mask used when figuring length of lines
* with tabs */
#define false 0
#define true 1
#ifndef EXTERN
#define EXTERN extern
#endif
FILE *input; /* the fid for the input file */
FILE *output; /* the output file */
EXTERN FILE *input; /* the fid for the input file */
EXTERN FILE *output; /* the output file */
#define CHECK_SIZE_CODE \
if (e_code >= l_code) { \
int nsize = l_code-s_code+400; \
#define CHECK_SIZE_CODE(desired_size) \
if (e_code + (desired_size) >= l_code) { \
int nsize = l_code-s_code + 400 + desired_size; \
int code_len = e_code-s_code; \
codebuf = (char *) realloc(codebuf, nsize); \
e_code = codebuf + (e_code-s_code) + 1; \
if (codebuf == NULL) \
err(1, NULL); \
e_code = codebuf + code_len + 1; \
l_code = codebuf + nsize - 5; \
s_code = codebuf + 1; \
}
#define CHECK_SIZE_COM \
if (e_com >= l_com) { \
int nsize = l_com-s_com+400; \
#define CHECK_SIZE_COM(desired_size) \
if (e_com + (desired_size) >= l_com) { \
int nsize = l_com-s_com + 400 + desired_size; \
int com_len = e_com - s_com; \
int blank_pos; \
if (last_bl != NULL) \
blank_pos = last_bl - combuf; \
else \
blank_pos = -1; \
combuf = (char *) realloc(combuf, nsize); \
e_com = combuf + (e_com-s_com) + 1; \
if (combuf == NULL) \
err(1, NULL); \
e_com = combuf + com_len + 1; \
if (blank_pos > 0) \
last_bl = combuf + blank_pos; \
l_com = combuf + nsize - 5; \
s_com = combuf + 1; \
}
#define CHECK_SIZE_LAB \
if (e_lab >= l_lab) { \
int nsize = l_lab-s_lab+400; \
#define CHECK_SIZE_LAB(desired_size) \
if (e_lab + (desired_size) >= l_lab) { \
int nsize = l_lab-s_lab + 400 + desired_size; \
int label_len = e_lab - s_lab; \
labbuf = (char *) realloc(labbuf, nsize); \
e_lab = labbuf + (e_lab-s_lab) + 1; \
if (labbuf == NULL) \
err(1, NULL); \
e_lab = labbuf + label_len + 1; \
l_lab = labbuf + nsize - 5; \
s_lab = labbuf + 1; \
}
#define CHECK_SIZE_TOKEN \
if (e_token >= l_token) { \
int nsize = l_token-s_token+400; \
#define CHECK_SIZE_TOKEN(desired_size) \
if (e_token + (desired_size) >= l_token) { \
int nsize = l_token-s_token + 400 + desired_size; \
int token_len = e_token - s_token; \
tokenbuf = (char *) realloc(tokenbuf, nsize); \
e_token = tokenbuf + (e_token-s_token) + 1; \
if (tokenbuf == NULL) \
err(1, NULL); \
e_token = tokenbuf + token_len + 1; \
l_token = tokenbuf + nsize - 5; \
s_token = tokenbuf + 1; \
}
EXTERN char *labbuf; /* buffer for label */
EXTERN char *s_lab; /* start ... */
EXTERN char *e_lab; /* .. and end of stored label */
EXTERN char *l_lab; /* limit of label buffer */
char *labbuf; /* buffer for label */
char *s_lab; /* start ... */
char *e_lab; /* .. and end of stored label */
char *l_lab; /* limit of label buffer */
EXTERN char *codebuf; /* buffer for code section */
EXTERN char *s_code; /* start ... */
EXTERN char *e_code; /* .. and end of stored code */
EXTERN char *l_code; /* limit of code section */
char *codebuf; /* buffer for code section */
char *s_code; /* start ... */
char *e_code; /* .. and end of stored code */
char *l_code; /* limit of code section */
EXTERN char *combuf; /* buffer for comments */
EXTERN char *s_com; /* start ... */
EXTERN char *e_com; /* ... and end of stored comments */
EXTERN char *l_com; /* limit of comment buffer */
char *combuf; /* buffer for comments */
char *s_com; /* start ... */
char *e_com; /* ... and end of stored comments */
char *l_com; /* limit of comment buffer */
#define token s_token
EXTERN char *tokenbuf; /* the last token scanned */
EXTERN char *s_token;
EXTERN char *e_token;
EXTERN char *l_token;
char *tokenbuf; /* the last token scanned */
char *s_token;
char *e_token;
char *l_token;
EXTERN char *in_buffer; /* input buffer */
EXTERN char *in_buffer_limit; /* the end of the input buffer */
EXTERN char *buf_ptr; /* ptr to next character to be taken from
* in_buffer */
EXTERN char *buf_end; /* ptr to first after last char in in_buffer */
char *in_buffer; /* input buffer */
char *in_buffer_limit; /* the end of the input buffer */
char *buf_ptr; /* ptr to next character to be taken from
* in_buffer */
char *buf_end; /* ptr to first after last char in in_buffer */
EXTERN char save_com[sc_size]; /* input text is saved here when looking for
* the brace after an if, while, etc */
EXTERN char *sc_end; /* pointer into save_com buffer */
char sc_buf[sc_size]; /* input text is saved here when looking for
* the brace after an if, while, etc */
char *save_com; /* start of the comment stored in sc_buf */
char *sc_end; /* pointer into save_com buffer */
EXTERN char *bp_save; /* saved value of buf_ptr when taking input
* from save_com */
EXTERN char *be_save; /* similarly saved value of buf_end */
char *bp_save; /* saved value of buf_ptr when taking input
* from save_com */
char *be_save; /* similarly saved value of buf_end */
EXTERN int pointer_as_binop;
EXTERN int blanklines_after_declarations;
EXTERN int blanklines_before_blockcomments;
EXTERN int blanklines_after_procs;
EXTERN int blanklines_around_conditional_compilation;
EXTERN int swallow_optional_blanklines;
EXTERN int n_real_blanklines;
EXTERN int prefix_blankline_requested;
EXTERN int postfix_blankline_requested;
EXTERN int break_comma; /* when true and not in parens, break after a
* comma */
EXTERN int btype_2; /* when true, brace should be on same line as
* if, while, etc */
EXTERN float case_ind; /* indentation level to be used for a "case
* n:" */
EXTERN int code_lines; /* count of lines with code */
EXTERN int had_eof; /* set to true when input is exhausted */
EXTERN int line_no; /* the current line number. */
EXTERN int max_col; /* the maximum allowable line length */
EXTERN int verbose; /* when true, non-essential error messages are
* printed */
EXTERN int cuddle_else; /* true if else should cuddle up to '}' */
EXTERN int star_comment_cont; /* true iff comment continuation lines should
* have stars at the beginning of each line. */
EXTERN int comment_delimiter_on_blankline;
EXTERN int troff; /* true iff were generating troff input */
EXTERN int procnames_start_line; /* if true, the names of procedures being
* defined get placed in column 1 (ie. a
* newline is placed between the type of the
* procedure and its name) */
EXTERN int proc_calls_space; /* If true, procedure calls look like:
* foo(bar) rather than foo (bar) */
EXTERN int format_col1_comments; /* If comments which start in column 1 are to
* be magically reformatted (just like
* comments that begin in later columns) */
EXTERN int inhibit_formatting; /* true if INDENT OFF is in effect */
EXTERN int suppress_blanklines; /* set iff following blanklines should be
* suppressed */
EXTERN int continuation_indent; /* set to the indentation between the edge of
* code and continuation lines */
EXTERN int lineup_to_parens; /* if true, continued code within parens will
* be lined up to the open paren */
EXTERN int Bill_Shannon; /* true iff a blank should always be inserted
* after sizeof */
EXTERN int blanklines_after_declarations_at_proctop; /* This is vaguely
* similar to
* blanklines_after_decla
* rations except that
* it only applies to
* the first set of
* declarations in a
* procedure (just after
* the first '{') and it
* causes a blank line
* to be generated even
* if there are no
* declarations */
EXTERN int block_comment_max_col;
EXTERN int extra_expression_indent; /* True if continuation lines from the
* expression part of "if(e)", "while(e)",
* "for(e;e;e)" should be indented an extra
* tab stop so that they don't conflict with
* the code that follows */
EXTERN int use_tabs; /* set true to use tabs for spacing,
* false uses all spaces */
struct options {
int blanklines_around_conditional_compilation;
int blanklines_after_declarations_at_proctop; /* this is vaguely
* similar to blanklines_after_decla except
* that in only applies to the first set of
* declarations in a procedure (just after
* the first '{') and it causes a blank line
* to be generated even if there are no
* declarations */
int blanklines_after_declarations;
int blanklines_after_procs;
int blanklines_before_blockcomments;
int leave_comma; /* if true, never break declarations after
* commas */
int btype_2; /* when true, brace should be on same line
* as if, while, etc */
int Bill_Shannon; /* true iff a blank should always be
* inserted after sizeof */
int comment_delimiter_on_blankline;
int decl_com_ind; /* the column in which comments after
* declarations should be put */
int cuddle_else; /* true if else should cuddle up to '}' */
int continuation_indent; /* set to the indentation between the
* edge of code and continuation lines */
float case_indent; /* The distance to indent case labels from the
* switch statement */
int com_ind; /* the column in which comments to the right
* of code should start */
int decl_indent; /* column to indent declared identifiers to */
int ljust_decl; /* true if declarations should be left
* justified */
int unindent_displace; /* comments not to the right of code
* will be placed this many
* indentation levels to the left of
* code */
int extra_expression_indent; /* true if continuation lines from
* the expression part of "if(e)",
* "while(e)", "for(e;e;e)" should be
* indented an extra tab stop so that they
* don't conflict with the code that follows */
int else_if; /* True iff else if pairs should be handled
* specially */
int function_brace_split; /* split function declaration and
* brace onto separate lines */
int format_col1_comments; /* If comments which start in column 1
* are to be magically reformatted (just
* like comments that begin in later columns) */
int format_block_comments; /* true if comments beginning with
* `/ * \n' are to be reformatted */
int indent_parameters;
int ind_size; /* the size of one indentation level */
int block_comment_max_col;
int local_decl_indent; /* like decl_indent but for locals */
int lineup_to_parens_always; /* if true, do not attempt to keep
* lined-up code within the margin */
int lineup_to_parens; /* if true, continued code within parens
* will be lined up to the open paren */
int proc_calls_space; /* If true, procedure calls look like:
* foo (bar) rather than foo(bar) */
int procnames_start_line; /* if true, the names of procedures
* being defined get placed in column 1 (ie.
* a newline is placed between the type of
* the procedure and its name) */
int space_after_cast; /* "b = (int) a" vs "b = (int)a" */
int star_comment_cont; /* true iff comment continuation lines
* should have stars at the beginning of
* each line. */
int swallow_optional_blanklines;
int auto_typedefs; /* set true to recognize identifiers
* ending in "_t" like typedefs */
int tabsize; /* the size of a tab */
int max_col; /* the maximum allowable line length */
int use_tabs; /* set true to use tabs for spacing, false
* uses all spaces */
int verbose; /* when true, non-essential error messages
* are printed */
} opt;
/* -troff font state information */
int found_err;
int n_real_blanklines;
int prefix_blankline_requested;
int postfix_blankline_requested;
int break_comma; /* when true and not in parens, break after a
* comma */
float case_ind; /* indentation level to be used for a "case
* n:" */
int code_lines; /* count of lines with code */
int had_eof; /* set to true when input is exhausted */
int line_no; /* the current line number. */
int inhibit_formatting; /* true if INDENT OFF is in effect */
int suppress_blanklines;/* set iff following blanklines should be
* suppressed */
struct fstate {
char font[4];
char size;
int allcaps:1;
};
#define STACKSIZE 256
EXTERN struct fstate
keywordf, /* keyword font */
stringf, /* string font */
boxcomf, /* Box comment font */
blkcomf, /* Block comment font */
scomf, /* Same line comment font */
bodyf; /* major body font */
#define STACK_SIZE 150
EXTERN struct parser_state {
int last_token;
struct fstate cfont; /* Current font */
int p_stack[STACK_SIZE]; /* this is the parsers stack */
int il[STACK_SIZE]; /* this stack stores indentation levels */
float cstk[STACK_SIZE];/* used to store case stmt indentation levels */
int box_com; /* set to true when we are in a "boxed"
struct parser_state {
int last_token;
int p_stack[STACKSIZE]; /* this is the parsers stack */
int il[STACKSIZE]; /* this stack stores indentation levels */
float cstk[STACKSIZE];/* used to store case stmt indentation levels */
int box_com; /* set to true when we are in a "boxed"
* comment. In that case, the first non-blank
* char should be lined up with the comment / */
int comment_delta, n_comment_delta;
int cast_mask; /* indicates which close parens close off
* casts */
int sizeof_mask; /* indicates which close parens close off
* sizeof''s */
int block_init; /* true iff inside a block initialization */
int block_init_level; /* The level of brace nesting in an
* char should be lined up with the / in / followed by * */
int comment_delta; /* used to set up indentation for all lines
* of a boxed comment after the first one */
int n_comment_delta;/* remembers how many columns there were
* before the start of a box comment so that
* forthcoming lines of the comment are
* indented properly */
int cast_mask; /* indicates which close parens potentially
* close off casts */
int not_cast_mask; /* indicates which close parens definitely
* close off something else than casts */
int block_init; /* true iff inside a block initialization */
int block_init_level; /* The level of brace nesting in an
* initialization */
int last_nl; /* this is true if the last thing scanned was
int last_nl; /* this is true if the last thing scanned was
* a newline */
int in_or_st; /* Will be true iff there has been a
int in_or_st; /* Will be true iff there has been a
* declarator (e.g. int or char) and no left
* paren since the last semicolon. When true,
* a '{' is starting a structure definition or
* an initialization list */
int bl_line; /* set to 1 by dump_line if the line is blank */
int col_1; /* set to true if the last token started in
int bl_line; /* set to 1 by dump_line if the line is blank */
int col_1; /* set to true if the last token started in
* column 1 */
int com_col; /* this is the column in which the current
* coment should start */
int com_ind; /* the column in which comments to the right
* of code should start */
int com_lines; /* the number of lines with comments, set by
int com_col; /* this is the column in which the current
* comment should start */
int com_lines; /* the number of lines with comments, set by
* dump_line */
int dec_nest; /* current nesting level for structure or init */
int decl_com_ind; /* the column in which comments after
* declarations should be put */
int decl_on_line; /* set to true if this line of code has part
int dec_nest; /* current nesting level for structure or init */
int decl_on_line; /* set to true if this line of code has part
* of a declaration on it */
int i_l_follow; /* the level to which ind_level should be set
int i_l_follow; /* the level to which ind_level should be set
* after the current line is printed */
int in_decl; /* set to true when we are in a declaration
int in_decl; /* set to true when we are in a declaration
* stmt. The processing of braces is then
* slightly different */
int in_stmt; /* set to 1 while in a stmt */
int ind_level; /* the current indentation level */
int ind_size; /* the size of one indentation level */
int ind_stmt; /* set to 1 if next line should have an extra
int in_stmt; /* set to 1 while in a stmt */
int ind_level; /* the current indentation level */
int ind_stmt; /* set to 1 if next line should have an extra
* indentation level because we are in the
* middle of a stmt */
int last_u_d; /* set to true after scanning a token which
int last_u_d; /* set to true after scanning a token which
* forces a following operator to be unary */
int leave_comma; /* if true, never break declarations after
* commas */
int ljust_decl; /* true if declarations should be left
* justified */
int out_coms; /* the number of comments processed, set by
int out_coms; /* the number of comments processed, set by
* pr_comment */
int out_lines; /* the number of lines written, set by
int out_lines; /* the number of lines written, set by
* dump_line */
int p_l_follow; /* used to remember how to indent following
int p_l_follow; /* used to remember how to indent following
* statement */
int paren_level; /* parenthesization level. used to indent
* within stmts */
short paren_indents[20]; /* column positions of each paren */
int pcase; /* set to 1 if the current line label is a
int paren_level; /* parenthesization level. used to indent
* within statements */
short paren_indents[20]; /* column positions of each paren */
int pcase; /* set to 1 if the current line label is a
* case. It is printed differently from a
* regular label */
int search_brace; /* set to true by parse when it is necessary
int search_brace; /* set to true by parse when it is necessary
* to buffer up all info up to the start of a
* stmt after an if, while, etc */
int unindent_displace; /* comments not to the right of code
* will be placed this many
* indentation levels to the left of
* code */
int use_ff; /* set to one if the current line should be
int use_ff; /* set to one if the current line should be
* terminated with a form feed */
int want_blank; /* set to true when the following token should
int want_blank; /* set to true when the following token should
* be prefixed by a blank. (Said prefixing is
* ignored in some cases.) */
int else_if; /* True iff else if pairs should be handled
* specially */
int decl_indent; /* column to indent declared identifiers to */
int its_a_keyword;
int sizeof_keyword;
int dumped_decl_indent;
float case_indent; /* The distance to indent case labels from the
* switch statement */
int in_parameter_declaration;
int indent_parameters;
int tos; /* pointer to top of stack */
char procname[100]; /* The name of the current procedure */
int just_saw_decl;
} ps;
int keyword; /* the type of a keyword or 0 */
int dumped_decl_indent;
int in_parameter_declaration;
int tos; /* pointer to top of stack */
char procname[100]; /* The name of the current procedure */
int just_saw_decl;
} ps;
EXTERN int ifdef_level;
EXTERN int rparen_count;
EXTERN struct parser_state state_stack[5];
EXTERN struct parser_state match_state[5];
int compute_code_target(void);
int compute_label_target(void);
int count_spaces(int, char *);
void diag(int, const char *,...) __attribute__((__format__(__printf__, 2, 3)));
void dump_line(void);
int eqin(const char *, const char *);
void fill_buffer(void);
int pad_output(int, int);
void scan_profile(FILE *);
void set_defaults(void);
void set_option(char *);
void addkey(char *, int);
void set_profile(void);
char *chfont(struct fstate *, struct fstate *, char *);
void parsefont(struct fstate *, const char *);
void writefdef(struct fstate *, int);
int lexi(void);
void reduce(void);
void parse(int);
void pr_comment(void);
void bakcopy(void);
int ifdef_level;
struct parser_state state_stack[5];
struct parser_state match_state[5];

View File

@ -1,37 +1,11 @@
/* $NetBSD: io.c,v 1.18 2019/02/03 03:19:29 mrg Exp $ */
/* $NetBSD: io.c,v 1.19 2019/04/04 15:22:13 kamil Exp $ */
/*
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -63,25 +37,32 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: io.c,v 1.18 2019/02/03 03:19:29 mrg Exp $");
#if defined(__NetBSD__)
__RCSID("$NetBSD: io.c,v 1.19 2019/04/04 15:22:13 kamil Exp $");
#elif defined(__FreeBSD__)
__FBSDID("$FreeBSD: head/usr.bin/indent/io.c 334927 2018-06-10 16:44:18Z pstef $");
#endif
#endif
#endif /* not lint */
#include <ctype.h>
#include <err.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
#include "indent.h"
int comment_open;
static int paren_target;
int comment_open;
static int paren_target;
static int pad_output(int current, int target);
void
dump_line(void)
@ -90,283 +71,198 @@ dump_line(void)
* prints the label section, followed by the
* code section with the appropriate nesting
* level, followed by any comments */
int cur_col, target_col;
static int not_first_line;
int cur_col,
target_col = 1;
static int not_first_line;
target_col = 0;
if (ps.procname[0]) {
if (troff) {
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
fprintf(output, ".Pr \"%s\"\n", ps.procname);
}
ps.ind_level = 0;
ps.procname[0] = 0;
if (ps.procname[0]) {
ps.ind_level = 0;
ps.procname[0] = 0;
}
if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
if (suppress_blanklines > 0)
suppress_blanklines--;
else {
ps.bl_line = true;
n_real_blanklines++;
}
if (s_code == e_code && s_lab == e_lab && s_com == e_com) {
if (suppress_blanklines > 0)
suppress_blanklines--;
else {
ps.bl_line = true;
n_real_blanklines++;
}
else if (!inhibit_formatting) {
suppress_blanklines = 0;
ps.bl_line = false;
if (prefix_blankline_requested && not_first_line) {
if (opt.swallow_optional_blanklines) {
if (n_real_blanklines == 1)
n_real_blanklines = 0;
}
else {
if (n_real_blanklines == 0)
n_real_blanklines = 1;
}
}
while (--n_real_blanklines >= 0)
putc('\n', output);
n_real_blanklines = 0;
if (ps.ind_level == 0)
ps.ind_stmt = 0; /* this is a class A kludge. dont do
* additional statement indentation if we are
* at bracket level 0 */
if (e_lab != s_lab || e_code != s_code)
++code_lines; /* keep count of lines with code */
if (e_lab != s_lab) { /* print lab, if any */
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
e_lab--;
*e_lab = '\0';
cur_col = pad_output(1, compute_label_target());
if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0
|| strncmp(s_lab, "#endif", 6) == 0)) {
char *s = s_lab;
if (e_lab[-1] == '\n') e_lab--;
do putc(*s++, output);
while (s < e_lab && 'a' <= *s && *s<='z');
while ((*s == ' ' || *s == '\t') && s < e_lab)
s++;
if (s < e_lab)
fprintf(output, s[0]=='/' && s[1]=='*' ? "\t%.*s" : "\t/* %.*s */",
(int)(e_lab - s), s);
}
else fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab);
cur_col = count_spaces(cur_col, s_lab);
}
else
cur_col = 1; /* there is no label section */
ps.pcase = false;
if (s_code != e_code) { /* print code section, if any */
char *p;
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
target_col = compute_code_target();
{
int i;
for (i = 0; i < ps.p_l_follow; i++)
if (ps.paren_indents[i] >= 0)
ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
}
cur_col = pad_output(cur_col, target_col);
for (p = s_code; p < e_code; p++)
if (*p == (char) 0200)
fprintf(output, "%d", target_col * 7);
else
putc(*p, output);
cur_col = count_spaces(cur_col, s_code);
}
if (s_com != e_com) { /* print comment, if any */
int target = ps.com_col;
char *com_st = s_com;
target += ps.comment_delta;
while (*com_st == '\t') /* consider original indentation in
* case this is a box comment */
com_st++, target += opt.tabsize;
while (target <= 0)
if (*com_st == ' ')
target++, com_st++;
else if (*com_st == '\t') {
target = opt.tabsize * (1 + (target - 1) / opt.tabsize) + 1;
com_st++;
}
} else
if (!inhibit_formatting) {
suppress_blanklines = 0;
ps.bl_line = false;
if (prefix_blankline_requested && not_first_line) {
if (swallow_optional_blanklines) {
if (n_real_blanklines == 1)
n_real_blanklines = 0;
} else {
if (n_real_blanklines == 0)
n_real_blanklines = 1;
}
}
while (--n_real_blanklines >= 0)
putc('\n', output);
n_real_blanklines = 0;
if (ps.ind_level == 0)
ps.ind_stmt = 0; /* this is a class A
* kludge. don't do
* additional statement
* indentation if we are
* at bracket level 0 */
if (e_lab != s_lab || e_code != s_code)
++code_lines; /* keep count of lines with
* code */
if (e_lab != s_lab) { /* print lab, if any */
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))
e_lab--;
cur_col = pad_output(1, compute_label_target());
if (s_lab[0] == '#' && (strncmp(s_lab, "#else", 5) == 0
|| strncmp(s_lab, "#endif", 6) == 0)) {
char *s = s_lab;
if (e_lab[-1] == '\n')
e_lab--;
do
putc(*s++, output);
while (s < e_lab && 'a' <= *s && *s <= 'z');
while ((*s == ' ' || *s == '\t') && s < e_lab)
s++;
if (s < e_lab)
fprintf(output, s[0] == '/' && s[1] == '*' ? "\t%.*s" : "\t/* %.*s */",
(int)(e_lab - s), s);
} else
fprintf(output, "%.*s", (int)(e_lab - s_lab), s_lab);
cur_col = count_spaces(cur_col, s_lab);
} else
cur_col = 1; /* there is no label section */
ps.pcase = false;
if (s_code != e_code) { /* print code section, if any */
char *p;
if (comment_open) {
comment_open = 0;
fprintf(output, ".*/\n");
}
target_col = compute_code_target();
{
int i;
for (i = 0; i < ps.p_l_follow; i++)
if (ps.paren_indents[i] >= 0)
ps.paren_indents[i] = -(ps.paren_indents[i] + target_col);
}
cur_col = pad_output(cur_col, target_col);
for (p = s_code; p < e_code; p++)
if (*p == (char) 0200)
fprintf(output, "%d", target_col * 7);
else
putc(*p, output);
cur_col = count_spaces(cur_col, s_code);
}
if (s_com != e_com) {
if (troff) {
int all_here = 0;
char *p;
if (e_com[-1] == '/' && e_com[-2] == '*')
e_com -= 2, all_here++;
while (e_com > s_com && e_com[-1] == ' ')
e_com--;
*e_com = 0;
p = s_com;
while (*p == ' ')
p++;
if (p[0] == '/' && p[1] == '*')
p += 2, all_here++;
else
if (p[0] == '*')
p += p[1] == '/' ? 2 : 1;
while (*p == ' ')
p++;
if (*p == 0)
goto inhibit_newline;
if (comment_open < 2 && ps.box_com) {
comment_open = 0;
fprintf(output, ".*/\n");
}
if (comment_open == 0) {
if ('a' <= *p && *p <= 'z')
*p = *p + 'A' - 'a';
if (e_com - p < 50 && all_here == 2) {
char *follow = p;
fprintf(output, "\n.nr C! \\w\1");
while (follow < e_com) {
switch (*follow) {
case '\n':
putc(' ', output);
case 1:
break;
case '\\':
putc('\\', output);
/* FALLTHROUGH */
default:
putc(*follow, output);
}
follow++;
}
putc(1, output);
}
fprintf(output, "\n./* %dp %d %dp\n",
ps.com_col * 7,
(s_code != e_code || s_lab != e_lab) - ps.box_com,
target_col * 7);
}
comment_open = 1 + ps.box_com;
while (*p) {
if (*p == BACKSLASH)
putc(BACKSLASH, output);
putc(*p++, output);
}
} else { /* print comment, if any */
int target = ps.com_col;
char *com_st = s_com;
target += ps.comment_delta;
while (*com_st == '\t')
com_st++, target += 8; /* ? */
while (target <= 0)
if (*com_st == ' ')
target++, com_st++;
else
if (*com_st == '\t')
target = ((target - 1) & ~7) + 9, com_st++;
else
target = 1;
if (cur_col > target) { /* if comment can't fit
* on this line, put it
* on next line */
putc('\n', output);
cur_col = 1;
++ps.out_lines;
}
while (e_com > com_st
&& isspace((unsigned char)e_com[-1]))
e_com--;
cur_col = pad_output(cur_col, target);
if (!ps.box_com) {
if (star_comment_cont
&& (com_st[1] != '*'
|| e_com <= com_st + 1)) {
if (com_st[1] == ' '
&& com_st[0] == ' '
&& e_com > com_st + 1)
com_st[1] = '*';
else
fwrite(" * ",
com_st[0] == '\t'
? 2
: com_st[0]=='*'
? 1
: 3, 1, output);
}
}
fwrite(com_st,
e_com - com_st, 1, output);
ps.comment_delta = ps.n_comment_delta;
cur_col = count_spaces(cur_col, com_st);
++ps.com_lines; /* count lines with
* comments */
}
}
if (ps.use_ff)
putc('\014', output);
else
putc('\n', output);
inhibit_newline:
++ps.out_lines;
if (ps.just_saw_decl == 1 && blanklines_after_declarations) {
prefix_blankline_requested = 1;
ps.just_saw_decl = 0;
} else
prefix_blankline_requested = postfix_blankline_requested;
postfix_blankline_requested = 0;
}
ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
else
target = 1;
if (cur_col > target) { /* if comment can't fit on this line,
* put it on next line */
putc('\n', output);
cur_col = 1;
++ps.out_lines;
}
while (e_com > com_st && isspace((unsigned char)e_com[-1]))
e_com--;
(void)pad_output(cur_col, target);
fwrite(com_st, e_com - com_st, 1, output);
ps.comment_delta = ps.n_comment_delta;
++ps.com_lines; /* count lines with comments */
}
if (ps.use_ff)
putc('\014', output);
else
putc('\n', output);
++ps.out_lines;
if (ps.just_saw_decl == 1 && opt.blanklines_after_declarations) {
prefix_blankline_requested = 1;
ps.just_saw_decl = 0;
}
else
prefix_blankline_requested = postfix_blankline_requested;
postfix_blankline_requested = 0;
}
ps.decl_on_line = ps.in_decl; /* if we are in the middle of a
* declaration, remember that fact for
* proper comment indentation */
ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
ps.ind_stmt = ps.in_stmt & ~ps.in_decl; /* next line should be
* indented if we have not
* completed this stmt and if
* we are not in the middle of
* a declaration */
ps.use_ff = false;
ps.dumped_decl_indent = 0;
*(e_lab = s_lab) = '\0';/* reset buffers */
*(e_code = s_code) = '\0';
*(e_com = s_com) = '\0';
ps.ind_level = ps.i_l_follow;
ps.paren_level = ps.p_l_follow;
ps.use_ff = false;
ps.dumped_decl_indent = 0;
*(e_lab = s_lab) = '\0'; /* reset buffers */
*(e_code = s_code) = '\0';
*(e_com = s_com = combuf + 1) = '\0';
ps.ind_level = ps.i_l_follow;
ps.paren_level = ps.p_l_follow;
if (ps.paren_level > 0)
paren_target = -ps.paren_indents[ps.paren_level - 1];
not_first_line = 1;
not_first_line = 1;
}
int
compute_code_target(void)
{
int target_col = ps.ind_size * ps.ind_level + 1;
int target_col = opt.ind_size * ps.ind_level + 1;
if (ps.paren_level) {
if (!lineup_to_parens)
target_col += continuation_indent * ps.paren_level;
else {
int w;
int t = paren_target;
if (ps.paren_level)
if (!opt.lineup_to_parens)
target_col += opt.continuation_indent *
(2 * opt.continuation_indent == opt.ind_size ? 1 : ps.paren_level);
else if (opt.lineup_to_parens_always)
target_col = paren_target;
else {
int w;
int t = paren_target;
if ((w = count_spaces(t, s_code) - max_col) > 0
&& count_spaces(target_col, s_code) <= max_col) {
t -= w + 1;
if (t > target_col)
target_col = t;
} else
target_col = t;
}
} else
if (ps.ind_stmt)
target_col += continuation_indent;
return target_col;
if ((w = count_spaces(t, s_code) - opt.max_col) > 0
&& count_spaces(target_col, s_code) <= opt.max_col) {
t -= w + 1;
if (t > target_col)
target_col = t;
}
else
target_col = t;
}
else if (ps.ind_stmt)
target_col += opt.continuation_indent;
return target_col;
}
int
compute_label_target(void)
{
return
ps.pcase ? (int) (case_ind * ps.ind_size) + 1
return
ps.pcase ? (int) (case_ind * opt.ind_size) + 1
: *s_lab == '#' ? 1
: ps.ind_size * (ps.ind_level - label_offset) + 1;
: opt.ind_size * (ps.ind_level - label_offset) + 1;
}
@ -388,95 +284,91 @@ compute_label_target(void)
void
fill_buffer(void)
{ /* this routine reads stuff from the input */
char *p;
int i;
FILE *f = input;
char *n;
char *p;
int i;
FILE *f = input;
if (bp_save != 0) { /* there is a partly filled input buffer left */
buf_ptr = bp_save; /* don't read anything, just switch
* buffers */
buf_end = be_save;
bp_save = be_save = 0;
if (buf_ptr < buf_end)
return; /* only return if there is really something in
if (bp_save != NULL) { /* there is a partly filled input buffer left */
buf_ptr = bp_save; /* do not read anything, just switch buffers */
buf_end = be_save;
bp_save = be_save = NULL;
if (buf_ptr < buf_end)
return; /* only return if there is really something in
* this buffer */
}
for (p = in_buffer;;) {
if (p >= in_buffer_limit) {
int size = (in_buffer_limit - in_buffer) * 2 + 10;
int offset = p - in_buffer;
in_buffer = realloc(in_buffer, size);
if (in_buffer == NULL)
errx(1, "input line too long");
p = in_buffer + offset;
in_buffer_limit = in_buffer + size - 2;
}
for (p = in_buffer;;) {
if (p >= in_buffer_limit) {
int size = (in_buffer_limit - in_buffer) * 2 + 10;
int offset = p - in_buffer;
n = (char *) realloc(in_buffer, size);
if (n == 0)
errx(1, "input line too long");
in_buffer = n;
p = in_buffer + offset;
in_buffer_limit = in_buffer + size - 2;
}
if ((i = getc(f)) == EOF) {
*p++ = ' ';
*p++ = '\n';
had_eof = true;
break;
}
*p++ = i;
if (i == '\n')
break;
if ((i = getc(f)) == EOF) {
*p++ = ' ';
*p++ = '\n';
had_eof = true;
break;
}
buf_ptr = in_buffer;
buf_end = p;
if (p[-2] == '/' && p[-3] == '*') {
if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
fill_buffer(); /* flush indent error message */
else {
int com = 0;
if (i != '\0')
*p++ = i;
if (i == '\n')
break;
}
buf_ptr = in_buffer;
buf_end = p;
if (p - in_buffer > 2 && p[-2] == '/' && p[-3] == '*') {
if (in_buffer[3] == 'I' && strncmp(in_buffer, "/**INDENT**", 11) == 0)
fill_buffer(); /* flush indent error message */
else {
int com = 0;
p = in_buffer;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '/' && p[1] == '*') {
p += 2;
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
&& p[4] == 'N' && p[5] == 'T') {
p += 6;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '*')
com = 1;
else {
if (*p == 'O') {
if (*++p == 'N')
p++, com = 1;
else
if (*p == 'F' && *++p == 'F')
p++, com = 2;
}
}
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
if (s_com != e_com || s_lab != e_lab || s_code != e_code)
dump_line();
if (!(inhibit_formatting = com - 1)) {
n_real_blanklines = 0;
postfix_blankline_requested = 0;
prefix_blankline_requested = 0;
suppress_blanklines = 1;
}
}
}
p = in_buffer;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '/' && p[1] == '*') {
p += 2;
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == 'I' && p[1] == 'N' && p[2] == 'D' && p[3] == 'E'
&& p[4] == 'N' && p[5] == 'T') {
p += 6;
while (*p == ' ' || *p == '\t')
p++;
if (*p == '*')
com = 1;
else if (*p == 'O') {
if (*++p == 'N')
p++, com = 1;
else if (*p == 'F' && *++p == 'F')
p++, com = 2;
}
while (*p == ' ' || *p == '\t')
p++;
if (p[0] == '*' && p[1] == '/' && p[2] == '\n' && com) {
if (s_com != e_com || s_lab != e_lab || s_code != e_code)
dump_line();
if (!(inhibit_formatting = com - 1)) {
n_real_blanklines = 0;
postfix_blankline_requested = 0;
prefix_blankline_requested = 0;
suppress_blanklines = 1;
}
}
}
}
}
if (inhibit_formatting) {
p = in_buffer;
do
putc(*p, output);
while (*p++ != '\n');
}
}
if (inhibit_formatting) {
p = in_buffer;
do
putc(*p, output);
while (*p++ != '\n');
}
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
@ -491,7 +383,7 @@ fill_buffer(void)
* ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
*
* PARAMETERS: current integer The current column target
* target integer The desired column
* nteger The desired column
*
* RETURNS: Integer value of the new column. (If current >= target, no action is
* taken, and current is returned.
@ -505,29 +397,33 @@ fill_buffer(void)
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
int
static int
pad_output(int current, int target)
/* writes tabs and blanks (if necessary) to
* get the current output position up to the
* target column */
/* current: the current column value */
/* target: position we want it at */
{
int curr; /* internal column pointer */
int tcur;
int curr; /* internal column pointer */
if (troff)
fprintf(output, "\\h'|%dp'", (target - 1) * 7);
else {
if (current >= target)
return (current); /* line is already long enough */
curr = current;
if (use_tabs) {
while ((tcur = ((curr - 1) & tabmask) + tabsize + 1) <= target) {
putc('\t', output);
curr = tcur;
}
}
while (curr++ < target)
putc(' ', output); /* pad with final blanks */
if (current >= target)
return (current); /* line is already long enough */
curr = current;
if (opt.use_tabs) {
int tcur;
while ((tcur = opt.tabsize * (1 + (curr - 1) / opt.tabsize) + 1) <= target) {
putc('\t', output);
curr = tcur;
}
return (target);
}
while (curr++ < target)
putc(' ', output); /* pad with final blanks */
return (target);
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
@ -549,139 +445,91 @@ pad_output(int current, int target)
*
*/
int
count_spaces(int current, char *buffer)
count_spaces_until(int cur, char *buffer, char *end)
/*
* this routine figures out where the character position will be after
* printing the text in buffer starting at column "current"
*/
{
char *buf; /* used to look thru buffer */
int cur; /* current character counter */
char *buf; /* used to look thru buffer */
cur = current;
for (buf = buffer; *buf != '\0' && buf != end; ++buf) {
switch (*buf) {
for (buf = buffer; *buf != '\0'; ++buf) {
switch (*buf) {
case '\n':
case 014: /* form feed */
cur = 1;
break;
case '\n':
case 014: /* form feed */
cur = 1;
break;
case '\t':
cur = opt.tabsize * (1 + (cur - 1) / opt.tabsize) + 1;
break;
case '\t':
cur = ((cur - 1) & tabmask) + tabsize + 1;
break;
case 010: /* backspace */
--cur;
break;
case 010: /* backspace */
--cur;
break;
default:
++cur;
break;
} /* end of switch */
} /* end of for loop */
return (cur);
default:
++cur;
break;
} /* end of switch */
} /* end of for loop */
return (cur);
}
int found_err;
void
diag(int level, const char *msg, ...)
int
count_spaces(int cur, char *buffer)
{
va_list ap;
va_start(ap, msg);
if (level)
found_err = 1;
if (output == stdout) {
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
vfprintf(stdout, msg, ap);
fprintf(stdout, " */\n");
} else {
fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
vfprintf(stdout, msg, ap);
fprintf(stderr, "\n");
}
va_end(ap);
return (count_spaces_until(cur, buffer, NULL));
}
void
writefdef(struct fstate *f, int nm)
diag4(int level, const char *msg, int a, int b)
{
fprintf(output, ".ds f%c %s\n.nr s%c %d\n",
nm, f->font, nm, f->size);
if (level)
found_err = 1;
if (output == stdout) {
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stdout, msg, a, b);
fprintf(stdout, " */\n");
}
else {
fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stderr, msg, a, b);
fprintf(stderr, "\n");
}
}
char *
chfont(struct fstate *of, struct fstate *nf, char *s)
{
if (of->font[0] != nf->font[0]
|| of->font[1] != nf->font[1]) {
*s++ = '\\';
*s++ = 'f';
if (nf->font[1]) {
*s++ = '(';
*s++ = nf->font[0];
*s++ = nf->font[1];
} else
*s++ = nf->font[0];
}
if (nf->size != of->size) {
*s++ = '\\';
*s++ = 's';
if (nf->size < of->size) {
*s++ = '-';
*s++ = '0' + of->size - nf->size;
} else {
*s++ = '+';
*s++ = '0' + nf->size - of->size;
}
}
return s;
}
void
parsefont(struct fstate *f, const char *s0)
diag3(int level, const char *msg, int a)
{
const char *s = s0;
int sizedelta = 0;
memset(f, 0, sizeof *f);
while (*s) {
if (isdigit((unsigned char)*s))
f->size = f->size * 10 + *s - '0';
else
if (isupper((unsigned char)*s)) {
if (f->font[0])
f->font[1] = *s;
else
f->font[0] = *s;
} else
if (*s == 'c')
f->allcaps = 1;
else
if (*s == '+')
sizedelta++;
else
if (*s == '-')
sizedelta--;
else {
errx(1, "bad font specification: %s", s0);
}
s++;
}
if (f->font[0] == 0)
f->font[0] = 'R';
if (bodyf.size == 0)
bodyf.size = 11;
if (f->size == 0)
f->size = bodyf.size + sizedelta;
else
if (sizedelta > 0)
f->size += bodyf.size;
else
f->size = bodyf.size - f->size;
if (level)
found_err = 1;
if (output == stdout) {
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stdout, msg, a);
fprintf(stdout, " */\n");
}
else {
fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stderr, msg, a);
fprintf(stderr, "\n");
}
}
void
diag2(int level, const char *msg)
{
if (level)
found_err = 1;
if (output == stdout) {
fprintf(stdout, "/**INDENT** %s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stdout, "%s", msg);
fprintf(stdout, " */\n");
}
else {
fprintf(stderr, "%s@%d: ", level == 0 ? "Warning" : "Error", line_no);
fprintf(stderr, "%s", msg);
fprintf(stderr, "\n");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,11 @@
/* $NetBSD: parse.c,v 1.8 2019/02/03 03:19:29 mrg Exp $ */
/* $NetBSD: parse.c,v 1.9 2019/04/04 15:22:13 kamil Exp $ */
/*
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -63,183 +37,201 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93";
#if defined(__NetBSD__)
__RCSID("$FreeBSD$");
#else
__RCSID("$NetBSD: parse.c,v 1.8 2019/02/03 03:19:29 mrg Exp $");
__FBSDID("$FreeBSD: head/usr.bin/indent/parse.c 337651 2018-08-11 19:20:06Z pstef $");
#endif
#endif
#endif /* not lint */
#include <err.h>
#include <stdio.h>
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
static void reduce(void);
/* tk: the code for the construct scanned */
void
parse(int tk)
parse(int tk) /* tk: the code for the construct scanned */
{
int i;
int i;
#ifdef debug
printf("%2d - %s\n", tk, token);
printf("%2d - %s\n", tk, token);
#endif
while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
/* true if we have an if without an else */
ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::=
* stmt reduction */
reduce(); /* see if this allows any reduction */
}
while (ps.p_stack[ps.tos] == ifhead && tk != elselit) {
/* true if we have an if without an else */
ps.p_stack[ps.tos] = stmt; /* apply the if(..) stmt ::= stmt
* reduction */
reduce(); /* see if this allows any reduction */
}
switch (tk) { /* go on and figure out what to do with the
switch (tk) { /* go on and figure out what to do with the
* input */
case decl: /* scanned a declaration word */
ps.search_brace = btype_2;
/* indicate that following brace should be on same line */
if (ps.p_stack[ps.tos] != decl) { /* only put one
* declaration onto
* stack */
break_comma = true; /* while in declaration,
* newline should be forced
* after comma */
ps.p_stack[++ps.tos] = decl;
ps.il[ps.tos] = ps.i_l_follow;
case decl: /* scanned a declaration word */
ps.search_brace = opt.btype_2;
/* indicate that following brace should be on same line */
if (ps.p_stack[ps.tos] != decl) { /* only put one declaration
* onto stack */
break_comma = true; /* while in declaration, newline should be
* forced after comma */
ps.p_stack[++ps.tos] = decl;
ps.il[ps.tos] = ps.i_l_follow;
if (ps.ljust_decl) { /* only do if we want left
* justified declarations */
ps.ind_level = 0;
for (i = ps.tos - 1; i > 0; --i)
if (ps.p_stack[i] == decl)
++ps.ind_level; /* indentation is number
* of declaration levels
* deep we are */
ps.i_l_follow = ps.ind_level;
}
}
break;
if (opt.ljust_decl) {/* only do if we want left justified
* declarations */
ps.ind_level = 0;
for (i = ps.tos - 1; i > 0; --i)
if (ps.p_stack[i] == decl)
++ps.ind_level; /* indentation is number of
* declaration levels deep we are */
ps.i_l_follow = ps.ind_level;
}
}
break;
case ifstmt: /* scanned if (...) */
if (ps.p_stack[ps.tos] == elsehead && ps.else_if) /* "else if ..." */
ps.i_l_follow = ps.il[ps.tos];
/* FALLTHROUGH */
case dolit: /* 'do' */
case forstmt: /* for (...) */
ps.p_stack[++ps.tos] = tk;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
++ps.i_l_follow;/* subsequent statements should be indented 1 */
ps.search_brace = btype_2;
break;
case ifstmt: /* scanned if (...) */
if (ps.p_stack[ps.tos] == elsehead && opt.else_if) /* "else if ..." */
/*
* Note that the stack pointer here is decremented, effectively
* reducing "else if" to "if". This saves a lot of stack space
* in case of a long "if-else-if ... else-if" sequence.
*/
ps.i_l_follow = ps.il[ps.tos--];
/* the rest is the same as for dolit and forstmt */
/* FALLTHROUGH */
case dolit: /* 'do' */
case forstmt: /* for (...) */
ps.p_stack[++ps.tos] = tk;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
++ps.i_l_follow; /* subsequent statements should be indented 1 */
ps.search_brace = opt.btype_2;
break;
case lbrace: /* scanned { */
break_comma = false; /* don't break comma in an initial
* list */
if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
|| ps.p_stack[ps.tos] == stmtl)
++ps.i_l_follow; /* it is a random, isolated
* stmt group or a declaration */
else {
if (s_code == e_code) {
/*
* only do this if there is nothing on the line
*/
--ps.ind_level;
/*
* it is a group as part of a while, for, etc.
*/
if (ps.p_stack[ps.tos] == swstmt && ps.case_indent >= 1)
--ps.ind_level;
/*
* for a switch, brace should be two levels out from the code
*/
}
}
case lbrace: /* scanned { */
break_comma = false; /* don't break comma in an initial list */
if (ps.p_stack[ps.tos] == stmt || ps.p_stack[ps.tos] == decl
|| ps.p_stack[ps.tos] == stmtl)
++ps.i_l_follow; /* it is a random, isolated stmt group or a
* declaration */
else {
if (s_code == e_code) {
/*
* only do this if there is nothing on the line
*/
--ps.ind_level;
/*
* it is a group as part of a while, for, etc.
*/
if (ps.p_stack[ps.tos] == swstmt && opt.case_indent >= 1)
--ps.ind_level;
/*
* for a switch, brace should be two levels out from the code
*/
}
}
ps.p_stack[++ps.tos] = lbrace;
ps.il[ps.tos] = ps.ind_level;
ps.p_stack[++ps.tos] = stmt;
/* allow null stmt between braces */
ps.il[ps.tos] = ps.i_l_follow;
break;
ps.p_stack[++ps.tos] = lbrace;
ps.il[ps.tos] = ps.ind_level;
ps.p_stack[++ps.tos] = stmt;
/* allow null stmt between braces */
ps.il[ps.tos] = ps.i_l_follow;
break;
case whilestmt: /* scanned while (...) */
if (ps.p_stack[ps.tos] == dohead) {
/* it is matched with do stmt */
ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
} else { /* it is a while loop */
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.i_l_follow;
++ps.i_l_follow;
ps.search_brace = btype_2;
}
case whilestmt: /* scanned while (...) */
if (ps.p_stack[ps.tos] == dohead) {
/* it is matched with do stmt */
ps.ind_level = ps.i_l_follow = ps.il[ps.tos];
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.ind_level = ps.i_l_follow;
}
else { /* it is a while loop */
ps.p_stack[++ps.tos] = whilestmt;
ps.il[ps.tos] = ps.i_l_follow;
++ps.i_l_follow;
ps.search_brace = opt.btype_2;
}
break;
break;
case elselit: /* scanned an else */
case elselit: /* scanned an else */
if (ps.p_stack[ps.tos] != ifhead)
diag(1, "Unmatched 'else'");
else {
ps.ind_level = ps.il[ps.tos]; /* indentation for else
* should be same as for
* if */
ps.i_l_follow = ps.ind_level + 1; /* everything following
* should be in 1 level */
ps.p_stack[ps.tos] = elsehead;
/* remember if with else */
ps.search_brace = btype_2 | ps.else_if;
}
break;
if (ps.p_stack[ps.tos] != ifhead)
diag2(1, "Unmatched 'else'");
else {
ps.ind_level = ps.il[ps.tos]; /* indentation for else should
* be same as for if */
ps.i_l_follow = ps.ind_level + 1; /* everything following should
* be in 1 level */
ps.p_stack[ps.tos] = elsehead;
/* remember if with else */
ps.search_brace = opt.btype_2 | opt.else_if;
}
break;
case rbrace: /* scanned a } */
/* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
if (ps.p_stack[ps.tos - 1] == lbrace) {
ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
ps.p_stack[ps.tos] = stmt;
} else
diag(1, "Stmt nesting error.");
break;
case rbrace: /* scanned a } */
/* stack should have <lbrace> <stmt> or <lbrace> <stmtl> */
if (ps.tos > 0 && ps.p_stack[ps.tos - 1] == lbrace) {
ps.ind_level = ps.i_l_follow = ps.il[--ps.tos];
ps.p_stack[ps.tos] = stmt;
}
else
diag2(1, "Statement nesting error");
break;
case swstmt: /* had switch (...) */
ps.p_stack[++ps.tos] = swstmt;
ps.cstk[ps.tos] = case_ind;
/* save current case indent level */
ps.il[ps.tos] = ps.i_l_follow;
case_ind = ps.i_l_follow + ps.case_indent; /* cases should be one
* level down from
* switch */
ps.i_l_follow += ps.case_indent + 1; /* statements should be
* two levels in */
ps.search_brace = btype_2;
break;
case swstmt: /* had switch (...) */
ps.p_stack[++ps.tos] = swstmt;
ps.cstk[ps.tos] = case_ind;
/* save current case indent level */
ps.il[ps.tos] = ps.i_l_follow;
case_ind = ps.i_l_follow + opt.case_indent; /* cases should be one
* level down from
* switch */
ps.i_l_follow += opt.case_indent + 1; /* statements should be two
* levels in */
ps.search_brace = opt.btype_2;
break;
case semicolon: /* this indicates a simple stmt */
break_comma = false; /* turn off flag to break after commas
* in a declaration */
ps.p_stack[++ps.tos] = stmt;
ps.il[ps.tos] = ps.ind_level;
break;
case semicolon: /* this indicates a simple stmt */
break_comma = false; /* turn off flag to break after commas in a
* declaration */
ps.p_stack[++ps.tos] = stmt;
ps.il[ps.tos] = ps.ind_level;
break;
default: /* this is an error */
diag(1, "Unknown code to parser");
return;
default: /* this is an error */
diag2(1, "Unknown code to parser");
return;
} /* end of switch */
} /* end of switch */
reduce(); /* see if any reduction can be done */
if (ps.tos >= STACKSIZE - 1)
errx(1, "Parser stack overflow");
reduce(); /* see if any reduction can be done */
#ifdef debug
for (i = 1; i <= ps.tos; ++i)
printf("(%d %d)", ps.p_stack[i], ps.il[i]);
printf("\n");
for (i = 1; i <= ps.tos; ++i)
printf("(%d %d)", ps.p_stack[i], ps.il[i]);
printf("\n");
#endif
return;
}
/*
* NAME: reduce
*
@ -279,84 +271,83 @@ parse(int tk)
/*----------------------------------------------*\
| REDUCTION PHASE |
\*----------------------------------------------*/
void
static void
reduce(void)
{
int i;
int i;
for (;;) { /* keep looping until there is nothing left to
for (;;) { /* keep looping until there is nothing left to
* reduce */
switch (ps.p_stack[ps.tos]) {
switch (ps.p_stack[ps.tos]) {
case stmt:
switch (ps.p_stack[ps.tos - 1]) {
case stmt:
switch (ps.p_stack[ps.tos - 1]) {
case stmt:
case stmtl:
/* stmtl stmt or stmt stmt */
ps.p_stack[--ps.tos] = stmtl;
break;
case stmt:
case stmtl:
/* stmtl stmt or stmt stmt */
ps.p_stack[--ps.tos] = stmtl;
break;
case dolit: /* <do> <stmt> */
ps.p_stack[--ps.tos] = dohead;
ps.i_l_follow = ps.il[ps.tos];
break;
case dolit: /* <do> <stmt> */
ps.p_stack[--ps.tos] = dohead;
ps.i_l_follow = ps.il[ps.tos];
break;
case ifstmt:
/* <if> <stmt> */
ps.p_stack[--ps.tos] = ifhead;
for (i = ps.tos - 1;
(
ps.p_stack[i] != stmt
&&
ps.p_stack[i] != stmtl
&&
ps.p_stack[i] != lbrace
);
--i);
ps.i_l_follow = ps.il[i];
/*
* for the time being, we will assume that there is no else on
* this if, and set the indentation level accordingly. If an
* else is scanned, it will be fixed up later
*/
break;
case ifstmt:
/* <if> <stmt> */
ps.p_stack[--ps.tos] = ifhead;
for (i = ps.tos - 1;
(
ps.p_stack[i] != stmt
&&
ps.p_stack[i] != stmtl
&&
ps.p_stack[i] != lbrace
);
--i);
ps.i_l_follow = ps.il[i];
/*
* for the time being, we will assume that there is no else on
* this if, and set the indentation level accordingly. If an
* else is scanned, it will be fixed up later
*/
break;
case swstmt:
/* <switch> <stmt> */
case_ind = ps.cstk[ps.tos - 1];
case swstmt:
/* <switch> <stmt> */
case_ind = ps.cstk[ps.tos - 1];
/* FALLTHROUGH */
case decl: /* finish of a declaration */
case elsehead:
/* <<if> <stmt> else> <stmt> */
case forstmt:
/* <for> <stmt> */
case whilestmt:
/* <while> <stmt> */
ps.p_stack[--ps.tos] = stmt;
ps.i_l_follow = ps.il[ps.tos];
break;
/* FALLTHROUGH */
case decl: /* finish of a declaration */
case elsehead:
/* <<if> <stmt> else> <stmt> */
case forstmt:
/* <for> <stmt> */
case whilestmt:
/* <while> <stmt> */
ps.p_stack[--ps.tos] = stmt;
ps.i_l_follow = ps.il[ps.tos];
break;
default: /* <anything else> <stmt> */
return;
default: /* <anything else> <stmt> */
return;
} /* end of section for <stmt> on top of stack */
break;
} /* end of section for <stmt> on top of stack */
break;
case whilestmt: /* while (...) on top */
if (ps.p_stack[ps.tos - 1] == dohead) {
/* it is termination of a do while */
ps.tos -= 2;
break;
}
else
return;
case whilestmt:/* while (...) on top */
if (ps.p_stack[ps.tos - 1] == dohead) {
/* it is termination of a do while */
ps.p_stack[--ps.tos] = stmt;
break;
} else
return;
default: /* anything else on top */
return;
default: /* anything else on top */
return;
}
}
}
}

View File

@ -1,37 +1,11 @@
/* $NetBSD: pr_comment.c,v 1.10 2016/02/25 13:23:27 ginsbach Exp $ */
/* $NetBSD: pr_comment.c,v 1.11 2019/04/04 15:22:13 kamil Exp $ */
/*
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Copyright (c) 1976 Board of Trustees of the University of Illinois.
* Copyright (c) 1985 Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -63,20 +37,28 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93";
#else
__RCSID("$NetBSD: pr_comment.c,v 1.10 2016/02/25 13:23:27 ginsbach Exp $");
#if defined(__NetBSD__)
__RCSID("$NetBSD: pr_comment.c,v 1.11 2019/04/04 15:22:13 kamil Exp $");
#elif defined(__FreeBSD__)
__FBSDID("$FreeBSD: head/usr.bin/indent/pr_comment.c 334927 2018-06-10 16:44:18Z pstef $");
#endif
#endif
#endif /* not lint */
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
/*
* NAME:
* pr_comment
@ -108,354 +90,274 @@ __RCSID("$NetBSD: pr_comment.c,v 1.10 2016/02/25 13:23:27 ginsbach Exp $");
* beginning of the input line are removed
*/
void
pr_comment(void)
{
int now_col; /* column we are in now */
int adj_max_col; /* Adjusted max_col for when we decide to
int now_col; /* column we are in now */
int adj_max_col; /* Adjusted max_col for when we decide to
* spill comments over the right margin */
char *last_bl; /* points to the last blank in the output
char *last_bl; /* points to the last blank in the output
* buffer */
char *t_ptr; /* used for moving string */
int unix_comment; /* tri-state variable used to decide if it is
* a unix-style comment. 0 means only blanks
* since start, 1 means regular style comment,
* 2 means unix style comment */
int break_delim = comment_delimiter_on_blankline;
int l_just_saw_decl = ps.just_saw_decl;
char *t_ptr; /* used for moving string */
int break_delim = opt.comment_delimiter_on_blankline;
int l_just_saw_decl = ps.just_saw_decl;
adj_max_col = opt.max_col;
ps.just_saw_decl = 0;
last_bl = NULL; /* no blanks found so far */
ps.box_com = false; /* at first, assume that we are not in
* a boxed comment or some other
* comment that should not be touched */
++ps.out_coms; /* keep track of number of comments */
/* Figure where to align and how to treat the comment */
if (ps.col_1 && !opt.format_col1_comments) { /* if comment starts in column
* 1 it should not be touched */
ps.box_com = true;
break_delim = false;
ps.com_col = 1;
}
else {
if (*buf_ptr == '-' || *buf_ptr == '*' ||
(*buf_ptr == '\n' && !opt.format_block_comments)) {
ps.box_com = true; /* A comment with a '-' or '*' immediately
* after the /+* is assumed to be a boxed
* comment. A comment with a newline
* immediately after the /+* is assumed to
* be a block comment and is treated as a
* box comment unless format_block_comments
* is nonzero (the default). */
break_delim = false;
}
if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
/* klg: check only if this line is blank */
/*
* If this (*and previous lines are*) blank, dont put comment way
* out at left
*/
ps.com_col = (ps.ind_level - opt.unindent_displace) * opt.ind_size + 1;
adj_max_col = opt.block_comment_max_col;
if (ps.com_col <= 1)
ps.com_col = 1 + !opt.format_col1_comments;
}
else {
int target_col;
break_delim = false;
if (s_code != e_code)
target_col = count_spaces(compute_code_target(), s_code);
else {
target_col = 1;
if (s_lab != e_lab)
target_col = count_spaces(compute_label_target(), s_lab);
}
ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? opt.decl_com_ind : opt.com_ind;
if (ps.com_col <= target_col)
ps.com_col = opt.tabsize * (1 + (target_col - 1) / opt.tabsize) + 1;
if (ps.com_col + 24 > adj_max_col)
adj_max_col = ps.com_col + 24;
}
}
if (ps.box_com) {
/*
* int ps.last_nl = 0; / * true iff the last significant thing
* we've seen is a newline
*/
int one_liner = 1; /* true iff this comment is a one-liner */
adj_max_col = max_col;
ps.just_saw_decl = 0;
last_bl = 0; /* no blanks found so far */
ps.box_com = false; /* at first, assume that we are not in a boxed
* comment or some other comment that should
* not be touched */
++ps.out_coms; /* keep track of number of comments */
unix_comment = 1; /* set flag to let us figure out if there is a
* unix-style comment ** DISABLED: use 0 to
* reenable this hack! */
* Find out how much indentation there was originally, because that
* much will have to be ignored by pad_output() in dump_line(). This
* is a box comment, so nothing changes -- not even indentation.
*
* The comment we're about to read usually comes from in_buffer,
* unless it has been copied into save_com.
*/
char *start;
/* Figure where to align and how to treat the comment */
start = buf_ptr >= save_com && buf_ptr < save_com + sc_size ?
sc_buf : in_buffer;
ps.n_comment_delta = 1 - count_spaces_until(1, start, buf_ptr - 2);
}
else {
ps.n_comment_delta = 0;
while (*buf_ptr == ' ' || *buf_ptr == '\t')
buf_ptr++;
}
ps.comment_delta = 0;
*e_com++ = '/'; /* put '/' followed by '*' into buffer */
*e_com++ = '*';
if (*buf_ptr != ' ' && !ps.box_com)
*e_com++ = ' ';
if (ps.col_1 && !format_col1_comments) { /* if comment starts in
* column 1 it should
* not be touched */
ps.box_com = true;
ps.com_col = 1;
} else {
if (*buf_ptr == '-' || *buf_ptr == '*' || *buf_ptr == '\n') {
ps.box_com = true; /* a comment with a '-', '*'
* or newline immediately
* after the start comment is
* assumed to be a boxed
* comment */
break_delim = 0;
}
if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code)) {
/* klg: check only if this line is blank */
/*
* If this (*and previous lines are*) blank, don't
* put comment way out at left
*/
ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
adj_max_col = block_comment_max_col;
if (ps.com_col <= 1)
ps.com_col = 1 + !format_col1_comments;
} else {
int target_col;
break_delim = 0;
if (s_code != e_code)
target_col = count_spaces(compute_code_target(), s_code);
else {
target_col = 1;
if (s_lab != e_lab)
target_col = count_spaces(compute_label_target(), s_lab);
}
ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
if (ps.com_col < target_col)
ps.com_col = ((target_col + 7) & ~7) + 1;
if (ps.com_col + 24 > adj_max_col)
adj_max_col = ps.com_col + 24;
}
/*
* Don't put a break delimiter if this is a one-liner that won't wrap.
*/
if (break_delim)
for (t_ptr = buf_ptr; *t_ptr != '\0' && *t_ptr != '\n'; t_ptr++) {
if (t_ptr >= buf_end)
fill_buffer();
if (t_ptr[0] == '*' && t_ptr[1] == '/') {
if (adj_max_col >= count_spaces_until(ps.com_col, buf_ptr, t_ptr + 2))
break_delim = false;
break;
}
}
if (ps.box_com) {
buf_ptr[-2] = 0;
ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
buf_ptr[-2] = '/';
} else {
ps.n_comment_delta = 0;
while (*buf_ptr == ' ' || *buf_ptr == '\t')
buf_ptr++;
}
ps.comment_delta = 0;
*e_com++ = '/'; /* put '/' + '*' into buffer */
*e_com++ = '*';
if (*buf_ptr != ' ' && !ps.box_com)
*e_com++ = ' ';
*e_com = '\0';
if (troff) {
now_col = 1;
adj_max_col = 80;
} else
now_col = count_spaces(ps.com_col, s_com); /* figure what column we
* would be in if we
* printed the comment
* now */
if (break_delim) {
char *t = e_com;
e_com = s_com + 2;
*e_com = 0;
if (opt.blanklines_before_blockcomments && ps.last_token != lbrace)
prefix_blankline_requested = 1;
dump_line();
e_com = s_com = t;
if (!ps.box_com && opt.star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
}
/* Start to copy the comment */
/* Start to copy the comment */
while (1) { /* this loop will go until the comment is
while (1) { /* this loop will go until the comment is
* copied */
if (!iscntrl((unsigned char)*buf_ptr) && *buf_ptr != '*')
ps.last_nl = 0;
CHECK_SIZE_COM;
switch (*buf_ptr) { /* this checks for various spcl cases */
case 014: /* check for a form feed */
if (!ps.box_com) { /* in a text comment, break
* the line here */
ps.use_ff = true;
/* fix so dump_line uses a form feed */
dump_line();
last_bl = 0;
*e_com++ = ' ';
*e_com++ = '*';
*e_com++ = ' ';
while (*++buf_ptr == ' ' || *buf_ptr == '\t');
} else {
if (++buf_ptr >= buf_end)
fill_buffer();
*e_com++ = 014;
}
break;
switch (*buf_ptr) { /* this checks for various spcl cases */
case 014: /* check for a form feed */
CHECK_SIZE_COM(3);
if (!ps.box_com) { /* in a text comment, break the line here */
ps.use_ff = true;
/* fix so dump_line uses a form feed */
dump_line();
last_bl = NULL;
if (!ps.box_com && opt.star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
while (*++buf_ptr == ' ' || *buf_ptr == '\t')
;
}
else {
if (++buf_ptr >= buf_end)
fill_buffer();
*e_com++ = 014;
}
break;
case '\n':
if (had_eof) { /* check for unexpected eof */
printf("Unterminated comment\n");
*e_com = '\0';
dump_line();
return;
}
one_liner = 0;
if (ps.box_com || ps.last_nl) { /* if this is a boxed
* comment, we don't
* ignore the newline */
if (s_com == e_com) {
*e_com++ = ' ';
*e_com++ = ' ';
}
*e_com = '\0';
if (!ps.box_com && e_com - s_com > 3) {
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
dump_line();
CHECK_SIZE_COM;
*e_com++ = ' ';
*e_com++ = ' ';
}
dump_line();
now_col = ps.com_col;
} else {
ps.last_nl = 1;
if (unix_comment != 1) { /* we not are in
* unix_style comment */
if (unix_comment == 0 && s_code == e_code) {
/*
* if it is a UNIX-style comment, ignore the
* requirement that previous line be blank for
* unindention
*/
ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
if (ps.com_col <= 1)
ps.com_col = 2;
}
unix_comment = 2; /* permanently remember
* that we are in this
* type of comment */
dump_line();
++line_no;
now_col = ps.com_col;
*e_com++ = ' ';
/*
* fix so that the star at the start of the line will line
* up
*/
do /* flush leading white space */
if (++buf_ptr >= buf_end)
fill_buffer();
while (*buf_ptr == ' ' || *buf_ptr == '\t');
break;
}
if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
last_bl = e_com - 1;
/*
* if there was a space at the end of the last line, remember
* where it was
*/
else { /* otherwise, insert one */
last_bl = e_com;
CHECK_SIZE_COM;
*e_com++ = ' ';
++now_col;
}
}
++line_no; /* keep track of input line number */
if (!ps.box_com) {
int nstar = 1;
do { /* flush any blanks and/or tabs at
* start of next line */
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '*' && --nstar >= 0) {
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '/')
goto end_of_comment;
}
} while (*buf_ptr == ' ' || *buf_ptr == '\t');
} else
if (++buf_ptr >= buf_end)
fill_buffer();
break; /* end of case for newline */
case '*': /* must check for possibility of being at end
* of comment */
if (++buf_ptr >= buf_end) /* get to next char
* after * */
fill_buffer();
if (unix_comment == 0) /* set flag to show we are not
* in unix-style comment */
unix_comment = 1;
if (*buf_ptr == '/') { /* it is the end!!! */
end_of_comment:
if (++buf_ptr >= buf_end)
fill_buffer();
if (*(e_com - 1) != ' ' && !ps.box_com) { /* insure blank before
* end */
*e_com++ = ' ';
++now_col;
}
if (break_delim == 1 && !one_liner && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (break_delim == 2 && e_com > s_com + 3
/* now_col > adj_max_col - 2 && !ps.box_com */ ) {
*e_com = '\0';
dump_line();
now_col = ps.com_col;
}
CHECK_SIZE_COM;
*e_com++ = '*';
*e_com++ = '/';
*e_com = '\0';
ps.just_saw_decl = l_just_saw_decl;
return;
} else {/* handle isolated '*' */
*e_com++ = '*';
++now_col;
}
break;
default: /* we have a random char */
if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
unix_comment = 1; /* we are not in
* unix-style comment */
*e_com = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (*e_com == '\t') /* keep track of column */
now_col = ((now_col - 1) & tabmask) + tabsize + 1;
else
if (*e_com == '\b') /* this is a backspace */
--now_col;
else
++now_col;
if (*e_com == ' ' || *e_com == '\t')
last_bl = e_com;
/* remember we saw a blank */
++e_com;
if (now_col > adj_max_col && !ps.box_com && unix_comment == 1
&& !iscntrl((unsigned char)e_com[-1])
&& !isblank((unsigned char)e_com[-1])) {
/*
* the comment is too long, it must be broken up
*/
if (break_delim == 1 && s_com[0] == '/'
&& s_com[1] == '*' && s_com[2] == ' ') {
char *t = e_com;
break_delim = 2;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments)
prefix_blankline_requested = 1;
dump_line();
e_com = t;
s_com[0] = s_com[1] = s_com[2] = ' ';
}
if (last_bl == 0) { /* we have seen no
* blanks */
last_bl = e_com; /* fake it */
*e_com++ = ' ';
}
*e_com = '\0'; /* print what we have */
*last_bl = '\0';
while (last_bl > s_com && iscntrl((unsigned char)last_bl[-1]) )
*--last_bl = 0;
e_com = last_bl;
dump_line();
*e_com++ = ' '; /* add blanks for continuation */
*e_com++ = ' ';
*e_com++ = ' ';
t_ptr = last_bl + 1;
last_bl = 0;
if (t_ptr >= e_com) {
while (*t_ptr == ' ' || *t_ptr == '\t')
t_ptr++;
while (*t_ptr != '\0') { /* move unprinted part
* of comment down in
* buffer */
if (*t_ptr == ' ' || *t_ptr == '\t')
last_bl = e_com;
*e_com++ = *t_ptr++;
}
}
*e_com = '\0';
now_col = count_spaces(ps.com_col, s_com); /* recompute current
* position */
}
break;
case '\n':
if (had_eof) { /* check for unexpected eof */
printf("Unterminated comment\n");
dump_line();
return;
}
last_bl = NULL;
CHECK_SIZE_COM(4);
if (ps.box_com || ps.last_nl) { /* if this is a boxed comment,
* we dont ignore the newline */
if (s_com == e_com)
*e_com++ = ' ';
if (!ps.box_com && e_com - s_com > 3) {
dump_line();
if (opt.star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
}
dump_line();
if (!ps.box_com && opt.star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
}
else {
ps.last_nl = 1;
if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
last_bl = e_com - 1;
/*
* if there was a space at the end of the last line, remember
* where it was
*/
else { /* otherwise, insert one */
last_bl = e_com;
*e_com++ = ' ';
}
}
++line_no; /* keep track of input line number */
if (!ps.box_com) {
int nstar = 1;
do { /* flush any blanks and/or tabs at start of
* next line */
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '*' && --nstar >= 0) {
if (++buf_ptr >= buf_end)
fill_buffer();
if (*buf_ptr == '/')
goto end_of_comment;
}
} while (*buf_ptr == ' ' || *buf_ptr == '\t');
}
else if (++buf_ptr >= buf_end)
fill_buffer();
break; /* end of case for newline */
case '*': /* must check for possibility of being at end
* of comment */
if (++buf_ptr >= buf_end) /* get to next char after * */
fill_buffer();
CHECK_SIZE_COM(4);
if (*buf_ptr == '/') { /* it is the end!!! */
end_of_comment:
if (++buf_ptr >= buf_end)
fill_buffer();
if (break_delim) {
if (e_com > s_com + 3) {
dump_line();
}
else
s_com = e_com;
*e_com++ = ' ';
}
if (e_com[-1] != ' ' && e_com[-1] != '\t' && !ps.box_com)
*e_com++ = ' '; /* ensure blank before end */
*e_com++ = '*', *e_com++ = '/', *e_com = '\0';
ps.just_saw_decl = l_just_saw_decl;
return;
}
else /* handle isolated '*' */
*e_com++ = '*';
break;
default: /* we have a random char */
now_col = count_spaces_until(ps.com_col, s_com, e_com);
do {
CHECK_SIZE_COM(1);
*e_com = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (*e_com == ' ' || *e_com == '\t')
last_bl = e_com; /* remember we saw a blank */
++e_com;
now_col++;
} while (!memchr("*\n\r\b\t", *buf_ptr, 6) &&
(now_col <= adj_max_col || !last_bl));
ps.last_nl = false;
if (now_col > adj_max_col && !ps.box_com && e_com[-1] > ' ') {
/*
* the comment is too long, it must be broken up
*/
if (last_bl == NULL) {
dump_line();
if (!ps.box_com && opt.star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
break;
}
*e_com = '\0';
e_com = last_bl;
dump_line();
if (!ps.box_com && opt.star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
for (t_ptr = last_bl + 1; *t_ptr == ' ' || *t_ptr == '\t';
t_ptr++)
;
last_bl = NULL;
/*
* t_ptr will be somewhere between e_com (dump_line() reset)
* and l_com. So it's safe to copy byte by byte from t_ptr
* to e_com without any CHECK_SIZE_COM().
*/
while (*t_ptr != '\0') {
if (*t_ptr == ' ' || *t_ptr == '\t')
last_bl = e_com;
*e_com++ = *t_ptr++;
}
}
break;
}
}
}