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