my $devnull = File::Spec->devnull;
my ($typedefs_file, $typedef_str, $code_base,
- $excludes, $indent, $build,
+ @excludes, $indent, $build,
$show_diff, $silent_diff, $help);
$help = 0;
"typedefs=s" => \$typedefs_file,
"list-of-typedefs=s" => \$typedef_str,
"code-base=s" => \$code_base,
- "excludes=s" => \$excludes,
+ "excludes=s" => \@excludes,
"indent=s" => \$indent,
"build" => \$build,
"show-diff" => \$show_diff,
run_build($code_base) if ($build);
-# command line option wins, then first non-option arg,
-# then environment (which is how --build sets it) ,
+# command line option wins, 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};
# build mode sets PGINDENT
# no non-option arguments given. so do everything in the current directory
$code_base ||= '.' unless @ARGV;
+my $sourcedir = locate_sourcedir();
+
# if it's the base of a postgres tree, we will exclude the files
# postgres wants excluded
-$excludes ||= "$code_base/src/tools/pgindent/exclude_file_patterns"
- if $code_base && -f "$code_base/src/tools/pgindent/exclude_file_patterns";
-
-# also look under the current directory for the exclude patterns file
-$excludes ||= "src/tools/pgindent/exclude_file_patterns"
- if -f "src/tools/pgindent/exclude_file_patterns";
+if ($sourcedir)
+{
+ my $exclude_candidate = "$sourcedir/exclude_file_patterns";
+ push (@excludes, $exclude_candidate) if -f $exclude_candidate;
+}
# The typedef list that's mechanically extracted by the buildfarm may omit
# some names we want to treat like typedefs, e.g. "bool" (which is a macro
my @files;
my $filtered_typedefs_fh;
-
sub check_indent
{
system("$indent -? < $devnull > $devnull 2>&1");
return;
}
+sub locate_sourcedir
+{
+ # try fairly hard to locate the sourcedir
+ my $where = $code_base || '.';
+ my $sub = "$where/src/tools/pgindent";
+ return $sub if -d $sub;
+ # try to find it from an ancestor directory
+ $sub = "../src/tools/pgindent";
+ foreach (1..4)
+ {
+ return $sub if -d $sub;
+ $sub = "../$sub";
+ }
+ return; # undef if nothing found
+}
sub load_typedefs
{
-
# try fairly hard to find the typedefs file if it's not set
- foreach my $try ('.', 'src/tools/pgindent', '/usr/local/etc')
+ foreach my $try ('.', $sourcedir, '/usr/local/etc')
{
- $typedefs_file ||= "$try/typedefs.list"
+ last if $typedefs_file;
+ next unless defined $try;
+ $typedefs_file = "$try/typedefs.list"
if (-f "$try/typedefs.list");
}
- # try to find typedefs by moving up directory levels
- my $tdtry = "..";
- foreach (1 .. 5)
- {
- $typedefs_file ||= "$tdtry/src/tools/pgindent/typedefs.list"
- if (-f "$tdtry/src/tools/pgindent/typedefs.list");
- $tdtry = "$tdtry/..";
- }
die "cannot locate typedefs file \"$typedefs_file\"\n"
unless $typedefs_file && -f $typedefs_file;
return $filter_typedefs_fh;
}
-
sub process_exclude
{
- if ($excludes && @files)
+ foreach my $excl (@excludes)
{
- open(my $eh, '<', $excludes)
- || die "cannot open exclude file \"$excludes\"\n";
+ last unless @files;
+ open(my $eh, '<', $excl)
+ || die "cannot open exclude file \"$excl\"\n";
while (my $line = <$eh>)
{
chomp $line;
return;
}
-
sub read_source
{
my $source_filename = shift;
return $source;
}
-
sub write_source
{
my $source = shift;
return;
}
-
sub pre_indent
{
my $source = shift;
return $source;
}
-
sub post_indent
{
my $source = shift;
return $source;
}
-
sub run_indent
{
my $source = shift;
return $diff;
}
-
sub run_build
{
eval "use LWP::Simple;"; ## no critic (ProhibitStringyEval);
return;
}
-
sub build_clean
{
my $code_base = shift || '.';
--build build the pg_bsd_indent program
--show-diff show the changes that would be made
--silent-diff exit with status 2 if any changes would be made
+The --excludes option can be given more than once.
EOF
if ($help)
{
write_source($source, $source_filename);
}
}
-
}
build_clean($code_base) if $build;
or build them if possible. They can also be specified via command line switches
or the environment.
+You can see all the options by running:
+
+ pgindent --help
+
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.
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.
+a PostgreSQL source tree, this option is usually not necessary, as it will
+find the file src/tools/pgindent/exclude_file_patterns. The --excludes option
+can be used more than once to specify multiple files containing exclusion
+patterns.
There are also two non-destructive modes of pgindent. If given the --show-diff
option pgindent will show the changes it would make, but doesn't actually make
them. If given instead the --silent-diff option, pgindent will exit with a
status of 2 if it finds any indent changes are required, but will not
make the changes or give any other information. This mode is intended for
-possible use in a git pre-commit hook.
+possible use in a git pre-commit hook. An example of its use in a git hook
+can be seen at https://wiki.postgresql.org/wiki/Working_with_Git#Using_git_hooks
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.
+case only these files will be changed, and nothing else will be touched.