[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: pr: floatingpoint error
From: 
Pádraig Brady 
Subject: 
Re: pr: floatingpoint error 
Date: 
Wed, 24 Oct 2012 10:26:13 +0100 
Useragent: 
Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120615 Thunderbird/13.0.1 
On 10/24/2012 09:03 AM, Ondrej Oprala wrote:
Hello,
one of our customers made a bug report, stating that pr nNUM FILE
causes a floating point exception if NUM >= 32
and I would really like to hear your opinion on how to solve this.
The easiest solution would be to document the <32 limit for the n option.
The more difficult one would be to support numbers of arbitrary length.
I was thinking about the second solution and AFAIK the line number is not
used in any arithmetic (apart from incrementation), so it could be represented
as
an array of digits, with a function incrementing the array from the rightmost
element
as needed. Then we would just print out the array one element at a time. It
would
probably cause a performance penalty though.
Thanks in advance for any advice or suggestions.
Ouch. Confirmed that this dumps core:
echo .  pr T n.32
We can fix that up with something like the following.
I'll add a test and commit.
cheers,
Pádraig.
diff git a/src/pr.c b/src/pr.c
index e97c434..3fada19 100644
 a/src/pr.c
+++ b/src/pr.c
@@ 630,10 +630,6 @@ static uintmax_t page_number;
2 moo 4 hoo 6 zoo */
static int line_number;
/* With line_number overflow, we use power_10 to cut off the higherorder
 digits of the line_number */
static int power_10;

/* (n) True means lines should be preceded by numbers. */
static bool numbered_lines = false;
@@ 1289,12 +1285,6 @@ init_parameters (int number_of_files)
printing files in parallel. */
if (parallel_files)
chars_used_by_number = number_width;

 /* We use power_10 to cut off the higherorder digits of the
 line_number in function add_line_number */
 tmp_i = chars_per_number;
 for (power_10 = 1; tmp_i > 0; tmp_i)
 power_10 = 10 * power_10;
}
chars_per_column = (chars_per_line  chars_used_by_number
@@ 1306,7 +1296,8 @@ init_parameters (int number_of_files)
if (numbered_lines)
{
free (number_buff);
 number_buff = xmalloc (2 * chars_per_number);
+ number_buff = xmalloc (MAX (chars_per_number,
+ INT_BUFSIZE_BOUND (line_number)) + 1);
}
/* Pick the maximum between the tab width and the width of an
@@ 2029,19 +2020,13 @@ add_line_number (COLUMN *p)
{
int i;
char *s;
 int left_cut;
+ int num_width;
/* Cutting off the higherorder digits is more informative than
 lowerorder cut off*/
 if (line_number < power_10)
 sprintf (number_buff, "%*d", chars_per_number, line_number);
 else
 {
 left_cut = line_number % power_10;
 sprintf (number_buff, "%0*d", chars_per_number, left_cut);
 }
+ lowerorder cut off. */
+ num_width = sprintf (number_buff, "%*d", chars_per_number, line_number);
line_number++;
 s = number_buff;
+ s = number_buff + (num_width  chars_per_number);
for (i = chars_per_number; i > 0; i)
(p>char_func) (*s++);