summaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2003-01-30 12:12:01 +0000
committerAndreas Gruenbacher <agruen@suse.de>2003-01-30 12:12:01 +0000
commit6b029c93fa2d380c5300931f7b6e20b08c63ab37 (patch)
tree4934dbf971070af68666aa23edc02fe7289ad256 /bin
parent96728d30b3059fea6fd05e17614a72274ddd40f4 (diff)
downloadquilt-6b029c93fa2d380c5300931f7b6e20b08c63ab37.tar.gz
Prepare for GNU Autoconf; Some cleanups in Makefile
Diffstat (limited to 'bin')
-rw-r--r--bin/.cvsignore2
-rw-r--r--bin/guards.in246
-rw-r--r--bin/quilt.in2
3 files changed, 248 insertions, 2 deletions
diff --git a/bin/.cvsignore b/bin/.cvsignore
index 3cbe4cc..71bd359 100644
--- a/bin/.cvsignore
+++ b/bin/.cvsignore
@@ -1 +1 @@
-quilt guards.1
+quilt guards.1 guards
diff --git a/bin/guards.in b/bin/guards.in
new file mode 100644
index 0000000..181268d
--- /dev/null
+++ b/bin/guards.in
@@ -0,0 +1,246 @@
+#!@PERL@ -w
+
+# This script is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# See the COPYING and AUTHORS files for more details.
+
+use FileHandle;
+use Getopt::Long;
+use strict;
+
+# Prototypes
+sub files_in($$);
+sub parse($$);
+sub help();
+
+sub slashme($) {
+ my ($dir) = @_;
+ $dir =~ s#([^/])$#$&/#; # append a slash if necessary
+ if ($dir eq './') {
+ return '';
+ } else {
+ return $dir;
+ }
+}
+
+# Generate a list of files in a directory
+#
+sub files_in($$) {
+ my ($dir, $path) = @_;
+ my $dh = new FileHandle;
+ my (@files, $file);
+
+
+ opendir $dh, length("$dir$path") ? "$dir$path" : '.'
+ or die "$dir$path: $!\n";
+ while ($file = readdir($dh)) {
+ next if $file =~ /^(\.|\.\.|\.#.*|CVS)$/;
+ if (-d "$dir$path$file") {
+ @files = (@files, files_in($dir, "$path$file/"));
+ } else {
+ #print "[$path$file]\n";
+ push @files, "$path$file";
+ }
+ }
+ closedir $dh;
+ return @files;
+}
+
+# Parse a configuration file
+# Callback called with ($patch, @guards) arguments
+#
+sub parse($$) {
+ my ($fh, $callback) = @_;
+
+ my $mode = 0;
+
+ while (<$fh>) {
+ my @guards = ();
+ s/(^|\s+)#.*//;
+ foreach my $token (split) {
+ if ($token =~ /^[-+]/) {
+ if ($mode == 1) {
+ @guards = ();
+ $mode = 0;
+ }
+ push @guards, $token;
+ } else {
+ $mode = 1;
+ #print "[" . join(",", @guards) . "] $patch\n";
+ &$callback($token, @guards);
+ }
+ }
+ }
+}
+
+# Command line options
+#
+my ($dir, $config, $default, $check) = ('', '-', 1, 0);
+my @path;
+
+# Help text
+#
+sub help() {
+ print "$0 - select from a list of files guarded by conditions\n";
+ print "SYNOPSIS: $0 [--prefix=dir] [--path=dir1:dir2:...]\n" .
+ " [--default=0|1] [--check] [--config=file] symbol ...\n\n" .
+ " (Default values: --path='" . join(':', @path) . "', " .
+ "--default=$default)\n";
+ exit 0;
+}
+
+# Parse command line options
+#
+Getopt::Long::Configure ("bundling");
+eval {
+ unless (GetOptions (
+ 'd|prefix=s' => \$dir,
+ 'c|config=s' => \$config,
+ 'C|check' => \$check,
+ 'p|path=s' => \@path,
+ 'D|default=i' => \$default,
+ 'h|help' => sub { help(); exit 0; })) {
+ help();
+ exit 1;
+ }
+};
+if ($@) {
+ print "$@";
+ help();
+ exit 1;
+}
+
+@path = ('.')
+ unless (@path);
+@path = split(/:/, join(':', @path));
+
+my $fh = ($config eq '-') ? \*STDIN : new FileHandle($config)
+ or die "$config: $!\n";
+
+$dir = slashme($dir);
+
+if ($check) {
+ # Check for duplicate files, or for files that are not referenced by
+ # the specification.
+
+ my $problems = 0;
+ my @files;
+
+ foreach (@path) {
+ @files = (@files, files_in($dir, slashme($_)));
+ }
+ my %files = map { $_ => 0 } @files;
+
+ parse($fh, sub {
+ my ($patch, @guards) = @_;
+ if (exists $files{$patch}) {
+ $files{$patch}++;
+ } else {
+ print "Not found: $dir$patch\n";
+ $problems++;
+ }});
+
+ $fh->close();
+
+ my ($file, $ref);
+ while (($file, $ref) = each %files) {
+ next if $ref == 1;
+
+ print "Unused: $file\n" if $ref == 0;
+ print "Multiple uses: $file\n" if $ref > 1;
+ $problems++;
+ }
+ exit $problems ? 1 : 0;
+
+} else {
+ # Generate a list of patches to apply.
+
+ my %symbols = map { $_ => 1 } @ARGV;
+
+ parse($fh, sub {
+ my ($patch, @guards) = @_;
+
+ my $selected;
+ if (@guards) {
+ # If the first guard is -xxx, the patch is included by default;
+ # if it is -xxx, the patch is excluded by default.
+ $selected = ($guards[0] =~ /^-/);
+
+ foreach (@guards) {
+ /^([-+])(!?)(.*)?/
+ or die "Bad guard '$_'\n";
+
+ # Check if the guard matches
+ if (($2 eq '!' && !exists $symbols{$3}) ||
+ ($2 eq '' && ( $3 eq '' || exists $symbols{$3}))) {
+ # Include or exclude
+ $selected = ($1 eq '+');
+ }
+ }
+ } else {
+ # If there are no guards, use the specified default result.
+ $selected = $default;
+ }
+
+ print "$dir$patch\n"
+ if $selected;
+ });
+
+ $fh->close();
+
+ exit 0;
+}
+
+__END__
+
+=head1 NAME
+
+guards - select from a list of files guarded by conditions
+
+=head1 SYNOPSIS
+
+F<guards> [--prefix=F<dir>] [--path=F<dir2:dir2:...>]
+ [--default=I<0>|I<1>] [--check] [--config=F<file>]
+ I<symbol> ...
+
+=head1 DESCRIPTION
+
+The script reads a configuration file that may contain so-called guards, file
+names, and comments, and writes those file names that satisfy all guards to
+standard output. The script takes a list of symbols as its arguments. Each line
+in the ocnfiguration file is processed separately. Lines may start with a
+number of guards. The following guards are defined:
+
+=over
+
++I<xxx> Include the file(s) on this line if the symbol I<xxx> is defined.
+
+-I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is defined.
+
++!I<xxx> Include the file(s) on this line if the symbol I<xxx> is not defined.
+
+-!I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is not defined.
+
+- Exclude this file. Used to avoid spurious I<--check> messages.
+
+=back
+
+The guards are processed left to right. The last guard that matches determines
+if the file is included. If no guard is specified, the I<--default>
+setting determines if the file is included.
+
+If no configuration file is specified, the script reads from standard input.
+
+The I<--check> option is used to compare the specification file against the
+file system. If files are referenced in the specification that do not exist, or
+if files are not enlisted in the specification file warnings are printed. The
+I<--path> option can be used to specify which directory or directories to scan.
+Multiple directories are eparated by a colon (C<:>) character. The
+I<--prefix> option specifies the location of the files.
+
+=head1 AUTHOR
+
+Andreas Gruenbacher <agruen@suse.de> (SuSE Linux AG)
+
diff --git a/bin/quilt.in b/bin/quilt.in
index d1a6867..521e0ba 100644
--- a/bin/quilt.in
+++ b/bin/quilt.in
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!@BASH@
# This script is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as