Commit 149ac7d4 authored by Bruce Momjian's avatar Bruce Momjian

Replace pgindent shell script with Perl script. Update perltidy

instructions to perltidy Perl files that lack Perl file extensions.

pgindent Perl coding by Andrew Dunstan, restructured by me.
parent 46394325
src/tools/pgindent/README
pgindent pgindent
======== ========
...@@ -26,9 +24,7 @@ This can format all PostgreSQL *.c and *.h files, but excludes *.y, and ...@@ -26,9 +24,7 @@ This can format all PostgreSQL *.c and *.h files, but excludes *.y, and
6) Run pgindent: 6) Run pgindent:
find . -name '*.[ch]' -type f -print | \ pgindent
egrep -v -f src/tools/pgindent/exclude_file_patterns | \
xargs -n100 src/tools/pgindent/pgindent src/tools/pgindent/typedefs.list
7) Remove any files that generate errors and restore their original 7) Remove any files that generate errors and restore their original
versions. versions.
...@@ -46,7 +42,14 @@ This can format all PostgreSQL *.c and *.h files, but excludes *.y, and ...@@ -46,7 +42,14 @@ This can format all PostgreSQL *.c and *.h files, but excludes *.y, and
9) Indent the Perl code: 9) Indent the Perl code:
find . -name \*.pl -o -name \*.pm | (
find . -name \*.pl -o -name \*.pm
find . -type f -exec file {} \; |
egrep -i ':.*perl[0-9]*\>' |
cut -d: -f1
) |
sort -u |
xargs perltidy --profile=src/tools/pgindent/perltidyrc xargs perltidy --profile=src/tools/pgindent/perltidyrc
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
......
#!/bin/sh #!/usr/bin/perl
# src/tools/pgindent/pgindent
# Known bugs:
#
# Blank line is added after parentheses; seen as a function definition, no space
# after *:
# y = (int) x *y;
#
# Structure/union pointers in function prototypes and definitions have an extra
# space after the asterisk:
#
# void x(struct xxc * a);
if [ "$#" -lt 2 ]
then echo "Usage: $(basename $0) typedefs file [...]" 1>&2
exit 1
fi
TYPEDEFS="$1"
shift
[ -z "$INDENT" ] && INDENT=pg_bsd_indent
INDENT_VERSION="1.1"
trap "rm -f /tmp/$$ /tmp/$$a" 0 1 2 3 15
# check the environment
entab </dev/null >/dev/null
if [ "$?" -ne 0 ]
then echo "Go to the src/tools/entab directory and do a 'make' and 'make install'." >&2
echo "This will put the 'entab' command in your path." >&2
echo "Then run $0 again."
exit 1
fi
$INDENT -? </dev/null >/dev/null 2>&1
if [ "$?" -ne 1 ]
then echo "You do not appear to have '$INDENT' installed on your system." >&2
exit 1
fi
if [ "`$INDENT -V`" != "$INDENT $INDENT_VERSION" ]
then echo "You do not appear to have $INDENT version $INDENT_VERSION installed on your system." >&2
exit 1
fi
$INDENT -gnu </dev/null >/dev/null 2>&1
if [ "$?" -eq 0 ]
then echo "You appear to have GNU indent rather than BSD indent." >&2
echo "See the pgindent/README file for a description of its problems." >&2
EXTRA_OPTS="-cdb -bli0 -npcs -cli4 -sc"
else
EXTRA_OPTS="-cli1"
fi
for FILE
do
cat "$FILE" |
# Convert // comments to /* */
sed 's;^\([ ]*\)//\(.*\)$;\1/* \2 */;g' |
# Mark some comments for special treatment later
sed 's;/\* *---;/*---X_X;g' |
# 'else' followed by a single-line comment, followed by
# a brace on the next line confuses BSD indent, so we push
# the comment down to the next line, then later pull it
# back up again. Add space before _PGMV or indent will add
# it for us.
sed 's;\([} ]\)else[ ]*\(/\*\)\(.*\*/\)[ ]*$;\1else\
\2 _PGMV\3;g' |
# Indent multi-line after-'else' comment so BSD indent will move it properly.
# We already moved down single-line comments above. Check for '*' to make
# sure we are not in a single-line comment that has other text on the line.
sed 's;\([} ]\)else[ ]*\(/\*[^\*]*\)[ ]*$;\1else\
\2;g' |
detab -t4 -qc |
# Work around bug where function that defines no local variables misindents
# switch() case lines and line after #else. Do not do for struct/enum.
awk ' BEGIN {line1 = ""; line2 = ""}
{
line2 = $0;
if (NR >= 2)
print line1;
if (NR >= 2 &&
line2 ~ /^{[ ]*$/ &&
line1 !~ /^struct/ &&
line1 !~ /^enum/ &&
line1 !~ /^typedef/ &&
line1 !~ /^extern[ ][ ]*"C"/ &&
line1 !~ /=/ &&
line1 ~ /\)/)
print "int pgindent_func_no_var_fix;";
line1 = line2;
}
END {
if (NR >= 1)
print line1;
}' |
# Prevent indenting of code in 'extern "C"' blocks. use strict;
awk ' BEGIN {line1 = ""; line2 = ""; skips = 0} use warnings;
{
line2 = $0;
if (skips > 0)
skips--;
if (line1 ~ /^#ifdef[ ]*__cplusplus/ &&
line2 ~ /^extern[ ]*"C"[ ]*$/)
{
print line1;
print line2;
if (getline && $0 ~ /^{[ ]*$/)
print "/* Open extern \"C\" */";
else print $0;
line2 = "";
skips = 2;
}
else if (line1 ~ /^#ifdef[ ]*__cplusplus/ &&
line2 ~ /^}[ ]*$/)
{
print line1;
print "/* Close extern \"C\" */";
line2 = "";
skips = 2;
}
else
if (skips == 0 && NR >= 2)
print line1;
line1 = line2;
}
END {
if (NR >= 1 && skips <= 1)
print line1;
}' |
# Protect backslashes in DATA(). use Cwd qw(abs_path getcwd);
sed 's;^DATA(.*$;/*&*/;' | use File::Find;
use File::Spec qw(devnull);
use File::Temp;
use IO::Handle;
use Getopt::Long;
use Readonly;
# Protect wrapping in CATALOG(). # Update for pg_bsd_indent version
sed 's;^CATALOG(.*$;/*&*/;' >/tmp/$$a Readonly my $INDENT_VERSION => "1.1";
Readonly my $devnull => File::Spec->devnull;
egrep -v '^(FD_SET|date|interval|timestamp|ANY)$' "$TYPEDEFS" | sed -e '/^$/d' > /tmp/$$b # Common indent settings
my $indent_opts =
"-bad -bap -bc -bl -d0 -cdb -nce -nfc1 -di12 -i4 -l79 -lp -nip -npro -bbb";
# We get the list of typedef's from /src/tools/find_typedef # indent-dependant settings
$INDENT -bad -bap -bc -bl -d0 -cdb -nce -nfc1 -di12 -i4 -l79 \ my $extra_opts = "";
-lp -nip -npro -bbb $EXTRA_OPTS -U/tmp/$$b \
/tmp/$$a >/tmp/$$ 2>&1
if [ "$?" -ne 0 -o -s /tmp/$$ ] my ($typedefs_file, $code_base, $excludes, $indent, $build);
then echo
echo "$FILE"
cat /tmp/$$
fi
cat /tmp/$$a |
# Restore DATA/CATALOG lines. my %options = (
sed 's;^/\*\(DATA(.*\)\*/$;\1;' | "typedefs=s" => \$typedefs_file,
sed 's;^/\*\(CATALOG(.*\)\*/$;\1;' | "code-base=s" => \$code_base,
"excludes=s" => \$excludes,
"indent=s" => \$indent,
"build" => \$build,);
GetOptions(%options) || die "bad command line";
# Remove tabs and retab with four spaces. run_build($code_base) if ($build);
detab -t8 -qc |
entab -t4 -qc |
sed 's;^/\* Open extern \"C\" \*/$;{;' |
sed 's;^/\* Close extern \"C\" \*/$;};' |
sed 's;/\*---X_X;/* ---;g' |
# Workaround indent bug for 'static'. # command line option wins, then first non-option arg,
sed 's;^static[ ][ ]*;static ;g' | # then environment (which is how --build sets it) ,
# then locations. based on current dir, then default location
$typedefs_file ||= shift if @ARGV && $ARGV[0] !~ /\\.[ch]$/;
$typedefs_file ||= $ENV{PGTYPEDEFS};
# Remove too much indenting after closing brace. # build mode sets PGINDENT and PGENTAB
sed 's;^} [ ]*;} ;' | $indent ||= $ENV{PGINDENT} || $ENV{INDENT} || "pg_bsd_indent";
my $entab = $ENV{PGENTAB} || "entab";
# Indent single-line after-'else' comment by only one tab. # no non-option arguments given. so do everything in the current directory
sed 's;\([} ]\)else[ ]*\(/\*.*\*/\)[ ]*$;\1else \2;g' | $code_base ||= '.' unless @ARGV;
# Pull in #endif comments. # if it's the base of a postgres tree, we will exclude the files
sed 's;^#endif[ ][ ]*/\*;#endif /*;' | # postgres wants excluded
$excludes ||= "$code_base/src/tools/pgindent/exclude_file_patterns"
if $code_base && -f "$code_base/src/tools/pgindent/exclude_file_patterns";
# Work around misindenting of function with no variables defined. # globals
awk ' my @files;
{ my $filtered_typedefs_fh;
if ($0 ~ /^[ ]*int[ ]*pgindent_func_no_var_fix;/)
sub check_indent
{
system("entab < $devnull");
if ($?)
{ {
if (getline && $0 != "") print STDERR
print $0; "Go to the src/tools/entab directory and do 'make' and 'make install'.\n",
"This will put the 'entab' command in your path.\n",
"Then run $0 again.\n";
exit 1;
} }
else print $0;
}' | system("$indent -? < $devnull > $devnull 2>&1");
if ($? >> 8 != 1)
# Add space after comments that start on tab stops.
sed 's;\([^ ]\)\(/\*.*\*/\)$;\1 \2;' |
# Move trailing * in function return type.
sed 's;^\([A-Za-z_][^ ]*\)[ ][ ]*\*$;\1 *;' |
# Remove un-needed braces around single statements.
# Do not use because it uglifies PG_TRY/PG_CATCH blocks and probably
# isn't needed for general use.
# awk '
# {
# line3 = $0;
# if (skips > 0)
# skips--;
# if (line1 ~ / *{$/ &&
# line2 ~ / *[^;{}]*;$/ &&
# line3 ~ / *}$/)
# {
# print line2;
# line2 = "";
# line3 = "";
# skips = 3;
# }
# else
# if (skips == 0 && NR >= 3)
# print line1;
# line1 = line2;
# line2 = line3;
# }
# END {
# if (NR >= 2 && skips <= 1)
# print line1;
# if (NR >= 1 && skips <= 2)
# print line2;
# }' |
# Remove blank line between opening brace and block comment.
awk '
{
line3 = $0;
if (skips > 0)
skips--;
if (line1 ~ / *{$/ &&
line2 ~ /^$/ &&
line3 ~ / *\/[*]$/)
{ {
print line1; print STDERR
print line3; "You do not appear to have 'indent' installed on your system.\n";
line2 = ""; exit 1;
line3 = "";
skips = 3;
}
else
if (skips == 0 && NR >= 3)
print line1;
line1 = line2;
line2 = line3;
} }
END {
if (NR >= 2 && skips <= 1) if (`$indent -V` !~ m/ $INDENT_VERSION$/)
print line1;
if (NR >= 1 && skips <= 2)
print line2;
}' |
# Pull up single-line comment after 'else' that was pulled down above
awk '
{
if (NR != 1)
{
if ($0 ~ "/[*] _PGMV")
{ {
# remove tag print STDERR
sub(" _PGMV", "", $0); "You do not appear to have $indent version $INDENT_VERSION installed on your system.\n";
# remove leading whitespace exit 1;
sub("^[ ]*", "", $0);
# add comment with single tab prefix
print prev_line" "$0;
# throw away current line
getline;
}
else
print prev_line;
}
prev_line = $0;
} }
END {
if (NR >= 1)
print prev_line;
}' |
# Remove trailing blank lines, helps with adding blank before trailing #endif. system("$indent -gnu < $devnull > $devnull 2>&1");
awk ' BEGIN {blank_lines = 0;} if ($? == 0)
{ {
line1 = $0; print STDERR
if (line1 ~ /^$/) "You appear to have GNU indent rather than BSD indent.\n",
blank_lines++; "See the pgindent/README file for a description of its problems.\n";
$extra_opts = "-cdb -bli0 -npcs -cli4 -sc";
}
else else
{ {
for (; blank_lines > 0; blank_lines--) $extra_opts = "-cli1";
printf "\n";
print line1;
} }
}' | }
# Remove blank line before #else, #elif, and #endif.
awk ' BEGIN {line1 = ""; line2 = ""; skips = 0} sub load_typedefs
{ {
line2 = $0;
if (skips > 0) # try fairly hard to find the typedefs file if it's not set
skips--;
if (line1 ~ /^$/ && foreach my $try ('.', 'src/tools/pgindent', '/usr/local/etc')
(line2 ~ /^#else/ ||
line2 ~ /^#elif/ ||
line2 ~ /^#endif/))
{ {
print line2; $typedefs_file ||= "$try/typedefs.list"
line2 = ""; if (-f "$try/typedefs.list");
skips = 2;
} }
else
if (skips == 0 && NR >= 2)
print line1;
line1 = line2;
}
END {
if (NR >= 1 && skips <= 1)
print line1;
}' |
# Add blank line before #endif if it is the last line in the file. # try to find typedefs by moving up directory levels
awk ' BEGIN {line1 = ""; line2 = ""} my $tdtry = "..";
foreach (1 .. 5)
{ {
line2 = $0; $typedefs_file ||= "$tdtry/src/tools/pgindent/typedefs.list"
if (NR >= 2) if (-f "$tdtry/src/tools/pgindent/typedefs.list");
print line1; $tdtry = "$tdtry/..";
line1 = line2;
} }
END { die "no typedefs file" unless $typedefs_file && -f $typedefs_file;
if (NR >= 1 && line2 ~ /^#endif/)
printf "\n"; open(my $typedefs_fh, '<', $typedefs_file)
print line1; || die "opening $typedefs_file: $!";
}' | my @typedefs = <$typedefs_fh>;
close($typedefs_fh);
# Move prototype names to the same line as return type. Useful for ctags.
# Indent should do this, but it does not. It formats prototypes just # remove certain entries
# like real functions. @typedefs =
awk ' BEGIN {paren_level = 0} grep { !m/^(FD_SET|date|interval|timestamp|ANY)\n?$/ } @typedefs;
{
if ($0 ~ /^[a-zA-Z_][a-zA-Z_0-9]*[^\(]*$/) # write filtered typedefs
my $filter_typedefs_fh = new File::Temp(TEMPLATE => "pgtypedefXXXXX");
print $filter_typedefs_fh @typedefs;
$filter_typedefs_fh->close();
# temp file remains because we return a file handle reference
return $filter_typedefs_fh;
}
sub process_exclude
{
if ($excludes && @files)
{ {
saved_len = 0; open(my $eh, '<', $excludes) || die "opening $excludes";
saved_lines[++saved_len] = $0; while (my $line = <$eh>)
if ((getline saved_lines[++saved_len]) == 0)
print saved_lines[1];
else
if (saved_lines[saved_len] !~ /^[a-zA-Z_][a-zA-Z_0-9]*\(/ ||
saved_lines[saved_len] ~ /^[a-zA-Z_][a-zA-Z_0-9]*\(.*\)$/ ||
saved_lines[saved_len] ~ /^[a-zA-Z_][a-zA-Z_0-9]*\(.*\);$/)
{ {
print saved_lines[1]; chomp $line;
print saved_lines[2]; my $rgx;
eval " \$rgx = qr!$line!;";
@files = grep { $_ !~ /$rgx/ } @files if $rgx;
} }
else close($eh);
{
while (1)
{
if ((getline saved_lines[++saved_len]) == 0)
break;
if (saved_lines[saved_len] ~ /^[^ ]/ ||
saved_lines[saved_len] !~ /,$/)
break;
} }
for (i=1; i <= saved_len; i++) }
sub read_source
{
my $source_filename = shift;
my $source;
open(my $src_fd, '<', $source_filename)
|| die "opening $source_filename: $!";
local ($/) = undef;
$source = <$src_fd>;
close($src_fd);
return $source;
}
sub write_source
{
my $source = shift;
my $source_filename = shift;
open(my $src_fh, '>', $source_filename)
|| die "opening $source_filename: $!";
print $src_fh $source;
close($src_fh);
}
sub pre_indent
{
my $source = shift;
# remove trailing whitespace
$source =~ s/\h+$//gm;
## Comments
# Convert // comments to /* */
$source =~ s!^(\h*)//(.*)$!$1/* $2 */!gm;
# 'else' followed by a single-line comment, followed by
# a brace on the next line confuses BSD indent, so we push
# the comment down to the next line, then later pull it
# back up again. Add space before _PGMV or indent will add
# it for us.
# AMD: A symptom of not getting this right is that you see errors like:
# FILE: ../../../src/backend/rewrite/rewriteHandler.c
# Error@2259:
# Stuff missing from end of file
$source =~ s!(\}|\h)else\h*(/\*)(.*\*/)\h*$!$1else\n $2 _PGMV$3!gm;
# Indent multi-line after-'else' comment so BSD indent will move it
# properly. We already moved down single-line comments above.
# Check for '*' to make sure we are not in a single-line comment that
# has other text on the line.
$source =~ s!(\}|\h)else\h*(/\*[^*]*)\h*$!$1else\n $2!gm;
# Mark some comments for special treatment later
$source =~ s!/\* +---!/*---X_X!g;
## Other
# Work around bug where function that defines no local variables
# misindents switch() case lines and line after #else. Do not do
# for struct/enum.
my @srclines = split(/\n/, $source);
foreach my $lno (1 .. $#srclines)
{ {
if (i == 1 && saved_lines[saved_len] ~ /\);$/) my $l2 = $srclines[$lno];
# Line is only a single open brace in column 0
next unless $l2 =~ /^\{\h*$/;
# previous line has a closing paren
next unless $srclines[ $lno - 1 ] =~ /\)/;
# previous line was struct, etc.
next
if $srclines[ $lno - 1 ] =~
m!=|^(struct|enum|\h*typedef|extern\h+"C")!;
$srclines[$lno] = "$l2\nint pgindent_func_no_var_fix;";
}
$source = join("\n", @srclines) . "\n"; # make sure there's a final \n
# Prevent indenting of code in 'extern "C"' blocks.
# we replace the braces with comments which we'll reverse later
my $extern_c_start = '/* Open extern "C" */';
my $extern_c_stop = '/* Close extern "C" */';
$source =~
s!(^#ifdef\h+__cplusplus.*\nextern\h+"C"\h*\n)\{\h*$!$1$extern_c_start!gm;
$source =~ s!(^#ifdef\h+__cplusplus.*\n)\}\h*$!$1$extern_c_stop!gm;
return $source;
}
sub post_indent
{
my $source = shift;
my $source_filename = shift;
# put back braces for extern "C"
$source =~ s!^/\* Open extern "C" \*/$!{!gm;
$source =~ s!^/\* Close extern "C" \*/$!}!gm;
## Comments
# remove special comment marker
$source =~ s!/\*---X_X!/* ---!g;
# Pull up single-line comment after 'else' that was pulled down above
$source =~ s!else\n\h+/\* _PGMV!else\t/*!g;
# Indent single-line after-'else' comment by only one tab.
$source =~ s!(\}|\h)else\h+(/\*.*\*/)\h*$!$1else\t$2!gm;
# Add tab before comments with no whitespace before them (on a tab stop)
$source =~ s!(\S)(/\*.*\*/)$!$1\t$2!gm;
# Remove blank line between opening brace and block comment.
$source =~ s!(\t*\{\n)\n(\h+/\*)$!$1$2!gm;
# cpp conditionals
# Reduce whitespace between #endif and comments to one tab
$source =~ s!^\#endif\h+/\*!#endif /*!gm;
# Remove blank line(s) before #else, #elif, and #endif
$source =~ s!\n\n+(\#else|\#elif|\#endif)!\n$1!g;
# Add blank line before #endif if it is the last line in the file
$source =~ s!\n(#endif.*)\n\z!\n\n$1\n!;
## Functions
# Work around misindenting of function with no variables defined.
$source =~ s!^\h*int\h+pgindent_func_no_var_fix;\h*\n{1,2}!!gm;
# Use a single space before '*' in function return types
$source =~ s!^([A-Za-z_]\S*)\h+\*$!$1 *!gm;
# Move prototype names to the same line as return type. Useful
# for ctags. Indent should do this, but it does not. It formats
# prototypes just like real functions.
my $ident = qr/[a-zA-Z_][a-zA-Z_0-9]*/;
my $comment = qr!/\*.*\*/!;
$source =~ s!
(\n$ident[^(\n]*)\n # e.g. static void
(
$ident\(\n? # func_name(
(.*,(\h*$comment)?\n)* # args b4 final ln
.*\);(\h*$comment)?$ # final line
)
!$1 . (substr($1,-1,1) eq '*' ? '' : ' ') . $2!gmxe;
## Other
# Remove too much indenting after closing brace.
$source =~ s!^\}\t\h+!}\t!gm;
# Workaround indent bug that places excessive space before 'static'.
$source =~ s!^static\h+!static !gm;
# Remove leading whitespace from typedefs
$source =~ s!^\h+typedef enum!typedef enum!gm
if $source_filename =~ 'libpq-(fe|events).h$';
# Remove trailing blank lines
$source =~ s!\n+\z!\n!;
return $source;
}
sub run_indent
{
my $source = shift;
my $error_message = shift;
my $cmd =
"$indent $indent_opts $extra_opts -U" . $filtered_typedefs_fh->filename;
my $tmp_fh = new File::Temp(TEMPLATE => "pgsrcXXXXX");
my $filename = $tmp_fh->filename;
print $tmp_fh $source;
$tmp_fh->close();
$$error_message = `$cmd $filename 2>&1`;
return "" if ($? || length($$error_message) > 0);
unlink "$filename.BAK";
open(my $src_out, '<', $filename);
local ($/) = undef;
$source = <$src_out>;
close($src_out);
return $source;
}
# XXX Ideally we'd implement entab/detab in pure perl.
sub detab
{
my $source = shift;
my $tmp_fh = new File::Temp(TEMPLATE => "pgdetXXXXX");
print $tmp_fh $source;
$tmp_fh->close();
open(my $entab, '-|', "$entab -d -t4 -qc " . $tmp_fh->filename);
local ($/) = undef;
$source = <$entab>;
close($entab);
return $source;
}
sub entab
{
my $source = shift;
my $tmp_fh = new File::Temp(TEMPLATE => "pgentXXXXX");
print $tmp_fh $source;
$tmp_fh->close();
open(my $entab, '-|',
"$entab -d -t8 -qc " . $tmp_fh->filename . " | $entab -t4 -qc");
local ($/) = undef;
$source = <$entab>;
close($entab);
return $source;
}
# for development diagnostics
sub diff
{
my $pre = shift;
my $post = shift;
my $flags = shift || "";
print STDERR "running diff\n";
my $pre_fh = new File::Temp(TEMPLATE => "pgdiffbXXXXX");
my $post_fh = new File::Temp(TEMPLATE => "pgdiffaXXXXX");
print $pre_fh $pre;
print $post_fh $post;
$pre_fh->close();
$post_fh->close();
system( "diff $flags "
. $pre_fh->filename . " "
. $post_fh->filename
. " >&2");
}
sub run_build
{
eval "use LWP::Simple;";
my $code_base = shift || '.';
my $save_dir = getcwd();
# look for the code root
foreach (1 .. 5)
{ {
printf "%s", saved_lines[i]; last if -d "$code_base/src/tools/pgindent";
if (substr(saved_lines[i], length(saved_lines[i]),1) != "*") $code_base = "$code_base/..";
printf " ";
} }
else print saved_lines[i];
die "no src/tools/pgindent directory in $code_base"
unless -d "$code_base/src/tools/pgindent";
chdir "$code_base/src/tools/pgindent";
my $rv = getstore("http://buildfarm.postgresql.org/cgi-bin/typedefs.pl",
"tmp_typedefs.list");
die "fetching typedefs.list" unless is_success($rv);
$ENV{PGTYPEDEFS} = abs_path('tmp_typedefs.list');
$rv =
getstore("ftp://ftp.postgresql.org/pub/dev/indent.netbsd.patched.tgz",
"indent.netbsd.patched.tgz");
die "fetching indent.netbsd.patched.tgz" unless is_success($rv);
# XXX add error checking here
mkdir "bsdindent";
chdir "bsdindent";
system("tar -z -xf ../indent.netbsd.patched.tgz");
system("make > $devnull 2>&1");
$ENV{PGINDENT} = abs_path('indent');
chdir "../../entab";
system("make > $devnull 2>&1");
$ENV{PGENTAB} = abs_path('entab');
chdir $save_dir;
}
sub build_clean
{
my $code_base = shift || '.';
# look for the code root
foreach (1 .. 5)
{
last if -d "$code_base/src/tools/pgindent";
$code_base = "$code_base/..";
} }
die "no src/tools/pgindent directory in $code_base"
unless -d "$code_base/src/tools/pgindent";
chdir "$code_base";
system("rm -rf src/tools/pgindent/bsdindent");
system("git clean -q -f src/tools/entab src/tools/pgindent");
}
# main
# get the list of files under code base, if it's set
File::Find::find(
{ wanted => sub {
my ($dev, $ino, $mode, $nlink, $uid, $gid);
(($dev, $ino, $mode, $nlink, $uid, $gid) = lstat($_))
&& -f _
&& /^.*\.[ch]\z/s
&& push(@files, $File::Find::name);
} }
},
$code_base) if $code_base;
process_exclude();
$filtered_typedefs_fh = load_typedefs();
check_indent();
# make sure we process any non-option arguments.
push(@files, @ARGV);
foreach my $source_filename (@files)
{
my $source = read_source($source_filename);
my $error_message = '';
$source = pre_indent($source);
# Protect backslashes in DATA() and wrapping in CATALOG()
$source = detab($source);
$source =~ s!^((DATA|CATALOG)\(.*)$!/*$1*/!gm;
$source = run_indent($source, \$error_message);
if ($source eq "")
{
print STDERR "Failure in $source_filename: " . $error_message . "\n";
next;
} }
else print $0;
}' |
# Fix indenting of typedef caused by __cplusplus in libpq-fe.h. # Restore DATA/CATALOG lines; must be done here so tab alignment is preserved
( $source =~ s!^/\*((DATA|CATALOG)\(.*)\*/$!$1!gm;
if echo "$FILE" | grep -q 'libpq-fe.h$' $source = entab($source);
then sed 's/^[ ]*typedef enum/typedef enum/'
else cat $source = post_indent($source, $source_filename);
fi
) | write_source($source, $source_filename);
# end }
cat >/tmp/$$ && cat /tmp/$$ >"$FILE"
done build_clean($code_base) if $build;
# The 'for' loop makes these backup files useless so delete them
rm -f *a.BAK
pgindent will indent .c and .h files according to the coding standards of
the PostgreSQL project. It needs several things to run, and tries to locate
or build them if possible. They can also be specified via command line switches
or the environment.
In its simplest form, if all the required objects are installed, simply run
it without any parameters at the top of the source tree you want to process.
pgindent
If you don't have all the requirements installed, pgindent will fetch and build
them for you, if you're in a PostgreSQL source tree:
pgindent --build
If your indent program is not installed in your path, you can specify it
by setting the environment variable INDENT, or PGINDENT, or by giving the
command line option --indent:
pgindent --indent=/opt/extras/bsdindent
Similarly, the entab program can be specified using the PGENTAB environment
variable, or using the --entab command line option.
pgindent also needs a file containing a list of typedefs. This can be
specified using the PGTYPEDEFS environment variable, or via the command line
--typedefs option. If neither is used, it will look for it within the
current source tree, or in /usr/local/etc/typedefs.list.
If you want to indent a source tree other than the current working directory,
you can specify it via the --code-base command line option.
We don't want to indent certain files in the PostgreSQL source. pgindent
will honor a file containing a list of patterns of files to avoid. This
file can be specified using the --excludes command line option. If indenting
a PostgreSQL source tree, this option isn't necessary, as it will find the file
src/tools/pgindent/exclude_file_patterns.
Any non-option arguments are taken as the names of files to be indented. In this
case only these files will be changed, and nothing else will be touched. If the
first non-option argument is not a .c or .h file, it is treated as the name
of a typedefs file for legacy reasons, but this use is deprecated - use the
--typedefs option instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment