[mm-common] Implement filename globbing within doc-install.pl



commit e0376dfa81b6f9fc13112e0a948664c86e459b71
Author: Daniel Elstner <daniel kitta gmail com>
Date:   Sun Aug 9 16:18:48 2009 +0200

    Implement filename globbing within doc-install.pl
    
    * util/doc-install.pl: Add a new --glob flag, which tells the script
    to interpret the source arguments as glob patterns instead of literal
    filenames.  Performing the filename glob expansion internally avoids
    excessively long argument lists, which can unfortunately be a problem
    with some platforms.  Also, remember the basename of every installed
    file, and use that information to skip over files whose basename has
    already been seen.
    * util/doc-postprocess.pl: Also perform globbing internally to avoid
    excessively long command lines.
    * build/doc-reference.am (MMDOCTOOLDIR): Use this separate variable
    instead of GMMPROC_DIR for the default location of the documentation
    utility scripts.
    (doc_postprocess), (doc_install), (tagfile_to_devhelp2): Derive
    default values from $(MMDOCTOOLDIR).  Include the interpreter command
    $(PERL) as part of the variable value, just in case someone needs to
    override the Perl interpreter as well.
    (install-data-local): Use the new --glob feature of doc-install.pl
    instead of having make expand the entire list of filenames into the
    shell command-line.
    (uninstall-local): Do not rely on globbing at the shell level for
    producing the list of files to delete, since it would probably exceed
    the command line length limits of some platforms.  Do not go back to
    rm -rf either, but use a combination of 'find' and 'rm -f' to restrict
    the deletion to those files that match the same glob pattern as the
    one used to select the files to install.

 build/doc-reference.am  |   51 ++++++++++++++++++++++++----------------------
 util/doc-install.pl     |   26 ++++++++++++++++++-----
 util/doc-postprocess.pl |    2 +-
 3 files changed, 48 insertions(+), 31 deletions(-)
---
diff --git a/build/doc-reference.am b/build/doc-reference.am
index 45f0703..58b97aa 100644
--- a/build/doc-reference.am
+++ b/build/doc-reference.am
@@ -40,11 +40,11 @@ htmlref_patterns ?=		\
 	reference/html/*.png	\
 	reference/html/*.gif
 
-# Locations of utilities shipped with gmmproc.  Made overridable
+# Locations of utilities shipped with glibmm.  Made overridable
 # in case the installed utilities cannot be used for some reason.
-doc_postprocess     ?= $(GMMPROC_DIR)/doc-postprocess.pl
-doc_install         ?= $(GMMPROC_DIR)/doc-install.pl
-tagfile_to_devhelp2 ?= $(GMMPROC_DIR)/tagfile-to-devhelp2.xsl
+doc_postprocess     ?= $(PERL) -- "$(MMDOCTOOLDIR)/doc-postprocess.pl"
+doc_install         ?= $(PERL) -- "$(MMDOCTOOLDIR)/doc-install.pl"
+tagfile_to_devhelp2 ?= "$(MMDOCTOOLDIR)/tagfile-to-devhelp2.xsl"
 
 # Names of the main output files.
 doxytagfile = reference/$(book_name).tag
@@ -57,31 +57,21 @@ devhelpfile = reference/$(book_name).devhelp2
 vpath_srclist = $(patsubst $(srcdir)/%,%,$(wildcard $(addprefix $(srcdir)/,$(1))))
 vpath_listall = $(sort $(wildcard $(1)) $(if $(srcdir:.=),$(vpath_srclist)))
 
-# Function: $(call vpath_resolve,FILENAME ...)
-# For each FILENAME, test whether the file exists relative to the current
-# directory.  If the file exists, return the filename unchanged, otherwise
-# prepend $(srcdir)/ to the filename.
-vpath_srctest = $(foreach file,$(1),$(or $(wildcard $(file)),$(srcdir)/$(file)))
-vpath_resolve = $(if $(srcdir:.=),$(vpath_srctest),$(1))
-
 # Installation directories.
 libdocdir    = $(datarootdir)/doc/$(book_name)
 referencedir = $(libdocdir)/reference
 htmlrefdir   = $(referencedir)/html
 devhelpdir   = $(datadir)/devhelp/books/$(book_name)
 
-# List of files in the HTML reference documentation.
-htmlreffiles = $(call vpath_listall,$(htmlref_patterns))
-
 dist_reference_DATA = $(doxytagfile)
 dist_devhelp_DATA   = $(devhelpfile)
-dist_noinst_DATA    = $(htmlreffiles)
+dist_noinst_DATA    = $(call vpath_listall,$(htmlref_patterns))
 
 DISTCLEANFILES       = reference/doxygen.log
 MAINTAINERCLEANFILES = $(doxytagfile) $(devhelpfile) reference/html/*
 
 # The generic bit of the doc-install.pl command line.
-doc_install_cmd = $(PERL) -- $(doc_install) --verbose --mode=0644
+doc_install_cmd = $(doc_install) --verbose --mode=0644
 
 # The command and options used to install the files from the HTML reference
 # documentation.  The $(subst) magic translates external tag references from
@@ -95,6 +85,14 @@ htmlref_install = $(doc_install_cmd) $(subst @$(datarootdir)/doc/,@../../../,$(D
 # default value.
 dist_devhelpDATA_INSTALL = $(doc_install_cmd) --book-base='$(htmlrefdir)' -T --
 
+# Helper variables to replicate each pattern with a $(srcdir)/ prefix.
+# Also add quoting to prevent the shell from expanding the patterns.
+htmlref_patterns_dup   = $(foreach file,$(htmlref_patterns),'$(file)' '$(srcdir)/$(file)')
+htmlref_patterns_vpath = $(if $(srcdir:.=),$(htmlref_patterns_dup),$(htmlref_patterns:%='%'))
+
+# Expand to a list of -name 'PATTERN' arguments for use with 'find'.
+htmlref_find_patterns  = $(patsubst %,-name '%' -o,$(notdir $(htmlref_patterns))) -false
+
 # The parameters to the Doxygen-to-Devhelp XSLT script
 dh_xsl_params =	--stringparam book_title '$(book_title)' \
 		--stringparam book_name '$(book_name)' \
@@ -108,17 +106,22 @@ doc_dependencies =
 endif
 
 # Install the HTML reference documentation files with just one invocation
-# of doc-install.pl to speed up the build process.
+# of doc-install.pl to speed up the build process.  Make use of the --glob
+# option, which tells it to perform filename globbing itself, like 'find'.
+# This helps to avoid excessively long command lines, as some platforms
+# have rather restrictive limits.
 install-data-local: reference/html/index.html
 	@$(NORMAL_INSTALL)
 	$(MKDIR_P) '$(DESTDIR)$(htmlrefdir)'
-	$(htmlref_install) -t '$(DESTDIR)$(htmlrefdir)' -- $(call vpath_resolve,$(htmlreffiles))
+	$(htmlref_install) -t '$(DESTDIR)$(htmlrefdir)' --glob -- $(htmlref_patterns_vpath)
 
-# Delete all files in the html installation directory, but avoid recursion
-# in order to limit the harm done if something goes horribly wrong.
+# Delete files from the html installation directory.  Avoid recursive
+# directory removal, and apply the same wildcard pattern as was used to
+# select files for installation.
 uninstall-local:
 	@$(NORMAL_UNINSTALL)
-	(cd '$(DESTDIR)$(htmlrefdir)' 2>/dev/null || exit 0; rm -f $(notdir $(htmlref_patterns)))
+	(cd '$(DESTDIR)$(htmlrefdir)' 2>/dev/null || exit 0; \
+	 find . -type f \( $(htmlref_find_patterns) \) -exec rm -f '{}' '+')
 	-test ! -r '$(DESTDIR)$(htmlrefdir)' || rmdir '$(DESTDIR)$(htmlrefdir)'
 
 # Regenerate the Doxygen configuration file automatically.
@@ -133,13 +136,13 @@ reference/html/%: | $(doxytagfile)
 # also functions as time stamp target for the documentation as a whole.
 $(doxytagfile): $(doc_dependencies) | reference/Doxyfile
 	-rm -f '$@'
-	-rm -f reference/html/*
+	-rm -fr reference/html
 	(echo '@INCLUDE =' reference/Doxyfile && echo 'INPUT =' $(doc_input)) | $(DOXYGEN) -
-	$(PERL) -- "$(doc_postprocess)" reference/html/*.html
+	$(doc_postprocess) 'reference/html/*.html'
 
 # Run XSL transformation to generate a Devhelp book from a Doxygen tag file.
 %.devhelp2: %.tag
-	$(XSLTPROC) $(dh_xsl_params) -o $@ "$(tagfile_to_devhelp2)" $<
+	$(XSLTPROC) $(dh_xsl_params) -o $@ $(tagfile_to_devhelp2) $<
 
 # Instruct GNU make to delete the targets of a rule after it failed, in
 # order to avoid the complication of handling that situation manually.
diff --git a/util/doc-install.pl b/util/doc-install.pl
index 3bca5f7..19515ad 100644
--- a/util/doc-install.pl
+++ b/util/doc-install.pl
@@ -1,6 +1,6 @@
 package main;
 
-# Copyright (c) 2009  Daniel Elstner <daniel kitta gmail com>
+# Copyright (c) 2009  Openismus GmbH  <http://www.openismus.com/>
 #
 # This file is part of mm-common.
 #
@@ -30,7 +30,8 @@ my $book_base;
 my $perm_mode;
 my $target_dir;
 my $target_nodir = '';
-my $verbose = '';
+my $expand_glob  = '';
+my $verbose      = '';
 
 sub path_basename ($)
 {
@@ -54,11 +55,12 @@ while setting permission modes.  For HTML files, translate references to
 external documentation.
 
 Mandatory arguments to long options are mandatory for short options, too.
-  -k, --book-base=BASEPATH          use reference BASEPATH for Devhelp book
+      --book-base=BASEPATH          use reference BASEPATH for Devhelp book
   -l, --tag-base=TAGFILE\ BASEPATH   use BASEPATH for references from TAGFILE
   -m, --mode=MODE                   override file permission MODE (octal)
   -t, --target-directory=DIRECTORY  copy all SOURCE arguments into DIRECTORY
   -T, --no-target-directory         treat DEST as normal file
+      --glob                        expand SOURCE as filename glob pattern
   -v, --verbose                     enable informational messages
   -?, --help                        display this help and exit
 EOF
@@ -156,11 +158,12 @@ $message_prefix = ($message_prefix || 'doc-install') . ': ';
   my @tags = ();
   my $mode = '0644';
 
-  GetOptions('book-base|k=s'         => \$book_base,
+  GetOptions('book-base=s'           => \$book_base,
              'tag-base|l=s'          => \ tags,
              'mode|m=s'              => \$mode,
              'target-directory|t=s'  => \$target_dir,
              'no-target-directory|T' => \$target_nodir,
+             'glob'                  => \$expand_glob,
              'verbose|v'             => \$verbose,
              'help|?'                => \&exit_help)
     or exit 2;
@@ -176,6 +179,7 @@ if ($target_nodir)
 {
   error('Conflicting target directory options') if (defined $target_dir);
   error('Source and destination filenames expected') unless ($#ARGV == 1);
+  error('Filename globbing requires target directory') if ($expand_glob);
 
   install_file($ARGV[0], $ARGV[1], path_basename($ARGV[1]));
   exit;
@@ -183,7 +187,7 @@ if ($target_nodir)
 
 unless (defined $target_dir)
 {
-  if ($#ARGV == 1)
+  if (!$expand_glob and $#ARGV == 1)
   {
     my $basename = path_basename($ARGV[1]);
 
@@ -197,11 +201,21 @@ unless (defined $target_dir)
 }
 error('No target directory specified') unless (defined($target_dir) and $target_dir ne '');
 
+ ARGV = map(glob, @ARGV) if ($expand_glob);
+my %basename_hash = ();
+
 foreach my $in_name (@ARGV)
 {
   my $basename = path_basename($in_name);
   my $out_name = File::Spec->catfile($target_dir, $basename);
 
-  install_file($in_name, $out_name, $basename);
+  # If there are multiple files with the same base name in the list, only
+  # the first one will be installed.  This behavior makes it very easy to
+  # implement a VPATH search for each individual file.
+  unless (exists $basename_hash{$basename})
+  {
+    $basename_hash{$basename} = undef;
+    install_file($in_name, $out_name, $basename);
+  }
 }
 exit;
diff --git a/util/doc-postprocess.pl b/util/doc-postprocess.pl
index 76a9f0a..7da75d8 100644
--- a/util/doc-postprocess.pl
+++ b/util/doc-postprocess.pl
@@ -21,7 +21,7 @@ use strict;
 use warnings;
 use bytes;
 
-foreach my $filename (@ARGV)
+foreach my $filename (map(glob, @ARGV))
 {
   my @outbuf = ();
   my $file;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]