Add comment explaining the meaning of encoding to data_out
[pspp-builds.git] / src / data / data-out.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006, 2009 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "data-out.h"
20
21 #include <ctype.h>
22 #include <float.h>
23 #include <math.h>
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <time.h>
27
28 #include <data/calendar.h>
29 #include <data/format.h>
30 #include <data/settings.h>
31 #include <data/value.h>
32
33 #include <libpspp/assertion.h>
34 #include <libpspp/float-format.h>
35 #include <libpspp/integer-format.h>
36 #include <libpspp/message.h>
37 #include <libpspp/misc.h>
38 #include <libpspp/str.h>
39 #include <libpspp/pool.h>
40 #include <libpspp/i18n.h>
41
42 #include "minmax.h"
43
44 #include "gettext.h"
45 #define _(msgid) gettext (msgid)
46 \f
47 /* A representation of a number that can be quickly rounded to
48    any desired number of decimal places (up to a specified
49    maximum). */
50 struct rounder
51   {
52     char string[64];    /* Magnitude of number with excess precision. */
53     int integer_digits; /* Number of digits before decimal point. */
54     int leading_nines;  /* Number of `9's or `.'s at start of string. */
55     int leading_zeros;  /* Number of `0's or `.'s at start of string. */
56     bool negative;      /* Is the number negative? */
57   };
58
59 static void rounder_init (struct rounder *, double number, int max_decimals);
60 static int rounder_width (const struct rounder *, int decimals,
61                           int *integer_digits, bool *negative);
62 static void rounder_format (const struct rounder *, int decimals,
63                             char *output);
64 \f
65 typedef void data_out_converter_func (const union value *,
66                                       const struct fmt_spec *,
67                                       char *);
68 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) \
69         static data_out_converter_func output_##METHOD;
70 #include "format.def"
71
72 static bool output_decimal (const struct rounder *, const struct fmt_spec *,
73                             bool require_affixes, char *);
74 static bool output_scientific (double, const struct fmt_spec *,
75                                bool require_affixes, char *);
76
77 static double power10 (int) PURE_FUNCTION;
78 static double power256 (int) PURE_FUNCTION;
79
80 static void output_infinite (double, const struct fmt_spec *, char *);
81 static void output_missing (const struct fmt_spec *, char *);
82 static void output_overflow (const struct fmt_spec *, char *);
83 static bool output_bcd_integer (double, int digits, char *);
84 static void output_binary_integer (uint64_t, int bytes, enum integer_format,
85                                    char *);
86 static void output_hex (const void *, size_t bytes, char *);
87 \f
88
89 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
90     {
91 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
92 #include "format.def"
93     };
94
95 /* Similar to data_out. Additionally recodes the output from
96    native form into the given legacy character ENCODING.
97    OUTPUT must be provided by the caller and must be at least
98    FORMAT->w long. No null terminator is appended to OUTPUT.
99 */
100 void
101 data_out_legacy (const union value *input, const char *encoding,
102                  const struct fmt_spec *format, char *output)
103 {
104   assert (fmt_check_output (format));
105
106   converters[format->type] (input, format, output);
107   if (0 != strcmp (encoding, LEGACY_NATIVE)
108       && fmt_get_category (format->type) != FMT_CAT_BINARY)
109     {
110       char *s  = recode_string (encoding, LEGACY_NATIVE, output, format->w );
111       memcpy (output, s, format->w);
112       free (s);
113     }
114 }
115
116 /* Converts the INPUT value into a UTF8 encoded string, according
117    to format specification FORMAT. 
118
119    VALUE must be the correct width for FORMAT, that is, its
120    width must be fmt_var_width(FORMAT).
121
122    ENCODING must be the encoding of INPUT.  Normally this can
123    be obtained by calling dict_get_encoding on the dictionary
124    with which INPUT is associated.
125
126    The return value is dynamically allocated, and must be freed
127    by the caller.  If POOL is non-null, then the return value is
128    allocated on that pool.
129 */
130 char *
131 data_out_pool (const union value *input, const char *encoding,
132                const struct fmt_spec *format, struct pool *pool)
133 {
134   char *output = xmalloc (format->w + 1);
135   char *t ;
136   assert (fmt_check_output (format));
137
138   converters[format->type] (input, format, output);
139   output[format->w] = '\0';
140
141   t =  recode_string_pool (UTF8, encoding, output, format->w, pool);
142   free (output);
143   return t;
144 }
145
146 char *
147 data_out (const union value *input, const char *encoding, const struct fmt_spec *format)
148 {
149   return data_out_pool (input, encoding, format, NULL);
150 }
151
152 \f
153 /* Main conversion functions. */
154
155 /* Outputs F, COMMA, DOT, DOLLAR, PCT, E, CCA, CCB, CCC, CCD, and
156    CCE formats. */
157 static void
158 output_number (const union value *input, const struct fmt_spec *format,
159                char *output)
160 {
161   double number = input->f;
162
163   if (number == SYSMIS)
164     output_missing (format, output);
165   else if (!isfinite (number))
166     output_infinite (number, format, output);
167   else
168     {
169       if (format->type != FMT_E && fabs (number) < 1.5 * power10 (format->w))
170         {
171           struct rounder r;
172           rounder_init (&r, number, format->d);
173
174           if (output_decimal (&r, format, true, output)
175               || output_scientific (number, format, true, output)
176               || output_decimal (&r, format, false, output))
177             return;
178         }
179
180       if (!output_scientific (number, format, false, output))
181         output_overflow (format, output);
182     }
183 }
184
185 /* Outputs N format. */
186 static void
187 output_N (const union value *input, const struct fmt_spec *format,
188           char *output)
189 {
190   double number = input->f * power10 (format->d);
191   if (input->f == SYSMIS || number < 0)
192     output_missing (format, output);
193   else
194     {
195       char buf[128];
196       number = fabs (round (number));
197       if (number < power10 (format->w)
198           && sprintf (buf, "%0*.0f", format->w, number) == format->w)
199         memcpy (output, buf, format->w);
200       else
201         output_overflow (format, output);
202     }
203 }
204
205 /* Outputs Z format. */
206 static void
207 output_Z (const union value *input, const struct fmt_spec *format,
208           char *output)
209 {
210   double number = input->f * power10 (format->d);
211   char buf[128];
212   if (input->f == SYSMIS)
213     output_missing (format, output);
214   else if (fabs (number) >= power10 (format->w)
215            || sprintf (buf, "%0*.0f", format->w,
216                        fabs (round (number))) != format->w)
217     output_overflow (format, output);
218   else
219     {
220       if (number < 0 && strspn (buf, "0") < format->w)
221         {
222           char *p = &buf[format->w - 1];
223           *p = "}JKLMNOPQR"[*p - '0'];
224         }
225       memcpy (output, buf, format->w);
226     }
227 }
228
229 /* Outputs P format. */
230 static void
231 output_P (const union value *input, const struct fmt_spec *format,
232           char *output)
233 {
234   if (output_bcd_integer (fabs (input->f * power10 (format->d)),
235                           format->w * 2 - 1, output)
236       && input->f < 0.0)
237     output[format->w - 1] |= 0xd;
238   else
239     output[format->w - 1] |= 0xf;
240 }
241
242 /* Outputs PK format. */
243 static void
244 output_PK (const union value *input, const struct fmt_spec *format,
245            char *output)
246 {
247   output_bcd_integer (input->f * power10 (format->d), format->w * 2, output);
248 }
249
250 /* Outputs IB format. */
251 static void
252 output_IB (const union value *input, const struct fmt_spec *format,
253            char *output)
254 {
255   double number = round (input->f * power10 (format->d));
256   if (input->f == SYSMIS
257       || number >= power256 (format->w) / 2 - 1
258       || number < -power256 (format->w) / 2)
259     memset (output, 0, format->w);
260   else
261     {
262       uint64_t integer = fabs (number);
263       if (number < 0)
264         integer = -integer;
265       output_binary_integer (integer, format->w,
266                              settings_get_output_integer_format (),
267                              output);
268     }
269 }
270
271 /* Outputs PIB format. */
272 static void
273 output_PIB (const union value *input, const struct fmt_spec *format,
274             char *output)
275 {
276   double number = round (input->f * power10 (format->d));
277   if (input->f == SYSMIS
278       || number < 0 || number >= power256 (format->w))
279     memset (output, 0, format->w);
280   else
281     output_binary_integer (number, format->w,
282                            settings_get_output_integer_format (), output);
283 }
284
285 /* Outputs PIBHEX format. */
286 static void
287 output_PIBHEX (const union value *input, const struct fmt_spec *format,
288                char *output)
289 {
290   double number = round (input->f);
291   if (input->f == SYSMIS)
292     output_missing (format, output);
293   else if (input->f < 0 || number >= power256 (format->w / 2))
294     output_overflow (format, output);
295   else
296     {
297       char tmp[8];
298       output_binary_integer (number, format->w / 2, INTEGER_MSB_FIRST, tmp);
299       output_hex (tmp, format->w / 2, output);
300     }
301 }
302
303 /* Outputs RB format. */
304 static void
305 output_RB (const union value *input, const struct fmt_spec *format,
306            char *output)
307 {
308   double d = input->f;
309   memcpy (output, &d, format->w);
310 }
311
312 /* Outputs RBHEX format. */
313 static void
314 output_RBHEX (const union value *input, const struct fmt_spec *format,
315               char *output)
316 {
317   double d = input->f;
318   output_hex (&d, format->w / 2, output);
319 }
320
321 /* Outputs DATE, ADATE, EDATE, JDATE, SDATE, QYR, MOYR, WKYR,
322    DATETIME, TIME, and DTIME formats. */
323 static void
324 output_date (const union value *input, const struct fmt_spec *format,
325              char *output)
326 {
327   double number = input->f;
328   int year, month, day, yday;
329
330   const char *template = fmt_date_template (format->type);
331   size_t template_width = strlen (template);
332   int excess_width = format->w - template_width;
333
334   char tmp[64];
335   char *p = tmp;
336
337   assert (format->w >= template_width);
338   if (number == SYSMIS)
339     goto missing;
340
341   if (fmt_get_category (format->type) == FMT_CAT_DATE)
342     {
343       if (number <= 0)
344         goto missing;
345       calendar_offset_to_gregorian (number / 60. / 60. / 24.,
346                                     &year, &month, &day, &yday);
347       number = fmod (number, 60. * 60. * 24.);
348     }
349   else
350     year = month = day = yday = 0;
351
352   while (*template != '\0')
353     {
354       int ch = *template;
355       int count = 1;
356       while (template[count] == ch)
357         count++;
358       template += count;
359
360       switch (ch)
361         {
362         case 'd':
363           if (count < 3)
364             p += sprintf (p, "%02d", day);
365           else
366             p += sprintf (p, "%03d", yday);
367           break;
368         case 'm':
369           if (count < 3)
370             p += sprintf (p, "%02d", month);
371           else
372             {
373               static const char *const months[12] =
374                 {
375                   "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
376                   "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
377                 };
378               p = stpcpy (p, months[month - 1]);
379             }
380           break;
381         case 'y':
382           if (count >= 4 || excess_width >= 2)
383             {
384               if (year <= 9999)
385                 p += sprintf (p, "%04d", year);
386               else if (format->type == FMT_DATETIME)
387                 p = stpcpy (p, "****");
388               else
389                 goto overflow;
390             }
391           else
392             {
393               int epoch =  settings_get_epoch ();
394               int offset = year - epoch;
395               if (offset < 0 || offset > 99)
396                 goto overflow;
397               p += sprintf (p, "%02d", abs (year) % 100);
398             }
399           break;
400         case 'q':
401           p += sprintf (p, "%d", (month - 1) / 3 + 1);
402           break;
403         case 'w':
404           p += sprintf (p, "%2d", (yday - 1) / 7 + 1);
405           break;
406         case 'D':
407           if (number < 0)
408             *p++ = '-';
409           number = fabs (number);
410           p += sprintf (p, "%*.0f", count, floor (number / 60. / 60. / 24.));
411           number = fmod (number, 60. * 60. * 24.);
412           break;
413         case 'H':
414           if (number < 0)
415             *p++ = '-';
416           number = fabs (number);
417           p += sprintf (p, "%0*.0f", count, floor (number / 60. / 60.));
418           number = fmod (number, 60. * 60.);
419           break;
420         case 'M':
421           p += sprintf (p, "%02d", (int) floor (number / 60.));
422           number = fmod (number, 60.);
423           excess_width = format->w - (p - tmp);
424           if (excess_width < 0)
425             goto overflow;
426           if (excess_width == 3 || excess_width == 4
427               || (excess_width >= 5 && format->d == 0))
428             p += sprintf (p, ":%02d", (int) number);
429           else if (excess_width >= 5)
430             {
431               int d = MIN (format->d, excess_width - 4);
432               int w = d + 3;
433               sprintf (p, ":%0*.*f", w, d, number);
434               if (settings_get_decimal_char (FMT_F) != '.')
435                 {
436                   char *cp = strchr (p, '.');
437                   if (cp != NULL)
438                     *cp = settings_get_decimal_char (FMT_F);
439                 }
440               p += strlen (p);
441             }
442           break;
443         case 'X':
444           *p++ = ' ';
445           break;
446         default:
447           assert (count == 1);
448           *p++ = ch;
449           break;
450         }
451     }
452
453   buf_copy_lpad (output, format->w, tmp, p - tmp, ' ');
454   return;
455
456  overflow:
457   output_overflow (format, output);
458   return;
459
460  missing:
461   output_missing (format, output);
462   return;
463 }
464
465 /* Outputs WKDAY format. */
466 static void
467 output_WKDAY (const union value *input, const struct fmt_spec *format,
468               char *output)
469 {
470   static const char *const weekdays[7] =
471     {
472       "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
473       "THURSDAY", "FRIDAY", "SATURDAY",
474     };
475
476   if (input->f >= 1 && input->f < 8)
477     buf_copy_str_rpad (output, format->w, weekdays[(int) input->f - 1], ' ');
478   else
479     {
480       if (input->f != SYSMIS)
481         msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
482       output_missing (format, output);
483     }
484 }
485
486 /* Outputs MONTH format. */
487 static void
488 output_MONTH (const union value *input, const struct fmt_spec *format,
489               char *output)
490 {
491   static const char *const months[12] =
492     {
493       "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
494       "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
495     };
496
497   if (input->f >= 1 && input->f < 13)
498     buf_copy_str_rpad (output, format->w, months[(int) input->f - 1], ' ');
499   else
500     {
501       if (input->f != SYSMIS)
502         msg (ME, _("Month number %f is not between 1 and 12."), input->f);
503       output_missing (format, output);
504     }
505 }
506
507 /* Outputs A format. */
508 static void
509 output_A (const union value *input, const struct fmt_spec *format,
510           char *output)
511 {
512   memcpy (output, value_str (input, format->w), format->w);
513 }
514
515 /* Outputs AHEX format. */
516 static void
517 output_AHEX (const union value *input, const struct fmt_spec *format,
518              char *output)
519 {
520   output_hex (value_str (input, format->w), format->w / 2, output);
521 }
522 \f
523 /* Decimal and scientific formatting. */
524
525 /* If REQUEST plus the current *WIDTH fits within MAX_WIDTH,
526    increments *WIDTH by REQUEST and return true.
527    Otherwise returns false without changing *WIDTH. */
528 static bool
529 allocate_space (int request, int max_width, int *width)
530 {
531   assert (*width <= max_width);
532   if (request + *width <= max_width)
533     {
534       *width += request;
535       return true;
536     }
537   else
538     return false;
539 }
540
541 /* Tries to compose the number represented by R, in the style of
542    FORMAT, into OUTPUT.  Returns true if successful, false on
543    failure, which occurs if FORMAT's width is too narrow.  If
544    REQUIRE_AFFIXES is true, then the prefix and suffix specified
545    by FORMAT's style must be included; otherwise, they may be
546    omitted to make the number fit. */
547 static bool
548 output_decimal (const struct rounder *r, const struct fmt_spec *format,
549                 bool require_affixes, char *output)
550 {
551   const struct fmt_number_style *style =
552     settings_get_style (format->type);
553
554   int decimals;
555
556   for (decimals = format->d; decimals >= 0; decimals--)
557     {
558       /* Formatted version of magnitude of NUMBER. */
559       char magnitude[64];
560
561       /* Number of digits in MAGNITUDE's integer and fractional parts. */
562       int integer_digits;
563
564       /* Amount of space within the field width already claimed.
565          Initially this is the width of MAGNITUDE, then it is reduced
566          in stages as space is allocated to prefixes and suffixes and
567          grouping characters. */
568       int width;
569
570       /* Include various decorations? */
571       bool add_neg_prefix;
572       bool add_affixes;
573       bool add_grouping;
574
575       /* Position in output. */
576       char *p;
577
578       /* Make sure there's room for the number's magnitude, plus
579          the negative suffix, plus (if negative) the negative
580          prefix. */
581       width = rounder_width (r, decimals, &integer_digits, &add_neg_prefix);
582       width += ss_length (style->neg_suffix);
583       if (add_neg_prefix)
584         width += ss_length (style->neg_prefix);
585       if (width > format->w)
586         continue;
587
588       /* If there's room for the prefix and suffix, allocate
589          space.  If the affixes are required, but there's no
590          space, give up. */
591       add_affixes = allocate_space (fmt_affix_width (style),
592                                     format->w, &width);
593       if (!add_affixes && require_affixes)
594         continue;
595
596       /* Check whether we should include grouping characters.
597          We need room for a complete set or we don't insert any at all.
598          We don't include grouping characters if decimal places were
599          requested but they were all dropped. */
600       add_grouping = (style->grouping != 0
601                       && integer_digits > 3
602                       && (format->d == 0 || decimals > 0)
603                       && allocate_space ((integer_digits - 1) / 3,
604                                          format->w, &width));
605
606       /* Format the number's magnitude. */
607       rounder_format (r, decimals, magnitude);
608
609       /* Assemble number. */
610       p = output;
611       if (format->w > width)
612         p = mempset (p, ' ', format->w - width);
613       if (add_neg_prefix)
614         p = mempcpy (p, ss_data (style->neg_prefix),
615                      ss_length (style->neg_prefix));
616       if (add_affixes)
617         p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
618       if (!add_grouping)
619         p = mempcpy (p, magnitude, integer_digits);
620       else
621         {
622           int i;
623           for (i = 0; i < integer_digits; i++)
624             {
625               if (i > 0 && (integer_digits - i) % 3 == 0)
626                 *p++ = style->grouping;
627               *p++ = magnitude[i];
628             }
629         }
630       if (decimals > 0)
631         {
632           *p++ = style->decimal;
633           p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
634         }
635       if (add_affixes)
636         p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
637       if (add_neg_prefix)
638         p = mempcpy (p, ss_data (style->neg_suffix),
639                      ss_length (style->neg_suffix));
640       else
641         p = mempset (p, ' ', ss_length (style->neg_suffix));
642       assert (p == output + format->w);
643
644       return true;
645     }
646   return false;
647 }
648
649 /* Formats NUMBER into OUTPUT in scientific notation according to
650    the style of the format specified in FORMAT. */
651 static bool
652 output_scientific (double number, const struct fmt_spec *format,
653                    bool require_affixes, char *output)
654 {
655   const struct fmt_number_style *style =
656     settings_get_style (format->type);
657   int width;
658   int fraction_width;
659   bool add_affixes;
660   char buf[64], *p;
661
662   /* Allocate minimum required space. */
663   width = 6 + ss_length (style->neg_suffix);
664   if (number < 0)
665     width += ss_length (style->neg_prefix);
666   if (width > format->w)
667     return false;
668
669   /* Check for room for prefix and suffix. */
670   add_affixes = allocate_space (fmt_affix_width (style), format->w, &width);
671   if (require_affixes && !add_affixes)
672     return false;
673
674   /* Figure out number of characters we can use for the fraction,
675      if any.  (If that turns out to be 1, then we'll output a
676      decimal point without any digits following; that's what the
677      # flag does in the call to sprintf, below.) */
678   fraction_width = MIN (MIN (format->d + 1, format->w - width), 16);
679   if (format->type != FMT_E && fraction_width == 1)
680     fraction_width = 0;
681   width += fraction_width;
682
683   /* Format (except suffix). */
684   p = buf;
685   if (width < format->w)
686     p = mempset (p, ' ', format->w - width);
687   if (number < 0)
688     p = mempcpy (p, ss_data (style->neg_prefix),
689                  ss_length (style->neg_prefix));
690   if (add_affixes)
691     p = mempcpy (p, ss_data (style->prefix), ss_length (style->prefix));
692   if (fraction_width > 0)
693     sprintf (p, "%#.*E", fraction_width - 1, fabs (number));
694   else
695     sprintf (p, "%.0E", fabs (number));
696
697   /* The C locale always uses a period `.' as a decimal point.
698      Translate to comma if necessary. */
699   if (style->decimal != '.')
700     {
701       char *cp = strchr (p, '.');
702       if (cp != NULL)
703         *cp = style->decimal;
704     }
705
706   /* Make exponent have exactly three digits, plus sign. */
707   {
708     char *cp = strchr (p, 'E') + 1;
709     long int exponent = strtol (cp, NULL, 10);
710     if (abs (exponent) > 999)
711       return false;
712     sprintf (cp, "%+04ld", exponent);
713   }
714
715   /* Add suffixes. */
716   p = strchr (p, '\0');
717   if (add_affixes)
718     p = mempcpy (p, ss_data (style->suffix), ss_length (style->suffix));
719   if (number < 0)
720     p = mempcpy (p, ss_data (style->neg_suffix),
721                  ss_length (style->neg_suffix));
722   else
723     p = mempset (p, ' ', ss_length (style->neg_suffix));
724
725   assert (p == buf + format->w);
726   memcpy (output, buf, format->w);
727
728   return true;
729 }
730 \f
731 /* Returns true if the magnitude represented by R should be
732    rounded up when chopped off at DECIMALS decimal places, false
733    if it should be rounded down. */
734 static bool
735 should_round_up (const struct rounder *r, int decimals)
736 {
737   int digit = r->string[r->integer_digits + decimals + 1];
738   assert (digit >= '0' && digit <= '9');
739   return digit >= '5';
740 }
741
742 /* Initializes R for formatting the magnitude of NUMBER to no
743    more than MAX_DECIMAL decimal places. */
744 static void
745 rounder_init (struct rounder *r, double number, int max_decimals)
746 {
747   assert (fabs (number) < 1e41);
748   assert (max_decimals >= 0 && max_decimals <= 16);
749   if (max_decimals == 0)
750     {
751       /* Fast path.  No rounding needed.
752
753          We append ".00" to the integer representation because
754          round_up assumes that fractional digits are present.  */
755       sprintf (r->string, "%.0f.00", fabs (round (number)));
756     }
757   else
758     {
759       /* Slow path.
760
761          This is more difficult than it really should be because
762          we have to make sure that numbers that are exactly
763          halfway between two representations are always rounded
764          away from zero.  This is not what sprintf normally does
765          (usually it rounds to even), so we have to fake it as
766          best we can, by formatting with extra precision and then
767          doing the rounding ourselves.
768
769          We take up to two rounds to format numbers.  In the
770          first round, we obtain 2 digits of precision beyond
771          those requested by the user.  If those digits are
772          exactly "50", then in a second round we format with as
773          many digits as are significant in a "double".
774
775          It might be better to directly implement our own
776          floating-point formatting routine instead of relying on
777          the system's sprintf implementation.  But the classic
778          Steele and White paper on printing floating-point
779          numbers does not hint how to do what we want, and it's
780          not obvious how to change their algorithms to do so.  It
781          would also be a lot of work. */
782       sprintf (r->string, "%.*f", max_decimals + 2, fabs (number));
783       if (!strcmp (r->string + strlen (r->string) - 2, "50"))
784         {
785           int binary_exponent, decimal_exponent, format_decimals;
786           frexp (number, &binary_exponent);
787           decimal_exponent = binary_exponent * 3 / 10;
788           format_decimals = (DBL_DIG + 1) - decimal_exponent;
789           if (format_decimals > max_decimals + 2)
790             sprintf (r->string, "%.*f", format_decimals, fabs (number));
791         }
792     }
793
794   if (r->string[0] == '0')
795     memmove (r->string, &r->string[1], strlen (r->string));
796
797   r->leading_zeros = strspn (r->string, "0.");
798   r->leading_nines = strspn (r->string, "9.");
799   r->integer_digits = strchr (r->string, '.') - r->string;
800   r->negative = number < 0;
801 }
802
803 /* Returns the number of characters required to format the
804    magnitude represented by R to DECIMALS decimal places.
805    The return value includes integer digits and a decimal point
806    and fractional digits, if any, but it does not include any
807    negative prefix or suffix or other affixes.
808
809    *INTEGER_DIGITS is set to the number of digits before the
810    decimal point in the output, between 0 and 40.
811
812    If R represents a negative number and its rounded
813    representation would include at least one nonzero digit,
814    *NEGATIVE is set to true; otherwise, it is set to false. */
815 static int
816 rounder_width (const struct rounder *r, int decimals,
817                int *integer_digits, bool *negative)
818 {
819   /* Calculate base measures. */
820   int width = r->integer_digits;
821   if (decimals > 0)
822     width += decimals + 1;
823   *integer_digits = r->integer_digits;
824   *negative = r->negative;
825
826   /* Rounding can cause adjustments. */
827   if (should_round_up (r, decimals))
828     {
829       /* Rounding up leading 9s adds a new digit (a 1). */
830       if (r->leading_nines >= width)
831         {
832           width++;
833           ++*integer_digits;
834         }
835     }
836   else
837     {
838       /* Rounding down. */
839       if (r->leading_zeros >= width)
840         {
841           /* All digits that remain after rounding are zeros.
842              Therefore we drop the negative sign. */
843           *negative = false;
844           if (r->integer_digits == 0 && decimals == 0)
845             {
846               /* No digits at all are left.  We need to display
847                  at least a single digit (a zero). */
848               assert (width == 0);
849               width++;
850               *integer_digits = 1;
851             }
852         }
853     }
854   return width;
855 }
856
857 /* Formats the magnitude represented by R into OUTPUT, rounding
858    to DECIMALS decimal places.  Exactly as many characters as
859    indicated by rounder_width are written.  No terminating null
860    is appended. */
861 static void
862 rounder_format (const struct rounder *r, int decimals, char *output)
863 {
864   int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
865   if (should_round_up (r, decimals))
866     {
867       if (r->leading_nines < base_width)
868         {
869           /* Rounding up.  This is the common case where rounding
870              up doesn't add an extra digit. */
871           char *p;
872           memcpy (output, r->string, base_width);
873           for (p = output + base_width - 1; ; p--)
874             {
875               assert (p >= output);
876               if (*p == '9')
877                 *p = '0';
878               else if (*p >= '0' && *p <= '8')
879                 {
880                   (*p)++;
881                   break;
882                 }
883               else
884                 assert (*p == '.');
885             }
886         }
887       else
888         {
889           /* Rounding up leading 9s causes the result to be a 1
890              followed by a number of 0s, plus a decimal point. */
891           char *p = output;
892           *p++ = '1';
893           p = mempset (p, '0', r->integer_digits);
894           if (decimals > 0)
895             {
896               *p++ = '.';
897               p = mempset (p, '0', decimals);
898             }
899           assert (p == output + base_width + 1);
900         }
901     }
902   else
903     {
904       /* Rounding down. */
905       if (r->integer_digits != 0 || decimals != 0)
906         {
907           /* Common case: just copy the digits. */
908           memcpy (output, r->string, base_width);
909         }
910       else
911         {
912           /* No digits remain.  The output is just a zero. */
913           output[0] = '0';
914         }
915     }
916 }
917 \f
918 /* Helper functions. */
919
920 /* Returns 10**X. */
921 static double PURE_FUNCTION
922 power10 (int x)
923 {
924   static const double p[] =
925     {
926       1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
927       1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
928       1e20, 1e21, 1e22, 1e23, 1e24, 1e25, 1e26, 1e27, 1e28, 1e29,
929       1e30, 1e31, 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39,
930       1e40,
931     };
932   return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
933 }
934
935 /* Returns 256**X. */
936 static double PURE_FUNCTION
937 power256 (int x)
938 {
939   static const double p[] =
940     {
941       1.0,
942       256.0,
943       65536.0,
944       16777216.0,
945       4294967296.0,
946       1099511627776.0,
947       281474976710656.0,
948       72057594037927936.0,
949       18446744073709551616.0
950     };
951   return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
952 }
953
954 /* Formats non-finite NUMBER into OUTPUT according to the width
955    given in FORMAT. */
956 static void
957 output_infinite (double number, const struct fmt_spec *format, char *output)
958 {
959   assert (!isfinite (number));
960
961   if (format->w >= 3)
962     {
963       const char *s;
964
965       if (isnan (number))
966         s = "NaN";
967       else if (isinf (number))
968         s = number > 0 ? "+Infinity" : "-Infinity";
969       else
970         s = "Unknown";
971
972       buf_copy_str_lpad (output, format->w, s, ' ');
973     }
974   else
975     output_overflow (format, output);
976 }
977
978 /* Formats OUTPUT as a missing value for the given FORMAT. */
979 static void
980 output_missing (const struct fmt_spec *format, char *output)
981 {
982   memset (output, ' ', format->w);
983
984   if (format->type != FMT_N)
985     {
986       int dot_ofs = (format->type == FMT_PCT ? 2
987                      : format->type == FMT_E ? 5
988                      : 1);
989       output[MAX (0, format->w - format->d - dot_ofs)] = '.';
990     }
991   else
992     output[format->w - 1] = '.';
993 }
994
995 /* Formats OUTPUT for overflow given FORMAT. */
996 static void
997 output_overflow (const struct fmt_spec *format, char *output)
998 {
999   memset (output, '*', format->w);
1000 }
1001
1002 /* Converts the integer part of NUMBER to a packed BCD number
1003    with the given number of DIGITS in OUTPUT.  If DIGITS is odd,
1004    the least significant nibble of the final byte in OUTPUT is
1005    set to 0.  Returns true if successful, false if NUMBER is not
1006    representable.  On failure, OUTPUT is cleared to all zero
1007    bytes. */
1008 static bool
1009 output_bcd_integer (double number, int digits, char *output)
1010 {
1011   char decimal[64];
1012
1013   assert (digits < sizeof decimal);
1014   if (number != SYSMIS
1015       && number >= 0.
1016       && number < power10 (digits)
1017       && sprintf (decimal, "%0*.0f", digits, round (number)) == digits)
1018     {
1019       const char *src = decimal;
1020       int i;
1021
1022       for (i = 0; i < digits / 2; i++)
1023         {
1024           int d0 = *src++ - '0';
1025           int d1 = *src++ - '0';
1026           *output++ = (d0 << 4) + d1;
1027         }
1028       if (digits % 2)
1029         *output = (*src - '0') << 4;
1030
1031       return true;
1032     }
1033   else
1034     {
1035       memset (output, 0, DIV_RND_UP (digits, 2));
1036       return false;
1037     }
1038 }
1039
1040 /* Writes VALUE to OUTPUT as a BYTES-byte binary integer of the
1041    given INTEGER_FORMAT. */
1042 static void
1043 output_binary_integer (uint64_t value, int bytes,
1044                        enum integer_format integer_format, char *output)
1045 {
1046   integer_put (value, integer_format, output, bytes);
1047 }
1048
1049 /* Converts the BYTES bytes in DATA to twice as many hexadecimal
1050    digits in OUTPUT. */
1051 static void
1052 output_hex (const void *data_, size_t bytes, char *output)
1053 {
1054   const uint8_t *data = data_;
1055   size_t i;
1056
1057   for (i = 0; i < bytes; i++)
1058     {
1059       static const char hex_digits[] = "0123456789ABCDEF";
1060       *output++ = hex_digits[data[i] >> 4];
1061       *output++ = hex_digits[data[i] & 15];
1062     }
1063 }