- (dtucker) [CREDITS Makefile.in configure.ac mdoc2man.awk mdoc2man.pl]

Replace mdoc2man.pl with mdoc2man.awk, provided by Peter Stuge.
This commit is contained in:
Darren Tucker 2003-09-07 12:34:54 +10:00
parent 7c600f24a4
commit 167bd9cfef
6 changed files with 350 additions and 597 deletions

View File

@ -70,6 +70,7 @@ Pavel Kankovsky <peak@argo.troja.mff.cuni.cz> - Security fixes
Pavel Troller <patrol@omni.sinus.cz> - Bugfixes
Pekka Savola <pekkas@netcore.fi> - Bugfixes
Peter Kocks <peter.kocks@baygate.com> - Makefile fixes
Peter Stuge <stuge@cdy.org> - mdoc2man.awk script
Phil Hands <phil@hands.com> - Debian scripts, assorted patches
Phil Karn <karn@ka9q.ampr.org> - Autoconf fixes
Philippe WILLEM <Philippe.WILLEM@urssaf.fr> - Bugfixes
@ -93,5 +94,5 @@ Apologies to anyone I have missed.
Damien Miller <djm@mindrot.org>
$Id: CREDITS,v 1.73 2003/08/11 13:03:53 dtucker Exp $
$Id: CREDITS,v 1.74 2003/09/07 02:34:54 dtucker Exp $

View File

@ -8,6 +8,8 @@
- (dtucker) [regress/sftp-cmds.sh] Skip quoted file test on Cygwin.
- (dtucker) [openbsd-compat/xcrypt.c] #elsif -> #elif
- (dtucker) [acconfig.h] Typo.
- (dtucker) [CREDITS Makefile.in configure.ac mdoc2man.awk mdoc2man.pl]
Replace mdoc2man.pl with mdoc2man.awk, provided by Peter Stuge.
20030906
- (dtucker) [acconfig.h configure.ac uidswap.c] Prefer setuid/setgid on AIX.
@ -1035,4 +1037,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au
$Id: ChangeLog,v 1.2968 2003/09/07 01:37:27 dtucker Exp $
$Id: ChangeLog,v 1.2969 2003/09/07 02:34:54 dtucker Exp $

View File

@ -1,4 +1,4 @@
# $Id: Makefile.in,v 1.246 2003/09/05 01:35:52 dtucker Exp $
# $Id: Makefile.in,v 1.247 2003/09/07 02:34:54 dtucker Exp $
# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
@ -46,6 +46,7 @@ LIBS=@LIBS@
LIBPAM=@LIBPAM@
LIBWRAP=@LIBWRAP@
AR=@AR@
AWK=@AWK@
RANLIB=@RANLIB@
INSTALL=@INSTALL@
PERL=@PERL@
@ -173,7 +174,7 @@ $(MANPAGES): $(MANPAGES_IN)
manpage=$(srcdir)/`echo $@ | sed 's/\.out$$//'`; \
fi; \
if test "$(MANTYPE)" = "man"; then \
$(FIXPATHSCMD) $${manpage} | $(PERL) $(srcdir)/mdoc2man.pl > $@; \
$(FIXPATHSCMD) $${manpage} | $(AWK) -f $(srcdir)/mdoc2man.awk > $@; \
else \
$(FIXPATHSCMD) $${manpage} > $@; \
fi

View File

@ -1,4 +1,4 @@
# $Id: configure.ac,v 1.144 2003/09/06 06:44:39 dtucker Exp $
# $Id: configure.ac,v 1.145 2003/09/07 02:34:54 dtucker Exp $
AC_INIT
AC_CONFIG_SRCDIR([ssh.c])
@ -9,6 +9,7 @@ AC_CANONICAL_HOST
AC_C_BIGENDIAN
# Checks for programs.
AC_PROG_AWK
AC_PROG_CPP
AC_PROG_RANLIB
AC_PROG_INSTALL

340
mdoc2man.awk Normal file
View File

@ -0,0 +1,340 @@
#!/usr/bin/awk
#
# Version history:
# v3, I put the program under a proper license
# Dan Nelson <dnelson@allantgroup.com> added .An, .Aq and fixed a typo
# v2, fixed to work on GNU awk --posix and MacOS X
# v1, first attempt, didn't work on MacOS X
#
# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
BEGIN {
optlist=0
oldoptlist=0
nospace=0
synopsis=0
reference=0
block=0
ext=0
extopt=0
literal=0
prenl=0
line=""
}
function wtail() {
retval=""
while(w<nwords) {
if(length(retval))
retval=retval OFS
retval=retval words[++w]
}
return retval
}
function add(str) {
for(;prenl;prenl--)
line=line "\n"
line=line str
}
! /^\./ {
for(;prenl;prenl--)
print ""
print
if(literal)
print ".br"
next
}
/^\.\\"/ { next }
{
option=0
parens=0
angles=0
sub("^\\.","")
nwords=split($0,words)
for(w=1;w<=nwords;w++) {
skip=0
if(match(words[w],"^Li|Pf$")) {
skip=1
} else if(match(words[w],"^Xo$")) {
skip=1
ext=1
if(length(line)&&!(match(line," $")||prenl))
add(OFS)
} else if(match(words[w],"^Xc$")) {
skip=1
ext=0
if(!extopt)
prenl++
w=nwords
} else if(match(words[w],"^Bd$")) {
skip=1
if(match(words[w+1],"-literal")) {
literal=1
prenl++
w=nwords
}
} else if(match(words[w],"^Ed$")) {
skip=1
literal=0
} else if(match(words[w],"^Ns$")) {
skip=1
if(!nospace)
nospace=1
sub(" $","",line)
} else if(match(words[w],"^No$")) {
skip=1
sub(" $","",line)
add(words[++w])
} else if(match(words[w],"^Dq$")) {
skip=1
add("``")
add(words[++w])
while(w<nwords&&!match(words[w+1],"^[\\.,]"))
add(OFS words[++w])
add("''")
if(!nospace&&match(words[w+1],"^[\\.,]"))
nospace=1
} else if(match(words[w],"^Sq|Ql$")) {
skip=1
add("`" words[++w] "'")
if(!nospace&&match(words[w+1],"^[\\.,]"))
nospace=1
} else if(match(words[w],"^Oo$")) {
skip=1
extopt=1
if(!nospace)
nospace=1
add("[")
} else if(match(words[w],"^Oc$")) {
skip=1
extopt=0
add("]")
}
if(!skip) {
if(!nospace&&length(line)&&!(match(line," $")||prenl))
add(OFS)
if(nospace==1)
nospace=0
}
if(match(words[w],"^Dd$")) {
date=wtail()
next
} else if(match(words[w],"^Dt$")) {
id=wtail()
next
} else if(match(words[w],"^Os$")) {
add(".TH " id " \"" date "\" \"" wtail() "\"")
} else if(match(words[w],"^Sh$")) {
add(".SH")
synopsis=match(words[w+1],"SYNOPSIS")
} else if(match(words[w],"^Xr$")) {
add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w])
} else if(match(words[w],"^Rs$")) {
split("",refauthors)
nrefauthors=0
reftitle=""
refissue=""
refdate=""
refopt=""
reference=1
next
} else if(match(words[w],"^Re$")) {
prenl++
for(i=nrefauthors-1;i>0;i--) {
add(refauthors[i])
if(i>1)
add(", ")
}
if(nrefauthors>1)
add(" and ")
add(refauthors[0] ", \\fI" reftitle "\\fP")
if(length(refissue))
add(", " refissue)
if(length(refdate))
add(", " refdate)
if(length(refopt))
add(", " refopt)
add(".")
reference=0
} else if(reference) {
if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
if(match(words[w],"^%T$")) {
reftitle=wtail()
sub("^\"","",reftitle)
sub("\"$","",reftitle)
}
if(match(words[w],"^%N$")) { refissue=wtail() }
if(match(words[w],"^%D$")) { refdate=wtail() }
if(match(words[w],"^%O$")) { refopt=wtail() }
} else if(match(words[w],"^Nm$")) {
if(synopsis) {
add(".br")
prenl++
}
n=words[++w]
if(!length(name))
name=n
if(!length(n))
n=name
add("\\fB" n "\\fP")
if(!nospace&&match(words[w+1],"^[\\.,]"))
nospace=1
} else if(match(words[w],"^Nd$")) {
add("\\- " wtail())
} else if(match(words[w],"^Fl$")) {
add("\\fB\\-" words[++w] "\\fP")
if(!nospace&&match(words[w+1],"^[\\.,]"))
nospace=1
} else if(match(words[w],"^Ar$")) {
add("\\fI")
if(w==nwords)
add("file ...\\fP")
else {
add(words[++w] "\\fP")
while(match(words[w+1],"^\\|$"))
add(OFS words[++w] " \\fI" words[++w] "\\fP")
}
if(!nospace&&match(words[w+1],"^[\\.,]"))
nospace=1
} else if(match(words[w],"^Cm$")) {
add("\\fB" words[++w] "\\fP")
while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
add(words[++w])
} else if(match(words[w],"^Op$")) {
option=1
if(!nospace)
nospace=1
add("[")
} else if(match(words[w],"^Pp$")) {
prenl++
} else if(match(words[w],"^An$")) {
prenl++
} else if(match(words[w],"^Ss$")) {
add(".SS")
} else if(match(words[w],"^Pa$")&&!option) {
add("\\fI")
w++
if(match(words[w],"^\\."))
add("\\&")
add(words[w] "\\fP")
while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
add(words[++w])
} else if(match(words[w],"^Dv$")) {
add(".BR")
} else if(match(words[w],"^Em|Ev$")) {
add(".IR")
} else if(match(words[w],"^Pq$")) {
add("(")
nospace=1
parens=1
} else if(match(words[w],"^Aq$")) {
add("<")
nospace=1
angles=1
} else if(match(words[w],"^S[xy]$")) {
add(".B " wtail())
} else if(match(words[w],"^Ic$")) {
plain=1
add("\\fB")
while(w<nwords) {
w++
if(match(words[w],"^Op$")) {
w++
add("[")
words[nwords]=words[nwords] "]"
}
if(match(words[w],"^Ar$")) {
add("\\fI" words[++w] "\\fP")
} else if(match(words[w],"^[\\.,]")) {
sub(" $","",line)
if(plain) {
add("\\fP")
plain=0
}
add(words[w])
} else {
if(!plain) {
add("\\fB")
plain=1
}
add(words[w])
}
if(!nospace)
add(OFS)
}
sub(" $","",line)
if(plain)
add("\\fP")
} else if(match(words[w],"^Bl$")) {
oldoptlist=optlist
if(match(words[w+1],"-bullet"))
optlist=1
else if(match(words[w+1],"-enum")) {
optlist=2
enum=0
} else if(match(words[w+1],"-tag"))
optlist=3
else if(match(words[w+1],"-item"))
optlist=4
else if(match(words[w+1],"-bullet"))
optlist=1
w=nwords
} else if(match(words[w],"^El$")) {
optlist=oldoptlist
} else if(match(words[w],"^It$")&&optlist) {
if(optlist==1)
add(".IP \\(bu")
else if(optlist==2)
add(".IP " ++enum ".")
else if(optlist==3) {
add(".TP")
prenl++
if(match(words[w+1],"^Pa|Ev$")) {
add(".B")
w++
}
} else if(optlist==4)
add(".IP")
} else if(match(words[w],"^Sm$")) {
if(match(words[w+1],"off"))
nospace=2
else if(match(words[w+1],"on"))
nospace=0
w++
} else if(!skip) {
add(words[w])
}
}
if(match(line,"^\\.[^a-zA-Z]"))
sub("^\\.","",line)
if(parens)
add(")")
if(angles)
add(">")
if(option)
add("]")
if(ext&&!extopt&&!match(line," $"))
add(OFS)
if(!ext&&!extopt&&length(line)) {
print line
prenl=0
line=""
}
}

View File

@ -1,592 +0,0 @@
#!/usr/bin/perl
###
### Quick usage: mdoc2man.pl < mdoc_manpage.8 > man_manpage.8
###
###
### Copyright (c) 2001 University of Illinois Board of Trustees
### Copyright (c) 2001 Mark D. Roth
### All rights reserved.
###
### Redistribution and use in source and binary forms, with or without
### modification, are permitted provided that the following conditions
### are met:
### 1. Redistributions of source code must retain the above copyright
### notice, this list of conditions and the following disclaimer.
### 2. Redistributions in binary form must reproduce the above copyright
### notice, this list of conditions and the following disclaimer in the
### documentation and/or other materials provided with the distribution.
### 3. All advertising materials mentioning features or use of this software
### must display the following acknowledgement:
### This product includes software developed by the University of
### Illinois at Urbana, and their contributors.
### 4. The University nor the names of their
### contributors may be used to endorse or promote products derived from
### this software without specific prior written permission.
###
### THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND
### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
### ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE
### FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
### DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
### OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
### HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
### LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
### OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
### SUCH DAMAGE.
###
use strict;
my ($name, $date, $id);
my ($line);
my ($optlist, $oldoptlist, $nospace, $enum, $synopsis);
my ($reference, $block, $ext, $extopt, $literal);
my (@refauthors, $reftitle, $refissue, $refdate, $refopt);
$optlist = 0; ### 1 = bullet, 2 = enum, 3 = tag, 4 = item
$oldoptlist = 0;
$nospace = 0;
$synopsis = 0;
$reference = 0;
$block = 0;
$ext = 0;
$extopt = 0;
$literal = 0;
while ($line = <STDIN>)
{
if ($line !~ /^\./)
{
print $line;
print ".br\n"
if ($literal);
next;
}
$line =~ s/^\.//;
next
if ($line =~ m/\\"/);
$line = ParseMacro($line);
print($line)
if (defined $line);
}
sub ParseMacro # ($line)
{
my ($line) = @_;
my (@words, $retval, $option, $parens);
@words = split(/\s+/, $line);
$retval = '';
$option = 0;
$parens = 0;
# print('@words = ', scalar(@words), ': ', join(' ', @words), "\n");
while ($_ = shift @words)
{
# print "WORD: $_\n";
next
if (/^(Li|Pf)$/);
if (/^Xo$/)
{
$ext = 1;
$retval .= ' '
if ($retval ne '' && $retval !~ m/[\n ]$/);
next;
}
if (/^Xc$/)
{
$ext = 0;
$retval .= "\n"
if (! $extopt);
last;
}
if (/^Bd$/)
{
$literal = 1
if ($words[0] eq '-literal');
$retval .= "\n";
last;
}
if (/^Ed$/)
{
$literal = 0;
last;
}
if (/^Ns$/)
{
$nospace = 1
if (! $nospace);
$retval =~ s/ $//;
next;
}
if (/^No$/)
{
$retval =~ s/ $//;
$retval .= shift @words;
next;
}
if (/^Dq$/)
{
$retval .= '``';
do
{
$retval .= (shift @words) . ' ';
}
while (@words > 0 && $words[0] !~ m/^[\.,]/);
$retval =~ s/ $//;
$retval .= '\'\'';
$nospace = 1
if (! $nospace && $words[0] =~ m/^[\.,]/);
next;
}
if (/^(Sq|Ql)$/)
{
$retval .= '`' . (shift @words) . '\'';
$nospace = 1
if (! $nospace && $words[0] =~ m/^[\.,]/);
next;
}
# if (/^Ic$/)
# {
# $retval .= '\\fB' . shift(@words) . '\\fP';
# next;
# }
if (/^Oo$/)
{
# $retval .= "[\\c\n";
$extopt = 1;
$nospace = 1
if (! $nospace);
$retval .= '[';
next;
}
if (/^Oc$/)
{
$extopt = 0;
$retval .= ']';
next;
}
$retval .= ' '
if (! $nospace && $retval ne '' && $retval !~ m/[\n ]$/);
$nospace = 0
if ($nospace == 1);
if (/^Dd$/)
{
$date = join(' ', @words);
return undef;
}
if (/^Dt$/)
{
$id = join(' ', @words);
return undef;
}
if (/^Os$/)
{
$retval .= '.TH '
. $id
. " \"$date\" \""
. join(' ', @words)
. "\"";
last;
}
if (/^Sh$/)
{
$retval .= '.SH';
if ($words[0] eq 'SYNOPSIS')
{
$synopsis = 1;
}
else
{
$synopsis = 0;
}
next;
}
if (/^Xr$/)
{
$retval .= '\\fB' . (shift @words) .
'\\fP(' . (shift @words) . ')'
. (shift @words);
last;
}
if (/^Rs/)
{
@refauthors = ();
$reftitle = '';
$refissue = '';
$refdate = '';
$refopt = '';
$reference = 1;
last;
}
if (/^Re/)
{
$retval .= "\n";
# authors
while (scalar(@refauthors) > 1)
{
$retval .= shift(@refauthors) . ', ';
}
$retval .= 'and '
if ($retval ne '');
$retval .= shift(@refauthors);
# title
$retval .= ', \\fI' . $reftitle . '\\fP';
# issue
$retval .= ', ' . $refissue
if ($refissue ne '');
# date
$retval .= ', ' . $refdate
if ($refdate ne '');
# optional info
$retval .= ', ' . $refopt
if ($refopt ne '');
$retval .= ".\n";
$reference = 0;
last;
}
if ($reference)
{
if (/^%A$/)
{
unshift(@refauthors, join(' ', @words));
last;
}
if (/^%T$/)
{
$reftitle = join(' ', @words);
$reftitle =~ s/^"//;
$reftitle =~ s/"$//;
last;
}
if (/^%N$/)
{
$refissue = join(' ', @words);
last;
}
if (/^%D$/)
{
$refdate = join(' ', @words);
last;
}
if (/^%O$/)
{
$refopt = join(' ', @words);
last;
}
}
if (/^Nm$/)
{
my $n = $name;
$n = shift @words
if (@words > 0);
$name = $n unless $name;
$retval .= ".br\n"
if ($synopsis);
$retval .= "\\fB$n\\fP";
$nospace = 1
if (! $nospace && $words[0] =~ m/^[\.,]/);
next;
}
if (/^Nd$/)
{
$retval .= '\\-';
next;
}
if (/^Fl$/)
{
$retval .= '\\fB\\-' . (shift @words) . '\\fP';
$nospace = 1
if (! $nospace && $words[0] =~ m/^[\.,]/);
next;
}
if (/^Ar$/)
{
$retval .= '\\fI';
if (! defined $words[0])
{
$retval .= 'file ...\\fP';
}
else
{
$retval .= shift(@words) . '\\fP';
while ($words[0] eq '|')
{
$retval .= ' ' . shift(@words);
$retval .= ' \\fI' . shift(@words);
$retval .= '\\fP';
}
}
$nospace = 1
if (! $nospace && $words[0] =~ m/^[\.,]/);
next;
}
if (/^Cm$/)
{
$retval .= '\\fB' . (shift @words) . '\\fP';
while ($words[0] =~ m/^[\.,:)]$/)
{
$retval .= shift(@words);
}
next;
}
if (/^Op$/)
{
$option = 1;
$nospace = 1
if (! $nospace);
$retval .= '[';
# my $tmp = pop(@words);
# $tmp .= ']';
# push(@words, $tmp);
next;
}
if (/^Pp$/)
{
$retval .= "\n";
next;
}
if (/^Ss$/)
{
$retval .= '.SS';
next;
}
if (/^Pa$/ && ! $option)
{
$retval .= '\\fI';
$retval .= '\\&'
if ($words[0] =~ m/^\./);
$retval .= (shift @words) . '\\fP';
while ($words[0] =~ m/^[\.,:;)]$/)
{
$retval .= shift(@words);
}
# $nospace = 1
# if (! $nospace && $words[0] =~ m/^[\.,:)]/);
next;
}
if (/^Dv$/)
{
$retval .= '.BR';
next;
}
if (/^(Em|Ev)$/)
{
$retval .= '.IR';
next;
}
if (/^Pq$/)
{
$retval .= '(';
$nospace = 1;
$parens = 1;
next;
}
if (/^(S[xy])$/)
{
$retval .= '.B ' . join(' ', @words);
last;
}
if (/^Ic$/)
{
$retval .= '\\fB';
while (defined $words[0]
&& $words[0] !~ m/^[\.,]/)
{
if ($words[0] eq 'Op')
{
shift(@words);
$retval .= '[';
my $tmp = pop(@words);
$tmp .= ']';
push(@words, $tmp);
next;
}
if ($words[0] eq 'Ar')
{
shift @words;
$retval .= '\\fI';
$retval .= shift @words;
$retval .= '\\fP';
}
else
{
$retval .= shift @words;
}
$retval .= ' '
if (! $nospace);
}
$retval =~ s/ $//;
$retval .= '\\fP';
$retval .= shift @words
if (defined $words[0]);
last;
}
if (/^Bl$/)
{
$oldoptlist = $optlist;
if ($words[0] eq '-bullet')
{
$optlist = 1;
}
elsif ($words[0] eq '-enum')
{
$optlist = 2;
$enum = 0;
}
elsif ($words[0] eq '-tag')
{
$optlist = 3;
}
elsif ($words[0] eq '-item')
{
$optlist = 4;
}
last;
}
if (/^El$/)
{
$optlist = $oldoptlist;
next;
}
if ($optlist && /^It$/)
{
if ($optlist == 1)
{
# bullets
$retval .= '.IP \\(bu';
next;
}
if ($optlist == 2)
{
# enum
$retval .= '.IP ' . (++$enum) . '.';
next;
}
if ($optlist == 3)
{
# tags
$retval .= ".TP\n";
if ($words[0] =~ m/^(Pa|Ev)$/)
{
shift @words;
$retval .= '.B';
}
next;
}
if ($optlist == 4)
{
# item
$retval .= ".IP\n";
next;
}
next;
}
if (/^Sm$/)
{
if ($words[0] eq 'off')
{
$nospace = 2;
}
elsif ($words[0] eq 'on')
{
# $retval .= "\n";
$nospace = 0;
}
shift @words;
next;
}
$retval .= "$_";
}
return undef
if ($retval eq '.');
$retval =~ s/^\.([^a-zA-Z])/$1/;
# $retval =~ s/ $//;
$retval .= ')'
if ($parens == 1);
$retval .= ']'
if ($option == 1);
# $retval .= ' '
# if ($nospace && $retval ne '' && $retval !~ m/\n$/);
# $retval .= ' '
# if ($extended && $retval !~ m/ $/);
$retval .= ' '
if ($ext && ! $extopt && $retval !~ m/ $/);
$retval .= "\n"
if (! $ext && ! $extopt && $retval ne '' && $retval !~ m/\n$/);
return $retval;
}