Import pg_bsd_indent sources.

This brings in an exact copy of the pg_bsd_indent repo as of
commit d301442799cea44e5ccb04331afc537764ec77c5 (2020-12-28).

Discussion: https://postgr.es/m/3935719.1675967430@sss.pgh.pa.us
Discussion: https://postgr.es/m/20200812223409.6di3y2qsnvynao7a@alap3.anarazel.de
This commit is contained in:
Tom Lane 2023-02-12 11:59:18 -05:00
parent dab07e8c68
commit 4e831f4cee
61 changed files with 5737 additions and 0 deletions

10
src/tools/pg_bsd_indent/.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Global excludes across all subdirectories
*.o
*.obj
*.exe
# Local excludes in root directory
/pg_bsd_indent
/*.out
/*.list
/tests.diff

View File

@ -0,0 +1,35 @@
#-------------------------------------------------------------------------
#
# Makefile for pg_bsd_indent
#
# Copyright (c) 2017, PostgreSQL Global Development Group
#
#-------------------------------------------------------------------------
PGFILEDESC = "pg_bsd_indent - indent C code nicely"
PGAPPICON = win32
PROGRAM = pg_bsd_indent
OBJS = args.o err.o indent.o io.o lexi.o parse.o pr_comment.o $(WIN32RES)
# clean junk left behind by "make test"
EXTRA_CLEAN = *.out *.list tests.diff
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
# pgxs.mk assumes too much about what "make check" means, so call it "test"
.PHONY: test
test: $(PROGRAM)
@rm -f tests.diff
@cp $(srcdir)/tests/*.list .
@for testsrc in $(srcdir)/tests/*.0; do \
test=`basename "$$testsrc" .0`; \
./$(PROGRAM) $$testsrc $$test.out -P$(srcdir)/tests/$$test.pro || echo FAILED >>$$test.out; \
diff -u $$testsrc.stdout $$test.out >>tests.diff 2>&1 || true; \
done
@cat tests.diff
@test '!' -s tests.diff
@echo Tests complete.

View File

@ -0,0 +1,100 @@
$FreeBSD: head/usr.bin/indent/README 105244 2002-10-16 13:58:39Z charnier $
This is the C indenter, it originally came from the University of Illinois
via some distribution tape for PDP-11 Unix. It has subsequently been
hacked upon by James Gosling @ CMU. It isn't very pretty, and really needs
to be completely redone, but it is probably the nicest C pretty printer
around.
Further additions to provide "Kernel Normal Form" were contributed
by the folks at Sun Microsystems.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> From mnetor!yunexus!oz@uunet.UU.NET Wed Mar 9 15:30:55 1988
> Date: Tue, 8 Mar 88 18:36:25 EST
> From: yunexus!oz@uunet.UU.NET (Ozan Yigit)
> To: bostic@okeeffe.berkeley.edu
> Cc: ccvaxa!willcox@uunet.UU.NET, jag@sun.com, rsalz@uunet.UU.NET
> In-Reply-To: Keith Bostic's message of Tue, 16 Feb 88 16:09:06 PST
> Subject: Re: Indent...
Thank you for your response about indent. I was wrong in my original
observation (or mis-observation :-). UCB did keep the Illinois
copyright intact.
The issue still is whether we can distribute indent, and if we can, which
version. David Willcox (the author) states that:
| Several people have asked me on what basis I claim that indent is in
| the public domain. I knew I would be sorry I made that posting.
|
| Some history. Way back in 1976, the project I worked on at the
| University of Illinois Center for Advanced Computation had a huge
| battle about how to format C code. After about a week of fighting, I
| got disgusted and wrote a program, which I called indent, to reformat C
| code. It had a bunch of different options that would let you format
| the output the way you liked. In particular, all of the different
| formats being championed were supported.
|
| It was my first big C program. It was ugly. It wasn't designed, it
| just sort of grew. But it pretty much worked, and it stopped most of
| the fighting.
|
| As a matter of form, I included a University of Illinois Copyright
| notice. However, my understanding was that, since the work was done
| on an ARPA contract, it was in the public domain.
|
| Time passed. Some years later, indent showed up on one of the early
| emacs distributions.
|
| 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
| care if they used it, and since then it has been on the BSD distributions.
|
| Somewhere along the way, several other unnamed people have had their
| hands in it. It was converted to understand version 7 C. (The
| original was version 6.) It was converted from its original filter
| interface to its current "blow away the user's file" interface.
| The $HOME/.indent.pro file parsing was added. Some more formatting
| options were added.
|
| The source I have right now has two copyright notices. One is the
| original from the UofI. One is from Berkeley.
|
| I am not a lawyer, and I certainly do not understand copyright law. As
| far as I am concerned, the bulk of this program, everything covered by
| the UofI copyright, is in the public domain, and worth every penny.
| 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 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.
Hence, the issue reduces to *which* one to distribute through
comp.sources.unix. I would suggest that with the permission of you
folks (given that you have parts copyrighted), we distribute the 4.3
version of indent, which appears to be the most up-to-date version. I
happen to have just about every known version of indent, including the
very original submission from the author to a unix tape, later the
G-Emacs version, any 4.n version, sun version and the Unipress
version. I still think we should not have to "go-back-in-time" and
re-do all the work you people have done.
I hope to hear from you as to what you think about this. You may of
course send 4.3 version to the moderator directly, or you can let me
know of your permission, and I will send the sources, or you can let
me know that 4.3 version is off-limits, in which case we would probably
have to revert to an older version. One way or another, I hope to get
a version of indent to comp.sources.unix.
regards.. oz
cc: ccvaxa!willcox
sun.com!jar
uunet!rsalz

View File

@ -0,0 +1,30 @@
pg_bsd_indent
This is a lightly modified version of the "indent" program maintained
by the FreeBSD project. The modifications are mostly to make it portable
to non-BSD-ish platforms, though we do have one formatting switch we
couldn't convince upstream to take.
To build it, you will need a Postgres installation, version 9.5 or newer.
(Once built, the program doesn't depend on that installation.)
To build, just say "make"; or if pg_config from your Postgres installation
isn't in your PATH, say
make PG_CONFIG=path/to/pg_config
Optionally, run "make test" for some simple sanity checks.
To install, copy pg_bsd_indent to somewhere in your usual PATH.
(If you say "make install", it will try to put it in your Postgres
installation directory, which is most likely not what you want for
long-term use.)
TODO: add build support and instructions for Windows
If you happen to be hacking upon the indent source code, the closest
approximation to the existing indentation style seems to be
./pg_bsd_indent -i4 -l79 -di12 -nfc1 -nlp -sac somefile.c
although this has by no means been rigorously adhered to.
(What was that saw about the shoemaker's children?)

View File

@ -0,0 +1,354 @@
/*-
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* 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. 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.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)args.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include "c.h"
/*
* Argument scanning and profile reading code. Default parameters are set
* here as well.
*/
#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.1.1"
/* profile types */
#define PRO_SPECIAL 1 /* special case */
#define PRO_BOOL 2 /* boolean */
#define PRO_INT 3 /* integer */
/* profile specials for booleans */
#define ON 1 /* turn it on */
#define OFF 0 /* turn it off */
/* profile specials for specials */
#define IGN 1 /* ignore it */
#define CLI 2 /* case label indent (float) */
#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
* must be first. Also, while (most) booleans occur more than once, the last
* default value is the one actually assigned.
*/
struct pro {
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, &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},
{"cp", PRO_INT, 0, 0, &else_endif_com_ind},
{"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},
{"fbs", PRO_BOOL, true, ON, &function_brace_split},
{"fc1", PRO_BOOL, true, ON, &format_col1_comments},
{"fcb", PRO_BOOL, true, ON, &format_block_comments},
{"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},
{"ldi", PRO_INT, -1, 0, &ps.local_decl_indent},
{"lpl", PRO_BOOL, false, ON, &lineup_to_parens_always},
{"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},
{"nfbs", PRO_BOOL, true, OFF, &function_brace_split},
{"nfc1", PRO_BOOL, true, OFF, &format_col1_comments},
{"nfcb", PRO_BOOL, true, OFF, &format_block_comments},
{"nip", PRO_BOOL, true, OFF, &ps.indent_parameters},
{"nlpl", PRO_BOOL, false, OFF, &lineup_to_parens_always},
{"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},
{"nsac", PRO_BOOL, false, OFF, &space_after_cast},
{"nsc", PRO_BOOL, true, OFF, &star_comment_cont},
{"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines},
{"ntpg", PRO_BOOL, false, OFF, &postgres_tab_rules},
{"nut", PRO_BOOL, true, OFF, &use_tabs},
{"nv", PRO_BOOL, false, OFF, &verbose},
{"pcs", PRO_BOOL, false, ON, &proc_calls_space},
{"psl", PRO_BOOL, true, ON, &procnames_start_line},
{"sac", PRO_BOOL, false, ON, &space_after_cast},
{"sc", PRO_BOOL, true, ON, &star_comment_cont},
{"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines},
{"st", PRO_SPECIAL, 0, STDIN, 0},
{"ta", PRO_BOOL, false, ON, &auto_typedefs},
{"tpg", PRO_BOOL, false, ON, &postgres_tab_rules},
{"ts", PRO_INT, 8, 0, &tabsize},
{"ut", PRO_BOOL, true, ON, &use_tabs},
{"v", PRO_BOOL, false, ON, &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(const char *profile_name)
{
FILE *f;
char fname[PATH_MAX];
static char prof[] = ".indent.pro";
if (profile_name == NULL)
snprintf(fname, sizeof(fname), "%s/%s", getenv("HOME"), prof);
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";
}
static void
scan_profile(FILE *f)
{
int comment, i;
char *p;
char buf[BUFSIZ];
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 (verbose)
printf("profile: %s\n", buf);
set_option(buf);
}
else if (i == EOF)
return;
}
}
static const char *
eqin(const char *s1, const char *s2)
{
while (*s1) {
if (*s1++ != *s2++)
return (NULL);
}
return (s2);
}
/*
* Set the defaults.
*/
void
set_defaults(void)
{
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_obj = p->p_default;
}
void
set_option(char *arg)
{
struct pro *p;
const char *param_start;
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) {
case PRO_SPECIAL:
switch (p->p_special) {
case IGN:
break;
case CLI:
if (*param_start == 0)
goto need_param;
ps.case_indent = atof(param_start);
break;
case STDIN:
if (input == NULL)
input = stdin;
if (output == NULL)
output = stdout;
break;
case KEY:
if (*param_start == 0)
goto need_param;
add_typename(param_start);
break;
case KEY_FILE:
if (*param_start == 0)
goto need_param;
add_typedefs_from_file(param_start);
break;
case VERSION:
printf("pg_bsd_indent %s (based on FreeBSD indent)\n", INDENT_VERSION);
exit(0);
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, 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

@ -0,0 +1,67 @@
/*-
* Copyright (c) 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.
*/
/*
* This is cut down to just the minimum that we need to build indent.
*/
#include "c.h"
#include <err.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
err(int eval, const char *fmt, ...)
{
int code = errno;
va_list ap;
va_start(ap, fmt);
if (fmt != NULL) {
vfprintf(stderr, fmt, ap);
fprintf(stderr, ": ");
}
fprintf(stderr, "%s\n", strerror(code));
va_end(ap);
exit(eval);
}
void
errx(int eval, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (fmt != NULL)
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
exit(eval);
}

View File

@ -0,0 +1,45 @@
/*-
* Copyright (c) 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.
*
* @(#)err.h 8.1 (Berkeley) 6/2/93
* $FreeBSD: stable/11/include/err.h 203964 2010-02-16 19:39:50Z imp $
*/
#ifndef _ERR_H_
#define _ERR_H_
/*
* This is cut down to just the minimum that we need to build indent.
*/
void err(int, const char *, ...)
pg_attribute_noreturn() pg_attribute_printf(2, 3);
void errx(int, const char *, ...)
pg_attribute_noreturn() pg_attribute_printf(2, 3);
#endif /* !_ERR_H_ */

View File

@ -0,0 +1,618 @@
.\" 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
.\" 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.
.\"
.\" @(#)indent.1 8.1 (Berkeley) 7/1/93
.\" $FreeBSD: head/usr.bin/indent/indent.1 309524 2016-12-04 03:10:25Z pfg $
.\"
.Dd December 2, 2016
.Dt INDENT 1
.Os
.Sh NAME
.Nm indent
.Nd indent and format C program source
.Sh SYNOPSIS
.Nm
.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 | Fl \&br
.Op Fl bs | Fl nbs
.Op Fl c Ns Ar n
.Op Fl cp 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 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 sac | Fl nsac
.Op Fl \&sc | Fl nsc
.Bk -words
.Op Fl sob | Fl nsob
.Ek
.Op Fl \&st
.Op Fl \&ta
.Op Fl T Ns Ar typename
.Op Fl tpg | Fl ntpg
.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
utility is a
.Em C
program formatter.
It reformats the
.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.
.Pp
.Sy NOTE :
If you only specify an
.Ar input-file ,
the formatting is
done `in-place', that is, the formatted file is written back into
.Ar input-file
and a backup copy of
.Ar input-file
is written in the current directory.
If
.Ar input-file
is named
.Sq Pa /blah/blah/file ,
the backup file is named
.Sq Pa file.BAK .
.Pp
If
.Ar output-file
is specified,
.Nm
checks to make sure that it is different from
.Ar input-file .
.Pp
The options listed below control the formatting style imposed by
.Nm .
.Bl -tag -width Op
.It Fl bacc , nbacc
If
.Fl bacc
is specified, a blank line is forced around every conditional
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 .
.It Fl bad , nbad
If
.Fl bad
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
is specified, a blank line is forced after every procedure body.
Default:
.Fl nbap .
.It Fl bbb , nbbb
If
.Fl bbb
is specified, a blank line is forced before every block comment.
Default:
.Fl nbbb .
.It Fl \&bc , nbc
If
.Fl \&bc
is specified, then a newline is forced after each comma in a declaration.
.Fl nbc
turns off this option.
Default:
.Fl \&nbc .
.It Fl \&bl , \&br
Specifying
.Fl \&bl
lines up compound statements like this:
.Bd -literal -offset indent
if (...)
{
code
}
.Ed
.Pp
Specifying
.Fl \&br
(the default) makes them look like this:
.Bd -literal -offset indent
if (...) {
code
}
.Ed
.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.
The default is 33.
.It Fl cp Ns Ar n
The column in which comments on #else and #endif start.
The default is 0, which effectively separates the directives from comments by
a single space.
.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:
.Bd -literal -offset indent
/*
* this is a comment
*/
.Ed
.Pp
Rather than like this:
.Bd -literal -offset indent
/* this is a comment */
.Ed
.Pp
This only affects block comments, not comments to the right of
code.
The default is
.Fl cdb .
.It Fl ce , nce
Enables (disables) forcing of `else's to cuddle up to the immediately preceding
`}'.
The default is
.Fl \&ce .
.It Fl \&ci Ns Ar n
Sets the continuation indent to be
.Ar n .
Continuation
lines will be indented that far from the beginning of the first line of the
statement.
Parenthesized expressions have extra indentation added to
indicate the nesting, unless
.Fl \&lp
is in effect
or the continuation indent is exactly half of the main indent.
.Fl \&ci
defaults to the same value as
.Fl i .
.It Fl cli Ns Ar n
Causes case labels to be indented
.Ar n
tab stops to the right of the containing
.Ic switch
statement.
.Fl cli0.5
causes case labels to be indented half a tab stop.
The
default is
.Fl cli0 .
.It Fl d Ns Ar n
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.
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,
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.
The default is
.Fl ndj .
.It Fl \&ei , nei
Enables (disables) special
.Ic else-if
processing.
If it is enabled, an
.Ic if
following an
.Ic else
will have the same indentation as the preceding
.Ic \&if
statement.
The default is
.Fl ei .
.It Fl eei , neei
Enables (disables) extra indentation on continuation lines of
the expression part of
.Ic if
and
.Ic while
statements.
These continuation lines will be indented one extra level.
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.
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 columns for one indentation level.
The default is 8.
.It Fl \&ip , nip
Enables (disables) the indentation of parameter declarations from the left
margin.
The default is
.Fl \&ip .
.It Fl l Ns Ar n
Maximum length of an output line.
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 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));
.Ed
.Pp
With
.Fl lp
in effect (the default) the code looks somewhat clearer:
.Bd -literal -offset indent
p1\ =\ first_procedure(second_procedure(p2,\ p3),
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 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,
\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 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 `('.
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.
The
default is
.Fl psl .
.It Fl sac , nsac
Control whether parenthesized type names in casts are followed by a space or
not.
The default is
.Fl nsac .
.It Fl \&sc , nsc
Enables (disables) the placement of asterisks (`*'s) at the left edge of all
comments.
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.
Default:
.Fl nsob .
.It Fl \&st
Causes
.Nm
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
to the list of type keywords.
Names accumulate:
.Fl T
can be specified more than once.
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 will not be formatted as nicely as
it should.
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
cannot find all
instances of
.Ic typedef .
.It Fl tpg , ntpg
If
.Fl tpg
is specified, follow Postgres rules about when to use spaces versus
tabs for indentation, that is, use a space instead of a tab if the
tab would move only one column and no tab will follow it.
Default:
.Fl ntpg .
.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.
The default is
.Fl ut .
.It Fl v , \&nv
.Fl v
turns on `verbose' mode;
.Fl \&nv
turns it off.
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.
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
.Nm
by creating a file called
.Pa .indent.pro
in your login directory and/or the current directory and including
whatever switches you like.
A `.indent.pro' in the current directory takes
precedence over the one in your login directory.
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.
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
may be adjusted to account for the change in indentation of the first line
of the comment.
.Pp
.Em Straight text .
All other comments are treated as straight text.
The
.Nm
utility fits as many words (separated by blanks, tabs, or newlines) on a
line as possible.
Blank lines break paragraphs.
.Ss Comment indentation
If a comment is on a line with code it is started in the `comment column',
which is set by the
.Fl c Ns Ns Ar n
command line parameter.
Otherwise, the comment is started at
.Ar n
indentation levels less than where code is currently being placed, where
.Ar n
is specified by the
.Fl d Ns Ns Ar n
command line parameter.
If the code on a line extends past the comment
column, the comment starts further to the right, and the right margin may be
automatically extended in extreme cases.
.Ss Preprocessor lines
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.
Conditional compilation
.Pq Ic #ifdef...#endif
is recognized and
.Nm
attempts to correctly
compensate for the syntactic peculiarities introduced.
.Ss C syntax
The
.Nm
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 malformed syntax.
In particular, the use of macros like:
.Pp
.Dl #define forever for(;;)
.Pp
is handled properly.
.Sh ENVIRONMENT
The
.Nm
utility uses the
.Ev HOME
environment variable.
.Sh FILES
.Bl -tag -width "./.indent.pro" -compact
.It Pa ./.indent.pro
profile file
.It Pa ~/.indent.pro
profile file
.El
.Sh HISTORY
The
.Nm
command appeared in
.Bx 4.2 .
.Sh BUGS
The
.Nm
utility has even more switches than
.Xr ls 1 .
.Pp
A common mistake is to try to indent all the
.Em C
programs in a directory by typing:
.Pp
.Dl indent *.c
.Pp
This is probably a bug, not a feature.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,51 @@
/*-
* Copyright (c) 2001 Jens Schweikhardt
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#if 0
__FBSDID("$FreeBSD: head/usr.bin/indent/indent.h 303746 2016-08-04 15:27:09Z pfg $");
#endif
#define nitems(array) (sizeof (array) / sizeof (array[0]))
void add_typename(const char *);
void alloc_typenames(void);
int compute_code_target(void);
int compute_label_target(void);
int count_spaces(int, char *);
int count_spaces_until(int, char *, char *);
int lexi(struct parser_state *);
void diag2(int, const char *);
void diag3(int, const char *, int);
void diag4(int, const char *, int, int);
void dump_line(void);
int lookahead(void);
void lookahead_reset(void);
void fill_buffer(void);
void parse(int);
void pr_comment(void);
void set_defaults(void);
void set_option(char *);
void set_profile(const char *);

View File

@ -0,0 +1,75 @@
/*-
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* 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. 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.
*
* @(#)indent_codes.h 8.1 (Berkeley) 6/6/93
* $FreeBSD: head/usr.bin/indent/indent_codes.h 309380 2016-12-02 01:25:51Z pfg $
*/
#define newline 1
#define lparen 2
#define rparen 3
#define unary_op 4
#define binary_op 5
#define postop 6
#define question 7
#define casestmt 8
#define colon 9
#define semicolon 10
#define lbrace 11
#define rbrace 12
#define ident 13
#define comma 14
#define comment 15
#define swstmt 16
#define preesc 17
#define form_feed 18
#define decl 19
#define sp_paren 20
#define sp_nparen 21
#define ifstmt 22
#define whilestmt 23
#define forstmt 24
#define stmt 25
#define stmtl 26
#define elselit 27
#define dolit 28
#define dohead 29
#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

@ -0,0 +1,343 @@
/*-
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* 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. 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.
*
* @(#)indent_globs.h 8.1 (Berkeley) 6/6/93
* $FreeBSD: head/usr.bin/indent/indent_globs.h 303735 2016-08-03 22:08:07Z pfg $
*/
#define BACKSLASH '\\'
#define bufsize 200 /* size of internal buffers */
#define sc_size 5000 /* size of save_com buffer */
#define label_offset 2 /* number of levels a label is placed to left
* of code */
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
/*
* Exactly one calling file should define this symbol. The global variables
* will be defined in that file, and just referenced elsewhere.
*/
#ifdef DECLARE_INDENT_GLOBALS
#define extern
#endif
extern FILE *input; /* the fid for the input file */
extern FILE *output; /* the output file */
#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); \
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(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); \
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(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); \
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(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); \
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 */
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 */
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 */
#define token s_token
extern char *tokenbuf; /* the last token scanned */
extern char *s_token;
extern char *e_token;
extern 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 */
extern char sc_buf[sc_size]; /* input text is saved here when looking for
* the brace after an if, while, etc */
extern char *save_com; /* start of the comment stored in sc_buf */
extern 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 */
extern int found_err;
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_block_comments; /* true if comments beginning with
* `/ * \n' are to be reformatted */
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 lineup_to_parens_always; /* if true, do not attempt to keep
* lined-up code within the margin */
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 function_brace_split; /* split function declaration and
* brace onto separate lines */
extern int use_tabs; /* set true to use tabs for spacing,
* false uses all spaces */
extern int auto_typedefs; /* set true to recognize identifiers
* ending in "_t" like typedefs */
extern int space_after_cast; /* "b = (int) a" vs "b = (int)a" */
extern int postgres_tab_rules; /* use Postgres tab-vs-space rules */
extern int tabsize; /* the size of a tab */
extern int else_endif_com_ind; /* the column in which comments to
* the right of #else and #endif
* should start */
extern int ifdef_level;
struct parser_state {
int last_token;
int p_stack[256]; /* this is the parsers stack */
int il[64]; /* this stack stores indentation levels */
float cstk[32]; /* 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 / 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
* a newline */
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
* column 1 */
int com_col; /* this is the column in which the current
* comment 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
* 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
* of a declaration on it */
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
* 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
* indentation level because we are in the
* middle of a stmt */
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
* pr_comment */
int out_lines; /* the number of lines written, set by
* dump_line */
int p_l_follow; /* used to remember how to indent following
* statement */
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
* 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
* terminated with a form feed */
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 local_decl_indent; /* like decl_indent but for locals */
int keyword; /* the type of a keyword or 0 */
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;
};
extern struct parser_state ps;
extern struct parser_state state_stack[5];
extern struct parser_state match_state[5];
/* Undo previous hackery */
#ifdef DECLARE_INDENT_GLOBALS
#undef extern
#endif

View File

@ -0,0 +1,608 @@
/*-
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* 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. 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.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include "c.h"
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
#include "indent.h"
int comment_open;
static int paren_target;
static char *lookahead_buf; /* malloc'd buffer, or NULL initially */
static char *lookahead_buf_end; /* end+1 of allocated space */
static char *lookahead_start; /* => next char for fill_buffer() to fetch */
static char *lookahead_ptr; /* => next char for lookahead() to fetch */
static char *lookahead_end; /* last+1 valid char in lookahead_buf */
static char *lookahead_bp_save; /* lookahead position in bp_save, if any */
static int pad_output(int current, int target);
void
dump_line(void)
{ /* dump_line is the routine that actually
* effects the printing of the new source. It
* prints the label section, followed by the
* code section with the appropriate nesting
* level, followed by any comments */
int cur_col,
target_col = 1;
static int not_first_line;
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++;
}
}
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. 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 += tabsize;
while (target <= 0)
if (*com_st == ' ')
target++, com_st++;
else if (*com_st == '\t')
target = tabsize * (1 + (target - 1) / tabsize) + 1, 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--;
(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 && 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
* 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 = 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;
}
int
compute_code_target(void)
{
int target_col = ps.ind_size * ps.ind_level + 1;
if (ps.paren_level)
if (!lineup_to_parens)
target_col += continuation_indent
* (2 * continuation_indent == ps.ind_size ? 1 : ps.paren_level);
else if (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;
}
int
compute_label_target(void)
{
return
ps.pcase ? (int) (case_ind * ps.ind_size) + 1
: *s_lab == '#' ? 1
: ps.ind_size * (ps.ind_level - label_offset) + 1;
}
/*
* Read data ahead of what has been collected into in_buffer.
*
* Successive calls get further and further ahead, until we hit EOF.
* Call lookahead_reset() to rescan from just beyond in_buffer.
*
* Lookahead is automatically reset whenever fill_buffer() reads beyond
* the lookahead buffer, i.e., you can't use this for "look behind".
*
* The standard pattern for potentially multi-line lookahead is to call
* lookahead_reset(), then enter a loop that scans forward from buf_ptr
* to buf_end, then (if necessary) calls lookahead() to read additional
* characters from beyond the end of the current line.
*/
int
lookahead(void)
{
/* First read whatever's in bp_save area */
if (lookahead_bp_save != NULL && lookahead_bp_save < be_save)
return (unsigned char) *lookahead_bp_save++;
/* Else, we have to examine and probably fill the main lookahead buffer */
while (lookahead_ptr >= lookahead_end) {
int i = getc(input);
if (i == EOF)
return i;
if (i == '\0')
continue; /* fill_buffer drops nulls, and so do we */
if (lookahead_end >= lookahead_buf_end) {
/* Need to allocate or enlarge lookahead_buf */
char *new_buf;
size_t req;
if (lookahead_buf == NULL) {
req = 64;
new_buf = malloc(req);
} else {
req = (lookahead_buf_end - lookahead_buf) * 2;
new_buf = realloc(lookahead_buf, req);
}
if (new_buf == NULL)
errx(1, "too much lookahead required");
lookahead_start = new_buf + (lookahead_start - lookahead_buf);
lookahead_ptr = new_buf + (lookahead_ptr - lookahead_buf);
lookahead_end = new_buf + (lookahead_end - lookahead_buf);
lookahead_buf = new_buf;
lookahead_buf_end = new_buf + req;
}
*lookahead_end++ = i;
}
return (unsigned char) *lookahead_ptr++;
}
/*
* Reset so that lookahead() will again scan from just beyond what's in
* in_buffer.
*/
void
lookahead_reset(void)
{
/* Reset the main lookahead buffer */
lookahead_ptr = lookahead_start;
/* If bp_save isn't NULL, we need to scan that first */
lookahead_bp_save = bp_save;
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: fill_buffer
*
* FUNCTION: Reads one line of input into in_buffer,
* sets up buf_ptr and buf_end to point to the line's start and end+1.
* (Note that the buffer does not get null-terminated.)
*
* HISTORY: initial coding November 1976 D A Willcox of CAC 1/7/77 A
* Willcox of CAC Added check for switch back to partly full input
* buffer from temporary buffer
*
*/
void
fill_buffer(void)
{ /* this routine reads stuff from the input */
char *p;
int i;
FILE *f = input;
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;
lookahead_bp_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;
}
if (lookahead_start < lookahead_end) {
i = (unsigned char) *lookahead_start++;
} else {
lookahead_start = lookahead_ptr = lookahead_end = lookahead_buf;
if ((i = getc(f)) == EOF) {
*p++ = ' ';
*p++ = '\n';
had_eof = true;
break;
}
}
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;
}
}
}
}
}
}
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
*
* All rights reserved
*
*
* NAME: pad_output
*
* FUNCTION: Writes tabs and spaces to move the current column up to the desired
* position.
*
* ALGORITHM: Put tabs and/or blanks into pobuf, then write pobuf.
*
* PARAMETERS: current integer The current column
* target integer The desired column
*
* RETURNS: Integer value of the new column. (If current >= target, no action is
* taken, and current is returned.
*
* GLOBALS: None
*
* CALLS: write (sys)
*
* CALLED BY: dump_line
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
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 */
if (current >= target)
return (current); /* line is already long enough */
curr = current;
if (use_tabs) {
int tcur;
while ((tcur = tabsize * (1 + (curr - 1) / tabsize) + 1) <= target) {
putc((!postgres_tab_rules ||
tcur != curr + 1 ||
target >= tcur + tabsize) ? '\t' : ' ', output);
curr = tcur;
}
}
while (curr++ < target)
putc(' ', output); /* pad with final blanks */
return (target);
}
/*
* Copyright (C) 1976 by the Board of Trustees of the University of Illinois
*
* All rights reserved
*
*
* NAME: count_spaces
*
* FUNCTION: Find out where printing of a given string will leave the current
* character position on output.
*
* ALGORITHM: Run thru input string and add appropriate values to current
* position.
*
* RETURNS: Integer value of position after printing "buffer" starting in column
* "current".
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
int
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 */
for (buf = buffer; *buf != '\0' && buf != end; ++buf) {
switch (*buf) {
case '\n':
case 014: /* form feed */
cur = 1;
break;
case '\t':
cur = tabsize * (1 + (cur - 1) / tabsize) + 1;
break;
case 010: /* backspace */
--cur;
break;
default:
++cur;
break;
} /* end of switch */
} /* end of for loop */
return (cur);
}
int
count_spaces(int cur, char *buffer)
{
return (count_spaces_until(cur, buffer, NULL));
}
void
diag4(int level, const char *msg, int a, int b)
{
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");
}
}
void
diag3(int level, const char *msg, int a)
{
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");
}
}

View File

@ -0,0 +1,724 @@
/*-
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* 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. 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.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)lexi.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include "c.h"
/*
* Here we have the token scanner for indent. It scans off one token and puts
* it in the global variable "token". It returns a code, indicating the type
* of token scanned.
*/
#include <err.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
#define alphanum 1
#ifdef undef
#define opchar 3
#endif
struct templ {
const char *rwd;
int rwcode;
};
/*
* This table has to be sorted alphabetically, because it'll be used in binary
* search. For the same reason, string must be the first thing in struct templ.
*/
struct templ specials[] =
{
{"_Bool", 4},
{"_Complex", 4},
{"_Imaginary", 4},
{"auto", 10},
{"bool", 4},
{"break", 9},
{"case", 8},
{"char", 4},
{"complex", 4},
{"const", 4},
{"continue", 12},
{"default", 8},
{"do", 6},
{"double", 4},
{"else", 6},
{"enum", 3},
{"extern", 10},
{"float", 4},
{"for", 5},
{"global", 4},
{"goto", 9},
{"if", 5},
{"imaginary", 4},
{"inline", 12},
{"int", 4},
{"long", 4},
{"offsetof", 1},
{"register", 10},
{"restrict", 12},
{"return", 9},
{"short", 4},
{"signed", 4},
{"sizeof", 2},
{"static", 10},
{"struct", 3},
{"switch", 7},
{"typedef", 11},
{"union", 3},
{"unsigned", 4},
{"void", 4},
{"volatile", 4},
{"while", 5}
};
const char **typenames;
int typename_count;
int typename_top = -1;
char chartype[128] =
{ /* this is used to facilitate the decision of
* what type (alphanumeric, operator) each
* character is */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 0, 1, 3, 3, 0,
0, 0, 3, 3, 0, 3, 0, 3,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 0, 3, 3, 3, 3,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 3, 1,
0, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 3, 0, 3, 0
};
static int
strcmp_type(const void *e1, const void *e2)
{
return (strcmp(e1, *(const char * const *)e2));
}
/*
* Decide whether "foo(..." is a function definition or declaration.
*
* At call, we are looking at the '('. Look ahead to find the first
* '{', ';' or ',' that is not within parentheses or comments; then
* it's a definition if we found '{', otherwise a declaration.
* Note that this rule is fooled by K&R-style parameter declarations,
* but telling the difference between those and function attributes
* seems like more trouble than it's worth. This code could also be
* fooled by mismatched parens or apparent comment starts within string
* literals, but that seems unlikely in the context it's used in.
*/
static int
is_func_definition(char *tp)
{
int paren_depth = 0;
int in_comment = false;
int in_slash_comment = false;
int lastc = 0;
/* We may need to look past the end of the current buffer. */
lookahead_reset();
for (;;) {
int c;
/* Fetch next character. */
if (tp < buf_end)
c = *tp++;
else {
c = lookahead();
if (c == EOF)
break;
}
/* Handle comments. */
if (in_comment) {
if (lastc == '*' && c == '/')
in_comment = false;
} else if (lastc == '/' && c == '*' && !in_slash_comment)
in_comment = true;
else if (in_slash_comment) {
if (c == '\n')
in_slash_comment = false;
} else if (lastc == '/' && c == '/')
in_slash_comment = true;
/* Count nested parens properly. */
else if (c == '(')
paren_depth++;
else if (c == ')') {
paren_depth--;
/*
* If we find unbalanced parens, we must have started inside a
* declaration.
*/
if (paren_depth < 0)
return false;
} else if (paren_depth == 0) {
/* We are outside any parentheses or comments. */
if (c == '{')
return true;
else if (c == ';' || c == ',')
return false;
}
lastc = c;
}
/* Hit EOF --- for lack of anything better, assume "not a definition". */
return false;
}
int
lexi(struct parser_state *state)
{
int unary_delim; /* this is set to 1 if the current token
* forces a following operator to be unary */
int code; /* internal code to be returned */
char qchar; /* the delimiter character for a string */
e_token = s_token; /* point to start of place to save token */
unary_delim = false;
state->col_1 = state->last_nl; /* tell world that this token started
* in column 1 iff the last thing
* scanned was a newline */
state->last_nl = false;
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
state->col_1 = false; /* leading blanks imply token is not in column
* 1 */
if (++buf_ptr >= buf_end)
fill_buffer();
}
/* Scan an alphanumeric token */
if (chartype[*buf_ptr & 127] == alphanum ||
(buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
/*
* we have a character or number
*/
struct templ *p;
if (isdigit((unsigned char)*buf_ptr) ||
(buf_ptr[0] == '.' && isdigit((unsigned char)buf_ptr[1]))) {
int seendot = 0,
seenexp = 0,
seensfx = 0;
/*
* base 2, base 8, base 16:
*/
if (buf_ptr[0] == '0' && buf_ptr[1] != '.') {
int len;
if (buf_ptr[1] == 'b' || buf_ptr[1] == 'B')
len = strspn(buf_ptr + 2, "01") + 2;
else if (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')
len = strspn(buf_ptr + 2, "0123456789ABCDEFabcdef") + 2;
else
len = strspn(buf_ptr + 1, "012345678") + 1;
if (len > 0) {
CHECK_SIZE_TOKEN(len);
memcpy(e_token, buf_ptr, len);
e_token += len;
buf_ptr += len;
}
else
diag2(1, "Unterminated literal");
}
else /* base 10: */
while (1) {
if (*buf_ptr == '.') {
if (seendot)
break;
else
seendot++;
}
CHECK_SIZE_TOKEN(3);
*e_token++ = *buf_ptr++;
if (!isdigit((unsigned char)*buf_ptr) && *buf_ptr != '.') {
if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
break;
else {
seenexp++;
seendot++;
*e_token++ = *buf_ptr++;
if (*buf_ptr == '+' || *buf_ptr == '-')
*e_token++ = *buf_ptr++;
}
}
}
while (1) {
CHECK_SIZE_TOKEN(2);
if (!(seensfx & 1) && (*buf_ptr == 'U' || *buf_ptr == 'u')) {
*e_token++ = *buf_ptr++;
seensfx |= 1;
continue;
}
if (!(seensfx & 2) && (strchr("fFlL", *buf_ptr) != NULL)) {
if (buf_ptr[1] == buf_ptr[0])
*e_token++ = *buf_ptr++;
*e_token++ = *buf_ptr++;
seensfx |= 2;
continue;
}
break;
}
}
else
while (chartype[*buf_ptr & 127] == alphanum || *buf_ptr == BACKSLASH) {
/* fill_buffer() terminates buffer with newline */
if (*buf_ptr == BACKSLASH) {
if (*(buf_ptr + 1) == '\n') {
buf_ptr += 2;
if (buf_ptr >= buf_end)
fill_buffer();
} else
break;
}
CHECK_SIZE_TOKEN(1);
/* copy it over */
*e_token++ = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
}
*e_token = '\0';
if (s_token[0] == 'L' && s_token[1] == '\0' &&
(*buf_ptr == '"' || *buf_ptr == '\''))
return (strpfx);
while (*buf_ptr == ' ' || *buf_ptr == '\t') { /* get rid of blanks */
if (++buf_ptr >= buf_end)
fill_buffer();
}
state->keyword = 0;
if (state->last_token == structure && !state->p_l_follow) {
/* if last token was 'struct' and we're not
* in parentheses, then this token
* should be treated as a declaration */
state->last_u_d = true;
return (decl);
}
/*
* Operator after identifier is binary unless last token was 'struct'
*/
state->last_u_d = (state->last_token == structure);
p = bsearch(s_token,
specials,
sizeof(specials) / sizeof(specials[0]),
sizeof(specials[0]),
strcmp_type);
if (p == NULL) { /* not a special keyword... */
char *u;
/* ... so maybe a type_t or a typedef */
if ((auto_typedefs && ((u = strrchr(s_token, '_')) != NULL) &&
strcmp(u, "_t") == 0) || (typename_top >= 0 &&
bsearch(s_token, typenames, typename_top + 1,
sizeof(typenames[0]), strcmp_type))) {
state->keyword = 4; /* a type name */
state->last_u_d = true;
goto found_typename;
}
} else { /* we have a keyword */
state->keyword = p->rwcode;
state->last_u_d = true;
switch (p->rwcode) {
case 7: /* it is a switch */
return (swstmt);
case 8: /* a case or default */
return (casestmt);
case 3: /* a "struct" */
/* FALLTHROUGH */
case 4: /* one of the declaration keywords */
found_typename:
if (state->p_l_follow) {
/* inside parens: cast, param list, offsetof or sizeof */
state->cast_mask |= (1 << state->p_l_follow) & ~state->not_cast_mask;
}
if (state->last_token == period || state->last_token == unary_op) {
state->keyword = 0;
break;
}
if (p != NULL && p->rwcode == 3)
return (structure);
if (state->p_l_follow)
break;
return (decl);
case 5: /* if, while, for */
return (sp_paren);
case 6: /* do, else */
return (sp_nparen);
case 10: /* storage class specifier */
return (storage);
case 11: /* typedef */
return (type_def);
default: /* all others are treated like any other
* identifier */
return (ident);
} /* end of switch */
} /* end of if (found_it) */
if (*buf_ptr == '(' && state->tos <= 1 && state->ind_level == 0 &&
state->in_parameter_declaration == 0 && state->block_init == 0) {
if (is_func_definition(buf_ptr)) {
strncpy(state->procname, token, sizeof state->procname - 1);
if (state->in_decl)
state->in_parameter_declaration = 1;
return (funcname);
}
}
/*
* The following hack attempts to guess whether or not the current
* token is in fact a declaration keyword -- one that has been
* typedefd
*/
else if (!state->p_l_follow && !state->block_init &&
!state->in_stmt &&
((*buf_ptr == '*' && buf_ptr[1] != '=') ||
isalpha((unsigned char)*buf_ptr)) &&
(state->last_token == semicolon || state->last_token == lbrace ||
state->last_token == rbrace)) {
state->keyword = 4; /* a type name */
state->last_u_d = true;
return decl;
}
if (state->last_token == decl) /* if this is a declared variable,
* then following sign is unary */
state->last_u_d = true; /* will make "int a -1" work */
return (ident); /* the ident is not in the list */
} /* end of processing for alphanum character */
/* Scan a non-alphanumeric token */
CHECK_SIZE_TOKEN(3); /* things like "<<=" */
*e_token++ = *buf_ptr; /* if it is only a one-character token, it is
* moved here */
*e_token = '\0';
if (++buf_ptr >= buf_end)
fill_buffer();
switch (*token) {
case '\n':
unary_delim = state->last_u_d;
state->last_nl = true; /* remember that we just had a newline */
code = (had_eof ? 0 : newline);
/*
* if data has been exhausted, the newline is a dummy, and we should
* return code to stop
*/
break;
case '\'': /* start of quoted character */
case '"': /* start of string */
qchar = *token;
do { /* copy the string */
while (1) { /* move one character or [/<char>]<char> */
if (*buf_ptr == '\n') {
diag2(1, "Unterminated literal");
goto stop_lit;
}
CHECK_SIZE_TOKEN(2);
*e_token = *buf_ptr++;
if (buf_ptr >= buf_end)
fill_buffer();
if (*e_token == BACKSLASH) { /* if escape, copy extra char */
if (*buf_ptr == '\n') /* check for escaped newline */
++line_no;
*++e_token = *buf_ptr++;
++e_token; /* we must increment this again because we
* copied two chars */
if (buf_ptr >= buf_end)
fill_buffer();
}
else
break; /* we copied one character */
} /* end of while (1) */
} while (*e_token++ != qchar);
stop_lit:
code = ident;
break;
case ('('):
case ('['):
unary_delim = true;
code = lparen;
break;
case (')'):
case (']'):
code = rparen;
break;
case '#':
unary_delim = state->last_u_d;
code = preesc;
break;
case '?':
unary_delim = true;
code = question;
break;
case (':'):
code = colon;
unary_delim = true;
break;
case (';'):
unary_delim = true;
code = semicolon;
break;
case ('{'):
unary_delim = true;
/*
* if (state->in_or_st) state->block_init = 1;
*/
/* ? code = state->block_init ? lparen : lbrace; */
code = lbrace;
break;
case ('}'):
unary_delim = true;
/* ? code = state->block_init ? rparen : rbrace; */
code = rbrace;
break;
case 014: /* a form feed */
unary_delim = state->last_u_d;
state->last_nl = true; /* remember this so we can set 'state->col_1'
* right */
code = form_feed;
break;
case (','):
unary_delim = true;
code = comma;
break;
case '.':
unary_delim = false;
code = period;
break;
case '-':
case '+': /* check for -, +, --, ++ */
code = (state->last_u_d ? unary_op : binary_op);
unary_delim = true;
if (*buf_ptr == token[0]) {
/* check for doubled character */
*e_token++ = *buf_ptr++;
/* buffer overflow will be checked at end of loop */
if (state->last_token == ident || state->last_token == rparen) {
code = (state->last_u_d ? unary_op : postop);
/* check for following ++ or -- */
unary_delim = false;
}
}
else if (*buf_ptr == '=')
/* check for operator += */
*e_token++ = *buf_ptr++;
else if (*buf_ptr == '>') {
/* check for operator -> */
*e_token++ = *buf_ptr++;
unary_delim = false;
code = unary_op;
state->want_blank = false;
}
break; /* buffer overflow will be checked at end of
* switch */
case '=':
if (state->in_or_st)
state->block_init = 1;
#ifdef undef
if (chartype[*buf_ptr & 127] == opchar) { /* we have two char assignment */
e_token[-1] = *buf_ptr++;
if ((e_token[-1] == '<' || e_token[-1] == '>') && e_token[-1] == *buf_ptr)
*e_token++ = *buf_ptr++;
*e_token++ = '='; /* Flip =+ to += */
*e_token = 0;
}
#else
if (*buf_ptr == '=') {/* == */
*e_token++ = '='; /* Flip =+ to += */
buf_ptr++;
*e_token = 0;
}
#endif
code = binary_op;
unary_delim = true;
break;
/* can drop thru!!! */
case '>':
case '<':
case '!': /* ops like <, <<, <=, !=, etc */
if (*buf_ptr == '>' || *buf_ptr == '<' || *buf_ptr == '=') {
*e_token++ = *buf_ptr;
if (++buf_ptr >= buf_end)
fill_buffer();
}
if (*buf_ptr == '=')
*e_token++ = *buf_ptr++;
code = (state->last_u_d ? unary_op : binary_op);
unary_delim = true;
break;
case '*':
unary_delim = true;
if (!state->last_u_d) {
if (*buf_ptr == '=')
*e_token++ = *buf_ptr++;
code = binary_op;
break;
}
while (*buf_ptr == '*' || isspace((unsigned char)*buf_ptr)) {
if (*buf_ptr == '*') {
CHECK_SIZE_TOKEN(1);
*e_token++ = *buf_ptr;
}
if (++buf_ptr >= buf_end)
fill_buffer();
}
code = unary_op;
break;
default:
if (token[0] == '/' && *buf_ptr == '*') {
/* it is start of comment */
*e_token++ = '*';
if (++buf_ptr >= buf_end)
fill_buffer();
code = comment;
unary_delim = state->last_u_d;
break;
}
while (*(e_token - 1) == *buf_ptr || *buf_ptr == '=') {
/*
* handle ||, &&, etc, and also things as in int *****i
*/
CHECK_SIZE_TOKEN(1);
*e_token++ = *buf_ptr;
if (++buf_ptr >= buf_end)
fill_buffer();
}
code = (state->last_u_d ? unary_op : binary_op);
unary_delim = true;
} /* end of switch */
if (buf_ptr >= buf_end) /* check for input buffer empty */
fill_buffer();
state->last_u_d = unary_delim;
CHECK_SIZE_TOKEN(1);
*e_token = '\0'; /* null terminate the token */
return (code);
}
void
alloc_typenames(void)
{
typenames = (const char **)malloc(sizeof(typenames[0]) *
(typename_count = 16));
if (typenames == NULL)
err(1, NULL);
}
void
add_typename(const char *key)
{
int comparison;
const char *copy;
if (typename_top + 1 >= typename_count) {
typenames = realloc((void *)typenames,
sizeof(typenames[0]) * (typename_count *= 2));
if (typenames == NULL)
err(1, NULL);
}
if (typename_top == -1)
typenames[++typename_top] = copy = strdup(key);
else if ((comparison = strcmp(key, typenames[typename_top])) >= 0) {
/* take advantage of sorted input */
if (comparison == 0) /* remove duplicates */
return;
typenames[++typename_top] = copy = strdup(key);
}
else {
int p;
for (p = 0; (comparison = strcmp(key, typenames[p])) > 0; p++)
/* find place for the new key */;
if (comparison == 0) /* remove duplicates */
return;
memmove(&typenames[p + 1], &typenames[p],
sizeof(typenames[0]) * (++typename_top - p));
typenames[p] = copy = strdup(key);
}
if (copy == NULL)
err(1, NULL);
}

View File

@ -0,0 +1,342 @@
/*-
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* 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. 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.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include "c.h"
#include <err.h>
#include <stdio.h>
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
static void reduce(void);
void
parse(int tk) /* tk: the code for the construct scanned */
{
int i;
#ifdef debug
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 */
}
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;
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;
case ifstmt: /* scanned if (...) */
if (ps.p_stack[ps.tos] == elsehead && ps.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 = 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
*/
}
}
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;
}
break;
case elselit: /* scanned an else */
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 = btype_2 | ps.else_if;
}
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 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 */
diag2(1, "Unknown code to parser");
return;
} /* end of switch */
if (ps.tos >= nitems(ps.p_stack) - 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");
#endif
return;
}
/*
* NAME: reduce
*
* FUNCTION: Implements the reduce part of the parsing algorithm
*
* ALGORITHM: The following reductions are done. Reductions are repeated
* until no more are possible.
*
* Old TOS New TOS
* <stmt> <stmt> <stmtl>
* <stmtl> <stmt> <stmtl>
* do <stmt> "dostmt"
* if <stmt> "ifstmt"
* switch <stmt> <stmt>
* decl <stmt> <stmt>
* "ifelse" <stmt> <stmt>
* for <stmt> <stmt>
* while <stmt> <stmt>
* "dostmt" while <stmt>
*
* On each reduction, ps.i_l_follow (the indentation for the following line)
* is set to the indentation level associated with the old TOS.
*
* PARAMETERS: None
*
* RETURNS: Nothing
*
* GLOBALS: ps.cstk ps.i_l_follow = ps.il ps.p_stack = ps.tos =
*
* CALLS: None
*
* CALLED BY: parse
*
* HISTORY: initial coding November 1976 D A Willcox of CAC
*
*/
/*----------------------------------------------*\
| REDUCTION PHASE |
\*----------------------------------------------*/
static void
reduce(void)
{
int i;
for (;;) { /* keep looping until there is nothing left to
* reduce */
switch (ps.p_stack[ps.tos]) {
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 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 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;
default: /* <anything else> <stmt> */
return;
} /* 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;
default: /* anything else on top */
return;
}
}
}

View File

@ -0,0 +1,358 @@
/*-
* Copyright (c) 1985 Sun Microsystems, Inc.
* Copyright (c) 1980, 1993
* The Regents of the University of California. All rights reserved.
* 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. 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.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)pr_comment.c 8.1 (Berkeley) 6/6/93";
#endif /* not lint */
#endif
#include "c.h"
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "indent_globs.h"
#include "indent_codes.h"
#include "indent.h"
/*
* NAME:
* pr_comment
*
* FUNCTION:
* This routine takes care of scanning and printing comments.
*
* ALGORITHM:
* 1) Decide where the comment should be aligned, and if lines should
* be broken.
* 2) If lines should not be broken and filled, just copy up to end of
* comment.
* 3) If lines should be filled, then scan thru input_buffer copying
* characters to com_buf. Remember where the last blank, tab, or
* newline was. When line is filled, print up to last blank and
* continue copying.
*
* HISTORY:
* November 1976 D A Willcox of CAC Initial coding
* 12/6/76 D A Willcox of CAC Modification to handle
* UNIX-style comments
*
*/
/*
* this routine processes comments. It makes an attempt to keep comments from
* going over the max line length. If a line is too long, it moves everything
* from the last blank to the next comment line. Blanks and tabs from the
* 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
* spill comments over the right margin */
char *last_bl; /* points to the last blank in the output
* buffer */
char *t_ptr; /* used for moving string */
int break_delim = comment_delimiter_on_blankline;
int l_just_saw_decl = ps.just_saw_decl;
adj_max_col = 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 && !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' && !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 - 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 = 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);
}
if (s_lab != e_lab && s_lab[1] == 'e' &&
(strncmp(s_lab, "#endif", 6) == 0 ||
strncmp(s_lab, "#else", 5) == 0))
ps.com_col = else_endif_com_ind <= target_col
? target_col + 1 : else_endif_com_ind;
else
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 = tabsize * (1 + (target_col - 1) / tabsize) + 1;
if (ps.com_col + 24 > adj_max_col)
adj_max_col = ps.com_col + 24;
}
}
if (ps.box_com) {
/*
* 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;
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++ = ' ';
/*
* 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 (break_delim) {
char *t = e_com;
e_com = s_com + 2;
*e_com = 0;
if (blanklines_before_blockcomments && ps.last_token != lbrace)
prefix_blankline_requested = 1;
dump_line();
e_com = s_com = t;
if (!ps.box_com && star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
}
/* Start to copy the comment */
while (1) { /* this loop will go until the comment is
* copied */
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 && 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");
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 (star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
}
dump_line();
if (!ps.box_com && 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 && star_comment_cont)
*e_com++ = ' ', *e_com++ = '*', *e_com++ = ' ';
break;
}
*e_com = '\0';
e_com = last_bl;
dump_line();
if (!ps.box_com && 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;
}
}
}

View File

@ -0,0 +1,9 @@
#define b00101010 -1
void t(void) {
unsigned a[] = {0b00101010, 0x00005678, 02, 17U};
float x[] = {.7f, 0.7f};
unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL};
if (0 b00101010)
return;
}

View File

@ -0,0 +1,11 @@
#define b00101010 -1
void
t(void)
{
unsigned a[] = {0b00101010, 0x00005678, 02, 17U};
float x[] = {.7f, 0.7f};
unsigned long ul[] = {0b00001111UL, 0x01010101UL, 02UL, 17UL};
if (0 b00101010)
return;
}

View File

@ -0,0 +1,52 @@
/* $FreeBSD$ */
typedef enum x {
aaaaaaaaaaaaaaaaaaaaaa = 1 << 0, /* test a */
bbbbbbbbbbbbbbbbb = 1 << 1, /* test b */
cccccccccccccc = 1 << 1, /* test c */
dddddddddddddddddddddddddddddd = 1 << 2 /* test d */
} x;
/* See r303597, r303598, r309219, and r309343 */
void t(void) {
/*
* Old indent wrapped the URL near where this sentence ends.
*
* https://www.freebsd.org/cgi/man.cgi?query=indent&apropos=0&sektion=0&manpath=FreeBSD+12-current&arch=default&format=html
*/
/*
* Old indent did not wrap to column 78
*
* aaaaaa bbbbbb cccccc dddddd eeeeee ffffff ggggg hhhhh iiiii jjjj kk
*/
/*
* Old indent unnecessarily removed the star comment continuation on the next line.
*
* *test*
*/
/* r309219 Go through linked list, freeing from the malloced (t[-1]) address. */
/* r309343 */
}
int c(void)
{
if (1) { /*- a christmas tree *
***
***** */
/*- another one *
***
***** */
7;
}
if (1) /*- a christmas tree *
***
***** */
/*- another one *
***
***** */
1;
}

View File

@ -0,0 +1,60 @@
/* $FreeBSD$ */
typedef enum x {
aaaaaaaaaaaaaaaaaaaaaa = 1 << 0, /* test a */
bbbbbbbbbbbbbbbbb = 1 << 1, /* test b */
cccccccccccccc = 1 << 1, /* test c */
dddddddddddddddddddddddddddddd = 1 << 2 /* test d */
} x;
/* See r303597, r303598, r309219, and r309343 */
void
t(void)
{
/*
* Old indent wrapped the URL near where this sentence ends.
*
* https://www.freebsd.org/cgi/man.cgi?query=indent&apropos=0&sektion=0&manpath=FreeBSD+12-current&arch=default&format=html
*/
/*
* Old indent did not wrap to column 78
*
* aaaaaa bbbbbb cccccc dddddd eeeeee ffffff ggggg hhhhh iiiii jjjj
* kk
*/
/*
* Old indent unnecessarily removed the star comment continuation on
* the next line.
*
* *test*
*/
/*
* r309219 Go through linked list, freeing from the malloced (t[-1])
* address.
*/
/* r309343 */
}
int
c(void)
{
if (1) { /*- a christmas tree *
***
***** */
/*- another one *
***
***** */
7;
}
if (1) /*- a christmas tree *
***
***** */
/*- another one *
***
***** */
1;
}

View File

@ -0,0 +1 @@
-bbb

View File

@ -0,0 +1,7 @@
#if 1 /* if */
#elif defined(test) /* elif */
#else /* else */
#endif /* endif */

View File

@ -0,0 +1,7 @@
#if 1 /* if */
#elif defined(test) /* elif */
#else /* else */
#endif /* endif */

View File

@ -0,0 +1,79 @@
/* $FreeBSD$ */
/* See r303570 */
typedef void (*voidptr) (int *);
static const struct
{
double x;
double y, z;
} n[m + 1] =
{
{
.0,
.9,
5
}
};
typedef struct Complex
{
double x;
double y;
} Complex;
void
t1 (char *a, int b,
void (*fn)(void))
{}
void t2 (char *x, int y)
{
int a,
b,
c;
int
*d,
*e,
*f;
int (*g)(),
(*h)(),
(*i)();
int j,
k,
l;
int m
,n
,o
;
int chars[ /* push the comma beyond column 74 .... */ ], x;
}
const int int_minimum_size =
MAXALIGN(offsetof(int, test)) + MAXIMUM_ALIGNOF;
int *int_create(void)
{
}
static
_attribute_printf(1, 2)
void
print_error(const char *fmt,...)
{
}
static LIST_HEAD(, alq) ald_active;
static int ald_shutingdown = 0;
struct thread *ald_thread;
static int
do_execve(
struct thread *td,
struct image_args *args,
struct mac *mac_p)
{
}

View File

@ -0,0 +1,73 @@
/* $FreeBSD$ */
/* See r303570 */
typedef void (*voidptr) (int *);
static const struct {
double x;
double y, z;
} n[m + 1] =
{
{
.0,
.9,
5
}
};
typedef struct Complex {
double x;
double y;
} Complex;
void
t1(char *a, int b,
void (*fn) (void))
{
}
void
t2(char *x, int y)
{
int a, b, c;
int
*d, *e, *f;
int (*g) (), (*h) (), (*i) ();
int j, k, l;
int m
,n
,o
;
int chars[ /* push the comma beyond column 74 .... */ ],
x;
}
const int int_minimum_size =
MAXALIGN(offsetof(int, test)) + MAXIMUM_ALIGNOF;
int *
int_create(void)
{
}
static
_attribute_printf(1, 2)
void
print_error(const char *fmt,...)
{
}
static LIST_HEAD(, alq) ald_active;
static int ald_shutingdown = 0;
struct thread *ald_thread;
static int
do_execve(
struct thread *td,
struct image_args *args,
struct mac *mac_p)
{
}

View File

@ -0,0 +1,42 @@
/* $FreeBSD$ */
/* See r303484 and r309342 */
void t(void) {
/* The two if statements below excercise two different code paths. */
if (1) /* a */ int a; else /* b */ int b;
if (1) /* a */
int a;
else /* b */
int b;
if (1) {
}
/* Old indent would remove the 3 blank lines above, awaiting "else". */
if (1) {
int a;
}
else if (0) {
int b;
}
/* test */
else
;
if (1)
;
else /* Old indent would get very confused here */
/* We also mustn't assume that there's only one comment */
/* before the left brace. */
{
}
}

View File

@ -0,0 +1,47 @@
/* $FreeBSD$ */
/* See r303484 and r309342 */
void
t(void)
{
/* The two if statements below excercise two different code paths. */
if (1) /* a */
int a;
else /* b */
int b;
if (1) /* a */
int a;
else /* b */
int b;
if (1)
{
}
/* Old indent would remove the 3 blank lines above, awaiting "else". */
if (1)
{
int a;
} else if (0)
{
int b;
}
/* test */
else
;
if (1)
;
else /* Old indent would get very confused here */
/* We also mustn't assume that there's only one comment */
/* before the left brace. */
{
}
}

View File

@ -0,0 +1 @@
-bl

View File

@ -0,0 +1,6 @@
typedef enum
{
PREWARM_PREFETCH, /* comment */
PREWARM_READ, /* more comment */
PREWARM_BUFFER /* more comment */
} PrewarmType;

View File

@ -0,0 +1,5 @@
typedef enum {
PREWARM_PREFETCH, /* comment */
PREWARM_READ, /* more comment */
PREWARM_BUFFER /* more comment */
} PrewarmType;

View File

@ -0,0 +1,27 @@
char * x(void)
{
type identifier;
type *pointer;
unused * value;
(void)unused * value;
dmax = (double)3 * 10.0;
dmin = (double)dmax * 10.0;
davg = (double)dmax * dmin;
return NULL;
}
int *
y(void) {
}
int
z(void) {
}
int x;
int *y;
int * * * * z;

View File

@ -0,0 +1,30 @@
char *
x(void)
{
type identifier;
type *pointer;
unused *value;
(void)unused * value;
dmax = (double)3 * 10.0;
dmin = (double)dmax * 10.0;
davg = (double)dmax * dmin;
return NULL;
}
int *
y(void)
{
}
int
z(void)
{
}
int x;
int *y;
int ****z;

View File

@ -0,0 +1,6 @@
/* $FreeBSD$ */
/* See r303499 */
void t(void) {
unsigned long x = 314UL;
float y = 3.14f;
}

View File

@ -0,0 +1,8 @@
/* $FreeBSD$ */
/* See r303499 */
void
t(void)
{
unsigned long x = 314UL;
float y = 3.14f;
}

View File

@ -0,0 +1,13 @@
/* $FreeBSD$ */
/* See r303489 */
void t(void) {
switch (1)
{
case 1: /* test */
case 2: /* test */
}
CLEANUP:
;
V: ;
U: ;
}

View File

@ -0,0 +1,14 @@
/* $FreeBSD$ */
/* See r303489 */
void
t(void)
{
switch (1) {
case 1: /* test */
case 2: /* test */
}
CLEANUP:
;
V: ;
U: ;
}

View File

@ -0,0 +1 @@
-nut

View File

@ -0,0 +1,15 @@
/* $FreeBSD$ */
/* See r309380 */
static int
do_execve(struct thread *td,
struct image_args *args,
struct mac *mac_p)
{
}
static LIST_HEAD(, alq) ald_active;
static int ald_shuttingdown = 0;
struct thread *ald_thread;

View File

@ -0,0 +1,13 @@
/* $FreeBSD$ */
/* See r309380 */
static int
do_execve(struct thread *td,
struct image_args *args,
struct mac *mac_p)
{
}
static LIST_HEAD(, alq) ald_active;
static int ald_shuttingdown = 0;
struct thread *ald_thread;

View File

@ -0,0 +1,4 @@
/* $FreeBSD$ */
void t(void) {
int a = (double) 8;
}

View File

@ -0,0 +1,6 @@
/* $FreeBSD$ */
void
t(void)
{
int a = (double)8;
}

View File

@ -0,0 +1 @@
-nsac

View File

@ -0,0 +1,5 @@
/* $FreeBSD$ */
/* See r303718 */
void t(void) {
int n = malloc(offsetof(struct s, f) + 1);
}

View File

@ -0,0 +1,7 @@
/* $FreeBSD$ */
/* See r303718 */
void
t(void)
{
int n = malloc(offsetof(struct s, f) + 1);
}

View File

@ -0,0 +1,26 @@
typedef void (*pgstat_page) (pgstattuple_type *, Relation, BlockNumber,
BufferAccessStrategy);
typedef char (*get_relation_stats_hook_type) (int *root,
unsigned *rte,
char attnum,
float *vardata);
void similarity_dist(int m)
{
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, 3 /* sizeof gmt */ ),
*here)];
float4 res = DatumGetFloat4(FunctionCall2(similarity,
(here),
here));
if (es->verbose)
{
char *sql = strVal(list_nth(fdw_private,
here));
}
rb->allocfunc(1);
rb2.allocfunc(7);
}

View File

@ -0,0 +1,26 @@
typedef void (*pgstat_page) (pgstattuple_type *, Relation, BlockNumber,
BufferAccessStrategy);
typedef char (*get_relation_stats_hook_type) (int *root,
unsigned *rte,
char attnum,
float *vardata);
void
similarity_dist(int m)
{
char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, 3 /* sizeof gmt */ ),
*here)];
float4 res = DatumGetFloat4(FunctionCall2(similarity,
(here),
here));
if (es->verbose) {
char *sql = strVal(list_nth(fdw_private,
here));
}
rb->allocfunc(1);
rb2.allocfunc(7);
}

View File

@ -0,0 +1 @@
-ts4 -i4 -di12 -Tallocfunc

View File

@ -0,0 +1,4 @@
/* $FreeBSD$ */
void t(void) {
int a = (double) 8;
}

View File

@ -0,0 +1,6 @@
/* $FreeBSD$ */
void
t(void)
{
int a = (double) 8;
}

View File

@ -0,0 +1 @@
-sac

View File

@ -0,0 +1,21 @@
/* $FreeBSD$ */
int f(struct x *a);
/* See r303485 */
void
t(void)
{
static const struct {
int a;
int b;
} c[] = {
{ D, E },
{ F, G }
};
}
void u(struct x a) {
int b;
struct y c = (struct y *)&a;
}

View File

@ -0,0 +1,23 @@
/* $FreeBSD$ */
int f(struct x *a);
/* See r303485 */
void
t(void)
{
static const struct {
int a;
int b;
} c[] = {
{D, E},
{F, G}
};
}
void
u(struct x a)
{
int b;
struct y c = (struct y *)&a;
}

View File

@ -0,0 +1,9 @@
/* $FreeBSD$ */
/* See r303599 */
#if defined(__i386__)
int a;
#elif defined(__amd64__)
int b;
#else
#error "Port me"
#endif

View File

@ -0,0 +1,9 @@
/* $FreeBSD$ */
/* See r303599 */
#if defined(__i386__)
int a;
#elif defined(__amd64__)
int b;
#else
#error "Port me"
#endif

View File

@ -0,0 +1 @@
-bad

View File

@ -0,0 +1,3 @@
/* $FreeBSD$ */
/* See r303735 */
void t(a *x, b *y, c *z);

View File

@ -0,0 +1,3 @@
/* $FreeBSD$ */
/* See r303735 */
void t(a *x, b *y, c * z);

View File

@ -0,0 +1,2 @@
b
a

View File

@ -0,0 +1 @@
-Utypes_from_file.list

View File

@ -0,0 +1,6 @@
/* $FreeBSD$ */
/* See r309220 */
#include <wchar.h>
wchar_t *x = L"test";
wchar_t y = L't';

View File

@ -0,0 +1,6 @@
/* $FreeBSD$ */
/* See r309220 */
#include <wchar.h>
wchar_t *x = L"test";
wchar_t y = L't';