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