help2man: update to 1.47.4

Also disable i18n because that seems to be causing many problem to Mac
users building Spot for git and not knowing how to install
Locale::gettext.

* tools/help2man: Update from upstream, plus the two changes from
2b4cf8e7cb and
f7b65001e9.
* bin/man/Makefile.am: Remove the -L flag.
This commit is contained in:
Alexandre Duret-Lutz 2016-09-03 19:10:53 +02:00
parent 2dfe429447
commit ca6435d847
2 changed files with 185 additions and 110 deletions

View file

@ -20,9 +20,9 @@
common_dep = $(top_srcdir)/configure.ac common_dep = $(top_srcdir)/configure.ac
x_to_1 = $(top_builddir)/tools/x-to-1 x_to_1 = $(top_builddir)/tools/x-to-1
convman = ARGP_HELP_FMT=header-col=0 $(SHELL) "$(x_to_1)" \ convman = ARGP_HELP_FMT=header-col=0 $(SHELL) "$(x_to_1)" \
"$(PERL)" "$(top_srcdir)/tools/help2man -N -L 'en_US.UTF-8'" "$(PERL)" "$(top_srcdir)/tools/help2man -N"
convman7 = ARGP_HELP_FMT=header-col=0 $(SHELL) "$(x_to_1)" \ convman7 = ARGP_HELP_FMT=header-col=0 $(SHELL) "$(x_to_1)" \
"$(PERL)" "$(top_srcdir)/tools/help2man -s7 -N -L 'en_US.UTF-8'" "$(PERL)" "$(top_srcdir)/tools/help2man -s7 -N"
dist_man1_MANS = \ dist_man1_MANS = \
autfilt.1 \ autfilt.1 \

View file

@ -2,7 +2,7 @@
# Generate a short man page from --help and --version output. # Generate a short man page from --help and --version output.
# Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, # Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
# 2010, 2011, 2012, 2015, 2016 Free Software Foundation, Inc. # 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -23,52 +23,37 @@
use 5.008; use 5.008;
use strict; use strict;
use Getopt::Long; use Getopt::Long;
use Text::ParseWords qw(shellwords);
use Text::Tabs qw(expand); use Text::Tabs qw(expand);
use POSIX qw(strftime setlocale LC_ALL); use POSIX qw(strftime setlocale LC_ALL);
use Locale::gettext;
use Encode qw(decode encode);
use I18N::Langinfo qw(langinfo CODESET);
my $this_program = 'help2man'; my $this_program = 'help2man';
my $this_version = '1.40.12'; my $this_version = '1.47.4';
my $encoding;
sub _ { $_[0] }
sub configure_locale
{ {
my $gettext = Locale::gettext->domain($this_program); my $locale = shift;
sub _ { $gettext->get($_[0]) } die "$this_program: no locale support (Locale::gettext required)\n"
unless $locale eq 'C';
my ($user_locale) = grep defined && length,
(map $ENV{$_}, qw(LANGUAGE LC_ALL LC_MESSAGES LANG)), 'C';
my $user_encoding = langinfo CODESET;
# Set localisation of date and executable's output.
sub configure_locale
{
delete @ENV{qw(LANGUAGE LC_MESSAGES LANG)};
setlocale LC_ALL, $ENV{LC_ALL} = shift || 'C';
$encoding = langinfo CODESET;
}
sub dec { $encoding ? decode $encoding, $_[0] : $_[0] }
sub enc { $encoding ? encode $encoding, $_[0] : $_[0] }
sub enc_user { encode $user_encoding, $_[0] }
sub kark # die with message formatted in the invoking user's locale
{
setlocale LC_ALL, $user_locale;
my $fmt = $gettext->get(shift);
my $errmsg = enc_user sprintf $fmt, @_;
die $errmsg, "\n";
}
} }
sub dec { $_[0] }
sub enc { $_[0] }
sub enc_user { $_[0] }
sub kark { die +(sprintf shift, @_), "\n" }
sub N_ { $_[0] } sub N_ { $_[0] }
sub program_basename;
sub get_option_value;
sub convert_option;
sub fix_italic_spacing;
my $version_info = enc_user sprintf _(<<'EOT'), $this_program, $this_version; my $version_info = enc_user sprintf _(<<'EOT'), $this_program, $this_version;
GNU %s %s GNU %s %s
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2010, Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009, 2010,
2011, 2012 Free Software Foundation, Inc. 2011, 2012, 2013, 2014, 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@ -138,21 +123,33 @@ my %opt_def = (
Getopt::Long::config('bundling'); Getopt::Long::config('bundling');
die $help_info unless GetOptions %opt_def and @ARGV == 1; die $help_info unless GetOptions %opt_def and @ARGV == 1;
configure_locale unless $encoding;
my %include = (); my %include = ();
my %replace = ();
my %append = (); my %append = ();
my @include = (); # retain order given in include file my %append_match = ();
my @sections = (); # retain order of include file or in-line *section*s
# Process include file (if given). Format is: # Process include file (if given). Format is:
# #
# [section name] # Optional initial text, ignored. May include lines starting with `-'
# verbatim text # which are processed as options.
# #
# or # [section]
# Verbatim text to be included in the named section. By default at
# the start, but in the case of `name' and `synopsis' the content
# will replace the autogenerated contents.
#
# [<section]
# Verbatim text to be inserted at the start of the named section.
#
# [=section]
# Verbatim text to replace the named section.
#
# [>section]
# Verbatim text to be appended to the end of the named section.
# #
# /pattern/ # /pattern/
# verbatim text # Verbatim text for inclusion below a paragraph matching `pattern'.
# #
while (@opt_include) while (@opt_include)
@ -164,7 +161,7 @@ while (@opt_include)
unless open INC, $inc; unless open INC, $inc;
my $key; my $key;
my $hash = \%include; my $hash;
while (<INC>) while (<INC>)
{ {
@ -179,7 +176,23 @@ while (@opt_include)
$key =~ s/^\s+//; $key =~ s/^\s+//;
$key =~ s/\s+$//; $key =~ s/\s+$//;
$hash = \%include; $hash = \%include;
push @include, $key unless $include{$key}; # Handle explicit [<section], [=section] and [>section]
if ($key =~ s/^([<>=])\s*//)
{
if ($1 eq '>') { $hash = \%append; }
elsif ($1 eq '=') { $hash = \%replace; }
}
# NAME/SYNOPSIS replace by default
elsif ($key eq _('NAME') or $key eq _('SYNOPSIS'))
{
$hash = \%replace;
}
else
{
$hash = \%include;
}
push @sections, $key;
next; next;
} }
@ -196,7 +209,7 @@ while (@opt_include)
die "$inc:$.:$@"; die "$inc:$.:$@";
} }
$hash = \%append; $hash = \%append_match;
next; next;
} }
@ -208,48 +221,57 @@ while (@opt_include)
# handle options # handle options
if (/^-/) if (/^-/)
{ {
local @ARGV = split; local @ARGV = shellwords $_;
GetOptions %opt_def; GetOptions %opt_def;
} }
next; next;
} }
$hash->{$key} ||= '';
$hash->{$key} .= $_; $hash->{$key} .= $_;
} }
close INC; close INC;
kark N_("%s: no valid information found in `%s'"), $this_program, $inc kark N_("%s: no valid information found in `%s'"), $this_program, $inc
unless $key; unless $key;
} }
# Compress trailing blank lines. # Compress trailing blank lines.
for my $hash (\(%include, %append)) for my $hash (\(%include, %replace, %append, %append_match))
{ {
for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ } for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ }
} }
sub get_option_value;
# Grab help and version info from executable. # Grab help and version info from executable.
my $help_text = get_option_value $ARGV[0], $help_option; my $help_text = get_option_value $ARGV[0], $help_option;
$version_text ||= get_option_value $ARGV[0], $version_option; $version_text ||= get_option_value $ARGV[0], $version_option;
# By default the generated manual pages will include the current date. This may
# however be overriden by setting the environment variable $SOURCE_DATE_EPOCH
# to an integer value of the seconds since the UNIX epoch. This is primarily
# intended to support reproducible builds (wiki.debian.org/ReproducibleBuilds)
# and will additionally ensure that the output date string is UTC.
my $epoch_secs = time;
if (exists $ENV{SOURCE_DATE_EPOCH} and $ENV{SOURCE_DATE_EPOCH} =~ /^(\d+)$/)
{
$epoch_secs = $1;
$ENV{TZ} = 'UTC';
}
# Translators: the following message is a strftime(3) format string, which in # Translators: the following message is a strftime(3) format string, which in
# the English version expands to the month as a word and the full year. It # the English version expands to the month as a word and the full year. It
# is used on the footer of the generated manual pages. If in doubt, you may # is used on the footer of the generated manual pages. If in doubt, you may
# just use %x as the value (which should be the full locale-specific date). # just use %x as the value (which should be the full locale-specific date).
my $date = enc strftime _("%B %Y"), localtime; my $date = enc strftime _("%B %Y"), localtime $epoch_secs;
(my $program = $ARGV[0]) =~ s!.*/!!; my $program = program_basename $ARGV[0];
my $package = $program; my $package = $program;
my $version; my $version;
if ($opt_output) if ($opt_output)
{ {
unlink $opt_output or kark N_("%s: can't unlink %s (%s)"), unlink $opt_output or kark N_("%s: can't unlink %s (%s)"),
$this_program, $opt_output, $! if -e $opt_output; $this_program, $opt_output, $! if -e $opt_output;
open STDOUT, ">$opt_output" open STDOUT, ">$opt_output"
or kark N_("%s: can't create %s (%s)"), $this_program, $opt_output, $!; or kark N_("%s: can't create %s (%s)"), $this_program, $opt_output, $!;
@ -271,14 +293,14 @@ if ($opt_output)
if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or
/^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/) /^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/)
{ {
$program = $1; $program = program_basename $1;
$package = $2; $package = $2;
$version = $3; $version = $3;
} }
elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/) elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/)
{ {
$program = $2; $program = program_basename $2;
$package = $1 ? "$1$2" : $2; $package = $1 ? "$1$program" : $program;
$version = $3; $version = $3;
} }
else else
@ -286,21 +308,21 @@ else
$version = $_; $version = $_;
} }
$program =~ s!.*/!!;
# No info for `info' itself. # No info for `info' itself.
$opt_no_info = 1 if $program eq 'info'; $opt_no_info = 1 if $program eq 'info';
if ($opt_name)
{
# --name overrides --include contents.
$replace{_('NAME')} = "$program \\- $opt_name\n";
}
# Translators: "NAME", "SYNOPSIS" and other one or two word strings in all # Translators: "NAME", "SYNOPSIS" and other one or two word strings in all
# upper case are manual page section headings. The man(1) manual page in your # upper case are manual page section headings. The man(1) manual page in your
# language, if available should provide the conventional translations. # language, if available should provide the conventional translations.
for ($include{_('NAME')}) for ($replace{_('NAME')} || ($include{_('NAME')} ||= ''))
{ {
if ($opt_name) # --name overrides --include contents. if ($_) # Use first name given as $program
{
$_ = "$program \\- $opt_name\n";
}
elsif ($_) # Use first name given as $program
{ {
$program = $1 if /^([^\s,]+)(?:,?\s*[^\s,\\-]+)*\s+\\?-/; $program = $1 if /^([^\s,]+)(?:,?\s*[^\s,\\-]+)*\s+\\?-/;
} }
@ -363,10 +385,11 @@ if ($help_text =~ s/^($PAT_USAGE):( +(\S+))(.*)((?:\n(?: {6}\1| *($PAT_USAGE_CON
s/\\fI$//; s/\\fI$//;
s/^\./\\&./; s/^\./\\&./;
$_ = fix_italic_spacing $_;
$synopsis .= "$_\n"; $synopsis .= "$_\n";
} }
$include{_('SYNOPSIS')} ||= $synopsis; $include{_('SYNOPSIS')} .= $synopsis;
} }
# Process text, initial section is DESCRIPTION. # Process text, initial section is DESCRIPTION.
@ -395,13 +418,13 @@ s/\\/\x82/g;
# "(?:[\\w-]+ +)?" in the bug reporting pattern is used to indicate an # "(?:[\\w-]+ +)?" in the bug reporting pattern is used to indicate an
# optional word, so that either "Report bugs" or "Report _program_ bugs" will # optional word, so that either "Report bugs" or "Report _program_ bugs" will
# be matched. # be matched.
my $PAT_BUGS = _('Report +(?:[\w-]+ +)?bugs|Email +bug +reports +to'); my $PAT_BUGS = _('Report +(?:[\w-]+ +)?bugs|Email +bug +reports +to');
my $PAT_AUTHOR = _('Written +by'); my $PAT_AUTHOR = _('Written +by');
my $PAT_OPTIONS = _('Options'); my $PAT_OPTIONS = _('Options');
my $PAT_ENVIRONMENT = _('Environment'); my $PAT_ENVIRONMENT = _('Environment');
my $PAT_FILES = _('Files'); my $PAT_FILES = _('Files');
my $PAT_EXAMPLES = _('Examples'); my $PAT_EXAMPLES = _('Examples');
my $PAT_FREE_SOFTWARE = _('This +is +free +software'); my $PAT_FREE_SOFTWARE = _('This +is +free +software');
# Start a new paragraph (if required) for these. # Start a new paragraph (if required) for these.
s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR) /$1\n\n$2 /og; s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR) /$1\n\n$2 /og;
@ -410,33 +433,40 @@ s/([^\n])\n($PAT_BUGS|$PAT_AUTHOR) /$1\n\n$2 /og;
# character. # character.
s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg; s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg;
sub convert_option;
while (length) while (length)
{ {
# Convert some standard paragraph names. # Convert some standard paragraph names.
if (s/^($PAT_OPTIONS): *\n//o) if (s/^($PAT_OPTIONS): *\n+//o)
{ {
$sect = _('OPTIONS'); $sect = _('OPTIONS');
next; next;
} }
if (s/^($PAT_ENVIRONMENT): *\n//o) if (s/^($PAT_ENVIRONMENT): *\n+//o)
{ {
$sect = _('ENVIRONMENT'); $sect = _('ENVIRONMENT');
next; next;
} }
if (s/^($PAT_FILES): *\n//o) if (s/^($PAT_FILES): *\n+//o)
{ {
$sect = _('FILES'); $sect = _('FILES');
next; next;
} }
elsif (s/^($PAT_EXAMPLES): *\n//o) elsif (s/^($PAT_EXAMPLES): *\n+//o)
{ {
$sect = _('EXAMPLES'); $sect = _('EXAMPLES');
next; next;
} }
# Copyright section # Custom section indicated by a line containing "*Section Name*".
if (s/^\*(\w(.*\w)?)\* *\n+//)
{
$sect = uc $1;
$sect =~ tr/*/ /; # also accept *Section*Name*
push @sections, $sect;
next;
}
# Copyright section.
if (/^Copyright /) if (/^Copyright /)
{ {
$sect = _('COPYRIGHT'); $sect = _('COPYRIGHT');
@ -461,7 +491,6 @@ while (length)
my $indent = $1; my $indent = $1;
my $prefix = $2; my $prefix = $2;
my $break = '.IP'; my $break = '.IP';
$include{$sect} ||= '';
while (s/^$indent\Q$prefix\E(\S.*)\n*//) while (s/^$indent\Q$prefix\E(\S.*)\n*//)
{ {
$include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n"; $include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n";
@ -472,12 +501,11 @@ while (length)
} }
my $matched = ''; my $matched = '';
$include{$sect} ||= '';
# Sub-sections have a trailing colon and the second line indented. # Sub-sections have a trailing colon and the second line indented.
if (s/^(\S.*:) *\n / /) if (s/^(\S.*:) *\n / /)
{ {
$matched .= $& if %append; $matched .= $& if %append_match;
$include{$sect} .= qq(.SS "$1"\n); $include{$sect} .= qq(.SS "$1"\n);
} }
@ -494,7 +522,7 @@ while (length)
s/^( {2}([+-]\S.{24}))$descrpat1//o || s/^( {2}([+-]\S.{24}))$descrpat1//o ||
s/^( {6}([+-]\S.{20}))$descrpat1//o) s/^( {6}([+-]\S.{20}))$descrpat1//o)
{ {
$matched .= $& if %append; $matched .= $& if %append_match;
$indent = length ($4 || "$1$3"); $indent = length ($4 || "$1$3");
$content = ".TP\n\x84$2\n\x84$5\n"; $content = ".TP\n\x84$2\n\x84$5\n";
unless ($4) unless ($4)
@ -507,23 +535,23 @@ while (length)
# Option without description. # Option without description.
elsif (s/^ {1,10}([+-]\S.*)\n//) elsif (s/^ {1,10}([+-]\S.*)\n//)
{ {
$matched .= $& if %append; $matched .= $& if %append_match;
$content = ".HP\n\x84$1\n"; $content = ".HP\n\x84$1\n";
$indent = 80; # not continued $indent = 80; # not continued
} }
# Indented paragraph with tag. # Indented paragraph with tag.
elsif (s/^( +(\S.*?) +)(\S.*)\n//) elsif (s/^( +(\S.*?))(?:( +)|\n( {20,}))(\S.*)\n//)
{ {
$matched .= $& if %append; $matched .= $& if %append_match;
$indent = length $1; $indent = length ($4 || "$1$3");
$content = ".TP\n\x84$2\n\x84$3\n"; $content = ".TP\n\x84$2\n\x84$5\n";
} }
# Indented paragraph. # Indented paragraph.
elsif (s/^( +)(\S.*)\n//) elsif (s/^( +)(\S.*)\n//)
{ {
$matched .= $& if %append; $matched .= $& if %append_match;
$indent = length $1; $indent = length $1;
$content = ".IP\n\x84$2\n"; $content = ".IP\n\x84$2\n";
} }
@ -532,7 +560,7 @@ while (length)
else else
{ {
s/(.*)\n//; s/(.*)\n//;
$matched .= $& if %append; $matched .= $& if %append_match;
$content = ".PP\n" if $include{$sect}; $content = ".PP\n" if $include{$sect};
$content .= "$1\n"; $content .= "$1\n";
} }
@ -540,7 +568,7 @@ while (length)
# Append continuations. # Append continuations.
while ($indent ? s/^ {$indent}(\S.*)\n// : s/^(\S.*)\n//) while ($indent ? s/^ {$indent}(\S.*)\n// : s/^(\S.*)\n//)
{ {
$matched .= $& if %append; $matched .= $& if %append_match;
$content .= "\x84$1\n"; $content .= "\x84$1\n";
} }
@ -554,20 +582,36 @@ while (length)
s/\x84'/\x81/g; s/\x84'/\x81/g;
s/\x84//g; s/\x84//g;
# Convert options. # Examples should be verbatim.
s/(^| )(-[][\w-]+(?:=[][\w=\/|()+<#.'"-]*)?)/$1 . convert_option $2/mge; unless ($sect eq _('EXAMPLES'))
s/\((-[][\w-]+(?:=[][\w=\/|()+<#.'"-]*)?)\)/"(" . convert_option $1 . ")"/mge; {
# Convert options.
s/(^| )(-[][\w-]+(?:=[][\w=\/|()+<#.'"-]*)?)/$1 . convert_option $2/mge;
s/\((-[][\w-]+(?:=[][\w=\/|()+<#.'"-]*)?)\)/"(" . convert_option $1 . ")"/mge;
# Escape remaining hyphens # Italicise filenames: /a/b, $VAR/c/d, ~/e/f
s!
(^|[ (]) # space/punctuation before
(
(?:\$\w+|~)? # leading variable, or tilde
(?:/\w(?:[\w.-]*\w)?)+ # path components
)
($|[ ,;.)]) # space/punctuation after
!$1\\fI$2\\fP$3!xmg;
$_ = fix_italic_spacing $_;
}
# Escape remaining hyphens.
s/-/\x83/g; s/-/\x83/g;
if ($sect eq 'COPYRIGHT') if ($sect eq _('COPYRIGHT'))
{ {
# Insert line breaks before additional copyright messages # Insert line breaks before additional copyright messages
# and the disclaimer. # and the disclaimer.
s/\n(Copyright |$PAT_FREE_SOFTWARE)/\n.br\n$1/og; s/\n(Copyright |$PAT_FREE_SOFTWARE)/\n.br\n$1/og;
} }
elsif ($sect eq 'REPORTING BUGS') elsif ($sect eq _('REPORTING BUGS'))
{ {
# Handle multi-line bug reporting sections of the form: # Handle multi-line bug reporting sections of the form:
# #
@ -579,14 +623,14 @@ while (length)
} }
# Check if matched paragraph contains /pat/. # Check if matched paragraph contains /pat/.
if (%append) if (%append_match)
{ {
for my $pat (keys %append) for my $pat (keys %append_match)
{ {
if ($matched =~ $pat) if ($matched =~ $pat)
{ {
$content .= ".PP\n" unless $append{$pat} =~ /^\./; $content .= ".PP\n" unless $append_match{$pat} =~ /^\./;
$content .= $append{$pat}; $content .= $append_match{$pat};
} }
} }
} }
@ -600,7 +644,6 @@ unless ($opt_no_info)
my $info_page = $opt_info || $program; my $info_page = $opt_info || $program;
$sect = _('SEE ALSO'); $sect = _('SEE ALSO');
$include{$sect} ||= '';
$include{$sect} .= ".PP\n" if $include{$sect}; $include{$sect} .= ".PP\n" if $include{$sect};
$include{$sect} .= sprintf _(<<'EOT'), $program, $program, $info_page; $include{$sect} .= sprintf _(<<'EOT'), $program, $program, $info_page;
The full documentation for The full documentation for
@ -617,6 +660,18 @@ should give you access to the complete manual.
EOT EOT
} }
# Append additional text.
while (my ($sect, $text) = each %append)
{
$include{$sect} .= $append{$sect};
}
# Replace sections.
while (my ($sect, $text) = each %replace)
{
$include{$sect} = $replace{$sect};
}
# Output header. # Output header.
print <<EOT; print <<EOT;
.\\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version. .\\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version.
@ -624,15 +679,17 @@ print <<EOT;
EOT EOT
# Section ordering. # Section ordering.
my @pre = (_('NAME'), _('SYNOPSIS'), _('DESCRIPTION'), _('OPTIONS'), my @pre = (_('NAME'), _('SYNOPSIS'), _('DESCRIPTION'), _('OPTIONS'));
_('ENVIRONMENT'), _('FILES'), _('EXAMPLES')); my @post = (_('ENVIRONMENT'), _('FILES'), _('EXAMPLES'), _('AUTHOR'),
_('REPORTING BUGS'), _('COPYRIGHT'), _('SEE ALSO'));
my @post = (_('AUTHOR'), _('REPORTING BUGS'), _('COPYRIGHT'), _('SEE ALSO')); my %filter = map { $_ => 1 } @pre, @post;
my $filter = join '|', @pre, @post;
# Output content. # Output content.
for my $sect (@pre, (grep ! /^($filter)$/o, @include), @post) my %done;
for my $sect (@pre, (grep !$filter{$_}, @sections), @post)
{ {
next if $done{$sect}++; # ignore duplicates
next unless $include{$sect};
if ($include{$sect}) if ($include{$sect})
{ {
my $quote = $sect =~ /\W/ ? '"' : ''; my $quote = $sect =~ /\W/ ? '"' : '';
@ -660,6 +717,15 @@ close STDOUT or kark N_("%s: error writing to %s (%s)"), $this_program,
exit; exit;
# Get program basename, and strip libtool "lt-" prefix if required.
sub program_basename
{
local $_ = shift;
s!.*/!!;
s/^lt-// if $opt_libtool;
$_;
}
# Call program with given option and return results. # Call program with given option and return results.
sub get_option_value sub get_option_value
{ {
@ -680,7 +746,7 @@ sub get_option_value
kark $err, $this_program, $opt, $prog, $extra; kark $err, $this_program, $opt, $prog, $extra;
} }
return $value; $value;
} }
# Convert option dashes to \- to stop nroff from hyphenating 'em, and # Convert option dashes to \- to stop nroff from hyphenating 'em, and
@ -704,3 +770,12 @@ sub convert_option
$_; $_;
} }
# Insert spacing escape characters \, and \/ before and after italic text. See
# http://www.gnu.org/software/groff/manual/html_node/Ligatures-and-Kerning.html
sub fix_italic_spacing
{
local $_ = shift;
s!\\fI(.*?)\\f([BRP])!\\fI\\,$1\\/\\f$2!g;
return $_;
}