From: Tom Lane <tgl@sss.pgh.pa.us>
To: Andres Freund <andres@anarazel.de>
Cc: pgsql-hackers@lists.postgresql.org
Subject: Re: Importing pg_bsd_indent into our source tree
Date: Sat, 11 Feb 2023 19:33:15 -0500
Message-ID: <725719.1676161995@sss.pgh.pa.us> (raw)
In-Reply-To: <718245.1676159640@sss.pgh.pa.us>
References: <3935719.1675967430@sss.pgh.pa.us>
<20230209210202.t6n35jaiuw6nl4dk@awork3.anarazel.de>
<20230209215532.oomwhj5jyggmciq7@awork3.anarazel.de>
<20230209221450.bkuozhhzlgpupx4d@awork3.anarazel.de>
<3966340.1675981162@sss.pgh.pa.us>
<20230209231013.gjpxs4gapxjatc64@awork3.anarazel.de>
<3972584.1675984746@sss.pgh.pa.us>
<20230210000841.4chvtmr4gkrfsotb@awork3.anarazel.de>
<3979957.1675988437@sss.pgh.pa.us>
<20230210003555.kyhyqq3imgocs62k@awork3.anarazel.de>
<3986263.1675989733@sss.pgh.pa.us>
<718245.1676159640@sss.pgh.pa.us>
I wrote:
> I'll let the cfbot loose on this, and if it runs the tests
> successfully I plan to go ahead and push.
cfbot didn't like that ...
regards, tom lane
Attachments:download all (4 files, .tar.gz)v3-0001-Import-pg_bsd_indent-sources.patch (text/x-diff, 186.2K) download
From 55d1373fb0f7df6745ef8c34274bc82cb84d15d0 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 11 Feb 2023 14:06:36 -0500
Subject: [PATCH v3 1/4] 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/20200812223409.6di3y2qsnvynao7a@alap3.anarazel.de
---
src/tools/pg_bsd_indent/.gitignore | 10 +
src/tools/pg_bsd_indent/Makefile | 35 +
src/tools/pg_bsd_indent/README | 100 ++
src/tools/pg_bsd_indent/README.pg_bsd_indent | 30 +
src/tools/pg_bsd_indent/args.c | 354 +++++
src/tools/pg_bsd_indent/err.c | 67 +
src/tools/pg_bsd_indent/err.h | 45 +
src/tools/pg_bsd_indent/indent.1 | 618 ++++++++
src/tools/pg_bsd_indent/indent.c | 1279 +++++++++++++++++
src/tools/pg_bsd_indent/indent.h | 51 +
src/tools/pg_bsd_indent/indent_codes.h | 75 +
src/tools/pg_bsd_indent/indent_globs.h | 343 +++++
src/tools/pg_bsd_indent/io.c | 608 ++++++++
src/tools/pg_bsd_indent/lexi.c | 724 ++++++++++
src/tools/pg_bsd_indent/parse.c | 342 +++++
src/tools/pg_bsd_indent/pr_comment.c | 358 +++++
src/tools/pg_bsd_indent/tests/binary.0 | 9 +
src/tools/pg_bsd_indent/tests/binary.0.stdout | 11 +
src/tools/pg_bsd_indent/tests/comments.0 | 52 +
.../pg_bsd_indent/tests/comments.0.stdout | 60 +
src/tools/pg_bsd_indent/tests/comments.pro | 1 +
src/tools/pg_bsd_indent/tests/cppelsecom.0 | 7 +
.../pg_bsd_indent/tests/cppelsecom.0.stdout | 7 +
src/tools/pg_bsd_indent/tests/declarations.0 | 79 +
.../pg_bsd_indent/tests/declarations.0.stdout | 73 +
src/tools/pg_bsd_indent/tests/elsecomment.0 | 42 +
.../pg_bsd_indent/tests/elsecomment.0.stdout | 47 +
src/tools/pg_bsd_indent/tests/elsecomment.pro | 1 +
src/tools/pg_bsd_indent/tests/enum.0 | 6 +
src/tools/pg_bsd_indent/tests/enum.0.stdout | 5 +
src/tools/pg_bsd_indent/tests/f_decls.0 | 27 +
.../pg_bsd_indent/tests/f_decls.0.stdout | 30 +
src/tools/pg_bsd_indent/tests/float.0 | 6 +
src/tools/pg_bsd_indent/tests/float.0.stdout | 8 +
src/tools/pg_bsd_indent/tests/label.0 | 13 +
src/tools/pg_bsd_indent/tests/label.0.stdout | 14 +
src/tools/pg_bsd_indent/tests/label.pro | 1 +
src/tools/pg_bsd_indent/tests/list_head.0 | 15 +
.../pg_bsd_indent/tests/list_head.0.stdout | 13 +
src/tools/pg_bsd_indent/tests/nsac.0 | 4 +
src/tools/pg_bsd_indent/tests/nsac.0.stdout | 6 +
src/tools/pg_bsd_indent/tests/nsac.pro | 1 +
src/tools/pg_bsd_indent/tests/offsetof.0 | 5 +
.../pg_bsd_indent/tests/offsetof.0.stdout | 7 +
src/tools/pg_bsd_indent/tests/parens.0 | 26 +
src/tools/pg_bsd_indent/tests/parens.0.stdout | 26 +
src/tools/pg_bsd_indent/tests/parens.pro | 1 +
src/tools/pg_bsd_indent/tests/sac.0 | 4 +
src/tools/pg_bsd_indent/tests/sac.0.stdout | 6 +
src/tools/pg_bsd_indent/tests/sac.pro | 1 +
src/tools/pg_bsd_indent/tests/struct.0 | 21 +
src/tools/pg_bsd_indent/tests/struct.0.stdout | 23 +
src/tools/pg_bsd_indent/tests/surplusbad.0 | 9 +
.../pg_bsd_indent/tests/surplusbad.0.stdout | 9 +
src/tools/pg_bsd_indent/tests/surplusbad.pro | 1 +
.../pg_bsd_indent/tests/types_from_file.0 | 3 +
.../tests/types_from_file.0.stdout | 3 +
.../pg_bsd_indent/tests/types_from_file.list | 2 +
.../pg_bsd_indent/tests/types_from_file.pro | 1 +
src/tools/pg_bsd_indent/tests/wchar.0 | 6 +
src/tools/pg_bsd_indent/tests/wchar.0.stdout | 6 +
61 files changed, 5737 insertions(+)
create mode 100644 src/tools/pg_bsd_indent/.gitignore
create mode 100644 src/tools/pg_bsd_indent/Makefile
create mode 100644 src/tools/pg_bsd_indent/README
create mode 100644 src/tools/pg_bsd_indent/README.pg_bsd_indent
create mode 100644 src/tools/pg_bsd_indent/args.c
create mode 100644 src/tools/pg_bsd_indent/err.c
create mode 100644 src/tools/pg_bsd_indent/err.h
create mode 100644 src/tools/pg_bsd_indent/indent.1
create mode 100644 src/tools/pg_bsd_indent/indent.c
create mode 100644 src/tools/pg_bsd_indent/indent.h
create mode 100644 src/tools/pg_bsd_indent/indent_codes.h
create mode 100644 src/tools/pg_bsd_indent/indent_globs.h
create mode 100644 src/tools/pg_bsd_indent/io.c
create mode 100644 src/tools/pg_bsd_indent/lexi.c
create mode 100644 src/tools/pg_bsd_indent/parse.c
create mode 100644 src/tools/pg_bsd_indent/pr_comment.c
create mode 100644 src/tools/pg_bsd_indent/tests/binary.0
create mode 100644 src/tools/pg_bsd_indent/tests/binary.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/comments.0
create mode 100644 src/tools/pg_bsd_indent/tests/comments.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/comments.pro
create mode 100644 src/tools/pg_bsd_indent/tests/cppelsecom.0
create mode 100644 src/tools/pg_bsd_indent/tests/cppelsecom.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/declarations.0
create mode 100644 src/tools/pg_bsd_indent/tests/declarations.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/elsecomment.0
create mode 100644 src/tools/pg_bsd_indent/tests/elsecomment.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/elsecomment.pro
create mode 100644 src/tools/pg_bsd_indent/tests/enum.0
create mode 100644 src/tools/pg_bsd_indent/tests/enum.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/f_decls.0
create mode 100644 src/tools/pg_bsd_indent/tests/f_decls.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/float.0
create mode 100644 src/tools/pg_bsd_indent/tests/float.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/label.0
create mode 100644 src/tools/pg_bsd_indent/tests/label.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/label.pro
create mode 100644 src/tools/pg_bsd_indent/tests/list_head.0
create mode 100644 src/tools/pg_bsd_indent/tests/list_head.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/nsac.0
create mode 100644 src/tools/pg_bsd_indent/tests/nsac.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/nsac.pro
create mode 100644 src/tools/pg_bsd_indent/tests/offsetof.0
create mode 100644 src/tools/pg_bsd_indent/tests/offsetof.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/parens.0
create mode 100644 src/tools/pg_bsd_indent/tests/parens.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/parens.pro
create mode 100644 src/tools/pg_bsd_indent/tests/sac.0
create mode 100644 src/tools/pg_bsd_indent/tests/sac.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/sac.pro
create mode 100644 src/tools/pg_bsd_indent/tests/struct.0
create mode 100644 src/tools/pg_bsd_indent/tests/struct.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/surplusbad.0
create mode 100644 src/tools/pg_bsd_indent/tests/surplusbad.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/surplusbad.pro
create mode 100644 src/tools/pg_bsd_indent/tests/types_from_file.0
create mode 100644 src/tools/pg_bsd_indent/tests/types_from_file.0.stdout
create mode 100644 src/tools/pg_bsd_indent/tests/types_from_file.list
create mode 100644 src/tools/pg_bsd_indent/tests/types_from_file.pro
create mode 100644 src/tools/pg_bsd_indent/tests/wchar.0
create mode 100644 src/tools/pg_bsd_indent/tests/wchar.0.stdout
diff --git a/src/tools/pg_bsd_indent/.gitignore b/src/tools/pg_bsd_indent/.gitignorenew file mode 100644index 0000000000..4c5d8dc691--- /dev/null+++ b/src/tools/pg_bsd_indent/.gitignore@@ -0,0 +1,10 @@+# Global excludes across all subdirectories+*.o+*.obj+*.exe++# Local excludes in root directory+/pg_bsd_indent+/*.out+/*.list+/tests.diffdiff --git a/src/tools/pg_bsd_indent/Makefile b/src/tools/pg_bsd_indent/Makefilenew file mode 100644index 0000000000..ee046f36f0--- /dev/null+++ b/src/tools/pg_bsd_indent/Makefile@@ -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.diff --git a/src/tools/pg_bsd_indent/README b/src/tools/pg_bsd_indent/READMEnew file mode 100644index 0000000000..33d016db62--- /dev/null+++ b/src/tools/pg_bsd_indent/README@@ -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+diff --git a/src/tools/pg_bsd_indent/README.pg_bsd_indent b/src/tools/pg_bsd_indent/README.pg_bsd_indentnew file mode 100644index 0000000000..85c3dcac1c--- /dev/null+++ b/src/tools/pg_bsd_indent/README.pg_bsd_indent@@ -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?)diff --git a/src/tools/pg_bsd_indent/args.c b/src/tools/pg_bsd_indent/args.cnew file mode 100644index 0000000000..1c83f57049--- /dev/null+++ b/src/tools/pg_bsd_indent/args.c@@ -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);+}diff --git a/src/tools/pg_bsd_indent/err.c b/src/tools/pg_bsd_indent/err.cnew file mode 100644index 0000000000..807319334b--- /dev/null+++ b/src/tools/pg_bsd_indent/err.c@@ -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);+}diff --git a/src/tools/pg_bsd_indent/err.h b/src/tools/pg_bsd_indent/err.hnew file mode 100644index 0000000000..a3e8f97825--- /dev/null+++ b/src/tools/pg_bsd_indent/err.h@@ -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_ */diff --git a/src/tools/pg_bsd_indent/indent.1 b/src/tools/pg_bsd_indent/indent.1new file mode 100644index 0000000000..131abfe70b--- /dev/null+++ b/src/tools/pg_bsd_indent/indent.1@@ -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.diff --git a/src/tools/pg_bsd_indent/indent.c b/src/tools/pg_bsd_indent/indent.cnew file mode 100644index 0000000000..d3a0ecefe9--- /dev/null+++ b/src/tools/pg_bsd_indent/indent.c@@ -0,0 +1,1279 @@+/*-+ * Copyright (c) 1985 Sun Microsystems, Inc.+ * Copyright (c) 1976 Board of Trustees of the University of Illinois.+ * Copyright (c) 1980, 1993+ * The Regents of the University of California. All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ * notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ * notice, this list of conditions and the following disclaimer in the+ * documentation and/or other materials provided with the distribution.+ * 3. 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[] = "@(#)indent.c 5.17 (Berkeley) 6/7/93";+#endif /* not lint */+#endif++#include "c.h"++#include <sys/param.h>+#include <err.h>+#include <fcntl.h>+#include <unistd.h>+#include <stdio.h>+#include <stdlib.h>+#include <string.h>+#include <ctype.h>++/* Tell indent_globs.h to define our global variables here */+#define DECLARE_INDENT_GLOBALS 1++#include "indent_globs.h"+#include "indent_codes.h"+#include "indent.h"++static void bakcopy(void);+static void indent_declaration(int, int);++const char *in_name = "Standard Input"; /* will always point to name of input+ * file */+const char *out_name = "Standard Output"; /* will always point to name+ * of output file */+char bakfile[MAXPATHLEN] = "";++int+main(int argc, char **argv)+{+ int dec_ind; /* current indentation for declarations */+ int di_stack[20]; /* a stack of structure indentation levels */+ int force_nl; /* when true, code must be broken */+ int hd_type = 0; /* used to store type of stmt for if (...),+ * for (...), etc */+ int i; /* local loop counter */+ int scase; /* set to true when we see a case, so we will+ * know what to do with the following colon */+ int sp_sw; /* when true, we are in the expression of+ * if(...), while(...), etc. */+ int squest; /* when this is positive, we have seen a ?+ * without the matching : in a <c>?<s>:<s>+ * construct */+ const char *t_ptr; /* used for copying tokens */+ int tabs_to_var; /* true if using tabs to indent to var name */+ int type_code; /* the type of token, returned by lexi */++ int last_else = 0; /* true iff last keyword was an else */+ const char *profile_name = NULL;+ struct parser_state transient_state; /* a copy for lookup */+++ /*-----------------------------------------------*\+ | INITIALIZATION |+ \*-----------------------------------------------*/++ found_err = 0;++ ps.p_stack[0] = stmt; /* this is the parser's stack */+ ps.last_nl = true; /* this is true if the last thing scanned was+ * a newline */+ ps.last_token = semicolon;+ combuf = (char *) malloc(bufsize);+ if (combuf == NULL)+ err(1, NULL);+ labbuf = (char *) malloc(bufsize);+ if (labbuf == NULL)+ err(1, NULL);+ codebuf = (char *) malloc(bufsize);+ if (codebuf == NULL)+ err(1, NULL);+ tokenbuf = (char *) malloc(bufsize);+ if (tokenbuf == NULL)+ err(1, NULL);+ alloc_typenames();+ l_com = combuf + bufsize - 5;+ l_lab = labbuf + bufsize - 5;+ l_code = codebuf + bufsize - 5;+ l_token = tokenbuf + bufsize - 5;+ combuf[0] = codebuf[0] = labbuf[0] = ' '; /* set up code, label, and+ * comment buffers */+ combuf[1] = codebuf[1] = labbuf[1] = '\0';+ ps.else_if = 1; /* Default else-if special processing to on */+ s_lab = e_lab = labbuf + 1;+ s_code = e_code = codebuf + 1;+ s_com = e_com = combuf + 1;+ s_token = e_token = tokenbuf + 1;++ in_buffer = (char *) malloc(10);+ if (in_buffer == NULL)+ err(1, NULL);+ in_buffer_limit = in_buffer + 8;+ buf_ptr = buf_end = in_buffer;+ line_no = 1;+ had_eof = ps.in_decl = ps.decl_on_line = break_comma = false;+ sp_sw = force_nl = false;+ ps.in_or_st = false;+ ps.bl_line = true;+ dec_ind = 0;+ di_stack[ps.dec_nest = 0] = 0;+ ps.want_blank = ps.in_stmt = ps.ind_stmt = false;++ scase = ps.pcase = false;+ squest = 0;+ sc_end = NULL;+ bp_save = NULL;+ be_save = NULL;++ output = NULL;+ tabs_to_var = 0;++ /*--------------------------------------------------*\+ | COMMAND LINE SCAN |+ \*--------------------------------------------------*/++#ifdef undef+ max_col = 78; /* -l78 */+ lineup_to_parens = 1; /* -lp */+ lineup_to_parens_always = 0; /* -nlpl */+ ps.ljust_decl = 0; /* -ndj */+ ps.com_ind = 33; /* -c33 */+ star_comment_cont = 1; /* -sc */+ ps.ind_size = 8; /* -i8 */+ verbose = 0;+ ps.decl_indent = 16; /* -di16 */+ ps.local_decl_indent = -1; /* if this is not set to some nonnegative value+ * by an arg, we will set this equal to+ * ps.decl_ind */+ ps.indent_parameters = 1; /* -ip */+ ps.decl_com_ind = 0; /* if this is not set to some positive value+ * by an arg, we will set this equal to+ * ps.com_ind */+ btype_2 = 1; /* -br */+ cuddle_else = 1; /* -ce */+ ps.unindent_displace = 0; /* -d0 */+ ps.case_indent = 0; /* -cli0 */+ format_block_comments = 1; /* -fcb */+ format_col1_comments = 1; /* -fc1 */+ procnames_start_line = 1; /* -psl */+ proc_calls_space = 0; /* -npcs */+ comment_delimiter_on_blankline = 1; /* -cdb */+ ps.leave_comma = 1; /* -nbc */+#endif++ for (i = 1; i < argc; ++i)+ if (strcmp(argv[i], "-npro") == 0)+ break;+ else if (argv[i][0] == '-' && argv[i][1] == 'P' && argv[i][2] != '\0')+ profile_name = argv[i]; /* non-empty -P (set profile) */+ set_defaults();+ if (i >= argc)+ set_profile(profile_name);++ for (i = 1; i < argc; ++i) {++ /*+ * look thru args (if any) for changes to defaults+ */+ if (argv[i][0] != '-') {/* no flag on parameter */+ if (input == NULL) { /* we must have the input file */+ in_name = argv[i]; /* remember name of input file */+ input = fopen(in_name, "r");+ if (input == NULL) /* check for open error */+ err(1, "%s", in_name);+ continue;+ }+ else if (output == NULL) { /* we have the output file */+ out_name = argv[i]; /* remember name of output file */+ if (strcmp(in_name, out_name) == 0) { /* attempt to overwrite+ * the file */+ errx(1, "input and output files must be different");+ }+ output = fopen(out_name, "w");+ if (output == NULL) /* check for create error */+ err(1, "%s", out_name);+ continue;+ }+ errx(1, "unknown parameter: %s", argv[i]);+ }+ else+ set_option(argv[i]);+ } /* end of for */+ if (input == NULL)+ input = stdin;+ if (output == NULL) {+ if (input == stdin)+ output = stdout;+ else {+ out_name = in_name;+ bakcopy();+ }+ }++ if (ps.com_ind <= 1)+ ps.com_ind = 2; /* dont put normal comments before column 2 */+ if (block_comment_max_col <= 0)+ block_comment_max_col = max_col;+ if (ps.local_decl_indent < 0) /* if not specified by user, set this */+ ps.local_decl_indent = ps.decl_indent;+ if (ps.decl_com_ind <= 0) /* if not specified by user, set this */+ ps.decl_com_ind = ps.ljust_decl ? (ps.com_ind <= 10 ? 2 : ps.com_ind - 8) : ps.com_ind;+ if (continuation_indent == 0)+ continuation_indent = ps.ind_size;+ fill_buffer(); /* get first batch of stuff into input buffer */++ parse(semicolon);+ {+ char *p = buf_ptr;+ int col = 1;++ while (1) {+ if (*p == ' ')+ col++;+ else if (*p == '\t')+ col = tabsize * (1 + (col - 1) / tabsize) + 1;+ else+ break;+ p++;+ }+ if (col > ps.ind_size)+ ps.ind_level = ps.i_l_follow = col / ps.ind_size;+ }++ /*+ * START OF MAIN LOOP+ */++ while (1) { /* this is the main loop. it will go until we+ * reach eof */+ int comment_buffered = false;++ type_code = lexi(&ps); /* lexi reads one token. The actual+ * characters read are stored in "token". lexi+ * returns a code indicating the type of token */++ /*+ * The following code moves newlines and comments following an if (),+ * while (), else, etc. up to the start of the following stmt to+ * a buffer. This allows proper handling of both kinds of brace+ * placement (-br, -bl) and cuddling "else" (-ce).+ */++ while (ps.search_brace) {+ switch (type_code) {+ case newline:+ if (sc_end == NULL) {+ save_com = sc_buf;+ save_com[0] = save_com[1] = ' ';+ sc_end = &save_com[2];+ }+ *sc_end++ = '\n';+ /*+ * We may have inherited a force_nl == true from the previous+ * token (like a semicolon). But once we know that a newline+ * has been scanned in this loop, force_nl should be false.+ *+ * However, the force_nl == true must be preserved if newline+ * is never scanned in this loop, so this assignment cannot be+ * done earlier.+ */+ force_nl = false;+ case form_feed:+ break;+ case comment:+ if (sc_end == NULL) {+ /*+ * Copy everything from the start of the line, because+ * pr_comment() will use that to calculate original+ * indentation of a boxed comment.+ */+ memcpy(sc_buf, in_buffer, buf_ptr - in_buffer - 4);+ save_com = sc_buf + (buf_ptr - in_buffer - 4);+ save_com[0] = save_com[1] = ' ';+ sc_end = &save_com[2];+ }+ comment_buffered = true;+ *sc_end++ = '/'; /* copy in start of comment */+ *sc_end++ = '*';+ for (;;) { /* loop until we get to the end of the comment */+ *sc_end = *buf_ptr++;+ if (buf_ptr >= buf_end)+ fill_buffer();+ if (*sc_end++ == '*' && *buf_ptr == '/')+ break; /* we are at end of comment */+ if (sc_end >= &save_com[sc_size]) { /* check for temp buffer+ * overflow */+ diag2(1, "Internal buffer overflow - Move big comment from right after if, while, or whatever");+ fflush(output);+ exit(1);+ }+ }+ *sc_end++ = '/'; /* add ending slash */+ if (++buf_ptr >= buf_end) /* get past / in buffer */+ fill_buffer();+ break;+ case lbrace:+ /*+ * Put KNF-style lbraces before the buffered up tokens and+ * jump out of this loop in order to avoid copying the token+ * again under the default case of the switch below.+ */+ if (sc_end != NULL && btype_2) {+ save_com[0] = '{';+ /*+ * Originally the lbrace may have been alone on its own+ * line, but it will be moved into "the else's line", so+ * if there was a newline resulting from the "{" before,+ * it must be scanned now and ignored.+ */+ while (isspace((unsigned char)*buf_ptr)) {+ if (++buf_ptr >= buf_end)+ fill_buffer();+ if (*buf_ptr == '\n')+ break;+ }+ goto sw_buffer;+ }+ /* FALLTHROUGH */+ default: /* it is the start of a normal statement */+ {+ int remove_newlines;++ remove_newlines =+ /* "} else" */+ (type_code == sp_nparen && *token == 'e' &&+ e_code != s_code && e_code[-1] == '}')+ /* "else if" */+ || (type_code == sp_paren && *token == 'i' &&+ last_else && ps.else_if);+ if (remove_newlines)+ force_nl = false;+ if (sc_end == NULL) { /* ignore buffering if+ * comment wasn't saved up */+ ps.search_brace = false;+ goto check_type;+ }+ while (sc_end > save_com && isblank((unsigned char)sc_end[-1])) {+ sc_end--;+ }+ if (swallow_optional_blanklines ||+ (!comment_buffered && remove_newlines)) {+ force_nl = !remove_newlines;+ while (sc_end > save_com && sc_end[-1] == '\n') {+ sc_end--;+ }+ }+ if (force_nl) { /* if we should insert a nl here, put+ * it into the buffer */+ force_nl = false;+ --line_no; /* this will be re-increased when the+ * newline is read from the buffer */+ *sc_end++ = '\n';+ *sc_end++ = ' ';+ if (verbose) /* print error msg if the line was+ * not already broken */+ diag2(0, "Line broken");+ }+ for (t_ptr = token; *t_ptr; ++t_ptr)+ *sc_end++ = *t_ptr;++ sw_buffer:+ ps.search_brace = false; /* stop looking for start of+ * stmt */+ bp_save = buf_ptr; /* save current input buffer */+ be_save = buf_end;+ buf_ptr = save_com; /* fix so that subsequent calls to+ * lexi will take tokens out of+ * save_com */+ *sc_end++ = ' ';/* add trailing blank, just in case */+ buf_end = sc_end;+ sc_end = NULL;+ break;+ }+ } /* end of switch */+ /*+ * We must make this check, just in case there was an unexpected+ * EOF.+ */+ if (type_code != 0) {+ /*+ * The only intended purpose of calling lexi() below is to+ * categorize the next token in order to decide whether to+ * continue buffering forthcoming tokens. Once the buffering+ * is over, lexi() will be called again elsewhere on all of+ * the tokens - this time for normal processing.+ *+ * Calling it for this purpose is a bug, because lexi() also+ * changes the parser state and discards leading whitespace,+ * which is needed mostly for comment-related considerations.+ *+ * Work around the former problem by giving lexi() a copy of+ * the current parser state and discard it if the call turned+ * out to be just a look ahead.+ *+ * Work around the latter problem by copying all whitespace+ * characters into the buffer so that the later lexi() call+ * will read them.+ */+ if (sc_end != NULL) {+ while (*buf_ptr == ' ' || *buf_ptr == '\t') {+ *sc_end++ = *buf_ptr++;+ if (sc_end >= &save_com[sc_size]) {+ errx(1, "input too long");+ }+ }+ if (buf_ptr >= buf_end) {+ fill_buffer();+ }+ }+ transient_state = ps;+ type_code = lexi(&transient_state); /* read another token */+ if (type_code != newline && type_code != form_feed &&+ type_code != comment && !transient_state.search_brace) {+ ps = transient_state;+ }+ }+ } /* end of while (search_brace) */+ last_else = 0;+check_type:+ if (type_code == 0) { /* we got eof */+ if (s_lab != e_lab || s_code != e_code+ || s_com != e_com) /* must dump end of line */+ dump_line();+ if (ps.tos > 1) /* check for balanced braces */+ diag2(1, "Stuff missing from end of file");++ if (verbose) {+ printf("There were %d output lines and %d comments\n",+ ps.out_lines, ps.out_coms);+ printf("(Lines with comments)/(Lines with code): %6.3f\n",+ (1.0 * ps.com_lines) / code_lines);+ }+ fflush(output);+ exit(found_err);+ }+ if (+ (type_code != comment) &&+ (type_code != newline) &&+ (type_code != preesc) &&+ (type_code != form_feed)) {+ if (force_nl &&+ (type_code != semicolon) &&+ (type_code != lbrace || !btype_2)) {+ /* we should force a broken line here */+ if (verbose)+ diag2(0, "Line broken");+ dump_line();+ ps.want_blank = false; /* dont insert blank at line start */+ force_nl = false;+ }+ ps.in_stmt = true; /* turn on flag which causes an extra level of+ * indentation. this is turned off by a ; or+ * '}' */+ if (s_com != e_com) { /* the turkey has embedded a comment+ * in a line. fix it */+ int len = e_com - s_com;++ CHECK_SIZE_CODE(len + 3);+ *e_code++ = ' ';+ memcpy(e_code, s_com, len);+ e_code += len;+ *e_code++ = ' ';+ *e_code = '\0'; /* null terminate code sect */+ ps.want_blank = false;+ e_com = s_com;+ }+ }+ else if (type_code != comment) /* preserve force_nl thru a comment */+ force_nl = false; /* cancel forced newline after newline, form+ * feed, etc */++++ /*-----------------------------------------------------*\+ | do switch on type of token scanned |+ \*-----------------------------------------------------*/+ CHECK_SIZE_CODE(3); /* maximum number of increments of e_code+ * before the next CHECK_SIZE_CODE or+ * dump_line() is 2. After that there's the+ * final increment for the null character. */+ switch (type_code) { /* now, decide what to do with the token */++ case form_feed: /* found a form feed in line */+ ps.use_ff = true; /* a form feed is treated much like a newline */+ dump_line();+ ps.want_blank = false;+ break;++ case newline:+ if (ps.last_token != comma || ps.p_l_follow > 0+ || !ps.leave_comma || ps.block_init || !break_comma || s_com != e_com) {+ dump_line();+ ps.want_blank = false;+ }+ ++line_no; /* keep track of input line number */+ break;++ case lparen: /* got a '(' or '[' */+ /* count parens to make Healy happy */+ if (++ps.p_l_follow == nitems(ps.paren_indents)) {+ diag3(0, "Reached internal limit of %d unclosed parens",+ nitems(ps.paren_indents));+ ps.p_l_follow--;+ }+ if (*token == '[')+ /* not a function pointer declaration or a function call */;+ else if (ps.in_decl && !ps.block_init && !ps.dumped_decl_indent &&+ ps.procname[0] == '\0' && ps.paren_level == 0) {+ /* function pointer declarations */+ indent_declaration(dec_ind, tabs_to_var);+ ps.dumped_decl_indent = true;+ }+ else if (ps.want_blank &&+ ((ps.last_token != ident && ps.last_token != funcname) ||+ /* offsetof (1) is never allowed a space; sizeof (2) gets+ * one iff -bs; all other keywords (>2) always get a space+ * before lparen */+ ps.keyword + Bill_Shannon > 2))+ *e_code++ = ' ';+ ps.want_blank = false;+ *e_code++ = token[0];+ ps.paren_indents[ps.p_l_follow - 1] = count_spaces_until(1, s_code, e_code) - 1;+ if (sp_sw && ps.p_l_follow == 1 && extra_expression_indent+ && ps.paren_indents[0] < 2 * ps.ind_size)+ ps.paren_indents[0] = 2 * ps.ind_size;+ if (ps.in_or_st && *token == '(' && ps.tos <= 2) {+ /*+ * this is a kluge to make sure that declarations will be+ * aligned right if proc decl has an explicit type on it, i.e.+ * "int a(x) {..."+ */+ parse(semicolon); /* I said this was a kluge... */+ ps.in_or_st = false; /* turn off flag for structure decl or+ * initialization */+ }+ /*+ * parenthesized type following sizeof or offsetof is not a cast,+ * and we assume the same for any other non-keyword identifier,+ * to support macros that take types+ */+ if (ps.last_token == ident &&+ (ps.keyword == 0 || ps.keyword == 1 || ps.keyword == 2))+ ps.not_cast_mask |= 1 << ps.p_l_follow;+ break;++ case rparen: /* got a ')' or ']' */+ if (ps.cast_mask & (1 << ps.p_l_follow) & ~ps.not_cast_mask) {+ ps.last_u_d = true;+ ps.cast_mask &= (1 << ps.p_l_follow) - 1;+ ps.want_blank = space_after_cast;+ } else+ ps.want_blank = true;+ ps.not_cast_mask &= (1 << ps.p_l_follow) - 1;+ if (--ps.p_l_follow < 0) {+ ps.p_l_follow = 0;+ diag3(0, "Extra %c", *token);+ }+ if (e_code == s_code) /* if the paren starts the line */+ ps.paren_level = ps.p_l_follow; /* then indent it */++ *e_code++ = token[0];++ if (sp_sw && (ps.p_l_follow == 0)) { /* check for end of if+ * (...), or some such */+ sp_sw = false;+ force_nl = true;/* must force newline after if */+ ps.last_u_d = true; /* inform lexi that a following+ * operator is unary */+ ps.in_stmt = false; /* dont use stmt continuation+ * indentation */++ parse(hd_type); /* let parser worry about if, or whatever */+ }+ ps.search_brace = btype_2; /* this should insure that constructs+ * such as main(){...} and int[]{...}+ * have their braces put in the right+ * place */+ break;++ case unary_op: /* this could be any unary operation */+ if (!ps.dumped_decl_indent && ps.in_decl && !ps.block_init &&+ ps.procname[0] == '\0' && ps.paren_level == 0) {+ /* pointer declarations */++ /*+ * if this is a unary op in a declaration, we should indent+ * this token+ */+ for (i = 0; token[i]; ++i)+ /* find length of token */;+ indent_declaration(dec_ind - i, tabs_to_var);+ ps.dumped_decl_indent = true;+ }+ else if (ps.want_blank)+ *e_code++ = ' ';++ {+ int len = e_token - s_token;++ CHECK_SIZE_CODE(len);+ memcpy(e_code, token, len);+ e_code += len;+ }+ ps.want_blank = false;+ break;++ case binary_op: /* any binary operation */+ {+ int len = e_token - s_token;++ CHECK_SIZE_CODE(len + 1);+ if (ps.want_blank)+ *e_code++ = ' ';+ memcpy(e_code, token, len);+ e_code += len;+ }+ ps.want_blank = true;+ break;++ case postop: /* got a trailing ++ or -- */+ *e_code++ = token[0];+ *e_code++ = token[1];+ ps.want_blank = true;+ break;++ case question: /* got a ? */+ squest++; /* this will be used when a later colon+ * appears so we can distinguish the+ * <c>?<n>:<n> construct */+ if (ps.want_blank)+ *e_code++ = ' ';+ *e_code++ = '?';+ ps.want_blank = true;+ break;++ case casestmt: /* got word 'case' or 'default' */+ scase = true; /* so we can process the later colon properly */+ goto copy_id;++ case colon: /* got a ':' */+ if (squest > 0) { /* it is part of the <c>?<n>: <n> construct */+ --squest;+ if (ps.want_blank)+ *e_code++ = ' ';+ *e_code++ = ':';+ ps.want_blank = true;+ break;+ }+ if (ps.in_or_st) {+ *e_code++ = ':';+ ps.want_blank = false;+ break;+ }+ ps.in_stmt = false; /* seeing a label does not imply we are in a+ * stmt */+ /*+ * turn everything so far into a label+ */+ {+ int len = e_code - s_code;++ CHECK_SIZE_LAB(len + 3);+ memcpy(e_lab, s_code, len);+ e_lab += len;+ *e_lab++ = ':';+ *e_lab = '\0';+ e_code = s_code;+ }+ force_nl = ps.pcase = scase; /* ps.pcase will be used by+ * dump_line to decide how to+ * indent the label. force_nl+ * will force a case n: to be+ * on a line by itself */+ scase = false;+ ps.want_blank = false;+ break;++ case semicolon: /* got a ';' */+ if (ps.dec_nest == 0)+ ps.in_or_st = false;/* we are not in an initialization or+ * structure declaration */+ scase = false; /* these will only need resetting in an error */+ squest = 0;+ if (ps.last_token == rparen)+ ps.in_parameter_declaration = 0;+ ps.cast_mask = 0;+ ps.not_cast_mask = 0;+ ps.block_init = 0;+ ps.block_init_level = 0;+ ps.just_saw_decl--;++ if (ps.in_decl && s_code == e_code && !ps.block_init &&+ !ps.dumped_decl_indent && ps.paren_level == 0) {+ /* indent stray semicolons in declarations */+ indent_declaration(dec_ind - 1, tabs_to_var);+ ps.dumped_decl_indent = true;+ }++ ps.in_decl = (ps.dec_nest > 0); /* if we were in a first level+ * structure declaration, we+ * arent any more */++ if ((!sp_sw || hd_type != forstmt) && ps.p_l_follow > 0) {++ /*+ * This should be true iff there were unbalanced parens in the+ * stmt. It is a bit complicated, because the semicolon might+ * be in a for stmt+ */+ diag2(1, "Unbalanced parens");+ ps.p_l_follow = 0;+ if (sp_sw) { /* this is a check for an if, while, etc. with+ * unbalanced parens */+ sp_sw = false;+ parse(hd_type); /* dont lose the if, or whatever */+ }+ }+ *e_code++ = ';';+ ps.want_blank = true;+ ps.in_stmt = (ps.p_l_follow > 0); /* we are no longer in the+ * middle of a stmt */++ if (!sp_sw) { /* if not if for (;;) */+ parse(semicolon); /* let parser know about end of stmt */+ force_nl = true;/* force newline after an end of stmt */+ }+ break;++ case lbrace: /* got a '{' */+ ps.in_stmt = false; /* dont indent the {} */+ if (!ps.block_init)+ force_nl = true;/* force other stuff on same line as '{' onto+ * new line */+ else if (ps.block_init_level <= 0)+ ps.block_init_level = 1;+ else+ ps.block_init_level++;++ if (s_code != e_code && !ps.block_init) {+ if (!btype_2) {+ dump_line();+ ps.want_blank = false;+ }+ else if (ps.in_parameter_declaration && !ps.in_or_st) {+ ps.i_l_follow = 0;+ if (function_brace_split) { /* dump the line prior to the+ * brace ... */+ dump_line();+ ps.want_blank = false;+ } else /* add a space between the decl and brace */+ ps.want_blank = true;+ }+ }+ if (ps.in_parameter_declaration)+ prefix_blankline_requested = 0;++ if (ps.p_l_follow > 0) { /* check for preceding unbalanced+ * parens */+ diag2(1, "Unbalanced parens");+ ps.p_l_follow = 0;+ if (sp_sw) { /* check for unclosed if, for, etc. */+ sp_sw = false;+ parse(hd_type);+ ps.ind_level = ps.i_l_follow;+ }+ }+ if (s_code == e_code)+ ps.ind_stmt = false; /* dont put extra indentation on line+ * with '{' */+ if (ps.in_decl && ps.in_or_st) { /* this is either a structure+ * declaration or an init */+ di_stack[ps.dec_nest] = dec_ind;+ if (++ps.dec_nest == nitems(di_stack)) {+ diag3(0, "Reached internal limit of %d struct levels",+ nitems(di_stack));+ ps.dec_nest--;+ }+ /* ? dec_ind = 0; */+ }+ else {+ ps.decl_on_line = false; /* we can't be in the middle of+ * a declaration, so don't do+ * special indentation of+ * comments */+ if (blanklines_after_declarations_at_proctop+ && ps.in_parameter_declaration)+ postfix_blankline_requested = 1;+ ps.in_parameter_declaration = 0;+ ps.in_decl = false;+ }+ dec_ind = 0;+ parse(lbrace); /* let parser know about this */+ if (ps.want_blank) /* put a blank before '{' if '{' is not at+ * start of line */+ *e_code++ = ' ';+ ps.want_blank = false;+ *e_code++ = '{';+ ps.just_saw_decl = 0;+ break;++ case rbrace: /* got a '}' */+ if (ps.p_stack[ps.tos] == decl && !ps.block_init) /* semicolons can be+ * omitted in+ * declarations */+ parse(semicolon);+ if (ps.p_l_follow) {/* check for unclosed if, for, else. */+ diag2(1, "Unbalanced parens");+ ps.p_l_follow = 0;+ sp_sw = false;+ }+ ps.just_saw_decl = 0;+ ps.block_init_level--;+ if (s_code != e_code && !ps.block_init) { /* '}' must be first on+ * line */+ if (verbose)+ diag2(0, "Line broken");+ dump_line();+ }+ *e_code++ = '}';+ ps.want_blank = true;+ ps.in_stmt = ps.ind_stmt = false;+ if (ps.dec_nest > 0) { /* we are in multi-level structure+ * declaration */+ dec_ind = di_stack[--ps.dec_nest];+ if (ps.dec_nest == 0 && !ps.in_parameter_declaration)+ ps.just_saw_decl = 2;+ ps.in_decl = true;+ }+ prefix_blankline_requested = 0;+ parse(rbrace); /* let parser know about this */+ ps.search_brace = cuddle_else && ps.p_stack[ps.tos] == ifhead+ && ps.il[ps.tos] >= ps.ind_level;+ if (ps.tos <= 1 && blanklines_after_procs && ps.dec_nest <= 0)+ postfix_blankline_requested = 1;+ break;++ case swstmt: /* got keyword "switch" */+ sp_sw = true;+ hd_type = swstmt; /* keep this for when we have seen the+ * expression */+ goto copy_id; /* go move the token into buffer */++ case sp_paren: /* token is if, while, for */+ sp_sw = true; /* the interesting stuff is done after the+ * expression is scanned */+ hd_type = (*token == 'i' ? ifstmt :+ (*token == 'w' ? whilestmt : forstmt));++ /*+ * remember the type of header for later use by parser+ */+ goto copy_id; /* copy the token into line */++ case sp_nparen: /* got else, do */+ ps.in_stmt = false;+ if (*token == 'e') {+ if (e_code != s_code && (!cuddle_else || e_code[-1] != '}')) {+ if (verbose)+ diag2(0, "Line broken");+ dump_line();/* make sure this starts a line */+ ps.want_blank = false;+ }+ force_nl = true;/* also, following stuff must go onto new line */+ last_else = 1;+ parse(elselit);+ }+ else {+ if (e_code != s_code) { /* make sure this starts a line */+ if (verbose)+ diag2(0, "Line broken");+ dump_line();+ ps.want_blank = false;+ }+ force_nl = true;/* also, following stuff must go onto new line */+ last_else = 0;+ parse(dolit);+ }+ goto copy_id; /* move the token into line */++ case type_def:+ case storage:+ prefix_blankline_requested = 0;+ goto copy_id;++ case structure:+ if (ps.p_l_follow > 0)+ goto copy_id;+ /* FALLTHROUGH */+ case decl: /* we have a declaration type (int, etc.) */+ parse(decl); /* let parser worry about indentation */+ if (ps.last_token == rparen && ps.tos <= 1) {+ if (s_code != e_code) {+ dump_line();+ ps.want_blank = 0;+ }+ }+ if (ps.in_parameter_declaration && ps.indent_parameters && ps.dec_nest == 0) {+ ps.ind_level = ps.i_l_follow = 1;+ ps.ind_stmt = 0;+ }+ ps.in_or_st = true; /* this might be a structure or initialization+ * declaration */+ ps.in_decl = ps.decl_on_line = true;+ if ( /* !ps.in_or_st && */ ps.dec_nest <= 0)+ ps.just_saw_decl = 2;+ prefix_blankline_requested = 0;+ for (i = 0; token[i++];); /* get length of token */++ if (ps.ind_level == 0 || ps.dec_nest > 0) {+ /* global variable or struct member in local variable */+ dec_ind = ps.decl_indent > 0 ? ps.decl_indent : i;+ tabs_to_var = (use_tabs ? ps.decl_indent > 0 : 0);+ } else {+ /* local variable */+ dec_ind = ps.local_decl_indent > 0 ? ps.local_decl_indent : i;+ tabs_to_var = (use_tabs ? ps.local_decl_indent > 0 : 0);+ }+ goto copy_id;++ case funcname:+ case ident: /* got an identifier or constant */+ if (ps.in_decl) {+ if (type_code == funcname) {+ ps.in_decl = false;+ if (procnames_start_line && s_code != e_code) {+ *e_code = '\0';+ dump_line();+ }+ else if (ps.want_blank) {+ *e_code++ = ' ';+ }+ ps.want_blank = false;+ }+ else if (!ps.block_init && !ps.dumped_decl_indent &&+ ps.paren_level == 0) { /* if we are in a declaration, we+ * must indent identifier */+ indent_declaration(dec_ind, tabs_to_var);+ ps.dumped_decl_indent = true;+ ps.want_blank = false;+ }+ }+ else if (sp_sw && ps.p_l_follow == 0) {+ sp_sw = false;+ force_nl = true;+ ps.last_u_d = true;+ ps.in_stmt = false;+ parse(hd_type);+ }+ copy_id:+ {+ int len = e_token - s_token;++ CHECK_SIZE_CODE(len + 1);+ if (ps.want_blank)+ *e_code++ = ' ';+ memcpy(e_code, s_token, len);+ e_code += len;+ }+ if (type_code != funcname)+ ps.want_blank = true;+ break;++ case strpfx:+ {+ int len = e_token - s_token;++ CHECK_SIZE_CODE(len + 1);+ if (ps.want_blank)+ *e_code++ = ' ';+ memcpy(e_code, token, len);+ e_code += len;+ }+ ps.want_blank = false;+ break;++ case period: /* treat a period kind of like a binary+ * operation */+ *e_code++ = '.'; /* move the period into line */+ ps.want_blank = false; /* dont put a blank after a period */+ break;++ case comma:+ ps.want_blank = (s_code != e_code); /* only put blank after comma+ * if comma does not start the+ * line */+ if (ps.in_decl && ps.procname[0] == '\0' && !ps.block_init &&+ !ps.dumped_decl_indent && ps.paren_level == 0) {+ /* indent leading commas and not the actual identifiers */+ indent_declaration(dec_ind - 1, tabs_to_var);+ ps.dumped_decl_indent = true;+ }+ *e_code++ = ',';+ if (ps.p_l_follow == 0) {+ if (ps.block_init_level <= 0)+ ps.block_init = 0;+ if (break_comma && (!ps.leave_comma ||+ count_spaces_until(compute_code_target(), s_code, e_code) >+ max_col - tabsize))+ force_nl = true;+ }+ break;++ case preesc: /* got the character '#' */+ if ((s_com != e_com) ||+ (s_lab != e_lab) ||+ (s_code != e_code))+ dump_line();+ CHECK_SIZE_LAB(1);+ *e_lab++ = '#'; /* move whole line to 'label' buffer */+ {+ int in_comment = 0;+ int com_start = 0;+ char quote = 0;+ int com_end = 0;++ while (*buf_ptr == ' ' || *buf_ptr == '\t') {+ buf_ptr++;+ if (buf_ptr >= buf_end)+ fill_buffer();+ }+ while (*buf_ptr != '\n' || (in_comment && !had_eof)) {+ CHECK_SIZE_LAB(2);+ *e_lab = *buf_ptr++;+ if (buf_ptr >= buf_end)+ fill_buffer();+ switch (*e_lab++) {+ case BACKSLASH:+ if (!in_comment) {+ *e_lab++ = *buf_ptr++;+ if (buf_ptr >= buf_end)+ fill_buffer();+ }+ break;+ case '/':+ if (*buf_ptr == '*' && !in_comment && !quote) {+ in_comment = 1;+ *e_lab++ = *buf_ptr++;+ com_start = e_lab - s_lab - 2;+ }+ break;+ case '"':+ if (quote == '"')+ quote = 0;+ break;+ case '\'':+ if (quote == '\'')+ quote = 0;+ break;+ case '*':+ if (*buf_ptr == '/' && in_comment) {+ in_comment = 0;+ *e_lab++ = *buf_ptr++;+ com_end = e_lab - s_lab;+ }+ break;+ }+ }++ while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))+ e_lab--;+ if (e_lab - s_lab == com_end && bp_save == NULL) {+ /* comment on preprocessor line */+ if (sc_end == NULL) { /* if this is the first comment,+ * we must set up the buffer */+ save_com = sc_buf;+ sc_end = &save_com[0];+ }+ else {+ *sc_end++ = '\n'; /* add newline between+ * comments */+ *sc_end++ = ' ';+ --line_no;+ }+ if (sc_end - save_com + com_end - com_start > sc_size)+ errx(1, "input too long");+ memmove(sc_end, s_lab + com_start, com_end - com_start);+ sc_end += com_end - com_start;+ e_lab = s_lab + com_start;+ while (e_lab > s_lab && (e_lab[-1] == ' ' || e_lab[-1] == '\t'))+ e_lab--;+ bp_save = buf_ptr; /* save current input buffer */+ be_save = buf_end;+ buf_ptr = save_com; /* fix so that subsequent calls to+ * lexi will take tokens out of+ * save_com */+ *sc_end++ = ' '; /* add trailing blank, just in case */+ buf_end = sc_end;+ sc_end = NULL;+ }+ CHECK_SIZE_LAB(1);+ *e_lab = '\0'; /* null terminate line */+ ps.pcase = false;+ }++ if (strncmp(s_lab, "#if", 3) == 0) { /* also ifdef, ifndef */+ if ((size_t)ifdef_level < nitems(state_stack)) {+ match_state[ifdef_level].tos = -1;+ state_stack[ifdef_level++] = ps;+ }+ else+ diag2(1, "#if stack overflow");+ }+ else if (strncmp(s_lab, "#el", 3) == 0) { /* else, elif */+ if (ifdef_level <= 0)+ diag2(1, s_lab[3] == 'i' ? "Unmatched #elif" : "Unmatched #else");+ else {+ match_state[ifdef_level - 1] = ps;+ ps = state_stack[ifdef_level - 1];+ }+ }+ else if (strncmp(s_lab, "#endif", 6) == 0) {+ if (ifdef_level <= 0)+ diag2(1, "Unmatched #endif");+ else+ ifdef_level--;+ } else {+ struct directives {+ int size;+ const char *string;+ }+ recognized[] = {+ {7, "include"},+ {6, "define"},+ {5, "undef"},+ {4, "line"},+ {5, "error"},+ {6, "pragma"}+ };+ int d = nitems(recognized);+ while (--d >= 0)+ if (strncmp(s_lab + 1, recognized[d].string, recognized[d].size) == 0)+ break;+ if (d < 0) {+ diag2(1, "Unrecognized cpp directive");+ break;+ }+ }+ if (blanklines_around_conditional_compilation) {+ postfix_blankline_requested++;+ n_real_blanklines = 0;+ }+ else {+ postfix_blankline_requested = 0;+ prefix_blankline_requested = 0;+ }+ break; /* subsequent processing of the newline+ * character will cause the line to be printed */++ case comment: /* we have gotten a / followed by * this is a biggie */+ pr_comment();+ break;+ } /* end of big switch stmt */++ *e_code = '\0'; /* make sure code section is null terminated */+ if (type_code != comment && type_code != newline && type_code != preesc)+ ps.last_token = type_code;+ } /* end of main while (1) loop */+}++/*+ * copy input file to backup file if in_name is /blah/blah/blah/file, then+ * backup file will be ".Bfile" then make the backup file the input and+ * original input file the output+ */+static void+bakcopy(void)+{+ int n,+ bakchn;+ char buff[8 * 1024];+ const char *p;++ /* construct file name .Bfile */+ for (p = in_name; *p; p++); /* skip to end of string */+ while (p > in_name && *p != '/') /* find last '/' */+ p--;+ if (*p == '/')+ p++;+ sprintf(bakfile, "%s.BAK", p);++ /* copy in_name to backup file */+ bakchn = creat(bakfile, 0600);+ if (bakchn < 0)+ err(1, "%s", bakfile);+ while ((n = read(fileno(input), buff, sizeof(buff))) > 0)+ if (write(bakchn, buff, n) != n)+ err(1, "%s", bakfile);+ if (n < 0)+ err(1, "%s", in_name);+ close(bakchn);+ fclose(input);++ /* re-open backup file as the input file */+ input = fopen(bakfile, "r");+ if (input == NULL)+ err(1, "%s", bakfile);+ /* now the original input file will be the output */+ output = fopen(in_name, "w");+ if (output == NULL) {+ unlink(bakfile);+ err(1, "%s", in_name);+ }+}++static void+indent_declaration(int cur_dec_ind, int tabs_to_var)+{+ int pos = e_code - s_code;+ char *startpos = e_code;++ /*+ * get the tab math right for indentations that are not multiples of tabsize+ */+ if ((ps.ind_level * ps.ind_size) % tabsize != 0) {+ pos += (ps.ind_level * ps.ind_size) % tabsize;+ cur_dec_ind += (ps.ind_level * ps.ind_size) % tabsize;+ }+ if (tabs_to_var) {+ int tpos;++ CHECK_SIZE_CODE(cur_dec_ind / tabsize);+ while ((tpos = tabsize * (1 + pos / tabsize)) <= cur_dec_ind) {+ *e_code++ = (!postgres_tab_rules ||+ tpos != pos + 1 ||+ cur_dec_ind >= tpos + tabsize) ? '\t' : ' ';+ pos = tpos;+ }+ }+ CHECK_SIZE_CODE(cur_dec_ind - pos + 1);+ while (pos < cur_dec_ind) {+ *e_code++ = ' ';+ pos++;+ }+ if (e_code == startpos && ps.want_blank) {+ *e_code++ = ' ';+ ps.want_blank = false;+ }+}diff --git a/src/tools/pg_bsd_indent/indent.h b/src/tools/pg_bsd_indent/indent.hnew file mode 100644index 0000000000..1708dbc19f--- /dev/null+++ b/src/tools/pg_bsd_indent/indent.h@@ -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 *);diff --git a/src/tools/pg_bsd_indent/indent_codes.h b/src/tools/pg_bsd_indent/indent_codes.hnew file mode 100644index 0000000000..24c43fa420--- /dev/null+++ b/src/tools/pg_bsd_indent/indent_codes.h@@ -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 37diff --git a/src/tools/pg_bsd_indent/indent_globs.h b/src/tools/pg_bsd_indent/indent_globs.hnew file mode 100644index 0000000000..398784b3f4--- /dev/null+++ b/src/tools/pg_bsd_indent/indent_globs.h@@ -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+#endifdiff --git a/src/tools/pg_bsd_indent/io.c b/src/tools/pg_bsd_indent/io.cnew file mode 100644index 0000000000..3ce8bfb70c--- /dev/null+++ b/src/tools/pg_bsd_indent/io.c@@ -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");+ }+}+diff --git a/src/tools/pg_bsd_indent/lexi.c b/src/tools/pg_bsd_indent/lexi.cnew file mode 100644index 0000000000..f01596a870--- /dev/null+++ b/src/tools/pg_bsd_indent/lexi.c@@ -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);+}diff --git a/src/tools/pg_bsd_indent/parse.c b/src/tools/pg_bsd_indent/parse.cnew file mode 100644index 0000000000..bf6b1697f9--- /dev/null+++ b/src/tools/pg_bsd_indent/parse.c@@ -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;++ }+ }+}diff --git a/src/tools/pg_bsd_indent/pr_comment.c b/src/tools/pg_bsd_indent/pr_comment.cnew file mode 100644index 0000000000..b0eacac1bb--- /dev/null+++ b/src/tools/pg_bsd_indent/pr_comment.c@@ -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;+ }+ }+}diff --git a/src/tools/pg_bsd_indent/tests/binary.0 b/src/tools/pg_bsd_indent/tests/binary.0new file mode 100644index 0000000000..0c5ebf7e8f--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/binary.0@@ -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;+}diff --git a/src/tools/pg_bsd_indent/tests/binary.0.stdout b/src/tools/pg_bsd_indent/tests/binary.0.stdoutnew file mode 100644index 0000000000..6118ac5055--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/binary.0.stdout@@ -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;+}diff --git a/src/tools/pg_bsd_indent/tests/comments.0 b/src/tools/pg_bsd_indent/tests/comments.0new file mode 100644index 0000000000..7b65c2eb55--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/comments.0@@ -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;+}diff --git a/src/tools/pg_bsd_indent/tests/comments.0.stdout b/src/tools/pg_bsd_indent/tests/comments.0.stdoutnew file mode 100644index 0000000000..8ca5aa518c--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/comments.0.stdout@@ -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;+}diff --git a/src/tools/pg_bsd_indent/tests/comments.pro b/src/tools/pg_bsd_indent/tests/comments.pronew file mode 100644index 0000000000..0959711b3d--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/comments.pro@@ -0,0 +1 @@+-bbb
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/cppelsecom.0 b/src/tools/pg_bsd_indent/tests/cppelsecom.0new file mode 100644index 0000000000..79aed65115--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/cppelsecom.0@@ -0,0 +1,7 @@+#if 1 /* if */++#elif defined(test) /* elif */++#else /* else */++#endif /* endif */diff --git a/src/tools/pg_bsd_indent/tests/cppelsecom.0.stdout b/src/tools/pg_bsd_indent/tests/cppelsecom.0.stdoutnew file mode 100644index 0000000000..047fc3d951--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/cppelsecom.0.stdout@@ -0,0 +1,7 @@+#if 1 /* if */++#elif defined(test) /* elif */++#else /* else */++#endif /* endif */diff --git a/src/tools/pg_bsd_indent/tests/declarations.0 b/src/tools/pg_bsd_indent/tests/declarations.0new file mode 100644index 0000000000..8419494989--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/declarations.0@@ -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)+{++}diff --git a/src/tools/pg_bsd_indent/tests/declarations.0.stdout b/src/tools/pg_bsd_indent/tests/declarations.0.stdoutnew file mode 100644index 0000000000..ab5a447a8b--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/declarations.0.stdout@@ -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)+{++}diff --git a/src/tools/pg_bsd_indent/tests/elsecomment.0 b/src/tools/pg_bsd_indent/tests/elsecomment.0new file mode 100644index 0000000000..61066c22b5--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/elsecomment.0@@ -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. */+ {+++ }+}diff --git a/src/tools/pg_bsd_indent/tests/elsecomment.0.stdout b/src/tools/pg_bsd_indent/tests/elsecomment.0.stdoutnew file mode 100644index 0000000000..7de23be089--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/elsecomment.0.stdout@@ -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. */+ {+++ }+}diff --git a/src/tools/pg_bsd_indent/tests/elsecomment.pro b/src/tools/pg_bsd_indent/tests/elsecomment.pronew file mode 100644index 0000000000..115c4768e7--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/elsecomment.pro@@ -0,0 +1 @@+-bl
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/enum.0 b/src/tools/pg_bsd_indent/tests/enum.0new file mode 100644index 0000000000..15057dc464--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/enum.0@@ -0,0 +1,6 @@+typedef enum+{+PREWARM_PREFETCH, /* comment */+PREWARM_READ, /* more comment */+PREWARM_BUFFER /* more comment */+} PrewarmType;diff --git a/src/tools/pg_bsd_indent/tests/enum.0.stdout b/src/tools/pg_bsd_indent/tests/enum.0.stdoutnew file mode 100644index 0000000000..fd4653b854--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/enum.0.stdout@@ -0,0 +1,5 @@+typedef enum {+ PREWARM_PREFETCH, /* comment */+ PREWARM_READ, /* more comment */+ PREWARM_BUFFER /* more comment */+} PrewarmType;diff --git a/src/tools/pg_bsd_indent/tests/f_decls.0 b/src/tools/pg_bsd_indent/tests/f_decls.0new file mode 100644index 0000000000..aeef03b704--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/f_decls.0@@ -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;diff --git a/src/tools/pg_bsd_indent/tests/f_decls.0.stdout b/src/tools/pg_bsd_indent/tests/f_decls.0.stdoutnew file mode 100644index 0000000000..bc21248552--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/f_decls.0.stdout@@ -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;diff --git a/src/tools/pg_bsd_indent/tests/float.0 b/src/tools/pg_bsd_indent/tests/float.0new file mode 100644index 0000000000..91f017fc1c--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/float.0@@ -0,0 +1,6 @@+/* $FreeBSD$ */+/* See r303499 */+void t(void) {+ unsigned long x = 314UL;+ float y = 3.14f;+}diff --git a/src/tools/pg_bsd_indent/tests/float.0.stdout b/src/tools/pg_bsd_indent/tests/float.0.stdoutnew file mode 100644index 0000000000..0f213182ff--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/float.0.stdout@@ -0,0 +1,8 @@+/* $FreeBSD$ */+/* See r303499 */+void+t(void)+{+ unsigned long x = 314UL;+ float y = 3.14f;+}diff --git a/src/tools/pg_bsd_indent/tests/label.0 b/src/tools/pg_bsd_indent/tests/label.0new file mode 100644index 0000000000..7798a4d5c2--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/label.0@@ -0,0 +1,13 @@+/* $FreeBSD$ */+/* See r303489 */+void t(void) {+ switch (1)+ {+ case 1: /* test */+ case 2: /* test */+ }+CLEANUP:+ ;+V: ;+U: ;+}diff --git a/src/tools/pg_bsd_indent/tests/label.0.stdout b/src/tools/pg_bsd_indent/tests/label.0.stdoutnew file mode 100644index 0000000000..22ec12272a--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/label.0.stdout@@ -0,0 +1,14 @@+/* $FreeBSD$ */+/* See r303489 */+void+t(void)+{+ switch (1) {+ case 1: /* test */+ case 2: /* test */+ }+CLEANUP:+ ;+V: ;+U: ;+}diff --git a/src/tools/pg_bsd_indent/tests/label.pro b/src/tools/pg_bsd_indent/tests/label.pronew file mode 100644index 0000000000..75d1fe1a12--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/label.pro@@ -0,0 +1 @@+-nut
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/list_head.0 b/src/tools/pg_bsd_indent/tests/list_head.0new file mode 100644index 0000000000..35874ebc4e--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/list_head.0@@ -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;++diff --git a/src/tools/pg_bsd_indent/tests/list_head.0.stdout b/src/tools/pg_bsd_indent/tests/list_head.0.stdoutnew file mode 100644index 0000000000..2ebcca5730--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/list_head.0.stdout@@ -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;diff --git a/src/tools/pg_bsd_indent/tests/nsac.0 b/src/tools/pg_bsd_indent/tests/nsac.0new file mode 100644index 0000000000..449eadf3ae--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/nsac.0@@ -0,0 +1,4 @@+/* $FreeBSD$ */+void t(void) {+ int a = (double) 8;+}diff --git a/src/tools/pg_bsd_indent/tests/nsac.0.stdout b/src/tools/pg_bsd_indent/tests/nsac.0.stdoutnew file mode 100644index 0000000000..78f3b28757--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/nsac.0.stdout@@ -0,0 +1,6 @@+/* $FreeBSD$ */+void+t(void)+{+ int a = (double)8;+}diff --git a/src/tools/pg_bsd_indent/tests/nsac.pro b/src/tools/pg_bsd_indent/tests/nsac.pronew file mode 100644index 0000000000..6bcbd2b1ff--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/nsac.pro@@ -0,0 +1 @@+-nsac
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/offsetof.0 b/src/tools/pg_bsd_indent/tests/offsetof.0new file mode 100644index 0000000000..078db19c29--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/offsetof.0@@ -0,0 +1,5 @@+/* $FreeBSD$ */+/* See r303718 */+void t(void) {+ int n = malloc(offsetof(struct s, f) + 1);+}diff --git a/src/tools/pg_bsd_indent/tests/offsetof.0.stdout b/src/tools/pg_bsd_indent/tests/offsetof.0.stdoutnew file mode 100644index 0000000000..199bf0fa07--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/offsetof.0.stdout@@ -0,0 +1,7 @@+/* $FreeBSD$ */+/* See r303718 */+void+t(void)+{+ int n = malloc(offsetof(struct s, f) + 1);+}diff --git a/src/tools/pg_bsd_indent/tests/parens.0 b/src/tools/pg_bsd_indent/tests/parens.0new file mode 100644index 0000000000..366536ce82--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/parens.0@@ -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);+}diff --git a/src/tools/pg_bsd_indent/tests/parens.0.stdout b/src/tools/pg_bsd_indent/tests/parens.0.stdoutnew file mode 100644index 0000000000..2258f8d2f0--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/parens.0.stdout@@ -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);+}diff --git a/src/tools/pg_bsd_indent/tests/parens.pro b/src/tools/pg_bsd_indent/tests/parens.pronew file mode 100644index 0000000000..e860911a11--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/parens.pro@@ -0,0 +1 @@+-ts4 -i4 -di12 -Tallocfuncdiff --git a/src/tools/pg_bsd_indent/tests/sac.0 b/src/tools/pg_bsd_indent/tests/sac.0new file mode 100644index 0000000000..449eadf3ae--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/sac.0@@ -0,0 +1,4 @@+/* $FreeBSD$ */+void t(void) {+ int a = (double) 8;+}diff --git a/src/tools/pg_bsd_indent/tests/sac.0.stdout b/src/tools/pg_bsd_indent/tests/sac.0.stdoutnew file mode 100644index 0000000000..1849b28337--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/sac.0.stdout@@ -0,0 +1,6 @@+/* $FreeBSD$ */+void+t(void)+{+ int a = (double) 8;+}diff --git a/src/tools/pg_bsd_indent/tests/sac.pro b/src/tools/pg_bsd_indent/tests/sac.pronew file mode 100644index 0000000000..2b21505c72--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/sac.pro@@ -0,0 +1 @@+-sac
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/struct.0 b/src/tools/pg_bsd_indent/tests/struct.0new file mode 100644index 0000000000..83142bfb19--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/struct.0@@ -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;+}diff --git a/src/tools/pg_bsd_indent/tests/struct.0.stdout b/src/tools/pg_bsd_indent/tests/struct.0.stdoutnew file mode 100644index 0000000000..3861312865--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/struct.0.stdout@@ -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;+}diff --git a/src/tools/pg_bsd_indent/tests/surplusbad.0 b/src/tools/pg_bsd_indent/tests/surplusbad.0new file mode 100644index 0000000000..07d07026db--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/surplusbad.0@@ -0,0 +1,9 @@+/* $FreeBSD$ */+/* See r303599 */+#if defined(__i386__)+int a;+#elif defined(__amd64__)+int b;+#else+#error "Port me"+#endifdiff --git a/src/tools/pg_bsd_indent/tests/surplusbad.0.stdout b/src/tools/pg_bsd_indent/tests/surplusbad.0.stdoutnew file mode 100644index 0000000000..b288970fb9--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/surplusbad.0.stdout@@ -0,0 +1,9 @@+/* $FreeBSD$ */+/* See r303599 */+#if defined(__i386__)+int a;+#elif defined(__amd64__)+int b;+#else+#error "Port me"+#endifdiff --git a/src/tools/pg_bsd_indent/tests/surplusbad.pro b/src/tools/pg_bsd_indent/tests/surplusbad.pronew file mode 100644index 0000000000..e828c8191c--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/surplusbad.pro@@ -0,0 +1 @@+-bad
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/types_from_file.0 b/src/tools/pg_bsd_indent/tests/types_from_file.0new file mode 100644index 0000000000..6efca24fe1--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/types_from_file.0@@ -0,0 +1,3 @@+/* $FreeBSD$ */+/* See r303735 */+void t(a *x, b *y, c *z);diff --git a/src/tools/pg_bsd_indent/tests/types_from_file.0.stdout b/src/tools/pg_bsd_indent/tests/types_from_file.0.stdoutnew file mode 100644index 0000000000..8776ca6ba8--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/types_from_file.0.stdout@@ -0,0 +1,3 @@+/* $FreeBSD$ */+/* See r303735 */+void t(a *x, b *y, c * z);diff --git a/src/tools/pg_bsd_indent/tests/types_from_file.list b/src/tools/pg_bsd_indent/tests/types_from_file.listnew file mode 100644index 0000000000..5f733616b1--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/types_from_file.list@@ -0,0 +1,2 @@+b+a
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/types_from_file.pro b/src/tools/pg_bsd_indent/tests/types_from_file.pronew file mode 100644index 0000000000..39eb911980--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/types_from_file.pro@@ -0,0 +1 @@+-Utypes_from_file.list
\ No newline at end of file
diff --git a/src/tools/pg_bsd_indent/tests/wchar.0 b/src/tools/pg_bsd_indent/tests/wchar.0new file mode 100644index 0000000000..9910e77857--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/wchar.0@@ -0,0 +1,6 @@+/* $FreeBSD$ */+/* See r309220 */+#include <wchar.h>++wchar_t *x = L"test";+wchar_t y = L't';diff --git a/src/tools/pg_bsd_indent/tests/wchar.0.stdout b/src/tools/pg_bsd_indent/tests/wchar.0.stdoutnew file mode 100644index 0000000000..92774abfdd--- /dev/null+++ b/src/tools/pg_bsd_indent/tests/wchar.0.stdout@@ -0,0 +1,6 @@+/* $FreeBSD$ */+/* See r309220 */+#include <wchar.h>++wchar_t *x = L"test";+wchar_t y = L't';--
2.31.1
v3-0002-Sync-pg_bsd_indent-s-copyright-notices-with-Postg.patch (text/x-diff, 10.2K) download
From da770680de94ba589cb29310f42f71c2373e81cf Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 11 Feb 2023 14:08:57 -0500
Subject: [PATCH v3 2/4] Sync pg_bsd_indent's copyright notices with Postgres
practice.
To avoid confusion, make the copyright notices in these files
match the 3-clause form of the BSD license, per the blanket
policy update that UC Berkeley issued years ago.
Discussion: https://postgr.es/m/20230123011002.fzcaa3krql3mqsfn@awork3.anarazel.de
---
src/tools/pg_bsd_indent/README | 37 ++++++++++++++++++++++++++
src/tools/pg_bsd_indent/args.c | 6 +----
src/tools/pg_bsd_indent/indent.c | 6 +----
src/tools/pg_bsd_indent/indent_codes.h | 6 +----
src/tools/pg_bsd_indent/indent_globs.h | 6 +----
src/tools/pg_bsd_indent/io.c | 6 +----
src/tools/pg_bsd_indent/lexi.c | 6 +----
src/tools/pg_bsd_indent/parse.c | 6 +----
src/tools/pg_bsd_indent/pr_comment.c | 6 +----
9 files changed, 45 insertions(+), 40 deletions(-)
diff --git a/src/tools/pg_bsd_indent/README b/src/tools/pg_bsd_indent/READMEindex 33d016db62..846855d318 100644--- a/src/tools/pg_bsd_indent/README+++ b/src/tools/pg_bsd_indent/README@@ -1,3 +1,40 @@+The FreeBSD originals of the files in this directory bear the+"4-clause" version of the BSD license. We have removed the+"advertising" clauses, as per UC Berkeley's directive here:+ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change+which reads:++July 22, 1999++To All Licensees, Distributors of Any Version of BSD:++As you know, certain of the Berkeley Software Distribution ("BSD") source+code files require that further distributions of products containing all or+portions of the software, acknowledge within their advertising materials+that such products contain software developed by UC Berkeley and its+contributors.++Specifically, the provision reads:++" * 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."++Effective immediately, licensees and distributors are no longer required to+include the acknowledgement within advertising materials. Accordingly, the+foregoing paragraph of those BSD Unix files containing it is hereby deleted+in its entirety.++William Hoskins+Director, Office of Technology Licensing+University of California, Berkeley++----------++What follows is the README file as maintained by FreeBSD indent.++----------
$FreeBSD: head/usr.bin/indent/README 105244 2002-10-16 13:58:39Z charnier $
diff --git a/src/tools/pg_bsd_indent/args.c b/src/tools/pg_bsd_indent/args.cindex 1c83f57049..b18eab5d39 100644--- a/src/tools/pg_bsd_indent/args.c+++ b/src/tools/pg_bsd_indent/args.c@@ -12,11 +12,7 @@
* 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+ * 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.
*
diff --git a/src/tools/pg_bsd_indent/indent.c b/src/tools/pg_bsd_indent/indent.cindex d3a0ecefe9..0024993844 100644--- a/src/tools/pg_bsd_indent/indent.c+++ b/src/tools/pg_bsd_indent/indent.c@@ -12,11 +12,7 @@
* 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+ * 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.
*
diff --git a/src/tools/pg_bsd_indent/indent_codes.h b/src/tools/pg_bsd_indent/indent_codes.hindex 24c43fa420..6576bef75d 100644--- a/src/tools/pg_bsd_indent/indent_codes.h+++ b/src/tools/pg_bsd_indent/indent_codes.h@@ -12,11 +12,7 @@
* 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+ * 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.
*
diff --git a/src/tools/pg_bsd_indent/indent_globs.h b/src/tools/pg_bsd_indent/indent_globs.hindex 398784b3f4..917961bd3d 100644--- a/src/tools/pg_bsd_indent/indent_globs.h+++ b/src/tools/pg_bsd_indent/indent_globs.h@@ -12,11 +12,7 @@
* 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+ * 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.
*
diff --git a/src/tools/pg_bsd_indent/io.c b/src/tools/pg_bsd_indent/io.cindex 3ce8bfb70c..4149424294 100644--- a/src/tools/pg_bsd_indent/io.c+++ b/src/tools/pg_bsd_indent/io.c@@ -12,11 +12,7 @@
* 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+ * 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.
*
diff --git a/src/tools/pg_bsd_indent/lexi.c b/src/tools/pg_bsd_indent/lexi.cindex f01596a870..943bf7ce6b 100644--- a/src/tools/pg_bsd_indent/lexi.c+++ b/src/tools/pg_bsd_indent/lexi.c@@ -12,11 +12,7 @@
* 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+ * 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.
*
diff --git a/src/tools/pg_bsd_indent/parse.c b/src/tools/pg_bsd_indent/parse.cindex bf6b1697f9..e707da639c 100644--- a/src/tools/pg_bsd_indent/parse.c+++ b/src/tools/pg_bsd_indent/parse.c@@ -12,11 +12,7 @@
* 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+ * 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.
*
diff --git a/src/tools/pg_bsd_indent/pr_comment.c b/src/tools/pg_bsd_indent/pr_comment.cindex b0eacac1bb..a9572b39ff 100644--- a/src/tools/pg_bsd_indent/pr_comment.c+++ b/src/tools/pg_bsd_indent/pr_comment.c@@ -12,11 +12,7 @@
* 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+ * 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.
*
--
2.31.1
v3-0003-Integrate-pg_bsd_indent-into-our-build-test-infra.patch (text/x-diff, 14.1K) download
From 3d6bd52162c733bf68e702efae569a945a630e3d Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 11 Feb 2023 18:38:14 -0500
Subject: [PATCH v3 3/4] Integrate pg_bsd_indent into our build/test
infrastructure.
Update the Makefile and build directions for in-tree build,
and add Meson build infrastructure. Also convert the ad-hoc
test target into a TAP test.
Currently, the Make build system will not build pg_bsd_indent
by default, while the Meson system will. Both will test it
during "make check-world" or "ninja test". Neither will install
it automatically. (We might change some of these decisions later.)
Also fix a couple of portability nits noted during early testing.
Also, exclude pg_bsd_indent from pgindent's purview; at least for
now, we'll leave it formatted similarly to the FreeBSD original.
Tom Lane and Andres Freund
Discussion: https://postgr.es/m/20200812223409.6di3y2qsnvynao7a@alap3.anarazel.de
---
GNUmakefile.in | 2 +-
src/Makefile | 2 +
src/meson.build | 2 +
src/tools/pg_bsd_indent/.gitignore | 12 +---
src/tools/pg_bsd_indent/Makefile | 62 ++++++++++++-------
src/tools/pg_bsd_indent/README | 37 +++++++++++
src/tools/pg_bsd_indent/README.pg_bsd_indent | 30 ---------
src/tools/pg_bsd_indent/args.c | 2 +-
src/tools/pg_bsd_indent/indent.c | 2 +-
src/tools/pg_bsd_indent/indent.h | 2 +-
src/tools/pg_bsd_indent/meson.build | 40 ++++++++++++
.../pg_bsd_indent/t/001_pg_bsd_indent.pl | 53 ++++++++++++++++
src/tools/pgindent/exclude_file_patterns | 4 ++
13 files changed, 186 insertions(+), 64 deletions(-)
delete mode 100644 src/tools/pg_bsd_indent/README.pg_bsd_indent
create mode 100644 src/tools/pg_bsd_indent/meson.build
create mode 100644 src/tools/pg_bsd_indent/t/001_pg_bsd_indent.pl
diff --git a/GNUmakefile.in b/GNUmakefile.inindex 5434467381..9c18c56233 100644--- a/GNUmakefile.in+++ b/GNUmakefile.in@@ -68,7 +68,7 @@ check check-tests installcheck installcheck-parallel installcheck-tests: CHECKPR
check check-tests installcheck installcheck-parallel installcheck-tests: submake-generated-headers
$(MAKE) -C src/test/regress $@
-$(call recurse,check-world,src/test src/pl src/interfaces contrib src/bin,check)+$(call recurse,check-world,src/test src/pl src/interfaces contrib src/bin src/tools/pg_bsd_indent,check)
$(call recurse,checkprep, src/test src/pl src/interfaces contrib src/bin)
$(call recurse,installcheck-world,src/test src/pl src/interfaces contrib src/bin,installcheck)
diff --git a/src/Makefile b/src/Makefileindex 79e274a476..94649c36c7 100644--- a/src/Makefile+++ b/src/Makefile@@ -66,11 +66,13 @@ clean:
$(MAKE) -C test $@
$(MAKE) -C tutorial NO_PGXS=1 $@
$(MAKE) -C test/isolation $@
+ $(MAKE) -C tools/pg_bsd_indent $@
distclean maintainer-clean:
$(MAKE) -C test $@
$(MAKE) -C tutorial NO_PGXS=1 $@
$(MAKE) -C test/isolation $@
+ $(MAKE) -C tools/pg_bsd_indent $@
rm -f Makefile.port Makefile.global
diff --git a/src/meson.build b/src/meson.buildindex 80fd2823a9..bceeca70f9 100644--- a/src/meson.build+++ b/src/meson.build@@ -13,6 +13,8 @@ subdir('pl')
subdir('interfaces')
+subdir('tools/pg_bsd_indent')+
### Generate a Makefile.global that's complete enough for PGXS to work.
#
diff --git a/src/tools/pg_bsd_indent/.gitignore b/src/tools/pg_bsd_indent/.gitignoreindex 4c5d8dc691..b27e3610d5 100644--- a/src/tools/pg_bsd_indent/.gitignore+++ b/src/tools/pg_bsd_indent/.gitignore@@ -1,10 +1,4 @@-# Global excludes across all subdirectories-*.o-*.obj-*.exe--# Local excludes in root directory
/pg_bsd_indent
-/*.out-/*.list-/tests.diff+# Generated by test suite+/log/+/tmp_check/diff --git a/src/tools/pg_bsd_indent/Makefile b/src/tools/pg_bsd_indent/Makefileindex ee046f36f0..ee3d494f40 100644--- a/src/tools/pg_bsd_indent/Makefile+++ b/src/tools/pg_bsd_indent/Makefile@@ -1,35 +1,55 @@
#-------------------------------------------------------------------------
#
-# Makefile for pg_bsd_indent+# src/tools/pg_bsd_indent/Makefile
#
-# Copyright (c) 2017, PostgreSQL Global Development Group+# Copyright (c) 2017-2023, 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)+subdir = src/tools/pg_bsd_indent+top_builddir = ../../..+include $(top_builddir)/src/Makefile.global-# clean junk left behind by "make test"-EXTRA_CLEAN = *.out *.list tests.diff+OBJS = \+ $(WIN32RES) \+ args.o \+ err.o \+ indent.o \+ io.o \+ lexi.o \+ parse.o \+ pr_comment.o-PG_CONFIG = pg_config-PGXS := $(shell $(PG_CONFIG) --pgxs)-include $(PGXS)+all: pg_bsd_indent-# pgxs.mk assumes too much about what "make check" means, so call it "test"+pg_bsd_indent: $(OBJS) | submake-libpgport+ $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)++install: all installdirs+ $(INSTALL_PROGRAM) pg_bsd_indent$(X) '$(DESTDIR)$(bindir)/pg_bsd_indent$(X)'++installdirs:+ $(MKDIR_P) '$(DESTDIR)$(bindir)'++uninstall:+ rm -f '$(DESTDIR)$(bindir)/pg_bsd_indent$(X)'++clean distclean maintainer-clean:+ rm -f pg_bsd_indent$(X) $(OBJS)+ rm -rf log/ tmp_check/++check:+ $(prove_check)++installcheck:+ $(prove_installcheck)++# Provide this alternate test name to allow testing pg_bsd_indent+# without building all of the surrounding Postgres installation.
.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.+test: pg_bsd_indent+ $(prove_installcheck)diff --git a/src/tools/pg_bsd_indent/README b/src/tools/pg_bsd_indent/READMEindex 846855d318..992d4fce61 100644--- a/src/tools/pg_bsd_indent/README+++ b/src/tools/pg_bsd_indent/README@@ -1,3 +1,40 @@+src/tools/pg_bsd_indent/README++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, configure the surrounding Postgres source tree,+then run "make" in this directory.+Optionally, run "make test" for some simple tests.++You'll need to install pg_bsd_indent somewhere in your PATH before+using it. Most likely, if you're a developer, you don't want to+put it in the same place as where the surrounding Postgres build+gets installed. Therefore, do this part with something like++ make install prefix=/usr/local++If you are using Meson to build, the standard build targets will+build pg_bsd_indent and also test it, but there is not currently+provision for installing it anywhere. Manually copy the built+executable from build/src/tools/pg_bsd_indent/pg_bsd_indent to+wherever you want to put it.+++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?)+We're not planning to re-indent to Postgres style, because that+would make it difficult to compare to the FreeBSD sources.++----------+
The FreeBSD originals of the files in this directory bear the
"4-clause" version of the BSD license. We have removed the
"advertising" clauses, as per UC Berkeley's directive here:
diff --git a/src/tools/pg_bsd_indent/README.pg_bsd_indent b/src/tools/pg_bsd_indent/README.pg_bsd_indentdeleted file mode 100644index 85c3dcac1c..0000000000--- a/src/tools/pg_bsd_indent/README.pg_bsd_indent+++ /dev/null@@ -1,30 +0,0 @@-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?)diff --git a/src/tools/pg_bsd_indent/args.c b/src/tools/pg_bsd_indent/args.cindex b18eab5d39..d08b086a88 100644--- a/src/tools/pg_bsd_indent/args.c+++ b/src/tools/pg_bsd_indent/args.c@@ -176,7 +176,7 @@ void
set_profile(const char *profile_name)
{
FILE *f;
- char fname[PATH_MAX];+ char fname[MAXPGPATH];
static char prof[] = ".indent.pro";
if (profile_name == NULL)
diff --git a/src/tools/pg_bsd_indent/indent.c b/src/tools/pg_bsd_indent/indent.cindex 0024993844..34205f2ead 100644--- a/src/tools/pg_bsd_indent/indent.c+++ b/src/tools/pg_bsd_indent/indent.c@@ -60,7 +60,7 @@ const char *in_name = "Standard Input"; /* will always point to name of input
* file */
const char *out_name = "Standard Output"; /* will always point to name
* of output file */
-char bakfile[MAXPATHLEN] = "";+char bakfile[MAXPGPATH] = "";
int
main(int argc, char **argv)
diff --git a/src/tools/pg_bsd_indent/indent.h b/src/tools/pg_bsd_indent/indent.hindex 1708dbc19f..d9fff8ccd6 100644--- a/src/tools/pg_bsd_indent/indent.h+++ b/src/tools/pg_bsd_indent/indent.h@@ -28,7 +28,7 @@
__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]))+#define nitems(x) (sizeof((x)) / sizeof((x)[0]))
void add_typename(const char *);
void alloc_typenames(void);
diff --git a/src/tools/pg_bsd_indent/meson.build b/src/tools/pg_bsd_indent/meson.buildnew file mode 100644index 0000000000..5545c097bf--- /dev/null+++ b/src/tools/pg_bsd_indent/meson.build@@ -0,0 +1,40 @@+# Copyright (c) 2022-2023, PostgreSQL Global Development Group++pg_bsd_indent_sources = files(+ 'args.c',+ 'err.c',+ 'indent.c',+ 'io.c',+ 'lexi.c',+ 'parse.c',+ 'pr_comment.c',+)++if host_system == 'windows'+ pg_bsd_indent_sources += rc_bin_gen.process(win32ver_rc, extra_args: [+ '--NAME', 'pg_bsd_indent',+ '--FILEDESC', 'pg_bsd_indent - indent C code nicely'])+endif++pg_bsd_indent = executable('pg_bsd_indent',+ pg_bsd_indent_sources,+ dependencies: [frontend_code],+ include_directories: include_directories('.'),+ kwargs: default_bin_args + {+ 'install': false,+# possibly at some point do this:+# 'install_dir': dir_pgxs / 'src/tools/pg_bsd_indent',+ },+)+bin_targets += pg_bsd_indent++tests += {+ 'name': 'pg_bsd_indent',+ 'sd': meson.current_source_dir(),+ 'bd': meson.current_build_dir(),+ 'tap': {+ 'tests': [+ 't/001_pg_bsd_indent.pl',+ ],+ },+}diff --git a/src/tools/pg_bsd_indent/t/001_pg_bsd_indent.pl b/src/tools/pg_bsd_indent/t/001_pg_bsd_indent.plnew file mode 100644index 0000000000..b40b3fdbbf--- /dev/null+++ b/src/tools/pg_bsd_indent/t/001_pg_bsd_indent.pl@@ -0,0 +1,53 @@+# pg_bsd_indent: some simple tests++# The test cases come from FreeBSD upstream, but this test scaffolding is ours.+# Copyright (c) 2017-2023, PostgreSQL Global Development Group++use strict;+use warnings;++use Cwd qw(getcwd);+use File::Copy "cp";+use File::Spec;++use PostgreSQL::Test::Utils;+use Test::More;++# We expect to be started in the source directory (even in a VPATH build);+# we want to run pg_bsd_indent in the tmp_check directory to reduce clutter.+# (Also, it's caller's responsibility that pg_bsd_indent be in the PATH.)+my $src_dir = getcwd;+chdir ${PostgreSQL::Test::Utils::tmp_check};++# Basic tests: pg_bsd_indent knows --version but not much else.+program_version_ok('pg_bsd_indent');++# Run pg_bsd_indent on pre-fab test cases.+# Any diffs in the generated files will be accumulated here.+my $diff_file = "tests.diff";++# Copy support files to current dir, so *.pro files don't need to know path.+while (my $file = glob("$src_dir/tests/*.list"))+{+ cp($file, ".") || die "cp $file failed: $!";+}++while (my $test_src = glob("$src_dir/tests/*.0"))+{+ # extract test basename+ my ($volume, $directories, $test) = File::Spec->splitpath($test_src);+ $test =~ s/\.0$//;+ # run pg_bsd_indent+ command_ok(+ [+ 'pg_bsd_indent', $test_src,+ "$test.out", "-P$src_dir/tests/$test.pro"+ ],+ "pg_bsd_indent succeeds on $test");+ # check result matches, adding any diff to $diff_file+ my $result = run_log([ 'diff', '-upd', "$test_src.stdout", "$test.out" ],+ '>>', $diff_file);+ ok($result, "pg_bsd_indent output matches for $test");+}++done_testing();diff --git a/src/tools/pgindent/exclude_file_patterns b/src/tools/pgindent/exclude_file_patternsindex f5c8857e31..6405a00511 100644--- a/src/tools/pgindent/exclude_file_patterns+++ b/src/tools/pgindent/exclude_file_patterns@@ -47,6 +47,10 @@ src/pl/plperl/ppport\.h$
src/pl/plperl/SPI\.c$
src/pl/plperl/Util\.c$
#
+# pg_bsd_indent has its own, idiosyncratic indentation style.+# We'll stick to that to permit comparison with the FreeBSD upstream.+src/tools/pg_bsd_indent/.*+#
# Exclude any temporary installations that may be in the tree.
/tmp_check/
/tmp_install/
--
2.31.1
v3-0004-Add-missing-test-dependency.patch (text/x-diff, 757B) download
From 2395910690a0d2ada0ca6df4fe8983e268811be9 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 11 Feb 2023 19:28:26 -0500
Subject: [PATCH v3 4/4] Add missing test dependency.
I'd supposed there was already such a dependency for 'check',
but nope. Per cfbot.
---
src/tools/pg_bsd_indent/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/tools/pg_bsd_indent/Makefile b/src/tools/pg_bsd_indent/Makefileindex ee3d494f40..b138bb8b12 100644--- a/src/tools/pg_bsd_indent/Makefile+++ b/src/tools/pg_bsd_indent/Makefile@@ -41,7 +41,7 @@ clean distclean maintainer-clean:
rm -f pg_bsd_indent$(X) $(OBJS)
rm -rf log/ tmp_check/
-check:+check: pg_bsd_indent
$(prove_check)
installcheck:
--
2.31.1
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: tgl@sss.pgh.pa.us, andres@anarazel.de, pgsql-hackers@lists.postgresql.org
Subject: Re: Importing pg_bsd_indent into our source tree
In-Reply-To: <725719.1676161995@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox