pivot-table: Define numeric formats of categories as well as their cells.
[pspp] / src / output / pivot-table.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2017, 2018 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 "output/pivot-table.h"
20
21 #include <stdlib.h>
22
23 #include "data/data-out.h"
24 #include "data/settings.h"
25 #include "data/value.h"
26 #include "data/variable.h"
27 #include "data/file-name.h"
28 #include "libpspp/hash-functions.h"
29 #include "libpspp/i18n.h"
30 #include "output/driver.h"
31 #include "output/spv/spv-table-look.h"
32
33 #include "gl/c-ctype.h"
34 #include "gl/configmake.h"
35 #include "gl/intprops.h"
36 #include "gl/minmax.h"
37 #include "gl/relocatable.h"
38 #include "gl/xalloc.h"
39 #include "gl/xmemdup0.h"
40 #include "gl/xsize.h"
41
42 #include "gettext.h"
43 #define _(msgid) gettext (msgid)
44 #define N_(msgid) msgid
45
46 static const struct fmt_spec *pivot_table_get_format (
47   const struct pivot_table *, const char *s);
48 \f
49 /* Pivot table display styling. */
50
51 /* Returns the name of AREA. */
52 const char *
53 pivot_area_to_string (enum pivot_area area)
54 {
55   switch (area)
56     {
57     case PIVOT_AREA_TITLE: return "title";
58     case PIVOT_AREA_CAPTION: return "caption";
59     case PIVOT_AREA_FOOTER: return "footer";
60     case PIVOT_AREA_CORNER: return "corner";
61     case PIVOT_AREA_COLUMN_LABELS: return "column labels";
62     case PIVOT_AREA_ROW_LABELS: return "row labels";
63     case PIVOT_AREA_DATA: return "data";
64     case PIVOT_AREA_LAYERS: return "layers";
65     case PIVOT_N_AREAS: default: return "**error**";
66     }
67 }
68
69 /* Returns the name of BORDER. */
70 const char *
71 pivot_border_to_string (enum pivot_border border)
72 {
73   switch (border)
74     {
75     case PIVOT_BORDER_TITLE:
76       return "title";
77
78     case PIVOT_BORDER_OUTER_LEFT:
79       return "left outer frame";
80     case PIVOT_BORDER_OUTER_TOP:
81       return "top outer frame";
82     case PIVOT_BORDER_OUTER_RIGHT:
83       return "right outer frame";
84     case PIVOT_BORDER_OUTER_BOTTOM:
85       return "bottom outer frame";
86
87     case PIVOT_BORDER_INNER_LEFT:
88       return "left inner frame";
89     case PIVOT_BORDER_INNER_TOP:
90       return "top inner frame";
91     case PIVOT_BORDER_INNER_RIGHT:
92       return "right inner frame";
93     case PIVOT_BORDER_INNER_BOTTOM:
94       return "bottom inner frame";
95
96     case PIVOT_BORDER_DATA_LEFT:
97       return "data area left";
98     case PIVOT_BORDER_DATA_TOP:
99       return "data area top";
100
101     case PIVOT_BORDER_DIM_ROW_HORZ:
102       return "row label horizontal dimension border";
103     case PIVOT_BORDER_DIM_ROW_VERT:
104       return "row label vertical dimension border";
105     case PIVOT_BORDER_DIM_COL_HORZ:
106       return "column label horizontal dimension border";
107     case PIVOT_BORDER_DIM_COL_VERT:
108       return "column label vertical dimension border";
109
110     case PIVOT_BORDER_CAT_ROW_HORZ:
111       return "row label horizontal category border";
112     case PIVOT_BORDER_CAT_ROW_VERT:
113       return "row label vertical category border";
114     case PIVOT_BORDER_CAT_COL_HORZ:
115       return "column label horizontal category border";
116     case PIVOT_BORDER_CAT_COL_VERT:
117       return "column label vertical category border";
118
119     case PIVOT_N_BORDERS:
120     default:
121       return "**error**";
122     }
123 }
124
125 void
126 pivot_table_sizing_uninit (struct pivot_table_sizing *sizing)
127 {
128   if (sizing)
129     {
130       free (sizing->widths);
131       free (sizing->breaks);
132       free (sizing->keeps);
133     }
134 }
135 \f
136 /* Pivot table looks. */
137
138 static const struct pivot_table_look *
139 default_look (const struct pivot_table_look *new)
140 {
141   static struct pivot_table_look *look;
142   if (new)
143     {
144       pivot_table_look_unref (look);
145       look = pivot_table_look_ref (new);
146     }
147   else if (!look)
148     {
149       char *error = pivot_table_look_read ("default.stt", &look);
150       if (error)
151         {
152           free (error);
153           look = pivot_table_look_ref (pivot_table_look_builtin_default ());
154         }
155     }
156   return look;
157 }
158
159 const struct pivot_table_look *
160 pivot_table_look_get_default (void)
161 {
162   return default_look (NULL);
163 }
164
165 void
166 pivot_table_look_set_default (const struct pivot_table_look *look)
167 {
168   default_look (look);
169 }
170
171 char * WARN_UNUSED_RESULT
172 pivot_table_look_read (const char *name, struct pivot_table_look **lookp)
173 {
174   *lookp = NULL;
175
176   /* Construct search path. */
177   const char *path[4];
178   size_t n = 0;
179   path[n++] = ".";
180   const char *home = getenv ("HOME");
181   char *allocated = NULL;
182   if (home != NULL)
183     path[n++] = allocated = xasprintf ("%s/.pspp/looks", home);
184   char *allocated2;
185   path[n++] = relocate2 (PKGDATADIR "/looks", &allocated2);
186   path[n++] = NULL;
187
188   /* Search path. */
189   char *file = fn_search_path (name, (char **) path);
190   if (!file)
191     {
192       char *name2 = xasprintf ("%s.stt", name);
193       file = fn_search_path (name2, (char **) path);
194       free (name2);
195     }
196   free (allocated);
197   free (allocated2);
198   if (!file)
199     return xasprintf ("%s: not found", name);
200
201   /* Read file. */
202   char *error = spv_table_look_read (file, lookp);
203   free (file);
204   return error;
205 }
206
207 const struct pivot_table_look *
208 pivot_table_look_builtin_default (void)
209 {
210   static struct pivot_table_look look = {
211     .ref_cnt = 1,
212
213     .omit_empty = true,
214     .row_labels_in_corner = true,
215     .width_ranges = {
216       [TABLE_HORZ] = { 36, 72 },
217       [TABLE_VERT] = { 36, 120 },
218     },
219
220     .areas = {
221 #define AREA(BOLD, H, V, L, R, T, B) {                         \
222     .cell_style = {                                             \
223       .halign = TABLE_HALIGN_##H,                               \
224       .valign = TABLE_VALIGN_##V,                               \
225       .margin = { [TABLE_HORZ][0] = L, [TABLE_HORZ][1] = R,     \
226                   [TABLE_VERT][0] = T, [TABLE_VERT][1] = B },   \
227     },                                                          \
228     .font_style = {                                             \
229       .bold = BOLD,                                             \
230       .fg = { [0] = CELL_COLOR_BLACK, [1] = CELL_COLOR_BLACK},  \
231       .bg = { [0] = CELL_COLOR_WHITE, [1] = CELL_COLOR_WHITE},  \
232       .size = 9,                                                \
233       .typeface = (char *) "Sans Serif",                        \
234     },                                                          \
235   }
236       [PIVOT_AREA_TITLE]         = AREA(true,  CENTER, CENTER,  8,11,1,8),
237       [PIVOT_AREA_CAPTION]       = AREA(false, LEFT,   TOP,     8,11,1,1),
238       [PIVOT_AREA_FOOTER]        = AREA(false, LEFT,   TOP,    11, 8,2,3),
239       [PIVOT_AREA_CORNER]        = AREA(false, LEFT,   BOTTOM,  8,11,1,1),
240       [PIVOT_AREA_COLUMN_LABELS] = AREA(false, CENTER, BOTTOM,  8,11,1,3),
241       [PIVOT_AREA_ROW_LABELS]    = AREA(false, LEFT,   TOP,     8,11,1,3),
242       [PIVOT_AREA_DATA]          = AREA(false, MIXED,  TOP,     8,11,1,1),
243       [PIVOT_AREA_LAYERS]        = AREA(false, LEFT,   BOTTOM,  8,11,1,3),
244 #undef AREA
245     },
246
247     .borders = {
248 #define BORDER(STROKE) { .stroke = STROKE, .color = CELL_COLOR_BLACK }
249       [PIVOT_BORDER_TITLE]        = BORDER(TABLE_STROKE_NONE),
250       [PIVOT_BORDER_OUTER_LEFT]   = BORDER(TABLE_STROKE_NONE),
251       [PIVOT_BORDER_OUTER_TOP]    = BORDER(TABLE_STROKE_NONE),
252       [PIVOT_BORDER_OUTER_RIGHT]  = BORDER(TABLE_STROKE_NONE),
253       [PIVOT_BORDER_OUTER_BOTTOM] = BORDER(TABLE_STROKE_NONE),
254       [PIVOT_BORDER_INNER_LEFT]   = BORDER(TABLE_STROKE_THICK),
255       [PIVOT_BORDER_INNER_TOP]    = BORDER(TABLE_STROKE_THICK),
256       [PIVOT_BORDER_INNER_RIGHT]  = BORDER(TABLE_STROKE_THICK),
257       [PIVOT_BORDER_INNER_BOTTOM] = BORDER(TABLE_STROKE_THICK),
258       [PIVOT_BORDER_DATA_LEFT]    = BORDER(TABLE_STROKE_THICK),
259       [PIVOT_BORDER_DATA_TOP]     = BORDER(TABLE_STROKE_THICK),
260       [PIVOT_BORDER_DIM_ROW_HORZ] = BORDER(TABLE_STROKE_SOLID),
261       [PIVOT_BORDER_DIM_ROW_VERT] = BORDER(TABLE_STROKE_NONE),
262       [PIVOT_BORDER_DIM_COL_HORZ] = BORDER(TABLE_STROKE_SOLID),
263       [PIVOT_BORDER_DIM_COL_VERT] = BORDER(TABLE_STROKE_SOLID),
264       [PIVOT_BORDER_CAT_ROW_HORZ] = BORDER(TABLE_STROKE_NONE),
265       [PIVOT_BORDER_CAT_ROW_VERT] = BORDER(TABLE_STROKE_NONE),
266       [PIVOT_BORDER_CAT_COL_HORZ] = BORDER(TABLE_STROKE_SOLID),
267       [PIVOT_BORDER_CAT_COL_VERT] = BORDER(TABLE_STROKE_SOLID),
268     },
269   };
270
271   return &look;
272 }
273
274 struct pivot_table_look *
275 pivot_table_look_new_builtin_default (void)
276 {
277   return pivot_table_look_unshare (
278     pivot_table_look_ref (pivot_table_look_builtin_default ()));
279 }
280
281 struct pivot_table_look *
282 pivot_table_look_ref (const struct pivot_table_look *look_)
283 {
284   assert (look_->ref_cnt > 0);
285
286   struct pivot_table_look *look = CONST_CAST (struct pivot_table_look *, look_);
287   look->ref_cnt++;
288   return look;
289 }
290
291 static char *
292 xstrdup_if_nonempty (const char *s)
293 {
294   return s && s[0] ? xstrdup (s) : NULL;
295 }
296
297 struct pivot_table_look *
298 pivot_table_look_unshare (struct pivot_table_look *old)
299 {
300   assert (old->ref_cnt > 0);
301   if (old->ref_cnt == 1)
302     return old;
303
304   pivot_table_look_unref (old);
305
306   struct pivot_table_look *new = xmemdup (old, sizeof *old);
307   new->ref_cnt = 1;
308   new->name = xstrdup_if_nonempty (old->name);
309   for (size_t i = 0; i < PIVOT_N_AREAS; i++)
310     table_area_style_copy (NULL, &new->areas[i], &old->areas[i]);
311   new->continuation = xstrdup_if_nonempty (old->continuation);
312
313   return new;
314 }
315
316 void
317 pivot_table_look_unref (struct pivot_table_look *look)
318 {
319   if (look)
320     {
321       assert (look->ref_cnt > 0);
322       if (!--look->ref_cnt)
323         {
324           free (look->name);
325           for (size_t i = 0; i < PIVOT_N_AREAS; i++)
326             table_area_style_uninit (&look->areas[i]);
327           free (look->continuation);
328           free (look);
329         }
330     }
331 }
332 \f
333 /* Axes. */
334
335 /* Returns the name of AXIS_TYPE. */
336 const char *
337 pivot_axis_type_to_string (enum pivot_axis_type axis_type)
338 {
339   switch (axis_type)
340     {
341     case PIVOT_AXIS_LAYER:
342       return "layer";
343
344     case PIVOT_AXIS_ROW:
345       return "row";
346
347     case PIVOT_AXIS_COLUMN:
348       return "column";
349
350     default:
351       return "<error>";
352     }
353 }
354
355 static enum pivot_axis_type
356 pivot_axis_type_transpose (enum pivot_axis_type axis_type)
357 {
358   assert (axis_type == PIVOT_AXIS_ROW || axis_type == PIVOT_AXIS_COLUMN);
359   return (axis_type == PIVOT_AXIS_ROW ? PIVOT_AXIS_COLUMN : PIVOT_AXIS_ROW);
360 }
361
362 /* Implementation of PIVOT_AXIS_FOR_EACH. */
363 size_t *
364 pivot_axis_iterator_next (size_t *indexes, const struct pivot_axis *axis)
365 {
366   if (!indexes)
367     {
368       if (axis->n_dimensions)
369         for (size_t i = 0; i < axis->n_dimensions; i++)
370           if (axis->dimensions[i]->n_leaves == 0)
371             return NULL;
372
373       size_t size = axis->n_dimensions * sizeof *indexes;
374       return xzalloc (MAX (size, 1));
375     }
376
377   for (size_t i = 0; i < axis->n_dimensions; i++)
378     {
379       const struct pivot_dimension *d = axis->dimensions[i];
380       if (++indexes[i] < d->n_leaves)
381         return indexes;
382
383       indexes[i] = 0;
384     }
385
386   free (indexes);
387   return NULL;
388 }
389 \f
390 /* Dimensions. */
391
392 static void
393 pivot_category_set_rc (struct pivot_category *category, const char *s)
394 {
395   const struct fmt_spec *format = pivot_table_get_format (
396     category->dimension->table, s);
397   if (format)
398     category->format = *format;
399
400   /* Ensure that the category itself, in addition to the cells within it, takes
401      the format.  (It's kind of rare for a category to have a numeric format
402      though.) */
403   struct pivot_value *name = category->name;
404   if (name->type == PIVOT_VALUE_NUMERIC && !name->numeric.format.w)
405     name->numeric.format = format ? *format : *settings_get_format ();
406 }
407
408 static void
409 pivot_category_create_leaves_valist (struct pivot_category *parent,
410                                      va_list args)
411 {
412   const char *s;
413   while ((s = va_arg (args, const char *)))
414     {
415       if (!strncmp (s, "RC_", 3))
416         {
417           assert (parent->n_subs);
418           pivot_category_set_rc (parent->subs[parent->n_subs - 1], s);
419         }
420       else
421         pivot_category_create_leaf (parent, pivot_value_new_text (s));
422     }
423 }
424
425 /* Creates a new dimension with the given NAME in TABLE and returns it.  The
426    dimension is added to axis AXIS_TYPE, becoming the outermost dimension on
427    that axis.
428
429    NAME should be a translatable name, but not actually translated yet,
430    e.g. enclosed in N_().  To use a different kind of value for a name, use
431    pivot_dimension_create__() instead.
432
433    The optional varargs parameters may be used to add an initial set of
434    categories to the dimension.  Each string should be a translatable category
435    name, but not actually translated yet, e.g. enclosed in N_().  Each string
436    may optionally be followod by a PIVOT_RC_* string that specifies the default
437    numeric format for cells in this category. */
438 struct pivot_dimension * SENTINEL (0)
439 (pivot_dimension_create) (struct pivot_table *table,
440                           enum pivot_axis_type axis_type,
441                           const char *name, ...)
442 {
443   struct pivot_dimension *d = pivot_dimension_create__ (
444     table, axis_type, pivot_value_new_text (name));
445
446   va_list args;
447   va_start (args, name);
448   pivot_category_create_leaves_valist (d->root, args);
449   va_end (args);
450
451   return d;
452 }
453
454 /* Creates a new dimension with the given NAME in TABLE and returns it.  The
455    dimension is added to axis AXIS_TYPE, becoming the outermost dimension on
456    that axis. */
457 struct pivot_dimension *
458 pivot_dimension_create__ (struct pivot_table *table,
459                           enum pivot_axis_type axis_type,
460                           struct pivot_value *name)
461 {
462   assert (pivot_table_is_empty (table));
463
464   struct pivot_dimension *d = xmalloc (sizeof *d);
465   *d = (struct pivot_dimension) {
466     .table = table,
467     .axis_type = axis_type,
468     .level = table->axes[axis_type].n_dimensions,
469     .top_index = table->n_dimensions,
470     .root = xmalloc (sizeof *d->root),
471   };
472
473   struct pivot_category *root = d->root;
474   *root = (struct pivot_category) {
475     .name = name,
476     .parent = NULL,
477     .dimension = d,
478     .show_label = false,
479     .data_index = SIZE_MAX,
480     .presentation_index = SIZE_MAX,
481   };
482
483   table->dimensions = xrealloc (
484     table->dimensions, (table->n_dimensions + 1) * sizeof *table->dimensions);
485   table->dimensions[table->n_dimensions++] = d;
486
487   struct pivot_axis *axis = &table->axes[axis_type];
488   axis->dimensions = xrealloc (
489     axis->dimensions, (axis->n_dimensions + 1) * sizeof *axis->dimensions);
490   axis->dimensions[axis->n_dimensions++] = d;
491
492   if (axis_type == PIVOT_AXIS_LAYER)
493     {
494       free (table->current_layer);
495       table->current_layer = xcalloc (axis[PIVOT_AXIS_LAYER].n_dimensions,
496                                       sizeof *table->current_layer);
497     }
498
499   /* axis->extent and axis->label_depth will be calculated later. */
500
501   return d;
502 }
503
504 void
505 pivot_dimension_destroy (struct pivot_dimension *d)
506 {
507   if (!d)
508     return;
509
510   pivot_category_destroy (d->root);
511   free (d->data_leaves);
512   free (d->presentation_leaves);
513   free (d);
514 }
515
516 /* Returns the first leaf node in an in-order traversal that is a child of
517    CAT. */
518 static const struct pivot_category * UNUSED
519 pivot_category_first_leaf (const struct pivot_category *cat)
520 {
521   if (pivot_category_is_leaf (cat))
522     return cat;
523
524   for (size_t i = 0; i < cat->n_subs; i++)
525     {
526       const struct pivot_category *first
527         = pivot_category_first_leaf (cat->subs[i]);
528       if (first)
529         return first;
530     }
531
532   return NULL;
533 }
534
535 /* Returns the next leaf node in an in-order traversal starting at CAT, which
536    must be a leaf. */
537 static const struct pivot_category * UNUSED
538 pivot_category_next_leaf (const struct pivot_category *cat)
539 {
540   assert (pivot_category_is_leaf (cat));
541
542   for (;;)
543     {
544       const struct pivot_category *parent = cat->parent;
545       if (!parent)
546         return NULL;
547       for (size_t i = cat->group_index + 1; i < parent->n_subs; i++)
548         {
549           const struct pivot_category *next
550             = pivot_category_first_leaf (parent->subs[i]);
551           if (next)
552             return next;
553         }
554
555       cat = cat->parent;
556     }
557 }
558
559 static void
560 pivot_category_add_child (struct pivot_category *child)
561 {
562   struct pivot_category *parent = child->parent;
563
564   assert (pivot_category_is_group (parent));
565   if (parent->n_subs >= parent->allocated_subs)
566     parent->subs = x2nrealloc (parent->subs, &parent->allocated_subs,
567                                sizeof *parent->subs);
568   parent->subs[parent->n_subs++] = child;
569 }
570
571 /* Adds leaf categories as a child of PARENT.  To create top-level categories
572    within dimension 'd', pass 'd->root' for PARENT.
573
574    Each of the varargs parameters should be a string, each of which should be a
575    translatable category name, but not actually translated yet, e.g. enclosed
576    in N_().  Each string may optionally be followod by a PIVOT_RC_* string that
577    specifies the default numeric format for cells in this category.
578
579    Returns the category index, which is just a 0-based array index, for the
580    first new category.
581
582    Leaves have to be created in in-order, that is, don't create a group and add
583    some leaves, then add leaves outside the group and try to add more leaves
584    inside it. */
585 int SENTINEL (0)
586 (pivot_category_create_leaves) (struct pivot_category *parent, ...)
587 {
588   int retval = parent->dimension->n_leaves;
589
590   va_list args;
591   va_start (args, parent);
592   pivot_category_create_leaves_valist (parent, args);
593   va_end (args);
594
595   return retval;
596 }
597
598 /* Creates a new leaf category with the given NAME as a child of PARENT.  To
599    create a top-level category within dimension 'd', pass 'd->root' for PARENT.
600    Returns the category index, which is just a 0-based array index, for the new
601    category.
602
603    Leaves have to be created in in-order, that is, don't create a group and add
604    some leaves, then add leaves outside the group and try to add more leaves
605    inside it. */
606 int
607 pivot_category_create_leaf (struct pivot_category *parent,
608                             struct pivot_value *name)
609 {
610   return pivot_category_create_leaf_rc (parent, name, NULL);
611 }
612
613 /* Creates a new leaf category with the given NAME as a child of PARENT.  To
614    create a top-level category within dimension 'd', pass 'd->root' for PARENT.
615    Returns the category index, which is just a 0-based array index, for the new
616    category.
617
618    If RC is nonnull and the name of a result category, the category is assigned
619    that result category.
620
621    Leaves have to be created in in-order, that is, don't create a group and add
622    some leaves, then add leaves outside the group and try to add more leaves
623    inside it. */
624 int
625 pivot_category_create_leaf_rc (struct pivot_category *parent,
626                                struct pivot_value *name, const char *rc)
627 {
628   struct pivot_dimension *d = parent->dimension;
629
630   struct pivot_category *leaf = xmalloc (sizeof *leaf);
631   *leaf = (struct pivot_category) {
632     .name = name,
633     .parent = parent,
634     .dimension = d,
635     .group_index = parent->n_subs,
636     .data_index = d->n_leaves,
637     .presentation_index = d->n_leaves,
638   };
639
640   if (d->n_leaves >= d->allocated_leaves)
641     {
642       d->data_leaves = x2nrealloc (d->data_leaves, &d->allocated_leaves,
643                                    sizeof *d->data_leaves);
644       d->presentation_leaves = xrealloc (
645         d->presentation_leaves,
646         d->allocated_leaves * sizeof *d->presentation_leaves);
647     }
648
649   d->data_leaves[d->n_leaves] = leaf;
650   d->presentation_leaves[d->n_leaves] = leaf;
651   d->n_leaves++;
652
653   pivot_category_add_child (leaf);
654
655   /* Make sure that the new child is the last in in-order. */
656   assert (!pivot_category_next_leaf (leaf));
657
658   pivot_category_set_rc (leaf, rc);
659
660   return leaf->data_index;
661 }
662
663 /* Adds a new category group named NAME as a child of PARENT.  To create a
664    top-level group within dimension 'd', pass 'd->root' for PARENT.
665
666    NAME should be a translatable name, but not actually translated yet,
667    e.g. enclosed in N_().  To use a different kind of value for a name, use
668    pivot_category_create_group__() instead.
669
670    The optional varargs parameters may be used to add an initial set of
671    categories to the group.  Each string should be a translatable category
672    name, but not actually translated yet, e.g. enclosed in N_().  Each string
673    may optionally be followod by a PIVOT_RC_* string that specifies the default
674    numeric format for cells in this category.
675
676    Returns the new group. */
677 struct pivot_category * SENTINEL (0)
678 (pivot_category_create_group) (struct pivot_category *parent,
679                                const char *name, ...)
680 {
681   struct pivot_category *group = pivot_category_create_group__ (
682     parent, pivot_value_new_text (name));
683
684   va_list args;
685   va_start (args, name);
686   pivot_category_create_leaves_valist (group, args);
687   va_end (args);
688
689   return group;
690 }
691
692 /* Adds a new category group named NAME as a child of PARENT.  To create a
693    top-level group within dimension 'd', pass 'd->root' for PARENT.  Returns
694    the new group. */
695 struct pivot_category *
696 pivot_category_create_group__ (struct pivot_category *parent,
697                                struct pivot_value *name)
698 {
699   struct pivot_dimension *d = parent->dimension;
700
701   struct pivot_category *group = xmalloc (sizeof *group);
702   *group = (struct pivot_category) {
703     .name = name,
704     .parent = parent,
705     .dimension = d,
706     .show_label = true,
707     .group_index = parent->n_subs,
708     .data_index = SIZE_MAX,
709     .presentation_index = SIZE_MAX,
710   };
711
712   pivot_category_add_child (group);
713
714   return group;
715 }
716
717 void
718 pivot_category_destroy (struct pivot_category *c)
719 {
720   if (!c)
721     return;
722
723   pivot_value_destroy (c->name);
724   for (size_t i = 0; i < c->n_subs; i++)
725     pivot_category_destroy (c->subs[i]);
726   free (c->subs);
727   free (c);
728 }
729 \f
730 /* Result classes.
731
732    These are usually the easiest way to control the formatting of numeric data
733    in a pivot table.  See pivot_dimension_create() for an explanation of their
734    use.  */
735 struct result_class
736   {
737     const char *name;           /* "RC_*". */
738     struct fmt_spec format;
739   };
740
741 /* Formats for most of the result classes. */
742 static struct result_class result_classes[] =
743   {
744     { PIVOT_RC_INTEGER,      { FMT_F,   40, 0 } },
745     { PIVOT_RC_PERCENT,      { FMT_PCT, 40, 1 } },
746     { PIVOT_RC_CORRELATION,  { FMT_F,   40, 3 } },
747     { PIVOT_RC_SIGNIFICANCE, { FMT_F,   40, 3 } },
748     { PIVOT_RC_RESIDUAL,     { FMT_F,   40, 2 } },
749     { PIVOT_RC_COUNT,        { 0, 0, 0 } },
750     { PIVOT_RC_OTHER,        { 0, 0, 0 } },
751   };
752
753 /* Has PIVOT_RC_COUNT been overridden by the user? */
754 static bool overridden_count_format;
755
756 static struct result_class *
757 pivot_result_class_find (const char *s)
758 {
759   for (size_t i = 0; i < sizeof result_classes / sizeof *result_classes; i++)
760     if (!strcmp (s, result_classes[i].name))
761       return &result_classes[i];
762   return NULL;
763 }
764
765 static const struct fmt_spec *
766 pivot_table_get_format (const struct pivot_table *table, const char *s)
767 {
768   if (!s)
769     return NULL;
770   else if (!strcmp (s, PIVOT_RC_OTHER))
771     return settings_get_format ();
772   else if (!strcmp (s, PIVOT_RC_COUNT) && !overridden_count_format)
773     return &table->weight_format;
774   else
775     {
776       const struct result_class *rc = pivot_result_class_find (s);
777       return rc ? &rc->format : NULL;
778     }
779 }
780
781 /* Sets the format specification for the result class named S (which should not
782    include the RC_ prefix) to *FORMAT.  Returns true if successful, false if S
783    does not name a known result class. */
784 bool
785 pivot_result_class_change (const char *s_, const struct fmt_spec *format)
786 {
787   char *s = xasprintf ("RC_%s", s_);
788   struct result_class *rc = pivot_result_class_find (s);
789   if (rc)
790     {
791       rc->format = *format;
792       if (!strcmp (s, PIVOT_RC_COUNT))
793         overridden_count_format = true;
794     }
795   free (s);
796
797   return rc != NULL;
798 }
799 \f
800 /* Pivot tables. */
801
802 /* Creates and returns a new pivot table with the given TITLE.  TITLE should be
803    a text string marked for translation but not actually translated yet,
804    e.g. N_("Descriptive Statistics").  The un-translated text string is used as
805    the pivot table's subtype.
806
807    This function is a shortcut for pivot_table_create__() for the most common
808    case.  Use pivot_table_create__() directly if the title should be some kind
809    of value other than an ordinary text string, or if the subtype should be
810    different from the title.
811
812    See the large comment at the top of pivot-table.h for general advice on
813    creating pivot tables. */
814 struct pivot_table *
815 pivot_table_create (const char *title)
816 {
817   return pivot_table_create__ (pivot_value_new_text (title), title);
818 }
819
820 /* Creates and returns a new pivot table with the given TITLE, and takes
821    ownership of TITLE.  The new pivot table's subtype is SUBTYPE, which should
822    be an untranslated English string that describes the contents of the table
823    at a high level without being specific about the variables or other context
824    involved.
825
826    TITLE and SUBTYPE may be NULL, but in that case the client must add them
827    later because they are both mandatory for a pivot table.
828
829    See the large comment at the top of pivot-table.h for general advice on
830    creating pivot tables. */
831 struct pivot_table *
832 pivot_table_create__ (struct pivot_value *title, const char *subtype)
833 {
834   struct pivot_table *table = xzalloc (sizeof *table);
835   table->ref_cnt = 1;
836   table->show_title = true;
837   table->show_caption = true;
838   table->weight_format = (struct fmt_spec) { FMT_F, 40, 0 };
839   table->title = title;
840   table->subtype = subtype ? pivot_value_new_text (subtype) : NULL;
841   table->command_c = output_get_command_name ();
842   table->look = pivot_table_look_ref (pivot_table_look_get_default ());
843
844   hmap_init (&table->cells);
845
846   return table;
847 }
848
849 /* Creates and returns a new pivot table with the given TITLE and a single cell
850    with the given CONTENT.
851
852    This is really just for error handling. */
853 struct pivot_table *
854 pivot_table_create_for_text (struct pivot_value *title,
855                              struct pivot_value *content)
856 {
857   struct pivot_table *table = pivot_table_create__ (title, "Error");
858
859   struct pivot_dimension *d = pivot_dimension_create (
860     table, PIVOT_AXIS_ROW, N_("Error"));
861   d->hide_all_labels = true;
862   pivot_category_create_leaf (d->root, pivot_value_new_text ("null"));
863
864   pivot_table_put1 (table, 0, content);
865
866   return table;
867 }
868
869 /* Increases TABLE's reference count, indicating that it has an additional
870    owner.  A pivot table that is shared among multiple owners must not be
871    modified. */
872 struct pivot_table *
873 pivot_table_ref (const struct pivot_table *table_)
874 {
875   struct pivot_table *table = CONST_CAST (struct pivot_table *, table_);
876   table->ref_cnt++;
877   return table;
878 }
879
880 /* Decreases TABLE's reference count, indicating that it has one fewer owner.
881    If TABLE no longer has any owners, it is freed. */
882 void
883 pivot_table_unref (struct pivot_table *table)
884 {
885   if (!table)
886     return;
887   assert (table->ref_cnt > 0);
888   if (--table->ref_cnt)
889     return;
890
891   free (table->current_layer);
892   pivot_table_look_unref (table->look);
893
894   for (int i = 0; i < TABLE_N_AXES; i++)
895     pivot_table_sizing_uninit (&table->sizing[i]);
896
897   for (int i = 0; i < sizeof table->ccs / sizeof *table->ccs; i++)
898     free (table->ccs[i]);
899
900   free (table->command_local);
901   free (table->command_c);
902   free (table->language);
903   free (table->locale);
904
905   free (table->dataset);
906   free (table->datafile);
907
908   for (size_t i = 0; i < table->n_footnotes; i++)
909     pivot_footnote_destroy (table->footnotes[i]);
910   free (table->footnotes);
911
912   pivot_value_destroy (table->title);
913   pivot_value_destroy (table->subtype);
914   pivot_value_destroy (table->corner_text);
915   pivot_value_destroy (table->caption);
916   free (table->notes);
917
918   for (size_t i = 0; i < table->n_dimensions; i++)
919     pivot_dimension_destroy (table->dimensions[i]);
920   free (table->dimensions);
921
922   for (size_t i = 0; i < PIVOT_N_AXES; i++)
923     free (table->axes[i].dimensions);
924
925   struct pivot_cell *cell, *next_cell;
926   HMAP_FOR_EACH_SAFE (cell, next_cell, struct pivot_cell, hmap_node,
927                       &table->cells)
928     {
929       hmap_delete (&table->cells, &cell->hmap_node);
930       pivot_value_destroy (cell->value);
931       free (cell);
932     }
933   hmap_destroy (&table->cells);
934
935   free (table);
936 }
937
938 /* Returns true if TABLE has more than one owner.  A pivot table that is shared
939    among multiple owners must not be modified. */
940 bool
941 pivot_table_is_shared (const struct pivot_table *table)
942 {
943   return table->ref_cnt > 1;
944 }
945
946 const struct pivot_table_look *
947 pivot_table_get_look (const struct pivot_table *table)
948 {
949   return table->look;
950 }
951
952 void
953 pivot_table_set_look (struct pivot_table *table,
954                       const struct pivot_table_look *look)
955 {
956   pivot_table_look_unref (table->look);
957   table->look = pivot_table_look_ref (look);
958 }
959
960 /* Sets the format used for PIVOT_RC_COUNT cells to the one used for variable
961    WV, which should be the weight variable for the dictionary whose data or
962    statistics are being put into TABLE.
963
964    This has no effect if WV is NULL. */
965 void
966 pivot_table_set_weight_var (struct pivot_table *table,
967                             const struct variable *wv)
968 {
969   if (wv)
970     pivot_table_set_weight_format (table, var_get_print_format (wv));
971 }
972
973 /* Sets the format used for PIVOT_RC_COUNT cells to WFMT, which should be the
974    format for the dictionary whose data or statistics are being put into TABLE.
975
976    This has no effect if WFMT is NULL. */
977 void
978 pivot_table_set_weight_format (struct pivot_table *table,
979                                const struct fmt_spec *wfmt)
980 {
981   if (wfmt)
982     table->weight_format = *wfmt;
983 }
984
985 /* Returns true if TABLE has no cells, false otherwise. */
986 bool
987 pivot_table_is_empty (const struct pivot_table *table)
988 {
989   return hmap_is_empty (&table->cells);
990 }
991
992 static unsigned int
993 pivot_cell_hash_indexes (const size_t *indexes, size_t n_idx)
994 {
995   return hash_bytes (indexes, n_idx * sizeof *indexes, 0);
996 }
997
998 static bool
999 equal_indexes (const size_t *a, const unsigned int *b, size_t n)
1000 {
1001   for (size_t i = 0; i < n; i++)
1002     if (a[i] != b[i])
1003       return false;
1004
1005   return true;
1006 }
1007
1008 static struct pivot_cell *
1009 pivot_table_lookup_cell__ (const struct pivot_table *table,
1010                             const size_t *dindexes, unsigned int hash)
1011 {
1012   struct pivot_cell *cell;
1013   HMAP_FOR_EACH_WITH_HASH (cell, struct pivot_cell, hmap_node, hash,
1014                            &table->cells)
1015     if (equal_indexes (dindexes, cell->idx, table->n_dimensions))
1016       return cell;
1017   return false;
1018 }
1019
1020 static struct pivot_cell *
1021 pivot_cell_allocate (size_t n_idx)
1022 {
1023   struct pivot_cell *cell UNUSED;
1024   return xmalloc (sizeof *cell + n_idx * sizeof *cell->idx);
1025 }
1026
1027 static struct pivot_cell *
1028 pivot_table_insert_cell (struct pivot_table *table, const size_t *dindexes)
1029 {
1030   unsigned int hash = pivot_cell_hash_indexes (dindexes, table->n_dimensions);
1031   struct pivot_cell *cell = pivot_table_lookup_cell__ (table, dindexes, hash);
1032   if (!cell)
1033     {
1034       cell = pivot_cell_allocate (table->n_dimensions);
1035       for (size_t i = 0; i < table->n_dimensions; i++)
1036         cell->idx[i] = dindexes[i];
1037       cell->value = NULL;
1038       hmap_insert (&table->cells, &cell->hmap_node, hash);
1039     }
1040   return cell;
1041 }
1042
1043 /* Puts VALUE in the cell in TABLE whose indexes are given by the N indexes in
1044    DINDEXES.  N must be the number of dimensions in TABLE.  Takes ownership of
1045    VALUE.
1046
1047    If VALUE is a numeric value without a specified format, this function checks
1048    each of the categories designated by DINDEXES[] and takes the format from
1049    the first category with a result class.  If none has a result class, uses
1050    the overall default numeric format. */
1051 void
1052 pivot_table_put (struct pivot_table *table, const size_t *dindexes, size_t n,
1053                  struct pivot_value *value)
1054 {
1055   assert (n == table->n_dimensions);
1056   for (size_t i = 0; i < n; i++)
1057     assert (dindexes[i] < table->dimensions[i]->n_leaves);
1058
1059   if (value->type == PIVOT_VALUE_NUMERIC && !value->numeric.format.w)
1060     {
1061       for (size_t i = 0; i < table->n_dimensions; i++)
1062         {
1063           const struct pivot_dimension *d = table->dimensions[i];
1064           if (dindexes[i] < d->n_leaves)
1065             {
1066               const struct pivot_category *c = d->data_leaves[dindexes[i]];
1067               if (c->format.w)
1068                 {
1069                   value->numeric.format = c->format;
1070                   goto done;
1071                 }
1072             }
1073         }
1074       value->numeric.format = *settings_get_format ();
1075
1076     done:;
1077     }
1078
1079   struct pivot_cell *cell = pivot_table_insert_cell (table, dindexes);
1080   pivot_value_destroy (cell->value);
1081   cell->value = value;
1082 }
1083
1084 /* Puts VALUE in the cell in TABLE with index IDX1.  TABLE must have 1
1085    dimension.  Takes ownership of VALUE.  */
1086 void
1087 pivot_table_put1 (struct pivot_table *table, size_t idx1,
1088                   struct pivot_value *value)
1089 {
1090   size_t dindexes[] = { idx1 };
1091   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1092 }
1093
1094 /* Puts VALUE in the cell in TABLE with index (IDX1, IDX2).  TABLE must have 2
1095    dimensions.  Takes ownership of VALUE.  */
1096 void
1097 pivot_table_put2 (struct pivot_table *table, size_t idx1, size_t idx2,
1098                   struct pivot_value *value)
1099 {
1100   size_t dindexes[] = { idx1, idx2 };
1101   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1102 }
1103
1104 /* Puts VALUE in the cell in TABLE with index (IDX1, IDX2, IDX3).  TABLE must
1105    have 3 dimensions.  Takes ownership of VALUE.  */
1106 void
1107 pivot_table_put3 (struct pivot_table *table, size_t idx1, size_t idx2,
1108                   size_t idx3, struct pivot_value *value)
1109 {
1110   size_t dindexes[] = { idx1, idx2, idx3 };
1111   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1112 }
1113
1114 /* Puts VALUE in the cell in TABLE with index (IDX1, IDX2, IDX3, IDX4).  TABLE
1115    must have 4 dimensions.  Takes ownership of VALUE.  */
1116 void
1117 pivot_table_put4 (struct pivot_table *table, size_t idx1, size_t idx2,
1118                   size_t idx3, size_t idx4, struct pivot_value *value)
1119 {
1120   size_t dindexes[] = { idx1, idx2, idx3, idx4 };
1121   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1122 }
1123
1124 /* Creates and returns a new footnote in TABLE with the given CONTENT and an
1125    automatically assigned marker.
1126
1127    The footnote will only appear in output if it is referenced.  Use
1128    pivot_value_add_footnote() to add a reference to the footnote. */
1129 struct pivot_footnote *
1130 pivot_table_create_footnote (struct pivot_table *table,
1131                              struct pivot_value *content)
1132 {
1133   return pivot_table_create_footnote__ (table, table->n_footnotes,
1134                                         NULL, content);
1135 }
1136
1137 static struct pivot_value *
1138 pivot_make_default_footnote_marker (int idx, bool show_numeric_markers)
1139 {
1140   char text[INT_BUFSIZE_BOUND (size_t)];
1141   if (show_numeric_markers)
1142     snprintf (text, sizeof text, "%d", idx + 1);
1143   else
1144     str_format_26adic (idx + 1, false, text, sizeof text);
1145   return pivot_value_new_user_text (text, -1);
1146 }
1147
1148 /* Creates or modifies a footnote in TABLE with 0-based number IDX (and creates
1149    all lower indexes as a side effect).  If MARKER is nonnull, sets the
1150    footnote's marker; if CONTENT is nonnull, sets the footnote's content. */
1151 struct pivot_footnote *
1152 pivot_table_create_footnote__ (struct pivot_table *table, size_t idx,
1153                                struct pivot_value *marker,
1154                                struct pivot_value *content)
1155 {
1156   if (idx >= table->n_footnotes)
1157     {
1158       while (idx >= table->allocated_footnotes)
1159         table->footnotes = x2nrealloc (table->footnotes,
1160                                        &table->allocated_footnotes,
1161                                        sizeof *table->footnotes);
1162       while (idx >= table->n_footnotes)
1163         {
1164           struct pivot_footnote *f = xmalloc (sizeof *f);
1165           f->idx = table->n_footnotes;
1166           f->marker = pivot_make_default_footnote_marker (
1167             f->idx, table->look->show_numeric_markers);
1168           f->content = NULL;
1169           f->show = true;
1170
1171           table->footnotes[table->n_footnotes++] = f;
1172         }
1173     }
1174
1175   struct pivot_footnote *f = table->footnotes[idx];
1176   if (marker)
1177     {
1178       pivot_value_destroy (f->marker);
1179       f->marker = marker;
1180     }
1181   if (content)
1182     {
1183       pivot_value_destroy (f->content);
1184       f->content = content;
1185     }
1186   return f;
1187 }
1188
1189 /* Frees the data owned by F. */
1190 void
1191 pivot_footnote_destroy (struct pivot_footnote *f)
1192 {
1193   if (f)
1194     {
1195       pivot_value_destroy (f->content);
1196       pivot_value_destroy (f->marker);
1197       free (f);
1198     }
1199 }
1200
1201 /* Converts per-axis presentation-order indexes, given in PINDEXES, into data
1202    indexes for each dimension in TABLE in DINDEXES[]. */
1203 void
1204 pivot_table_convert_indexes_ptod (const struct pivot_table *table,
1205                                   const size_t *pindexes[PIVOT_N_AXES],
1206                                   size_t dindexes[/* table->n_dimensions */])
1207 {
1208   for (size_t i = 0; i < PIVOT_N_AXES; i++)
1209     {
1210       const struct pivot_axis *axis = &table->axes[i];
1211
1212       for (size_t j = 0; j < axis->n_dimensions; j++)
1213         {
1214           const struct pivot_dimension *d = axis->dimensions[j];
1215           dindexes[d->top_index]
1216             = d->presentation_leaves[pindexes[i][j]]->data_index;
1217         }
1218     }
1219 }
1220
1221 size_t *
1222 pivot_table_enumerate_axis (const struct pivot_table *table,
1223                             enum pivot_axis_type axis_type,
1224                             const size_t *layer_indexes, bool omit_empty,
1225                             size_t *n)
1226 {
1227   const struct pivot_axis *axis = &table->axes[axis_type];
1228   if (!axis->n_dimensions)
1229     {
1230       size_t *enumeration = xnmalloc (2, sizeof *enumeration);
1231       enumeration[0] = 0;
1232       enumeration[1] = SIZE_MAX;
1233       if (n)
1234         *n = 1;
1235       return enumeration;
1236     }
1237   else if (!axis->extent)
1238     {
1239       size_t *enumeration = xmalloc (sizeof *enumeration);
1240       *enumeration = SIZE_MAX;
1241       if (n)
1242         *n = 0;
1243       return enumeration;
1244     }
1245
1246   size_t *enumeration = xnmalloc (xsum (xtimes (axis->extent,
1247                                                 axis->n_dimensions), 1),
1248                                   sizeof *enumeration);
1249   size_t *p = enumeration;
1250   size_t *dindexes = XCALLOC (table->n_dimensions, size_t);
1251
1252   size_t *axis_indexes;
1253   PIVOT_AXIS_FOR_EACH (axis_indexes, axis)
1254     {
1255       if (omit_empty)
1256         {
1257           enum pivot_axis_type axis2_type
1258             = pivot_axis_type_transpose (axis_type);
1259
1260           size_t *axis2_indexes;
1261           PIVOT_AXIS_FOR_EACH (axis2_indexes, &table->axes[axis2_type])
1262             {
1263               const size_t *pindexes[PIVOT_N_AXES];
1264               pindexes[PIVOT_AXIS_LAYER] = layer_indexes;
1265               pindexes[axis_type] = axis_indexes;
1266               pindexes[axis2_type] = axis2_indexes;
1267               pivot_table_convert_indexes_ptod (table, pindexes, dindexes);
1268               if (pivot_table_get (table, dindexes))
1269                 goto found;
1270             }
1271           continue;
1272
1273         found:
1274           free (axis2_indexes);
1275         }
1276
1277       memcpy (p, axis_indexes, axis->n_dimensions * sizeof *p);
1278       p += axis->n_dimensions;
1279     }
1280   if (omit_empty && p == enumeration)
1281     {
1282       PIVOT_AXIS_FOR_EACH (axis_indexes, axis)
1283         {
1284           memcpy (p, axis_indexes, axis->n_dimensions * sizeof *p);
1285           p += axis->n_dimensions;
1286         }
1287     }
1288   *p = SIZE_MAX;
1289   if (n)
1290     *n = (p - enumeration) / axis->n_dimensions;
1291
1292   free (dindexes);
1293   return enumeration;
1294 }
1295
1296 static const struct pivot_cell *
1297 pivot_table_lookup_cell (const struct pivot_table *table,
1298                           const size_t *dindexes)
1299 {
1300   unsigned int hash = pivot_cell_hash_indexes (dindexes, table->n_dimensions);
1301   return pivot_table_lookup_cell__ (table, dindexes, hash);
1302 }
1303
1304 const struct pivot_value *
1305 pivot_table_get (const struct pivot_table *table, const size_t *dindexes)
1306 {
1307   const struct pivot_cell *cell = pivot_table_lookup_cell (table, dindexes);
1308   return cell ? cell->value : NULL;
1309 }
1310
1311 struct pivot_value *
1312 pivot_table_get_rw (struct pivot_table *table, const size_t *dindexes)
1313 {
1314   struct pivot_cell *cell = pivot_table_insert_cell (table, dindexes);
1315   if (!cell->value)
1316     cell->value = pivot_value_new_user_text ("", -1);
1317   return cell->value;
1318 }
1319
1320 static void
1321 distribute_extra_depth (struct pivot_category *category, size_t extra_depth)
1322 {
1323   if (pivot_category_is_group (category) && category->n_subs)
1324     for (size_t i = 0; i < category->n_subs; i++)
1325       distribute_extra_depth (category->subs[i], extra_depth);
1326   else
1327     category->extra_depth += extra_depth;
1328 }
1329
1330 static void
1331 pivot_category_assign_label_depth (struct pivot_category *category,
1332                                    bool dimension_labels_in_corner)
1333 {
1334   category->extra_depth = 0;
1335
1336   if (pivot_category_is_group (category))
1337     {
1338       size_t depth = 0;
1339       for (size_t i = 0; i < category->n_subs; i++)
1340         {
1341           pivot_category_assign_label_depth (category->subs[i], false);
1342           depth = MAX (depth, category->subs[i]->label_depth);
1343         }
1344
1345       for (size_t i = 0; i < category->n_subs; i++)
1346         {
1347           struct pivot_category *sub = category->subs[i];
1348
1349           size_t extra_depth = depth - sub->label_depth;
1350           if (extra_depth)
1351             distribute_extra_depth (sub, extra_depth);
1352
1353           sub->label_depth = depth;
1354         }
1355
1356       category->show_label_in_corner = (category->show_label
1357                                         && dimension_labels_in_corner);
1358       category->label_depth
1359         = (category->show_label && !category->show_label_in_corner
1360            ? depth + 1 : depth);
1361     }
1362   else
1363     category->label_depth = 1;
1364 }
1365
1366 static bool
1367 pivot_axis_assign_label_depth (struct pivot_table *table,
1368                              enum pivot_axis_type axis_type,
1369                              bool dimension_labels_in_corner)
1370 {
1371   struct pivot_axis *axis = &table->axes[axis_type];
1372   bool any_label_shown_in_corner = false;
1373   axis->label_depth = 0;
1374   axis->extent = 1;
1375   for (size_t i = 0; i < axis->n_dimensions; i++)
1376     {
1377       struct pivot_dimension *d = axis->dimensions[i];
1378       pivot_category_assign_label_depth (d->root, dimension_labels_in_corner);
1379       d->label_depth = d->hide_all_labels ? 0 : d->root->label_depth;
1380       axis->label_depth += d->label_depth;
1381       axis->extent *= d->n_leaves;
1382
1383       if (d->root->show_label_in_corner)
1384         any_label_shown_in_corner = true;
1385     }
1386   return any_label_shown_in_corner;
1387 }
1388
1389 void
1390 pivot_table_assign_label_depth (struct pivot_table *table)
1391 {
1392   pivot_axis_assign_label_depth (table, PIVOT_AXIS_COLUMN, false);
1393   if (pivot_axis_assign_label_depth (
1394         table, PIVOT_AXIS_ROW, (table->look->row_labels_in_corner
1395                                 && !table->corner_text))
1396       && table->axes[PIVOT_AXIS_COLUMN].label_depth == 0)
1397     table->axes[PIVOT_AXIS_COLUMN].label_depth = 1;
1398   pivot_axis_assign_label_depth (table, PIVOT_AXIS_LAYER, false);
1399 }
1400 \f
1401 static void
1402 indent (int indentation)
1403 {
1404   for (int i = 0; i < indentation * 2; i++)
1405     putchar (' ');
1406 }
1407
1408 static void
1409 pivot_value_dump (const struct pivot_value *value)
1410 {
1411   char *s = pivot_value_to_string (value, SETTINGS_VALUE_SHOW_DEFAULT,
1412                                    SETTINGS_VALUE_SHOW_DEFAULT);
1413   fputs (s, stdout);
1414   free (s);
1415 }
1416
1417 static void
1418 pivot_table_dump_value (const struct pivot_value *value, const char *name,
1419                       int indentation)
1420 {
1421   if (value)
1422     {
1423       indent (indentation);
1424       printf ("%s: ", name);
1425       pivot_value_dump (value);
1426       putchar ('\n');
1427     }
1428 }
1429
1430 static void
1431 pivot_table_dump_string (const char *string, const char *name, int indentation)
1432 {
1433   if (string)
1434     {
1435       indent (indentation);
1436       printf ("%s: %s\n", name, string);
1437     }
1438 }
1439
1440 static void
1441 pivot_category_dump (const struct pivot_category *c, int indentation)
1442 {
1443   indent (indentation);
1444   printf ("%s \"", pivot_category_is_leaf (c) ? "leaf" : "group");
1445   pivot_value_dump (c->name);
1446   printf ("\" ");
1447
1448   if (pivot_category_is_leaf (c))
1449     printf ("data_index=%zu\n", c->data_index);
1450   else
1451     {
1452       printf (" (label %s)", c->show_label ? "shown" : "hidden");
1453       printf ("\n");
1454
1455       for (size_t i = 0; i < c->n_subs; i++)
1456         pivot_category_dump (c->subs[i], indentation + 1);
1457     }
1458 }
1459
1460 void
1461 pivot_dimension_dump (const struct pivot_dimension *d, int indentation)
1462 {
1463   indent (indentation);
1464   printf ("%s dimension %zu (where 0=innermost), label_depth=%d:\n",
1465           pivot_axis_type_to_string (d->axis_type), d->level, d->label_depth);
1466
1467   pivot_category_dump (d->root, indentation + 1);
1468 }
1469
1470 static void
1471 table_area_style_dump (enum pivot_area area, const struct table_area_style *a,
1472                        int indentation)
1473 {
1474   indent (indentation);
1475   printf ("%s: ", pivot_area_to_string (area));
1476   font_style_dump (&a->font_style);
1477   putchar (' ');
1478   cell_style_dump (&a->cell_style);
1479   putchar ('\n');
1480 }
1481
1482 static void
1483 table_border_style_dump (enum pivot_border border,
1484                          const struct table_border_style *b, int indentation)
1485 {
1486   indent (indentation);
1487   printf ("%s: %s ", pivot_border_to_string (border),
1488           table_stroke_to_string (b->stroke));
1489   cell_color_dump (&b->color);
1490   putchar ('\n');
1491 }
1492
1493 static char ***
1494 compose_headings (const struct pivot_axis *axis,
1495                   const size_t *column_enumeration,
1496                   enum settings_value_show show_values,
1497                   enum settings_value_show show_variables)
1498 {
1499   if (!axis->n_dimensions || !axis->extent || !axis->label_depth)
1500     return NULL;
1501
1502   char ***headings = xnmalloc (axis->label_depth, sizeof *headings);
1503   for (size_t i = 0; i < axis->label_depth; i++)
1504     headings[i] = xcalloc (axis->extent, sizeof **headings);
1505
1506   const size_t *indexes;
1507   size_t column = 0;
1508   PIVOT_ENUMERATION_FOR_EACH (indexes, column_enumeration, axis)
1509     {
1510       int row = axis->label_depth - 1;
1511       for (int dim_index = 0; dim_index < axis->n_dimensions; dim_index++)
1512         {
1513           const struct pivot_dimension *d = axis->dimensions[dim_index];
1514           if (d->hide_all_labels)
1515             continue;
1516           for (const struct pivot_category *c
1517                  = d->presentation_leaves[indexes[dim_index]];
1518                c;
1519                c = c->parent)
1520             {
1521               if (pivot_category_is_leaf (c) || (c->show_label
1522                                                  && !c->show_label_in_corner))
1523                 {
1524                   headings[row][column] = pivot_value_to_string (
1525                     c->name, show_values, show_variables);
1526                   if (!*headings[row][column])
1527                     headings[row][column] = xstrdup ("<blank>");
1528                   row--;
1529                 }
1530             }
1531         }
1532       column++;
1533     }
1534
1535   return headings;
1536 }
1537
1538 static void
1539 free_headings (const struct pivot_axis *axis, char ***headings)
1540 {
1541   for (size_t i = 0; i < axis->label_depth; i++)
1542     {
1543       for (size_t j = 0; j < axis->extent; j++)
1544         free (headings[i][j]);
1545       free (headings[i]);
1546     }
1547   free (headings);
1548 }
1549
1550 static void
1551 pivot_table_sizing_dump (const char *name,
1552                          const int width_ranges[2],
1553                          const struct pivot_table_sizing *s,
1554                          int indentation)
1555 {
1556   indent (indentation);
1557   printf ("%ss: min=%d, max=%d\n", name, width_ranges[0], width_ranges[1]);
1558   if (s->n_widths)
1559     {
1560       indent (indentation + 1);
1561       printf ("%s widths:", name);
1562       for (size_t i = 0; i < s->n_widths; i++)
1563         printf (" %d", s->widths[i]);
1564       printf ("\n");
1565     }
1566   if (s->n_breaks)
1567     {
1568       indent (indentation + 1);
1569       printf ("break after %ss:", name);
1570       for (size_t i = 0; i < s->n_breaks; i++)
1571         printf (" %zu", s->breaks[i]);
1572       printf ("\n");
1573     }
1574   if (s->n_keeps)
1575     {
1576       indent (indentation + 1);
1577       printf ("keep %ss together:", name);
1578       for (size_t i = 0; i < s->n_keeps; i++)
1579         printf (" [%zu,%zu]",
1580                 s->keeps[i].ofs,
1581                 s->keeps[i].ofs + s->keeps[i].n - 1);
1582       printf ("\n");
1583     }
1584 }
1585
1586 void
1587 pivot_table_dump (const struct pivot_table *table, int indentation)
1588 {
1589   if (!table)
1590     return;
1591
1592   int old_decimal = settings_get_decimal_char (FMT_COMMA);
1593   if (table->decimal == '.' || table->decimal == ',')
1594     settings_set_decimal_char (table->decimal);
1595
1596   pivot_table_dump_value (table->title, "title", indentation);
1597   pivot_table_dump_value (table->subtype, "subtype", indentation);
1598   pivot_table_dump_string (table->command_c, "command", indentation);
1599   pivot_table_dump_string (table->dataset, "dataset", indentation);
1600   pivot_table_dump_string (table->datafile, "datafile", indentation);
1601   pivot_table_dump_string (table->notes, "notes", indentation);
1602   pivot_table_dump_string (table->look->name, "table-look", indentation);
1603   if (table->date)
1604     {
1605       indent (indentation);
1606
1607       struct tm *tm = localtime (&table->date);
1608       printf ("date: %d-%02d-%02d %d:%02d:%02d\n", tm->tm_year + 1900,
1609               tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
1610               tm->tm_sec);
1611     }
1612
1613   indent (indentation);
1614   printf ("sizing:\n");
1615   pivot_table_sizing_dump ("column", table->look->width_ranges[TABLE_HORZ],
1616                            &table->sizing[TABLE_HORZ], indentation + 1);
1617   pivot_table_sizing_dump ("row", table->look->width_ranges[TABLE_VERT],
1618                            &table->sizing[TABLE_VERT], indentation + 1);
1619
1620   indent (indentation);
1621   printf ("areas:\n");
1622   for (enum pivot_area area = 0; area < PIVOT_N_AREAS; area++)
1623     table_area_style_dump (area, &table->look->areas[area], indentation + 1);
1624
1625   indent (indentation);
1626   printf ("borders:\n");
1627   for (enum pivot_border border = 0; border < PIVOT_N_BORDERS; border++)
1628     table_border_style_dump (border, &table->look->borders[border],
1629                              indentation + 1);
1630
1631   for (size_t i = 0; i < table->n_dimensions; i++)
1632     pivot_dimension_dump (table->dimensions[i], indentation);
1633
1634   /* Presentation and data indexes. */
1635   size_t *dindexes = XCALLOC (table->n_dimensions, size_t);
1636
1637   const struct pivot_axis *layer_axis = &table->axes[PIVOT_AXIS_LAYER];
1638   if (layer_axis->n_dimensions)
1639     {
1640       indent (indentation);
1641       printf ("current layer:");
1642
1643       for (size_t i = 0; i < layer_axis->n_dimensions; i++)
1644         {
1645           const struct pivot_dimension *d = layer_axis->dimensions[i];
1646           char *name = pivot_value_to_string (d->root->name,
1647                                               table->show_values,
1648                                               table->show_variables);
1649           char *value = pivot_value_to_string (
1650             d->data_leaves[table->current_layer[i]]->name,
1651             table->show_values, table->show_variables);
1652           printf (" %s=%s", name, value);
1653           free (value);
1654           free (name);
1655         }
1656
1657       putchar ('\n');
1658     }
1659
1660   size_t *layer_indexes;
1661   size_t layer_iteration = 0;
1662   PIVOT_AXIS_FOR_EACH (layer_indexes, &table->axes[PIVOT_AXIS_LAYER])
1663     {
1664       indent (indentation);
1665       printf ("layer %zu:", layer_iteration++);
1666
1667       const struct pivot_axis *layer_axis = &table->axes[PIVOT_AXIS_LAYER];
1668       for (size_t i = 0; i < layer_axis->n_dimensions; i++)
1669         {
1670           const struct pivot_dimension *d = layer_axis->dimensions[i];
1671
1672           fputs (i == 0 ? " " : ", ", stdout);
1673           pivot_value_dump (d->root->name);
1674           fputs (" =", stdout);
1675
1676           struct pivot_value **names = xnmalloc (d->n_leaves, sizeof *names);
1677           size_t n_names = 0;
1678           for (const struct pivot_category *c
1679                  = d->presentation_leaves[layer_indexes[i]];
1680                c;
1681                c = c->parent)
1682             {
1683               if (pivot_category_is_leaf (c) || c->show_label)
1684                 names[n_names++] = c->name;
1685             }
1686
1687           for (size_t i = n_names; i-- > 0;)
1688             {
1689               putchar (' ');
1690               pivot_value_dump (names[i]);
1691             }
1692           free (names);
1693         }
1694       putchar ('\n');
1695
1696       size_t *column_enumeration = pivot_table_enumerate_axis (
1697         table, PIVOT_AXIS_COLUMN, layer_indexes, table->look->omit_empty, NULL);
1698       size_t *row_enumeration = pivot_table_enumerate_axis (
1699         table, PIVOT_AXIS_ROW, layer_indexes, table->look->omit_empty, NULL);
1700
1701       char ***column_headings = compose_headings (
1702         &table->axes[PIVOT_AXIS_COLUMN], column_enumeration,
1703         table->show_values, table->show_variables);
1704       for (size_t y = 0; y < table->axes[PIVOT_AXIS_COLUMN].label_depth; y++)
1705         {
1706           indent (indentation + 1);
1707           for (size_t x = 0; x < table->axes[PIVOT_AXIS_COLUMN].extent; x++)
1708             {
1709               if (x)
1710                 fputs ("; ", stdout);
1711               if (column_headings[y][x])
1712                 fputs (column_headings[y][x], stdout);
1713             }
1714           putchar ('\n');
1715         }
1716       free_headings (&table->axes[PIVOT_AXIS_COLUMN], column_headings);
1717
1718       indent (indentation + 1);
1719       printf ("-----------------------------------------------\n");
1720
1721       char ***row_headings = compose_headings (
1722         &table->axes[PIVOT_AXIS_ROW], row_enumeration,
1723         table->show_values, table->show_variables);
1724
1725       size_t x = 0;
1726       const size_t *pindexes[PIVOT_N_AXES]
1727         = { [PIVOT_AXIS_LAYER] = layer_indexes };
1728       PIVOT_ENUMERATION_FOR_EACH (pindexes[PIVOT_AXIS_ROW], row_enumeration,
1729                                   &table->axes[PIVOT_AXIS_ROW])
1730         {
1731           indent (indentation + 1);
1732
1733           size_t i = 0;
1734           for (size_t y = 0; y < table->axes[PIVOT_AXIS_ROW].label_depth; y++)
1735             {
1736               if (i++)
1737                 fputs ("; ", stdout);
1738               if (row_headings[y][x])
1739                 fputs (row_headings[y][x], stdout);
1740             }
1741
1742           printf (" | ");
1743
1744           i = 0;
1745           PIVOT_ENUMERATION_FOR_EACH (pindexes[PIVOT_AXIS_COLUMN],
1746                                       column_enumeration,
1747                                       &table->axes[PIVOT_AXIS_COLUMN])
1748             {
1749               if (i++)
1750                 printf ("; ");
1751
1752               pivot_table_convert_indexes_ptod (table, pindexes, dindexes);
1753               const struct pivot_value *value = pivot_table_get (
1754                 table, dindexes);
1755               if (value)
1756                 pivot_value_dump (value);
1757             }
1758           printf ("\n");
1759
1760           x++;
1761         }
1762
1763       free (column_enumeration);
1764       free (row_enumeration);
1765       free_headings (&table->axes[PIVOT_AXIS_ROW], row_headings);
1766     }
1767
1768   pivot_table_dump_value (table->caption, "caption", indentation);
1769
1770   for (size_t i = 0; i < table->n_footnotes; i++)
1771     {
1772       const struct pivot_footnote *f = table->footnotes[i];
1773       indent (indentation);
1774       putchar ('[');
1775       if (f->marker)
1776         pivot_value_dump (f->marker);
1777       else
1778         printf ("%zu", f->idx);
1779       putchar (']');
1780       pivot_value_dump (f->content);
1781       putchar ('\n');
1782     }
1783
1784   free (dindexes);
1785   settings_set_decimal_char (old_decimal);
1786 }
1787 \f
1788 static const char *
1789 consume_int (const char *p, size_t *n)
1790 {
1791   *n = 0;
1792   while (c_isdigit (*p))
1793     *n = *n * 10 + (*p++ - '0');
1794   return p;
1795 }
1796
1797 static size_t
1798 pivot_format_inner_template (struct string *out, const char *template,
1799                              char escape,
1800                              struct pivot_value **values, size_t n_values,
1801                              enum settings_value_show show_values,
1802                              enum settings_value_show show_variables)
1803 {
1804   size_t args_consumed = 0;
1805   while (*template && *template != ':')
1806     {
1807       if (*template == '\\' && template[1])
1808         {
1809           ds_put_byte (out, template[1] == 'n' ? '\n' : template[1]);
1810           template += 2;
1811         }
1812       else if (*template == escape)
1813         {
1814           size_t index;
1815           template = consume_int (template + 1, &index);
1816           if (index >= 1 && index <= n_values)
1817             {
1818               pivot_value_format (values[index - 1], show_values,
1819                                   show_variables, out);
1820               args_consumed = MAX (args_consumed, index);
1821             }
1822         }
1823       else
1824         ds_put_byte (out, *template++);
1825     }
1826   return args_consumed;
1827 }
1828
1829 static const char *
1830 pivot_extract_inner_template (const char *template, const char **p)
1831 {
1832   *p = template;
1833
1834   for (;;)
1835     {
1836       if (*template == '\\' && template[1] != '\0')
1837         template += 2;
1838       else if (*template == ':')
1839         return template + 1;
1840       else if (*template == '\0')
1841         return template;
1842       else
1843         template++;
1844     }
1845 }
1846
1847 static void
1848 pivot_format_template (struct string *out, const char *template,
1849                        const struct pivot_argument *args, size_t n_args,
1850                        enum settings_value_show show_values,
1851                        enum settings_value_show show_variables)
1852 {
1853   while (*template)
1854     {
1855       if (*template == '\\' && template[1] != '\0')
1856         {
1857           ds_put_byte (out, template[1] == 'n' ? '\n' : template[1]);
1858           template += 2;
1859         }
1860       else if (*template == '^')
1861         {
1862           size_t index;
1863           template = consume_int (template + 1, &index);
1864           if (index >= 1 && index <= n_args && args[index - 1].n > 0)
1865             pivot_value_format (args[index - 1].values[0],
1866                                 show_values, show_variables, out);
1867         }
1868       else if (*template == '[')
1869         {
1870           const char *tmpl[2];
1871           template = pivot_extract_inner_template (template + 1, &tmpl[0]);
1872           template = pivot_extract_inner_template (template, &tmpl[1]);
1873           template += *template == ']';
1874
1875           size_t index;
1876           template = consume_int (template, &index);
1877           if (index < 1 || index > n_args)
1878             continue;
1879
1880           const struct pivot_argument *arg = &args[index - 1];
1881           size_t left = arg->n;
1882           while (left)
1883             {
1884               struct pivot_value **values = arg->values + (arg->n - left);
1885               int tmpl_idx = left == arg->n && *tmpl[0] != ':' ? 0 : 1;
1886               char escape = "%^"[tmpl_idx];
1887               size_t used = pivot_format_inner_template (
1888                 out, tmpl[tmpl_idx], escape, values, left,
1889                 show_values, show_variables);
1890               if (!used || used > left)
1891                 break;
1892               left -= used;
1893             }
1894         }
1895       else
1896         ds_put_byte (out, *template++);
1897     }
1898 }
1899
1900 static enum settings_value_show
1901 interpret_show (enum settings_value_show global_show,
1902                 enum settings_value_show table_show,
1903                 enum settings_value_show value_show,
1904                 bool has_label)
1905 {
1906   return (!has_label ? SETTINGS_VALUE_SHOW_VALUE
1907           : value_show != SETTINGS_VALUE_SHOW_DEFAULT ? value_show
1908           : table_show != SETTINGS_VALUE_SHOW_DEFAULT ? table_show
1909           : global_show);
1910 }
1911
1912 /* Appends a text representation of the body of VALUE to OUT.  SHOW_VALUES and
1913    SHOW_VARIABLES control whether variable and value labels are included.
1914
1915    The "body" omits subscripts and superscripts and footnotes.
1916
1917    Returns true if OUT is a number (or a number plus a value label), false
1918    otherwise.  */
1919 bool
1920 pivot_value_format_body (const struct pivot_value *value,
1921                          enum settings_value_show show_values,
1922                          enum settings_value_show show_variables,
1923                          struct string *out)
1924 {
1925   enum settings_value_show show;
1926   bool numeric = false;
1927
1928   switch (value->type)
1929     {
1930     case PIVOT_VALUE_NUMERIC:
1931       show = interpret_show (settings_get_show_values (),
1932                              show_values,
1933                              value->numeric.show,
1934                              value->numeric.value_label != NULL);
1935       if (show & SETTINGS_VALUE_SHOW_VALUE)
1936         {
1937           char *s = data_out (&(union value) { .f = value->numeric.x },
1938                               "UTF-8", &value->numeric.format);
1939           ds_put_cstr (out, s + strspn (s, " "));
1940           free (s);
1941         }
1942       if (show & SETTINGS_VALUE_SHOW_LABEL)
1943         {
1944           if (show & SETTINGS_VALUE_SHOW_VALUE)
1945             ds_put_byte (out, ' ');
1946           ds_put_cstr (out, value->numeric.value_label);
1947         }
1948       numeric = !(show & SETTINGS_VALUE_SHOW_LABEL);
1949       break;
1950
1951     case PIVOT_VALUE_STRING:
1952       show = interpret_show (settings_get_show_values (),
1953                              show_values,
1954                              value->string.show,
1955                              value->string.value_label != NULL);
1956       if (show & SETTINGS_VALUE_SHOW_VALUE)
1957         {
1958           if (value->string.hex)
1959             {
1960               for (const uint8_t *p = CHAR_CAST (uint8_t *, value->string.s);
1961                    *p; p++)
1962                 ds_put_format (out, "%02X", *p);
1963             }
1964           else
1965             ds_put_cstr (out, value->string.s);
1966         }
1967       if (show & SETTINGS_VALUE_SHOW_LABEL)
1968         {
1969           if (show & SETTINGS_VALUE_SHOW_VALUE)
1970             ds_put_byte (out, ' ');
1971           ds_put_cstr (out, value->string.value_label);
1972         }
1973       break;
1974
1975     case PIVOT_VALUE_VARIABLE:
1976       show = interpret_show (settings_get_show_variables (),
1977                              show_variables,
1978                              value->variable.show,
1979                              value->variable.var_label != NULL);
1980       if (show & SETTINGS_VALUE_SHOW_VALUE)
1981         ds_put_cstr (out, value->variable.var_name);
1982       if (show & SETTINGS_VALUE_SHOW_LABEL)
1983         {
1984           if (show & SETTINGS_VALUE_SHOW_VALUE)
1985             ds_put_byte (out, ' ');
1986           ds_put_cstr (out, value->variable.var_label);
1987         }
1988       break;
1989
1990     case PIVOT_VALUE_TEXT:
1991       ds_put_cstr (out, value->text.local);
1992       break;
1993
1994     case PIVOT_VALUE_TEMPLATE:
1995       pivot_format_template (out, value->template.local, value->template.args,
1996                              value->template.n_args, show_values,
1997                              show_variables);
1998       break;
1999     }
2000
2001   return numeric;
2002 }
2003
2004 /* Appends a text representation of VALUE to OUT.  SHOW_VALUES and
2005    SHOW_VARIABLES control whether variable and value labels are included.
2006
2007    Subscripts and footnotes are included. */
2008 void
2009 pivot_value_format (const struct pivot_value *value,
2010                     enum settings_value_show show_values,
2011                     enum settings_value_show show_variables,
2012                     struct string *out)
2013 {
2014   pivot_value_format_body (value, show_values, show_variables, out);
2015
2016   if (value->n_subscripts)
2017     {
2018       for (size_t i = 0; i < value->n_subscripts; i++)
2019         ds_put_format (out, "%c%s", i ? ',' : '_', value->subscripts[i]);
2020     }
2021
2022   for (size_t i = 0; i < value->n_footnotes; i++)
2023     {
2024       ds_put_byte (out, '^');
2025       pivot_value_format (value->footnotes[i]->marker,
2026                           show_values, show_variables, out);
2027     }
2028 }
2029
2030 /* Returns a text representation of VALUE.  The caller must free the string,
2031    with free(). */
2032 char *
2033 pivot_value_to_string (const struct pivot_value *value,
2034                        enum settings_value_show show_values,
2035                        enum settings_value_show show_variables)
2036 {
2037   struct string s = DS_EMPTY_INITIALIZER;
2038   pivot_value_format (value, show_values, show_variables, &s);
2039   return ds_steal_cstr (&s);
2040 }
2041
2042 /* Frees the data owned by V. */
2043 void
2044 pivot_value_destroy (struct pivot_value *value)
2045 {
2046   if (value)
2047     {
2048       font_style_uninit (value->font_style);
2049       free (value->font_style);
2050       free (value->cell_style);
2051       /* Do not free the elements of footnotes because VALUE does not own
2052          them. */
2053       free (value->footnotes);
2054
2055       for (size_t i = 0; i < value->n_subscripts; i++)
2056         free (value->subscripts[i]);
2057       free (value->subscripts);
2058
2059       switch (value->type)
2060         {
2061         case PIVOT_VALUE_NUMERIC:
2062           free (value->numeric.var_name);
2063           free (value->numeric.value_label);
2064           break;
2065
2066         case PIVOT_VALUE_STRING:
2067           free (value->string.s);
2068           free (value->string.var_name);
2069           free (value->string.value_label);
2070           break;
2071
2072         case PIVOT_VALUE_VARIABLE:
2073           free (value->variable.var_name);
2074           free (value->variable.var_label);
2075           break;
2076
2077         case PIVOT_VALUE_TEXT:
2078           free (value->text.local);
2079           if (value->text.c != value->text.local)
2080             free (value->text.c);
2081           if (value->text.id != value->text.local
2082               && value->text.id != value->text.c)
2083             free (value->text.id);
2084           break;
2085
2086         case PIVOT_VALUE_TEMPLATE:
2087           free (value->template.local);
2088           if (value->template.id != value->template.local)
2089             free (value->template.id);
2090           for (size_t i = 0; i < value->template.n_args; i++)
2091             pivot_argument_uninit (&value->template.args[i]);
2092           free (value->template.args);
2093           break;
2094         }
2095       free (value);
2096     }
2097 }
2098
2099 /* Sets AREA to the style to use for VALUE, with defaults coming from
2100    DEFAULT_STYLE for the parts of the style that VALUE doesn't override. */
2101 void
2102 pivot_value_get_style (struct pivot_value *value,
2103                        const struct font_style *base_font_style,
2104                        const struct cell_style *base_cell_style,
2105                        struct table_area_style *area)
2106 {
2107   font_style_copy (NULL, &area->font_style, (value->font_style
2108                                              ? value->font_style
2109                                              : base_font_style));
2110   area->cell_style = *(value->cell_style
2111                        ? value->cell_style
2112                        : base_cell_style);
2113 }
2114
2115 /* Copies AREA into VALUE's style. */
2116 void
2117 pivot_value_set_style (struct pivot_value *value,
2118                        const struct table_area_style *area)
2119 {
2120   if (value->font_style)
2121     font_style_uninit (value->font_style);
2122   else
2123     value->font_style = xmalloc (sizeof *value->font_style);
2124   font_style_copy (NULL, value->font_style, &area->font_style);
2125
2126   if (!value->cell_style)
2127     value->cell_style = xmalloc (sizeof *value->cell_style);
2128   *value->cell_style = area->cell_style;
2129 }
2130
2131 /* Frees the data owned by ARG (but not ARG itself). */
2132 void
2133 pivot_argument_uninit (struct pivot_argument *arg)
2134 {
2135   if (arg)
2136     {
2137       for (size_t i = 0; i < arg->n; i++)
2138         pivot_value_destroy (arg->values[i]);
2139       free (arg->values);
2140     }
2141 }
2142
2143 /* Creates and returns a new pivot_value whose contents is the null-terminated
2144    string TEXT.  Takes ownership of TEXT.
2145
2146    This function is for text strings provided by the user (with the exception
2147    that pivot_value_new_variable() should be used for variable names).  For
2148    strings that are part of the PSPP user interface, such as names of
2149    procedures, statistics, annotations, error messages, etc., use
2150    pivot_value_new_text(). */
2151 struct pivot_value *
2152 pivot_value_new_user_text_nocopy (char *text)
2153 {
2154   struct pivot_value *value = xmalloc (sizeof *value);
2155   *value = (struct pivot_value) {
2156     .type = PIVOT_VALUE_TEXT,
2157     .text = {
2158       .local = text,
2159       .c = text,
2160       .id = text,
2161       .user_provided = true,
2162     }
2163   };
2164   return value;
2165 }
2166
2167 /* Creates and returns a new pivot_value whose contents is the LENGTH bytes of
2168    TEXT.  Use SIZE_MAX if TEXT is null-teriminated and its length is not known
2169    in advance.
2170
2171    This function is for text strings provided by the user (with the exception
2172    that pivot_value_new_variable() should be used for variable names).  For
2173    strings that are part of the PSPP user interface, such as names of
2174    procedures, statistics, annotations, error messages, etc., use
2175    pivot_value_new_text().j
2176
2177    The caller retains ownership of TEXT.*/
2178 struct pivot_value *
2179 pivot_value_new_user_text (const char *text, size_t length)
2180 {
2181   return pivot_value_new_user_text_nocopy (
2182     xmemdup0 (text, length != SIZE_MAX ? length : strlen (text)));
2183 }
2184
2185 /* Creates and returns new pivot_value whose contents is TEXT, which should be
2186    a translatable string, but not actually translated yet, e.g. enclosed in
2187    N_().  This function is for text strings that are part of the PSPP user
2188    interface, such as names of procedures, statistics, annotations, error
2189    messages, etc.  For strings that come from the user, use
2190    pivot_value_new_user_text(). */
2191 struct pivot_value *
2192 pivot_value_new_text (const char *text)
2193 {
2194   char *c = xstrdup (text);
2195   char *local = xstrdup (gettext (c));
2196
2197   struct pivot_value *value = xmalloc (sizeof *value);
2198   *value = (struct pivot_value) {
2199     .type = PIVOT_VALUE_TEXT,
2200     .text = {
2201       .local = local,
2202       .c = c,
2203       .id = c,
2204       .user_provided = false,
2205     }
2206   };
2207   return value;
2208 }
2209
2210 /* Same as pivot_value_new_text() but its argument is a printf()-like format
2211    string. */
2212 struct pivot_value * PRINTF_FORMAT (1, 2)
2213 pivot_value_new_text_format (const char *format, ...)
2214 {
2215   va_list args;
2216   va_start (args, format);
2217   char *c = xvasprintf (format, args);
2218   va_end (args);
2219
2220   va_start (args, format);
2221   char *local = xvasprintf (gettext (format), args);
2222   va_end (args);
2223
2224   struct pivot_value *value = xmalloc (sizeof *value);
2225   *value = (struct pivot_value) {
2226     .type = PIVOT_VALUE_TEXT,
2227     .text = {
2228       .local = local,
2229       .c = c,
2230       .id = xstrdup (c),
2231       .user_provided = false,
2232     }
2233   };
2234   return value;
2235 }
2236
2237 /* Returns a new pivot_value that represents X.
2238
2239    The format to use for X is unspecified.  Usually the easiest way to specify
2240    a format is through assigning a result class to one of the categories that
2241    the pivot_value will end up in.  If that is not suitable, then the caller
2242    can use pivot_value_set_rc() or assign directly to value->numeric.format. */
2243 struct pivot_value *
2244 pivot_value_new_number (double x)
2245 {
2246   struct pivot_value *value = xmalloc (sizeof *value);
2247   *value = (struct pivot_value) {
2248     .type = PIVOT_VALUE_NUMERIC,
2249     .numeric = { .x = x, },
2250   };
2251   return value;
2252 }
2253
2254 /* Returns a new pivot_value that represents X, formatted as an integer. */
2255 struct pivot_value *
2256 pivot_value_new_integer (double x)
2257 {
2258   struct pivot_value *value = pivot_value_new_number (x);
2259   value->numeric.format = (struct fmt_spec) { FMT_F, 40, 0 };
2260   return value;
2261 }
2262
2263 /* Returns a new pivot_value that represents VALUE, formatted as for
2264    VARIABLE. */
2265 struct pivot_value *
2266 pivot_value_new_var_value (const struct variable *variable,
2267                            const union value *value)
2268 {
2269   struct pivot_value *pv = pivot_value_new_value (
2270     value, var_get_width (variable), var_get_print_format (variable),
2271     var_get_encoding (variable));
2272
2273   char *var_name = xstrdup (var_get_name (variable));
2274   if (var_is_alpha (variable))
2275     pv->string.var_name = var_name;
2276   else
2277     pv->numeric.var_name = var_name;
2278
2279   const char *label = var_lookup_value_label (variable, value);
2280   if (label)
2281     {
2282       if (var_is_alpha (variable))
2283         pv->string.value_label = xstrdup (label);
2284       else
2285         pv->numeric.value_label = xstrdup (label);
2286     }
2287
2288   return pv;
2289 }
2290
2291 /* Returns a new pivot_value that represents VALUE, with the given WIDTH,
2292    formatted with FORMAT.  For a string value, ENCODING must be its character
2293    encoding. */
2294 struct pivot_value *
2295 pivot_value_new_value (const union value *value, int width,
2296                        const struct fmt_spec *format, const char *encoding)
2297 {
2298   struct pivot_value *pv = xzalloc (sizeof *pv);
2299   if (width > 0)
2300     {
2301       char *s = recode_string (UTF8, encoding, CHAR_CAST (char *, value->s),
2302                                width);
2303       size_t n = strlen (s);
2304       while (n > 0 && s[n - 1] == ' ')
2305         s[--n] = '\0';
2306
2307       pv->type = PIVOT_VALUE_STRING;
2308       pv->string.s = s;
2309       pv->string.hex = format->type == FMT_AHEX;
2310     }
2311   else
2312     {
2313       pv->type = PIVOT_VALUE_NUMERIC;
2314       pv->numeric.x = value->f;
2315       pv->numeric.format = *format;
2316     }
2317
2318   return pv;
2319 }
2320
2321 /* Returns a new pivot_value for VARIABLE. */
2322 struct pivot_value *
2323 pivot_value_new_variable (const struct variable *variable)
2324 {
2325   struct pivot_value *value = xmalloc (sizeof *value);
2326   *value = (struct pivot_value) {
2327     .type = PIVOT_VALUE_VARIABLE,
2328     .variable = {
2329       .var_name = xstrdup (var_get_name (variable)),
2330       .var_label = xstrdup_if_nonempty (var_get_label (variable)),
2331     },
2332   };
2333   return value;
2334 }
2335
2336 /* Attaches a reference to FOOTNOTE to V. */
2337 void
2338 pivot_value_add_footnote (struct pivot_value *v,
2339                           const struct pivot_footnote *footnote)
2340 {
2341   /* Some legacy tables include numerous duplicate footnotes.  Suppress
2342      them. */
2343   for (size_t i = 0; i < v->n_footnotes; i++)
2344     if (v->footnotes[i] == footnote)
2345       return;
2346
2347   v->footnotes = xrealloc (v->footnotes,
2348                            (v->n_footnotes + 1) * sizeof *v->footnotes);
2349   v->footnotes[v->n_footnotes++] = footnote;
2350 }
2351
2352 /* If VALUE is a numeric value, and RC is a result class such as
2353    PIVOT_RC_COUNT, changes VALUE's format to the result class's. */
2354 void
2355 pivot_value_set_rc (const struct pivot_table *table, struct pivot_value *value,
2356                     const char *rc)
2357 {
2358   if (value->type == PIVOT_VALUE_NUMERIC)
2359     {
2360       const struct fmt_spec *f = pivot_table_get_format (table, rc);
2361       if (f)
2362         value->numeric.format = *f;
2363     }
2364 }
2365