Bug 31392

Summary: fmt(1) does format nroff source correctly
Product: Base System Reporter: Kurt Zeilenga <Kurt>
Component: binAssignee: ru <ru>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.4-STABLE   
Hardware: Any   
OS: Any   

Description Kurt Zeilenga 2001-10-20 22:40:01 UTC
    fmt(1) provided with 4.4 does not recongize nroff directives
    and treats lines containing them as regular text.  Previous
    versions previously recongized nroff directives and only
    formatted text outside of these directives.

Fix: 

Workaround is to use fmt(1) as provided with 4.3.
How-To-Repeat: 
    fmt <<EOF
    .ti 0
    fmt should produce two lines, not one.
    EOF
Comment 1 Giorgos Keramidas 2001-11-11 03:11:05 UTC
>   Description
>          
>    fmt(1) provided with 4.4 does not recongize nroff directives
>    and treats lines containing them as regular text.  Previous
>    versions previously recongized nroff directives and only
>    formatted text outside of these directives.
>
>   How-To-Repeat
>          
>    fmt <<EOF
>    .ti 0
>    fmt should produce two lines, not one.
>    EOF

The rewrite of fmt(1) at revision 1.12 -> 1.13 of fmt.c behaves differently,
but this is not really a bug.  The new fmt(1) tries to fill as much of the
input line as possible before sending it to the output stream, while the
former fmt(1) implementation copied '\n' to it's output unchanged, thus
keeping the lines that are shorter than the `goal length' to their original
length.

I'm not sure if the original behavior was more `correct' or more `wrong'
in some sense, but this is definitely a change in behavior.  I tested fmt
from RELENG_4_3_0_RELEASE today, and fmt of -CURRENT and they do behave
differently :-/
Comment 2 Kurt 2001-11-11 16:41:32 UTC
At 07:11 PM 2001-11-10, charon@labs.gr wrote:
>>   Description
>>          
>>    fmt(1) provided with 4.4 does not recongize nroff directives
>>    and treats lines containing them as regular text.  Previous
>>    versions previously recongized nroff directives and only
>>    formatted text outside of these directives.
>>
>>   How-To-Repeat
>>          
>>    fmt <<EOF
>>    .ti 0
>>    fmt should produce two lines, not one.
>>    EOF
>
>The rewrite of fmt(1) at revision 1.12 -> 1.13 of fmt.c behaves differently,
>but this is not really a bug.

I've been using fmt(1) to format [nt]roff files (such as man
pages) for 20 years, fmt has behaved in a certain behavior
manner.  While you can argue all you want about which behavior
is more 'correct' or more 'wrong', I argue that changing
historical behavior is plain 'wrong' a very good technical
reason.  Where one does have good reason to introduce new behavior,
it should be optional. Or, at least, the historical behavior
is be available as an option.

>The new fmt(1) tries to fill as much of the
>input line as possible before sending it to the output stream, while the
>former fmt(1) implementation copied '\n' to it's output unchanged, thus
>keeping the lines that are shorter than the `goal length' to their original
>length.
>
>I'm not sure if the original behavior was more `correct' or more `wrong'
>in some sense, but this is definitely a change in behavior.  I tested fmt
>from RELENG_4_3_0_RELEASE today, and fmt of -CURRENT and they do behave
>differently :-/
Comment 3 Giorgos Keramidas 2001-11-11 16:51:43 UTC
Kurt D. Zeilenga <Kurt@OpenLDAP.org> wrote:
> At 07:11 PM 2001-11-10, charon@labs.gr wrote:
> >
> >The rewrite of fmt(1) at revision 1.12 -> 1.13 of fmt.c behaves differently,
> >but this is not really a bug.
>
> I've been using fmt(1) to format [nt]roff files (such as man
> pages) for 20 years, fmt has behaved in a certain behavior
> manner.  While you can argue all you want about which behavior
> is more 'correct' or more 'wrong', I argue that changing
> historical behavior is plain 'wrong' a very good technical
> reason.  Where one does have good reason to introduce new behavior,
> it should be optional. Or, at least, the historical behavior
> is be available as an option.

I am not arguing for or against any of the two.  I've used fmt in
SunOS systems a few years back, but I don't remember if it behaved the
same way.  I just noted that this is definitely a change in behavior
and a likely POLA violation.

I'm already reading through the new fmt(1) code to see how easy it is
to provide the old behavior.  Any patches, are welcome :)
Comment 4 ru freebsd_committer freebsd_triage 2001-11-27 18:39:16 UTC
Hi!

I've checked that the old fmt(1) really had an undocumented
feature to not format lines starting with the dot character.
I have also checked that System V's fmt(1) has this feature.
The below patch is believed to fix the problem.

Index: fmt.1
===================================================================
RCS file: /home/ncvs/src/usr.bin/fmt/fmt.1,v
retrieving revision 1.9
diff -u -p -r1.9 fmt.1
--- fmt.1	2001/08/15 14:53:55	1.9
+++ fmt.1	2001/11/27 18:35:24
@@ -79,6 +79,11 @@ The spacing at the beginning of the inpu
 as are blank lines and interword spacing.
 Lines are joined or split only at white space; that is, words are never
 joined or hyphenated.
+.Nm
+does not fill lines beginning with a
+.Ql \&.
+(dot), for compatibility with
+.Xr nroff 1 .
 .Pp
 The options are as follows:
 .Bl -tag -width indent
Index: fmt.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/fmt/fmt.c,v
retrieving revision 1.16
diff -u -p -r1.16 fmt.c
--- fmt.c	2001/08/15 14:53:55	1.16
+++ fmt.c	2001/11/27 18:35:32
@@ -395,6 +395,7 @@ process_stream(FILE *stream, const char 
       }
       /* We need a new paragraph if and only if:
        *   this line is blank,
+       *   OR it's a troff request,
        *   OR it's a mail header,
        *   OR it's not a mail header AND the last line was one,
        *   OR the indentation has changed
@@ -402,6 +403,7 @@ process_stream(FILE *stream, const char 
        *      AND this isn't the second line of an indented paragraph.
        */
       if ( length==0
+           || (length>0 && line[0]=='.')
            || header_type==hdr_Header
            || (header_type==hdr_NonHeader && prev_header_type>hdr_NonHeader)
            || (np!=last_indent
@@ -411,6 +413,11 @@ process_stream(FILE *stream, const char 
         para_line_number = 0;
         first_indent = np;
         last_indent = np;
+        /* nroff compatibility: don't fill lines beginning with a dot */
+        if (length>0 && line[0]=='.') {
+          printf("%.*s\n", (int)length, line);
+          continue;
+        }
         if (header_type==hdr_Header) last_indent=2;	/* for cont. lines */
         if (length==0) {
           putchar('\n');

-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age
Comment 5 ru freebsd_committer freebsd_triage 2001-11-27 18:41:03 UTC
State Changed
From-To: open->feedback

Patch has been sent to originator. 


Comment 6 ru freebsd_committer freebsd_triage 2002-01-11 19:26:33 UTC
On Tue, Nov 27, 2001 at 08:39:16PM +0200, Ruslan Ermilov wrote:
> Hi!
> 
> I've checked that the old fmt(1) really had an undocumented
> feature to not format lines starting with the dot character.
> I have also checked that System V's fmt(1) has this feature.
> The below patch is believed to fix the problem.
> 
I've committed a different version of the patch that adds
new option -n, and makes fmt(1) do not format troff by
default.  Will MFC it shortly.


Cheers,
-- 
Ruslan Ermilov		Oracle Developer/DBA,
ru@sunbay.com		Sunbay Software AG,
ru@FreeBSD.org		FreeBSD committer,
+380.652.512.251	Simferopol, Ukraine

http://www.FreeBSD.org	The Power To Serve
http://www.oracle.com	Enabling The Information Age
Comment 7 ru freebsd_committer freebsd_triage 2002-01-14 09:49:09 UTC
State Changed
From-To: feedback->closed

Fix merged into 4.5-RC.