Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pod::Man bug #1786

Closed
p5pRT opened this issue Apr 5, 2000 · 11 comments
Closed

Pod::Man bug #1786

p5pRT opened this issue Apr 5, 2000 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Apr 5, 2000

Migrated from rt.perl.org#3042 (status was 'resolved')

Searchable as RT3042$

@p5pRT
Copy link
Author

p5pRT commented Apr 5, 2000

From @millert

Pod​::Man (and thus pod2man) generates man pages with a syntax error.
Given a sequence like this​:
  C<I<FLAGS> & IPC_CREAT>

pod2man will generate​:
  \f(CW\*(C`\f(CI\s\-1FLAGS\s0\f(CW & IPC_CREAT\*(C'\fR

Note the extraneous backslash before the relative font size change.
This elicits the following warning from groff (at least in version
1.11)​: "missing closing delimiter" and the first character of the
string to be made into small caps is gobbled up, resulting in
somewhat less useful/readable manual pages. Browsing the source,
there is a comment that things in a C<> should not hae guesswork()
applied to them. Perhaps this should apply to escapes within a C<>
as well? It seems like the 'literal' nature of the escape is being
ignored when the I<> is seen (maybe keep a stack of attributes).

Perl Info

Flags:
    category=library
    severity=high

Site configuration information for perl v5.6.0:

Configured by root at Wed Apr  5 21:56:58 MDT 2000.

Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration:
  Platform:
    osname=openbsd, osvers=2.6, archname=i386-openbsd
    uname='openbsd'
    config_args='-Dopenbsd_distribution=defined -dsE'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define 
    use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
  Compiler:
    cc='cc', optimize='-O2', gccversion=2.95.2 19991024 (release)
    cppflags='-fno-strict-aliasing -I/usr/local/include'
    ccflags ='-fno-strict-aliasing -I/usr/local/include'
    stdchar='char', d_stdstdio=undef, usevfork=true
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='ld', ldflags =''
    libpth=/usr/lib
    libs=-lm -lc
    libc=/usr/lib/libc.a, so=so, useshrplib=true, libperl=libperl.so.6.0
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=define, ccdlflags=' '
    cccdlflags='-DPIC -fPIC ', lddlflags='-Bshareable '

Locally applied patches:
    


@INC for perl v5.6.0:
    /usr/libdata/perl5/i386-openbsd/5.6.0
    /usr/local/libdata/perl5/i386-openbsd/5.6.0
    /usr/libdata/perl5
    /usr/local/libdata/perl5
    /usr/local/libdata/perl5/site_perl/i386-openbsd
    /usr/libdata/perl5/site_perl/i386-openbsd
    /usr/local/libdata/perl5/site_perl
    /usr/libdata/perl5/site_perl
    /usr/lib/perl5/site_perl
    .


Environment for perl v5.6.0:
    HOME=/home/millert
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/millert/bin/OpenBSD.i386:/home/millert/bin:/home/millert/bin/scripts:/usr/local/gnu/bin:/usr/local/bin:/usr/local/sbin:/usr/local/etc:/usr/local/rcs/bin:/usr/local/mh/bin:/usr/local/news/bin:/usr/local/emacs/bin:/usr/local/netpbm/bin:/usr/local/mtools/bin:/usr/local/netscape/bin:/usr/local/ghostscript/bin:/usr/local/X.V11R5/bin:/usr/local/X.V11R6/bin:/usr/local/frame/bin:/usr/local/teTeX/bin:/usr/local/cvs-1.10.1/bin:/usr/local/games/bin:/usr/local/archivers/bin:/usr/local/ssh/bin:/usr/local/skey/bin:/usr/local/cdrecord/bin:/bin:/sbin:/usr/games:/usr/bin:/usr/sbin:/usr/etc:/etc:/usr/X11/bin/.:/usr/X11R6/bin/.:/usr/local/bin/.:/usr/obj/bin/.:/usr/src/bin/.
    PERL_BADLANG (unset)
    SHELL=/usr/local/bin/tcsh

@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2000

From [Unknown Contact. See original ticket]

Todd C Miller <Todd.Miller@​courtesan.com> writes​:

Pod​::Man (and thus pod2man) generates man pages with a syntax error.
Given a sequence like this​:
C<I<FLAGS> & IPC_CREAT>

pod2man will generate​:
\f(CW\*(C`\f(CI\s\-1FLAGS\s0\f(CW & IPC_CREAT\*(C'\fR

That was an annoying one. Thanks for the catch. Could you try this patch
and let me know if it fixes the problem?

diff -u -r1.2 Man.pm
--- Man.pm 2000/03/19 07​:30​:13 1.2
+++ Man.pm 2000/04/09 03​:37​:39
@​@​ -550,6 +550,21 @​@​
  return bless \ "$tmp", 'Pod​::Man​::String';
  }

+ # C<> needs to fix hyphens and underscores but can't apply guesswork and
+ # can't just apply those fixes to the entire string, since then it might
+ # mess up the results of guesswork on substrings. So we do this
+ # somewhat roundabout way of handling it.
+ if ($command eq 'C') {
+ my @​children = $seq->parse_tree ()->children;
+ for (@​children) {
+ unless (ref) {
+ s/-/\\-/g;
+ s/__/_\\|_/g;
+ }
+ }
+ $seq->parse_tree ()->children (@​children);
+ }
+
  # C<>, L<>, X<>, and E<> don't apply guesswork to their contents.
  local $_ = $self->collapse ($seq->parse_tree, $command =~ /^[CELX]$/);

@​@​ -576,8 +591,6 @​@​
  } elsif ($command eq 'I') {
  return bless \ ('\f(IS' . $_ . '\f(IE'), 'Pod​::Man​::String';
  } elsif ($command eq 'C') {
- s/-/\\-/g;
- s/__/_\\|_/g;
  return bless \ ('\f(FS\*(C`' . $_ . "\\*(C'\\f(FE"),
  'Pod​::Man​::String';
  }

@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2000

From @millert

Yup, seems to do the trick.

- todd

In message <ylr9cgaqll.fsf@​windlord.stanford.edu>
  so spake Russ Allbery (rra)​:

That was an annoying one. Thanks for the catch. Could you try this patch
and let me know if it fixes the problem?

diff -u -r1.2 Man.pm
--- Man.pm 2000/03/19 07​:30​:13 1.2
+++ Man.pm 2000/04/09 03​:37​:39
@​@​ -550,6 +550,21 @​@​
return bless \ "$tmp", 'Pod​::Man​::String';
}

+ # C<> needs to fix hyphens and underscores but can't apply guesswork and
+ # can't just apply those fixes to the entire string, since then it might
+ # mess up the results of guesswork on substrings. So we do this
+ # somewhat roundabout way of handling it.
+ if ($command eq 'C') {
+ my @​children = $seq->parse_tree ()->children;
+ for (@​children) {
+ unless (ref) {
+ s/-/\\-/g;
+ s/__/_\\|_/g;
+ }
+ }
+ $seq->parse_tree ()->children (@​children);
+ }
+
# C<>, L<>, X<>, and E<> don't apply guesswork to their contents.
local $_ = $self->collapse ($seq->parse_tree, $command =~ /^[CELX]$/);

@​@​ -576,8 +591,6 @​@​
} elsif ($command eq 'I') {
return bless \ ('\f(IS' . $_ . '\f(IE'), 'Pod​::Man​::String';
} elsif ($command eq 'C') {
- s/-/\\-/g;
- s/__/_\\|_/g;
return bless \ ('\f(FS\*(C`' . $_ . "\\*(C'\\f(FE"),
'Pod​::Man​::String';
}

--
Russ Allbery (rra@​stanford.edu) <http​://www.eyrie.org/~eagle/>

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2000

From @millert

Looks like there is still a problem. If you use​:
  C<-u>
Pod​::Man will now output​:
  \f(CW\*(C`\-u\*(C'\fR
which, when formatted by nroff, still has the backslash in place.
Now granted, it makes more sense to us B<-u> (which doesn't have this
problem), but that's not the point :-) For a test case, the following
suffices​:

=pod

=head1 SYNOPSIS

foo C<-v>

=cut

- todd

In message <ylr9cgaqll.fsf@​windlord.stanford.edu>
  so spake Russ Allbery (rra)​:

That was an annoying one. Thanks for the catch. Could you try this patch
and let me know if it fixes the problem?

diff -u -r1.2 Man.pm
--- Man.pm 2000/03/19 07​:30​:13 1.2
+++ Man.pm 2000/04/09 03​:37​:39
@​@​ -550,6 +550,21 @​@​
return bless \ "$tmp", 'Pod​::Man​::String';
}

+ # C<> needs to fix hyphens and underscores but can't apply guesswork and
+ # can't just apply those fixes to the entire string, since then it might
+ # mess up the results of guesswork on substrings. So we do this
+ # somewhat roundabout way of handling it.
+ if ($command eq 'C') {
+ my @​children = $seq->parse_tree ()->children;
+ for (@​children) {
+ unless (ref) {
+ s/-/\\-/g;
+ s/__/_\\|_/g;
+ }
+ }
+ $seq->parse_tree ()->children (@​children);
+ }
+
# C<>, L<>, X<>, and E<> don't apply guesswork to their contents.
local $_ = $self->collapse ($seq->parse_tree, $command =~ /^[CELX]$/);

@​@​ -576,8 +591,6 @​@​
} elsif ($command eq 'I') {
return bless \ ('\f(IS' . $_ . '\f(IE'), 'Pod​::Man​::String';
} elsif ($command eq 'C') {
- s/-/\\-/g;
- s/__/_\\|_/g;
return bless \ ('\f(FS\*(C`' . $_ . "\\*(C'\\f(FE"),
'Pod​::Man​::String';
}

--
Russ Allbery (rra@​stanford.edu) <http​://www.eyrie.org/~eagle/>

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2000

From [Unknown Contact. See original ticket]

Todd C Miller <Todd.Miller@​courtesan.com> writes​:

Looks like there is still a problem. If you use​:
C<-u>
Pod​::Man will now output​:
\f(CW\*(C`\-u\*(C'\fR
which, when formatted by nroff, still has the backslash in place.
Now granted, it makes more sense to us B<-u> (which doesn't have this
problem), but that's not the point :-) For a test case, the following
suffices​:

Which backslash?

windlord​:~> nroff -man - | uniq
\f(CW\*(C`\-u\*(C'\fR
-u

That looks exactly right to me.... Maybe your nroff is broken?

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2000

From @millert

In message <ylaeilpu23.fsf@​windlord.stanford.edu>
  so spake Russ Allbery (rra)​:

Which backslash?

windlord​:~> nroff -man - | uniq
\f(CW\*(C`\-u\*(C'\fR
-u

That looks exactly right to me.... Maybe your nroff is broken?

Sorry, that must have been a mispaste. What pod2man produces is​:
  \f(CW\*(C`\e-u\*(C'\fR

which does have the backslash in the formatted output. The
"\\" is replaced by "\\e" by verbatim().

- todd

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2000

From [Unknown Contact. See original ticket]

Todd C Miller <Todd.Miller@​courtesan.com> writes​:

Sorry, that must have been a mispaste. What pod2man produces is​:
\f(CW\*(C`\e-u\*(C'\fR

which does have the backslash in the formatted output. The
"\\" is replaced by "\\e" by verbatim().

Ah! I see.

Brad, this bit of code looks odd to me, from Pod​::InputObjects in
Pod​::Parser 1.13​:

sub children {
  my $self = shift;
  if (@​_ > 0) {
  @​{ $self } = (@​_ == 1 and ref $_[0]) ? ${ @​_ } : @​_;
  }
  return @​{ $self };
}

Shouldn't that be "(@​_ == 1 and ref $_[0]) ? @​{ @​_ } : @​_"? I believe
the current code will evaluate @​_ in a scalar context and then always try
to dereference "1" as a scalar reference if @​_ == 1.

Todd, try this patch. I wasn't properly tagging the pre-processed text
blocks inside a C<> sequence.

--- Man.pm 2000/04/09 09​:23​:54 1.3
+++ Man.pm 2000/04/24 00​:13​:49
@​@​ -555,14 +555,20 @​@​
  # mess up the results of guesswork on substrings. So we do this
  # somewhat roundabout way of handling it.
  if ($command eq 'C') {
- my @​children = $seq->parse_tree ()->children;
- for (@​children) {
- unless (ref) {
- s/-/\\-/g;
- s/__/_\\|_/g;
+ my @​children = map {
+ my $block = $_;
+ if (ref $block) {
+ $block;
+ } else {
+ $block =~ s/-/\\-/g;
+ $block =~ s/__/_\\|_/g;
+ bless \ "$block", 'Pod​::Man​::String';
  }
- }
- $seq->parse_tree ()->children (@​children);
+ } $seq->parse_tree ()->children;
+
+ # The extra empty block is to work around a bug in the children
+ # method in Pod​::Parser 1.13.
+ $seq->parse_tree ()->children ('', @​children);
  }

  # C<>, L<>, X<>, and E<> don't apply guesswork to their contents.

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2000

From @millert

That has some other problems. For instance, compare the formatted output of
pod2man on perlfaq.pod before and after this patch. You end up with an
errant character at the end of some lines which results in weird
formatting glitches like the following​:

- o How can I make `\w' match national character sets?
+ o How can I make `744

And nroff (actually groff) complains about things like​:
  <standard input>​:580​: normal or special character expected (got a space)

However, fixing the children() sub in Pod​::Parser as you suggest
and applying your patch w/o the empty block workaround *does* behave
better, although it looks like nroff is trying to be smart about
splitting on hyphens so you get the following​:

- o How can I match a locale-smart version of
- `/[a\-zA\-Z]/'?
+ o How can I match a locale-smart version of `/[a-zA-
+ Z]/'?

This is because the '-' is not escaped with a backslash any more.
We do want a baclslash, just not a \e.

- todd

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2000

From [Unknown Contact. See original ticket]

Todd C Miller <Todd.Miller@​courtesan.com> writes​:

That has some other problems. For instance, compare the formatted
output of pod2man on perlfaq.pod before and after this patch. You end
up with an errant character at the end of some lines which results in
weird formatting glitches like the following​:

- o How can I make `\w' match national character sets?
+ o How can I make `744

*grumble*

Okay, this is good, actually. It made me take a close look at this and
realize that I was doing these fixups in completely the wrong place. Try
this patch against a virgin 5.6.0 Man.pm; I see no differences in the
output when run against perlfaq.pod between this and the 1.01 version, and
it should fix the bugs with hyphens. It also has the plus of not needing
to call the children() method at all.

--- Man.pm 2000/03/19 07​:30​:13 1.2
+++ Man.pm 2000/04/24 02​:13​:40
@​@​ -1,5 +1,5 @​@​
# Pod​::Man -- Convert POD data to formatted *roff input.
-# $Id​: Man.pm,v 1.2 2000/03/19 07​:30​:13 eagle Exp $
+# $Id​: Man.pm,v 1.3 2000/04/09 09​:23​:54 eagle Exp $
#
# Copyright 1999, 2000 by Russ Allbery <rra@​stanford.edu>
#
@​@​ -38,7 +38,7 @​@​
# Perl core and too many things could munge CVS magic revision strings.
# This number should ideally be the same as the CVS revision in podlators,
# however.
-$VERSION = 1.02;
+$VERSION = 1.04;

############################################################################
@​@​ -550,8 +550,11 @​@​
  return bless \ "$tmp", 'Pod​::Man​::String';
  }

- # C<>, L<>, X<>, and E<> don't apply guesswork to their contents.
- local $_ = $self->collapse ($seq->parse_tree, $command =~ /^[CELX]$/);
+ # C<>, L<>, X<>, and E<> don't apply guesswork to their contents. C<>
+ # needs some additional special handling.
+ my $literal = ($command =~ /^[CELX]$/);
+ $literal++ if $command eq 'C';
+ local $_ = $self->collapse ($seq->parse_tree, $literal);

  # Handle E<> escapes.
  if ($command eq 'E') {
@​@​ -576,8 +579,6 @​@​
  } elsif ($command eq 'I') {
  return bless \ ('\f(IS' . $_ . '\f(IE'), 'Pod​::Man​::String';
  } elsif ($command eq 'C') {
- s/-/\\-/g;
- s/__/_\\|_/g;
  return bless \ ('\f(FS\*(C`' . $_ . "\\*(C'\\f(FE"),
  'Pod​::Man​::String';
  }
@​@​ -830,8 +831,10 @​@​
# text (not call guesswork on it), and returns the concatenation of all of
# the text strings in that parse tree. If the literal flag isn't true,
# guesswork() will be called on all plain scalars in the parse tree.
-# Assumes that everything in the parse tree is either a scalar or a
-# reference to a scalar.
+# Otherwise, just escape backslashes in the normal case. If collapse is
+# being called on a C<> sequence, literal is set to 2, and we do some
+# additional cleanup. Assumes that everything in the parse tree is either a
+# scalar or a reference to a scalar.
sub collapse {
  my ($self, $ptree, $literal) = @​_;
  if ($literal) {
@​@​ -840,6 +843,8 @​@​
  $$_;
  } else {
  s/\\/\\e/g;
+ s/-/\\-/g if $literal > 1;
+ s/__/_\\|_/g if $literal > 1;
  $_;
  }
  } $ptree->children);

@p5pRT
Copy link
Author

p5pRT commented Apr 23, 2000

From @millert

Looks good to me. Both C<-i> and C<I<FOO BAR>> act the way they ought.

- todd

In message <yl66t86y7p.fsf@​windlord.stanford.edu>
  so spake Russ Allbery (rra)​:

Todd C Miller <Todd.Miller@​courtesan.com> writes​:

That has some other problems. For instance, compare the formatted
output of pod2man on perlfaq.pod before and after this patch. You end
up with an errant character at the end of some lines which results in
weird formatting glitches like the following​:

- o How can I make `\w' match national character sets?
+ o How can I make `744

*grumble*

Okay, this is good, actually. It made me take a close look at this and
realize that I was doing these fixups in completely the wrong place. Try
this patch against a virgin 5.6.0 Man.pm; I see no differences in the
output when run against perlfaq.pod between this and the 1.01 version, and
it should fix the bugs with hyphens. It also has the plus of not needing
to call the children() method at all.

--- Man.pm 2000/03/19 07​:30​:13 1.2
+++ Man.pm 2000/04/24 02​:13​:40
@​@​ -1,5 +1,5 @​@​
# Pod​::Man -- Convert POD data to formatted *roff input.
-# $Id​: Man.pm,v 1.2 2000/03/19 07​:30​:13 eagle Exp $
+# $Id​: Man.pm,v 1.3 2000/04/09 09​:23​:54 eagle Exp $
#
# Copyright 1999, 2000 by Russ Allbery <rra@​stanford.edu>
#
@​@​ -38,7 +38,7 @​@​
# Perl core and too many things could munge CVS magic revision strings.
# This number should ideally be the same as the CVS revision in podlators,
# however.
-$VERSION = 1.02;
+$VERSION = 1.04;

############################################################################
@​@​ -550,8 +550,11 @​@​
return bless \ "$tmp", 'Pod​::Man​::String';
}

- # C<>, L<>, X<>, and E<> don't apply guesswork to their contents.
- local $_ = $self->collapse ($seq->parse_tree, $command =~ /^[CELX]$/);
+ # C<>, L<>, X<>, and E<> don't apply guesswork to their contents. C<>
+ # needs some additional special handling.
+ my $literal = ($command =~ /^[CELX]$/);
+ $literal++ if $command eq 'C';
+ local $_ = $self->collapse ($seq->parse_tree, $literal);

 \# Handle E\<> escapes\.
 if \($command eq 'E'\) \{

@​@​ -576,8 +579,6 @​@​
} elsif ($command eq 'I') {
  return bless \ ('\f(IS' . $_ . '\f(IE'), 'Pod​::Man​::String';
} elsif ($command eq 'C') {
- s/-/\\-/g;
- s/__/_\\|_/g;
return bless \ ('\f(FS\*(C`' . $_ . "\\*(C'\\f(FE"),
'Pod​::Man​::String';
}
@​@​ -830,8 +831,10 @​@​
# text (not call guesswork on it), and returns the concatenation of all of
# the text strings in that parse tree. If the literal flag isn't true,
# guesswork() will be called on all plain scalars in the parse tree.
-# Assumes that everything in the parse tree is either a scalar or a
-# reference to a scalar.
+# Otherwise, just escape backslashes in the normal case. If collapse is
+# being called on a C<> sequence, literal is set to 2, and we do some
+# additional cleanup. Assumes that everything in the parse tree is either a
+# scalar or a reference to a scalar.
sub collapse {
my ($self, $ptree, $literal) = @​_;
if ($literal) {
@​@​ -840,6 +843,8 @​@​
$$_;
} else {
s/\\/\\e/g;
+ s/-/\\-/g if $literal > 1;
+ s/__/_\\|_/g if $literal > 1;
$_;
}
} $ptree->children);

--
Russ Allbery (rra@​stanford.edu) <http​://www.eyrie.org/~eagle/>

@p5pRT
Copy link
Author

p5pRT commented Apr 24, 2000

From [Unknown Contact. See original ticket]

Russ Allbery <rra@​stanford.edu> wrote

Brad, this bit of code looks odd to me, from Pod​::InputObjects in
Pod​::Parser 1.13​:

sub children {
my $self = shift;
if (@​_ > 0) {
@​{ $self } = (@​_ == 1 and ref $_[0]) ? ${ @​_ } : @​_;
}
return @​{ $self };
}

Shouldn't that be "(@​_ == 1 and ref $_[0]) ? @​{ @​_ } : @​_"?

Do you *really* want to operate on @​1 ? :-)

Perhaps you mean "(@​_ == 1 and ref $_[0]) ? @​{$_[0}} : @​_" ?

Mike Guy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant