my $devnull = File::Spec->devnull;
-my ($typedefs_file, $typedef_str, $code_base, $excludes, $indent, $build);
+my ($typedefs_file, $typedef_str, $code_base,
+ $excludes, $indent, $build,
+ $show_diff, $silent_diff, $help);
+
+$help = 0;
my %options = (
+ "help" => \$help,
"typedefs=s" => \$typedefs_file,
"list-of-typedefs=s" => \$typedef_str,
"code-base=s" => \$code_base,
"excludes=s" => \$excludes,
"indent=s" => \$indent,
- "build" => \$build,);
-GetOptions(%options) || die "bad command line argument\n";
+ "build" => \$build,
+ "show-diff" => \$show_diff,
+ "silent-diff" => \$silent_diff,);
+GetOptions(%options) || usage("bad command line argument");
+
+usage() if $help;
+
+usage("Cannot have both --silent-diff and --show-diff")
+ if $silent_diff && $show_diff;
run_build($code_base) if ($build);
sub post_indent
{
- my $source = shift;
- my $source_filename = shift;
+ my $source = shift;
# Restore CATALOG lines
$source =~ s!^/\*(CATALOG\(.*)\*/$!$1!gm;
close($src_out);
return $source;
-
}
-
-# for development diagnostics
-sub diff
+sub show_diff
{
- my $pre = shift;
- my $post = shift;
- my $flags = shift || "";
-
- print STDERR "running diff\n";
+ my $indented = shift;
+ my $source_filename = shift;
- my $pre_fh = new File::Temp(TEMPLATE => "pgdiffbXXXXX");
- my $post_fh = new File::Temp(TEMPLATE => "pgdiffaXXXXX");
+ my $post_fh = new File::Temp(TEMPLATE => "pgdiffXXXXX");
- print $pre_fh $pre;
- print $post_fh $post;
+ print $post_fh $indented;
- $pre_fh->close();
$post_fh->close();
- system( "diff $flags "
- . $pre_fh->filename . " "
- . $post_fh->filename
- . " >&2");
- return;
+ my $diff = `diff -upd $source_filename $post_fh->filename 2>&1`;
+ return $diff;
}
return;
}
+sub usage
+{
+ my $message = shift;
+ my $helptext = <<'EOF';
+Usage:
+pgindent [OPTION]... [FILE]...
+Options:
+ --help show this message and quit
+ --typedefs=FILE file containing a list of typedefs
+ --list-of-typedefs=STR string containing typedefs, space separated
+ --code-base=DIR path to the base of PostgreSQL source code
+ --excludes=PATH file containing list of filename patterns to ignore
+ --indent=PATH path to pg_bsd_indent program
+ --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
+EOF
+ if ($help)
+ {
+ print $helptext;
+ exit 0;
+ }
+ else
+ {
+ print STDERR "$message\n", $helptext;
+ exit 1;
+ }
+}
# main
foreach my $source_filename (@files)
{
+ # ignore anything that's not a .c or .h file
+ next unless $source_filename =~ /\.[ch]$/;
# Automatically ignore .c and .h files that correspond to a .y or .l
# file. indent tends to get badly confused by Bison/flex output,
next;
}
- $source = post_indent($source, $source_filename);
+ $source = post_indent($source);
+
+ if ($source ne $orig_source)
+ {
+ if ($silent_diff)
+ {
+ exit 2;
+ }
+ elsif ($show_diff)
+ {
+ print show_diff($source, $source_filename);
+ }
+ else
+ {
+ write_source($source, $source_filename);
+ }
+ }
- write_source($source, $source_filename) if $source ne $orig_source;
}
build_clean($code_base) if $build;
+
+exit 0;
a PostgreSQL source tree, this option isn't necessary, as it will find the file
src/tools/pgindent/exclude_file_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.
+
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