data-out: Make binary output buffer big enough for a null terminator.
[pspp.git] / src / data / data-out.c
blob563c63566acee081d3752786ea6850a9bb2bb1b4
1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2006, 2009, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
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.
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.
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/>. */
17 #include <config.h>
19 #include "data/data-out.h"
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>
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"
43 #include "gl/minmax.h"
44 #include "gl/c-snprintf.h"
46 #include "gettext.h"
47 #define _(msgid) gettext (msgid)
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
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? */
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);
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"
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 *);
81 static double power10 (int) PURE_FUNCTION;
82 static double power256 (int) PURE_FUNCTION;
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 *);
93 static data_out_converter_func *const converters[FMT_NUMBER_OF_FORMATS] =
95 #define FMT(NAME, METHOD, IMIN, OMIN, IO, CATEGORY) output_##METHOD,
96 #include "format.def"
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.
104 VALUE must be the correct width for FORMAT, that is, its width must be
105 fmt_var_width(FORMAT).
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)
115 assert (fmt_check_output (format));
116 if (format.type == FMT_A)
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);
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
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);
138 static char *
139 binary_to_utf8 (const char *in, struct pool *pool)
141 uint8_t *out = pool_alloc_unaligned (pool, strlen (in) * 2 + 1);
142 uint8_t *p = out;
144 while (*in != '\0')
146 uint8_t byte = *in++;
147 int mblen = u8_uctomb (p, byte, 2);
148 assert (mblen > 0);
149 p += mblen;
151 *p = '\0';
153 return CHAR_CAST (char *, out);
156 /* Converts the INPUT value into a UTF-8 encoded string, according to format
157 specification FORMAT.
159 VALUE must be the correct width for FORMAT, that is, its width must be
160 fmt_var_width(FORMAT).
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.
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)
173 assert (fmt_check_output (format));
174 if (format.type == FMT_A)
176 char *in = CHAR_CAST (char *, input->s);
177 return recode_string_pool (UTF8, input_encoding, in, format.w, pool);
179 else if (fmt_get_category (format.type) == FMT_CAT_BINARY)
181 char tmp[17];
183 assert (format.w + 1 <= sizeof tmp);
184 converters[format.type] (input, format, settings, tmp);
185 return binary_to_utf8 (tmp, pool);
187 else
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;
194 output = pool_alloc_unaligned (pool, size);
195 converters[format.type] (input, format, settings, output);
196 return output;
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)
209 if (fmt_get_category (format.type) & (FMT_CAT_BASIC | FMT_CAT_CUSTOM))
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)
216 struct fmt_spec wide_format = {
217 .type = format.type,
218 .w = 40,
219 .d = format.d,
221 output_number (input, wide_format, settings, tmp);
222 return pool_strdup (pool, tmp + strspn (tmp, " "));
226 return data_out_pool (input, encoding, format, settings, pool);
229 char *
230 data_out (const union value *input, const char *input_encoding,
231 struct fmt_spec format, const struct fmt_settings *settings)
233 return data_out_pool (input, input_encoding, format, settings, NULL);
237 /* Main conversion functions. */
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)
245 double number = input->f;
247 if (number == SYSMIS)
248 output_missing (format, output);
249 else if (!isfinite (number))
250 output_infinite (number, format, output);
251 else
253 const struct fmt_number_style *style =
254 fmt_settings_get_style (settings, format.type);
256 if (format.type != FMT_E && fabs (number) < 1.5 * power10 (format.w))
258 struct rounder r;
259 rounder_init (&r, style, number, format.d);
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;
267 if (!output_scientific (number, format, style, false, output))
268 output_overflow (format, output);
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)
277 double number = input->f * power10 (format.d);
278 if (input->f == SYSMIS || number < 0)
279 output_missing (format, output);
280 else
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);
291 output[format.w] = '\0';
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)
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)
307 if (number < 0 && strspn (buf, "0") < format.w)
309 char *p = &buf[format.w - 1];
310 *p = "}JKLMNOPQR"[*p - '0'];
312 memcpy (output, buf, format.w);
313 output[format.w] = '\0';
315 else
316 output_overflow (format, output);
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)
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;
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)
337 output_bcd_integer (input->f * power10 (format.d), format.w * 2, output);
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)
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
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);
360 output[format.w] = '\0';
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)
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);
376 output[format.w] = '\0';
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)
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
391 char tmp[8];
392 output_binary_integer (number, format.w / 2, INTEGER_MSB_FIRST, tmp);
393 output_hex (tmp, format.w / 2, output);
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)
403 double d = input->f;
404 memcpy (output, &d, format.w);
406 output[format.w] = '\0';
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)
414 double d = input->f;
416 output_hex (&d, format.w / 2, output);
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)
425 double number = input->f;
426 int year, month, day, yday;
428 const char *template = fmt_date_template (format.type, format.w);
430 char tmp[64];
431 char *p = tmp;
433 if (number == SYSMIS)
434 goto missing;
436 if (fmt_get_category (format.type) == FMT_CAT_DATE)
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.);
444 else
445 year = month = day = yday = 0;
447 while (*template != '\0')
449 int excess_width;
451 int ch = *template;
452 int count = 1;
453 while (template[count] == ch)
454 count++;
455 template += count;
457 switch (ch)
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
470 static const char *const months[12] =
472 "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
473 "JUL", "AUG", "SEP", "OCT", "NOV", "DEC",
475 p = stpcpy (p, months[month - 1]);
477 break;
478 case 'y':
479 if (count >= 4)
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;
488 else
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);
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)
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 != '.')
537 char *cp = strchr (p, '.');
538 if (cp != NULL)
539 *cp = settings->decimal;
541 p += strlen (p);
543 goto done;
544 default:
545 assert (count == 1);
546 *p++ = ch;
547 break;
551 done:
552 buf_copy_lpad (output, format.w, tmp, p - tmp, ' ');
553 output[format.w] = '\0';
554 return;
556 overflow:
557 output_overflow (format, output);
558 return;
560 missing:
561 output_missing (format, output);
562 return;
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)
570 static const char *const weekdays[7] =
572 "SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY",
573 "THURSDAY", "FRIDAY", "SATURDAY",
576 if (input->f >= 1 && input->f < 8)
578 buf_copy_str_rpad (output, format.w,
579 weekdays[(int) input->f - 1], ' ');
580 output[format.w] = '\0';
582 else
584 if (input->f != SYSMIS)
585 msg (ME, _("Weekday number %f is not between 1 and 7."), input->f);
586 output_missing (format, output);
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)
596 static const char *const months[12] =
598 "JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
599 "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER",
602 if (input->f >= 1 && input->f < 13)
604 buf_copy_str_rpad (output, format.w, months[(int) input->f - 1], ' ');
605 output[format.w] = '\0';
607 else
609 if (input->f != SYSMIS)
610 msg (ME, _("Month number %f is not between 1 and 12."), input->f);
611 output_missing (format, output);
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)
622 NOT_REACHED ();
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)
630 output_hex (input->s, format.w / 2, output);
633 /* Decimal and scientific formatting. */
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)
641 assert (*width <= max_width);
642 if (request + *width <= max_width)
644 *width += request;
645 return true;
647 else
648 return false;
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)
662 int decimals;
664 for (decimals = format.d; decimals >= 0; decimals--)
666 /* Formatted version of magnitude of NUMBER. */
667 char magnitude[64];
669 /* Number of digits in MAGNITUDE's integer and fractional parts. */
670 int integer_digits;
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;
678 /* Include various decorations? */
679 bool add_neg_prefix;
680 bool add_affixes;
681 bool add_grouping;
683 /* Position in output. */
684 char *p;
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;
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;
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));
714 /* Format the number's magnitude. */
715 rounder_format (r, decimals, magnitude);
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
729 int i;
730 for (i = 0; i < integer_digits; i++)
732 if (i > 0 && (integer_digits - i) % 3 == 0)
733 *p++ = style->grouping;
734 *p++ = magnitude[i];
737 if (decimals > 0)
739 *p++ = style->decimal;
740 p = mempcpy (p, &magnitude[integer_digits + 1], decimals);
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);
749 assert (p >= output + format.w);
750 assert (p <= output + format.w + style->extra_bytes);
751 *p = '\0';
753 return true;
755 return false;
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)
765 int width;
766 int fraction_width;
767 bool add_affixes;
768 char *p;
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;
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;
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;
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));
804 /* The C locale always uses a period `.' as a decimal point.
805 Translate to comma if necessary. */
806 if (style->decimal != '.')
808 char *cp = strchr (p, '.');
809 if (cp != NULL)
810 *cp = style->decimal;
813 /* Make exponent have exactly three digits, plus sign. */
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);
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);
831 assert (p >= output + format.w);
832 assert (p <= output + format.w + style->extra_bytes);
833 *p = '\0';
835 return true;
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)
844 int digit = r->string[r->integer_digits + decimals + 1];
845 assert (digit >= '0' && digit <= '9');
846 return digit >= '5';
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)
855 assert (fabs (number) < 1e41);
856 assert (max_decimals >= 0 && max_decimals <= 16);
857 if (max_decimals == 0)
859 /* Fast path. No rounding needed.
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)));
865 else
867 /* Slow path.
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.
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".
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"))
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));
902 if (r->string[0] == '0' && !style->include_leading_zero)
903 memmove (r->string, &r->string[1], strlen (r->string));
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;
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.
919 *INTEGER_DIGITS is set to the number of digits before the
920 decimal point in the output, between 0 and 40.
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)
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;
936 /* Rounding can cause adjustments. */
937 if (should_round_up (r, decimals))
939 /* Rounding up leading 9s adds a new digit (a 1). */
940 if (r->leading_nines >= width)
942 width++;
943 ++*integer_digits;
946 else
948 /* Rounding down. */
949 if (r->leading_zeros >= width)
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)
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;
964 return width;
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)
974 int base_width = r->integer_digits + (decimals > 0 ? decimals + 1 : 0);
975 if (should_round_up (r, decimals))
977 if (r->leading_nines < base_width)
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--)
985 assert (p >= output);
986 if (*p == '9')
987 *p = '0';
988 else if (*p >= '0' && *p <= '8')
990 (*p)++;
991 break;
993 else
994 assert (*p == '.');
997 else
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)
1006 *p++ = '.';
1007 p = mempset (p, '0', decimals);
1009 assert (p == output + base_width + 1);
1012 else
1014 /* Rounding down. */
1015 if (r->integer_digits != 0 || decimals != 0)
1017 /* Common case: just copy the digits. */
1018 memcpy (output, r->string, base_width);
1020 else
1022 /* No digits remain. The output is just a zero. */
1023 output[0] = '0';
1028 /* Helper functions. */
1030 /* Returns 10**X. */
1031 static double PURE_FUNCTION
1032 power10 (int x)
1034 static const double p[] =
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,
1042 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (10.0, x);
1045 /* Returns 256**X. */
1046 static double PURE_FUNCTION
1047 power256 (int x)
1049 static const double p[] =
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
1061 return x >= 0 && x < sizeof p / sizeof *p ? p[x] : pow (256.0, x);
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)
1069 assert (!isfinite (number));
1071 if (format.w >= 3)
1073 const char *s;
1075 if (isnan (number))
1076 s = "NaN";
1077 else if (isinf (number))
1078 s = number > 0 ? "+Infinity" : "-Infinity";
1079 else
1080 s = "Unknown";
1082 buf_copy_str_lpad (output, format.w, s, ' ');
1084 else
1085 output_overflow (format, output);
1087 output[format.w] = '\0';
1090 /* Formats OUTPUT as a missing value for the given FORMAT. */
1091 static void
1092 output_missing (struct fmt_spec format, char *output)
1094 memset (output, ' ', format.w);
1096 if (format.type != FMT_N)
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)] = '.';
1103 else
1104 output[format.w - 1] = '.';
1106 output[format.w] = '\0';
1109 /* Formats OUTPUT for overflow given FORMAT. */
1110 static void
1111 output_overflow (struct fmt_spec format, char *output)
1113 memset (output, '*', format.w);
1114 output[format.w] = '\0';
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)
1126 char decimal[64];
1128 assert (digits < sizeof decimal);
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)
1136 const char *src = decimal;
1137 int i;
1139 for (i = 0; i < digits / 2; i++)
1141 int d0 = *src++ - '0';
1142 int d1 = *src++ - '0';
1143 *output++ = (d0 << 4) + d1;
1145 if (digits % 2)
1146 *output = (*src - '0') << 4;
1148 return true;
1150 else
1152 memset (output, 0, DIV_RND_UP (digits, 2));
1153 return false;
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)
1163 integer_put (value, integer_format, output, bytes);
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)
1171 const uint8_t *data = data_;
1172 size_t i;
1174 for (i = 0; i < bytes; i++)
1176 static const char hex_digits[] = "0123456789ABCDEF";
1177 *output++ = hex_digits[data[i] >> 4];
1178 *output++ = hex_digits[data[i] & 15];
1180 *output = '\0';