--- toast 2004/09/22 04:27:51 1.345 +++ toast 2004/09/25 23:55:10 1.346 @@ -287,6 +287,7 @@ "ignorecase" => "true", "showurls" => "true", "infodir" => "true", + "xmlcatalog" => "true", "protect" => "false", "relative" => "false", "debugrewrite" => "false", @@ -1381,21 +1382,22 @@ ############################################################################## -sub newenvvar($$;$) +sub newenvvar($$;$;$) { - my($varname, $subdirs, $default) = @_; - my(@dirs) = map(path(armdir, $_), split(/:/, $subdirs)); + my($varname, $subdirs, $default, $delim) = @_; + $delim ||= ":"; + my(@dirs) = map(path(armdir, $_), split(/$delim/, $subdirs)); my($current) = exists($ENV{$varname}) ? $ENV{$varname} : $default; if(defined($current)) { my(%have); - $have{$_} = 1 for split(/:/, $current); + $have{$_} = 1 for split(/$delim/, $current); @dirs = grep(!$have{$_}, @dirs); push(@dirs, $current); } - return($varname, join(":", @dirs)); + return($varname, join($delim, @dirs)); } sub newenv() @@ -1407,13 +1409,15 @@ chomp($out) if defined($out); $defaultman = $out if defined($out) && $out =~ m!^/! && $out !~ /\n/; } + my($x) = path(qw(etc xml catalog)); my(@vars); push(@vars, newenvvar("PATH", "sbin:bin")); push(@vars, newenvvar("MANPATH", "man", $defaultman)); - push(@vars, newenvvar("INFOPATH", "info", "")); + push(@vars, newenvvar("INFOPATH", "info", "")) if infodir; push(@vars, newenvvar("CPATH", "include")); push(@vars, newenvvar("LIBRARY_PATH", "lib")); + push(@vars, newenvvar("XML_CATALOG_FILES", $x, "/$x", " ")) if xmlcatalog; # there's also a LIBRARY_RUN_PATH or something that affects ld somehow... return @vars; } @@ -3425,6 +3429,54 @@ optrelln($rootdir, $p = path($p, $_)) for unpath($armdir), unpath($rootdir); } +sub mkxmlcatalog($@) +{ + my($name, @contents) = @_; + writefile($name, qq[<?xml version="1.0"?> +<!DOCTYPE catalog PUBLIC "-//OASIS//DTD Entity Resolution XML Catalog V1.0//EN" "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">\n], + map(" $_\n", @contents), "</catalog>\n"); +} + +sub compiledata($$) +{ + my($srcdir, $rootdir) = @_; + my(@installdir); + + # docbook-xml, maybe other things too? + my($cat) = path($srcdir, "catalog.xml"); + if(-r($cat)) + { + my($name, $version); + whilefile + { + ($name, $version) = (lc($1), $2) if m!//DTD (\w+) XML V([\d\.]+)//!i; + !$version; + } $cat; + @installdir = (qw(share xml), $name, $version) if $version; + } + + # docbook-xsl + my(@ls) = ls($srcdir); + if(!@installdir && scalar(@ls) == 1 && $ls[0] =~ /^docbook-xsl-/) + { + $srcdir = path($srcdir, $ls[0]); + @installdir = qw(share xml docbook-xsl); + my($cat) = path($srcdir, "catalog.xml"); + my($rewritePrefix) = path(armdir, @installdir); + mkxmlcatalog($cat, qq[<rewriteURI uriStartString="http://docbook.sourceforge.net/release/xsl/current" rewritePrefix="$rewritePrefix"/>]) unless -r($cat); + } + + return false unless @installdir; + my($dir) = $rootdir; + for(@installdir) + { + md($dir); + $dir = path($dir, $_); + } + return mv($srcdir, $dir); +} + sub compilebin($$) { my($srcdir, $rootdir) = @_; @@ -3548,7 +3600,9 @@ sub compile($$$) { my($srcdir, $rootdir, $helperdir) = @_; - compilebin($srcdir, $rootdir) || compilehelp($srcdir, $rootdir, $helperdir); + compiledata($srcdir, $rootdir) || + compilebin($srcdir, $rootdir) || + compilehelp($srcdir, $rootdir, $helperdir); polishrootdir($rootdir, armdir); } @@ -3829,6 +3883,50 @@ safechmod($mode, $dir); } +sub rebuildxmlcatalog(@) +{ + return true unless xmlcatalog; + + my($armdir) = @_; + my($etcdir) = path($armdir, "etc"); + my($xmldir) = path($etcdir, "xml"); + my($master) = path($xmldir, "catalog"); + return true if -l($master); + + my(@subcats); + my($dir) = path($armdir, qw[share xml]); + dfs + ( + $dir, + sub { true }, + sub { push(@subcats, $_) if m!/catalog.xml$!; true }, + sub { true }, + ) if -d($dir); + + return -e($master) ? rm($master) : true unless @subcats; + + for(grep(!-d, $etcdir, $xmldir)) + { + my($parent) = dirname($_); + my($mode) = getmode($parent); + safechmod(0777, $parent); + md($_); + safechmod($mode, $parent); + } + + my($mode) = getmode($xmldir); + safechmod(0777, $xmldir); + safechmod(0666, $master) if -e($master); + mkxmlcatalog($master, map(qq[<nextCatalog catalog="$_"/>], sort(@subcats))); + safechmod($mode, $xmldir); + + if(protect) + { + safechmod(0444, $master); + safechmod(0555, $_) for($xmldir, $etcdir, $armdir); + } +} + sub arm(@) { my($name, $version, $build, @urls) = @_; @@ -3897,6 +3995,7 @@ ); rebuildinfodir(armdir); + rebuildxmlcatalog(armdir); run(postarmprog) if postarmprog; unlock(armdir); @@ -3988,6 +4087,7 @@ } @nvb; # can't replace @nvb with ($n, $v, $b) due to perl 5.6.1 bug (?) rebuildinfodir($armdir) if $changed; + rebuildxmlcatalog($armdir) if $changed; run(postarmprog) if ++$i == scalar(@armdirs) && $anychanged && postarmprog; unlock($armdir); } @@ -5965,8 +6065,9 @@ directory will be left in its current position instead of being moved to the front. Other environment variables are similarly affected: C<MANPATH> (used to find man pages), C<INFOPATH> (used by GNU info), C<CPATH> (used -by gcc to find include files), and C<LIBRARY_PATH> (used by GNU ld to -find libraries; not to be confused with C<LD_LIBRARY_PATH>, which also +by gcc to find include files), C<XML_CATALOG_FILES> (used by DocBook and +other tools to locate XML catalogs), and C<LIBRARY_PATH> (used by GNU ld +to find libraries; not to be confused with C<LD_LIBRARY_PATH>, which also affects shared library loading at run time). Note that if C<MANPATH> in particular is unset, B<toast env> will run C<man -w> to try to get the default value; if this causes problems, it may help to ensure that @@ -6410,7 +6511,7 @@ for that package was given explicitly on the command line. Default: enabled. -=item S<B<--infodir> | B<noinfodir>> +=item S<B<--infodir> | B<--noinfodir>> When B<infodir> is enabled, B<toast arm> and B<toast disarm> will create a file in B<armdir> called C<info/dir>; if the file already exists, it will @@ -6419,6 +6520,21 @@ file in B<armdir>; all the other files are symbolic links. If B<infodir> is disabled, B<toast arm> and B<toast disarm> will delete the C<info/dir> file, if present, instead of rebuilding it. Default: enabled. + +=item S<B<--xmlcatalog> | B<--noxmlcatalog>> + +When B<xmlcatalog> is enabled, B<toast arm> and B<toast disarm> will +maintain a catalog file in B<armdir> called C<etc/xml/catalog>, whose +presence and contents depend on the contents of B<armdir>'s C<share/xml> +subdirectory. If the catalog already exists, it may be overwritten +or deleted. It may be convenient to refer to this catalog from the real +master XML catalog file (outside of B<armdir>), in order to allow programs +to locate XML DTDs, XSL style sheets, and perhaps other XMLish things +in B<armdir>. This is most likely to come up in the context of DocBook. +If B<xmlcatalog> is disabled, B<toast arm> and B<toast disarm> will not +create an XML catalog and will ignore any existing catalog. Note that +this option is implicitly disabled if any package installed in B<armdir> +itself provides an C<etc/xml/catalog> file. Default: enabled. =item S<B<--protect> | B<--noprotect>>