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