All of lore.kernel.org
 help / color / mirror / Atom feed
* cal: bug on FreeBSD
@ 2016-03-08 13:37 Rüdiger Meier
  2016-03-08 22:35 ` Sami Kerola
  0 siblings, 1 reply; 6+ messages in thread
From: Rüdiger Meier @ 2016-03-08 13:37 UTC (permalink / raw)
  To: util-linux

Hi,

cal skips the first day of the week if it has 2 digits.

# diff ./cal
 Mo Tu We Th Fr Sa Su
              1  2  3
  4  5  6  7  8  9 10
-11 12 13 14 15 16 17
-18 19 20 21 22 23 24
-25 26 27 28 29 30
+ 12 13 14 15 16 17
+ 19 20 21 22 23 24
+ 26 27 28 29 30

The bug was introduced by my own commit
07ac4aa9  cal: all output must use my_putstring

This is the related code in cal_output_months()

for (d = DAYS_IN_WEEK * week_line;
     d < DAYS_IN_WEEK * week_line + DAYS_IN_WEEK; d++) {
	if (0 < i->days[d]) {
		if (reqday == i->days[d])
			sprintf(out, "%*s%s%*d%s", skip - (ctl->julian ? 3 : 2),
			       "", Senter, (ctl->julian ? 3 : 2),
			       i->days[d], Sexit);
		else
			sprintf(out, "%*d", skip, i->days[d]);
/*                             ^^^^^
 *         if we print this with fputs instead of my_putstring/putp
 *         below than it looks good */
	} else
		sprintf(out, "%*s", skip, "");
	my_putstring(out);
	if (skip < (int)ctl->day_width)
		skip++;
}


Is putp() broken on that machine or could we fix it?

cu,
Rudi

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: cal: bug on FreeBSD
  2016-03-08 13:37 cal: bug on FreeBSD Rüdiger Meier
@ 2016-03-08 22:35 ` Sami Kerola
  2016-03-08 22:59   ` Rüdiger Meier
  0 siblings, 1 reply; 6+ messages in thread
From: Sami Kerola @ 2016-03-08 22:35 UTC (permalink / raw)
  To: Rüdiger Meier; +Cc: util-linux

On 8 March 2016 at 13:37, Rüdiger Meier <sweet_f_a@gmx.de> wrote:
> cal skips the first day of the week if it has 2 digits.
>
> # diff ./cal
>  Mo Tu We Th Fr Sa Su
>               1  2  3
>   4  5  6  7  8  9 10
> -11 12 13 14 15 16 17
> -18 19 20 21 22 23 24
> -25 26 27 28 29 30
> + 12 13 14 15 16 17
> + 19 20 21 22 23 24
> + 26 27 28 29 30
>
> The bug was introduced by my own commit
> 07ac4aa9  cal: all output must use my_putstring
>
> This is the related code in cal_output_months()
>
> for (d = DAYS_IN_WEEK * week_line;
>      d < DAYS_IN_WEEK * week_line + DAYS_IN_WEEK; d++) {
>         if (0 < i->days[d]) {
>                 if (reqday == i->days[d])
>                         sprintf(out, "%*s%s%*d%s", skip - (ctl->julian ? 3 : 2),
>                                "", Senter, (ctl->julian ? 3 : 2),
>                                i->days[d], Sexit);
>                 else
>                         sprintf(out, "%*d", skip, i->days[d]);
> /*                             ^^^^^
>  *         if we print this with fputs instead of my_putstring/putp
>  *         below than it looks good */
>         } else
>                 sprintf(out, "%*s", skip, "");
>         my_putstring(out);
>         if (skip < (int)ctl->day_width)
>                 skip++;
> }
>
>
> Is putp() broken on that machine or could we fix it?

Hi Rudi,

Does this happen with putp() only? The following should enable you to
test the fputs() output.

-- snip
diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 2a53b89..3e513ad 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -291,6 +291,7 @@ int main(int argc, char **argv)
  Senter = my_tgetstr("smso");
  Sexit = my_tgetstr("rmso");
  }
+ has_term = 0;
  }
  }
 #endif
-- snip

p.s. What is 'that' machine.. just wondering if problem could be reproduced.

-- 
Sami Kerola
http://www.iki.fi/kerolasa/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: cal: bug on FreeBSD
  2016-03-08 22:35 ` Sami Kerola
@ 2016-03-08 22:59   ` Rüdiger Meier
  2016-05-20 10:27     ` Karel Zak
  0 siblings, 1 reply; 6+ messages in thread
From: Rüdiger Meier @ 2016-03-08 22:59 UTC (permalink / raw)
  To: kerolasa; +Cc: util-linux



On Tuesday 08 March 2016 23:35:01 Sami Kerola wrote:
> On 8 March 2016 at 13:37, Rdiger Meier <sweet_f_a@gmx.de> wrote:
> > cal skips the first day of the week if it has 2 digits.
> >
> > # diff ./cal
> >  Mo Tu We Th Fr Sa Su
> >               1  2  3
> >   4  5  6  7  8  9 10
> > -11 12 13 14 15 16 17
> > -18 19 20 21 22 23 24
> > -25 26 27 28 29 30
> > + 12 13 14 15 16 17
> > + 19 20 21 22 23 24
> > + 26 27 28 29 30
> >
> > The bug was introduced by my own commit
> > 07ac4aa9  cal: all output must use my_putstring
> >
> > This is the related code in cal_output_months()
> >
> > for (d =DAYS_IN_WEEK * week_line;
> >      d < DAYS_IN_WEEK * week_line + DAYS_IN_WEEK; d++) {
> >         if (0 < i->days[d]) {
> >                 if (reqday = i->days[d])
> >                         sprintf(out, "%*s%s%*d%s", skip - (ctl->julian ?
> > 3 : 2), "", Senter, (ctl->julian ? 3 : 2), i->days[d], Sexit);
> >                 else
> >                         sprintf(out, "%*d", skip, i->days[d]);
> > /*                             ^^^^^
> >  *         if we print this with fputs instead of my_putstring/putp
> >  *         below than it looks good */
> >         } else
> >                 sprintf(out, "%*s", skip, "");
> >         my_putstring(out);
> >         if (skip < (int)ctl->day_width)
> >                 skip++;
> > }
> >
> >
> > Is putp() broken on that machine or could we fix it?
>
> Hi Rudi,
>
> Does this happen with putp() only? The following should enable you to
> test the fputs() output.

It's only broken with putp, I tried it like this

diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index c687c6c..ea3187e 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -680,15 +680,22 @@ static void cal_output_months(struct cal_month *month, const struct cal_control
                        for (d = DAYS_IN_WEEK * week_line;
                             d < DAYS_IN_WEEK * week_line + DAYS_IN_WEEK; d++) {
                                if (0 < i->days[d]) {
-                                       if (reqday == i->days[d])
+                                       if (reqday == i->days[d]) {
                                                sprintf(out, "%*s%s%*d%s", skip - (ctl->julian ? 3 : 2),
                                                       "", Senter, (ctl->julian ? 3 : 2),
                                                       i->days[d], Sexit);
-                                       else
+                                               my_putstring(out);
+                                       } else {
                                                sprintf(out, "%*d", skip, i->days[d]);
-                               } else
+                                               //my_putstring(out);
+                                               //printf("%s",out);
+                                               fputs(out, stdout);
+                                               //putp(out);
+                                       }
+                               } else {
                                        sprintf(out, "%*s", skip, "");
-                               my_putstring(out);
+                                       my_putstring(out);
+                               }
                                if (skip < (int)ctl->day_width)
                                        skip++;
                        }

> p.s. What is 'that' machine.. just wondering if problem could be
> reproduced.

It's a FreeBSD 10.2. It's easy to run it via qemu like this
$ qemu-kvm  -smp 2 -m 1024 -cdrom FreeBSD-10.2-RELEASE-amd64-bootonly.iso -drive if=virtio,file=freebsd.qcow2

cu,
Rudi

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: cal: bug on FreeBSD
  2016-03-08 22:59   ` Rüdiger Meier
@ 2016-05-20 10:27     ` Karel Zak
  2016-05-21  8:08       ` Sami Kerola
  0 siblings, 1 reply; 6+ messages in thread
From: Karel Zak @ 2016-05-20 10:27 UTC (permalink / raw)
  To: Rüdiger Meier; +Cc: kerolasa, util-linux

On Tue, Mar 08, 2016 at 11:59:43PM +0100, Rüdiger Meier wrote:
> On Tuesday 08 March 2016 23:35:01 Sami Kerola wrote:
> > Does this happen with putp() only? The following should enable you to
> > test the fputs() output.
> 
> It's only broken with putp, I tried it like this

It's BSD specific problem, putp (aka tputs) interprets the string.
That's fine as tputs is sensitive to sequences prefixed by $< and
everything else is printed to terminal. 

BUT probably because BSD has origins in 70' LSD era there is a
special exception (ncurses sources tinfo/lib_tputs.c):

    #if BSD_TPUTS
       /*
        * This ugly kluge deals with the fact that some ancient BSD
        * programs (like nethack) actually do the likes of tputs("50") to
        * get delays.
        */
        if (isdigit(UChar(*string))) {
        ...
        }
    #endif

and the number is interpreted as argument for delay_output() and never
printed to the output.

It seems we're little bit fragile with putp() as it's primarily
designed for terminfo string variables than for a generic output.
Unfortunately mix tputs() and fputs() is also no perfect due to
buffering issues (commit 07ac4aa9d4f36a6618fd3ab1423bc33e3903ddbd).

The easy fix is to disable ncurses support for BSD (words like fuck
and suck are allowed in the commit message for this case:-).

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: cal: bug on FreeBSD
  2016-05-20 10:27     ` Karel Zak
@ 2016-05-21  8:08       ` Sami Kerola
  2016-05-21 17:16         ` Sami Kerola
  0 siblings, 1 reply; 6+ messages in thread
From: Sami Kerola @ 2016-05-21  8:08 UTC (permalink / raw)
  To: Karel Zak; +Cc: Rüdiger Meier, util-linux

On 20 May 2016 at 11:27, Karel Zak <kzak@redhat.com> wrote:
> On Tue, Mar 08, 2016 at 11:59:43PM +0100, Rüdiger Meier wrote:
>> On Tuesday 08 March 2016 23:35:01 Sami Kerola wrote:
>> > Does this happen with putp() only? The following should enable you to
>> > test the fputs() output.
>>
>> It's only broken with putp, I tried it like this
>
> It's BSD specific problem, putp (aka tputs) interprets the string.
> That's fine as tputs is sensitive to sequences prefixed by $< and
> everything else is printed to terminal.
>
> BUT probably because BSD has origins in 70' LSD era there is a
> special exception (ncurses sources tinfo/lib_tputs.c):
>
>     #if BSD_TPUTS
>        /*
>         * This ugly kluge deals with the fact that some ancient BSD
>         * programs (like nethack) actually do the likes of tputs("50") to
>         * get delays.
>         */
>         if (isdigit(UChar(*string))) {
>         ...
>         }
>     #endif
>
> and the number is interpreted as argument for delay_output() and never
> printed to the output.
>
> It seems we're little bit fragile with putp() as it's primarily
> designed for terminfo string variables than for a generic output.
> Unfortunately mix tputs() and fputs() is also no perfect due to
> buffering issues (commit 07ac4aa9d4f36a6618fd3ab1423bc33e3903ddbd).
>
> The easy fix is to disable ncurses support for BSD (words like fuck
> and suck are allowed in the commit message for this case:-).

How about disabling just the kludge instead of ncurses altogether?

The change below is also available in the git repository:
git://github.com/kerolasa/lelux-utiliteetit.git cal-bsd-fix

--->8----
From: Sami Kerola <kerolasa@iki.fi>
Date: Sat, 21 May 2016 08:47:38 +0100
Subject: [PATCH] cal: make BSD not to do ugly hack when calling tputs()

On BSD systems tputs("<number>") is interpreted as argument for
delay_output() and never printed to the output when BSD_TPUTS is
defined.  The cal(1) does not need such delays, and is printing
various date numbers so disable this unwanted BSDism.

Reported-by: Ruediger Meier <ruediger.meier@ga-group.nl>
Based-on-fix-by: Karel Zak <kzak@redhat.com>
Reference: http://www.spinics.net/lists/util-linux-ng/msg12931.html
Reference: https://github.com/freebsd/freebsd-base-graphics/blob/05dac67f853adbb295eaff5bb65b005d958317a1/contrib/ncurses/ncurses/tinfo/lib_tputs.c#L305-332
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
---
 misc-utils/cal.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/misc-utils/cal.c b/misc-utils/cal.c
index 3e20530..4735278 100644
--- a/misc-utils/cal.c
+++ b/misc-utils/cal.c
@@ -87,6 +87,15 @@ static const char *Senter = "", *Sexit = ""; /*
enter and exit standout mode */
 # include <term.h>
 #endif

+/*
+ * Disable ugly BSD hack that makes puts("<number>") to not to be printed.
+ * http://www.spinics.net/lists/util-linux-ng/msg12931.html
+ * https://github.com/freebsd/freebsd-base-graphics/blob/master/contrib/ncurses/ncurses/tinfo/lib_tputs.c#L305-332
+ */
+#ifdef BSD_TPUTS
+# unset BSD_TPUTS
+#endif
+
 static int setup_terminal(char *term)
 {
 #if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW)
-- 
2.8.2

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: cal: bug on FreeBSD
  2016-05-21  8:08       ` Sami Kerola
@ 2016-05-21 17:16         ` Sami Kerola
  0 siblings, 0 replies; 6+ messages in thread
From: Sami Kerola @ 2016-05-21 17:16 UTC (permalink / raw)
  To: Karel Zak; +Cc: Rüdiger Meier, util-linux

On 21 May 2016 at 09:08, Sami Kerola <kerolasa@iki.fi> wrote:
> +#ifdef BSD_TPUTS
> +# unset BSD_TPUTS
> +#endif

There are couple problems with this change. First of all the BSD_TPUTS
is a complier directive that should be unset to avoid the problems when
compiling ncurses. Fidling after the ncurses compilation with this define
makes no difference what so ever. Secondly there weren't enough
swearing in the commit message.

-- 
Sami Kerola
http://www.iki.fi/kerolasa/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-05-21 17:16 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-08 13:37 cal: bug on FreeBSD Rüdiger Meier
2016-03-08 22:35 ` Sami Kerola
2016-03-08 22:59   ` Rüdiger Meier
2016-05-20 10:27     ` Karel Zak
2016-05-21  8:08       ` Sami Kerola
2016-05-21 17:16         ` Sami Kerola

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.