spv-file-format: Document "show-title" option.
[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
1061   if (value->type == PIVOT_VALUE_NUMERIC && !value->numeric.format.w)
1062     {
1063       for (size_t i = 0; i < table->n_dimensions; i++)
1064         {
1065           const struct pivot_dimension *d = table->dimensions[i];
1066           if (dindexes[i] < d->n_leaves)
1067             {
1068               const struct pivot_category *c = d->data_leaves[dindexes[i]];
1069               if (c->format.w)
1070                 {
1071                   value->numeric.format = c->format;
1072                   goto done;
1073                 }
1074             }
1075         }
1076       value->numeric.format = *settings_get_format ();
1077
1078     done:;
1079     }
1080
1081   struct pivot_cell *cell = pivot_table_insert_cell (table, dindexes);
1082   pivot_value_destroy (cell->value);
1083   cell->value = value;
1084 }
1085
1086 /* Puts VALUE in the cell in TABLE with index IDX1.  TABLE must have 1
1087    dimension.  Takes ownership of VALUE.  */
1088 void
1089 pivot_table_put1 (struct pivot_table *table, size_t idx1,
1090                   struct pivot_value *value)
1091 {
1092   size_t dindexes[] = { idx1 };
1093   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1094 }
1095
1096 /* Puts VALUE in the cell in TABLE with index (IDX1, IDX2).  TABLE must have 2
1097    dimensions.  Takes ownership of VALUE.  */
1098 void
1099 pivot_table_put2 (struct pivot_table *table, size_t idx1, size_t idx2,
1100                   struct pivot_value *value)
1101 {
1102   size_t dindexes[] = { idx1, idx2 };
1103   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1104 }
1105
1106 /* Puts VALUE in the cell in TABLE with index (IDX1, IDX2, IDX3).  TABLE must
1107    have 3 dimensions.  Takes ownership of VALUE.  */
1108 void
1109 pivot_table_put3 (struct pivot_table *table, size_t idx1, size_t idx2,
1110                   size_t idx3, struct pivot_value *value)
1111 {
1112   size_t dindexes[] = { idx1, idx2, idx3 };
1113   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1114 }
1115
1116 /* Puts VALUE in the cell in TABLE with index (IDX1, IDX2, IDX3, IDX4).  TABLE
1117    must have 4 dimensions.  Takes ownership of VALUE.  */
1118 void
1119 pivot_table_put4 (struct pivot_table *table, size_t idx1, size_t idx2,
1120                   size_t idx3, size_t idx4, struct pivot_value *value)
1121 {
1122   size_t dindexes[] = { idx1, idx2, idx3, idx4 };
1123   pivot_table_put (table, dindexes, sizeof dindexes / sizeof *dindexes, value);
1124 }
1125
1126 /* Creates and returns a new footnote in TABLE with the given CONTENT and an
1127    automatically assigned marker.
1128
1129    The footnote will only appear in output if it is referenced.  Use
1130    pivot_value_add_footnote() to add a reference to the footnote. */
1131 struct pivot_footnote *
1132 pivot_table_create_footnote (struct pivot_table *table,
1133                              struct pivot_value *content)
1134 {
1135   return pivot_table_create_footnote__ (table, table->n_footnotes,
1136                                         NULL, content);
1137 }
1138
1139 static struct pivot_value *
1140 pivot_make_default_footnote_marker (int idx, bool show_numeric_markers)
1141 {
1142   char text[INT_BUFSIZE_BOUND (size_t)];
1143   if (show_numeric_markers)
1144     snprintf (text, sizeof text, "%d", idx + 1);
1145   else
1146     str_format_26adic (idx + 1, false, text, sizeof text);
1147   return pivot_value_new_user_text (text, -1);
1148 }
1149
1150 /* Creates or modifies a footnote in TABLE with 0-based number IDX (and creates
1151    all lower indexes as a side effect).  If MARKER is nonnull, sets the
1152    footnote's marker; if CONTENT is nonnull, sets the footnote's content. */
1153 struct pivot_footnote *
1154 pivot_table_create_footnote__ (struct pivot_table *table, size_t idx,
1155                                struct pivot_value *marker,
1156                                struct pivot_value *content)
1157 {
1158   if (idx >= table->n_footnotes)
1159     {
1160       while (idx >= table->allocated_footnotes)
1161         table->footnotes = x2nrealloc (table->footnotes,
1162                                        &table->allocated_footnotes,
1163                                        sizeof *table->footnotes);
1164       while (idx >= table->n_footnotes)
1165         {
1166           struct pivot_footnote *f = xmalloc (sizeof *f);
1167           f->idx = table->n_footnotes;
1168           f->marker = pivot_make_default_footnote_marker (
1169             f->idx, table->look->show_numeric_markers);
1170           f->content = NULL;
1171           f->show = true;
1172
1173           table->footnotes[table->n_footnotes++] = f;
1174         }
1175     }
1176
1177   struct pivot_footnote *f = table->footnotes[idx];
1178   if (marker)
1179     {
1180       pivot_value_destroy (f->marker);
1181       f->marker = marker;
1182     }
1183   if (content)
1184     {
1185       pivot_value_destroy (f->content);
1186       f->content = content;
1187     }
1188   return f;
1189 }
1190
1191 /* Frees the data owned by F. */
1192 void
1193 pivot_footnote_destroy (struct pivot_footnote *f)
1194 {
1195   if (f)
1196     {
1197       pivot_value_destroy (f->content);
1198       pivot_value_destroy (f->marker);
1199       free (f);
1200     }
1201 }
1202
1203 /* Converts per-axis presentation-order indexes, given in PINDEXES, into data
1204    indexes for each dimension in TABLE in DINDEXES[]. */
1205 void
1206 pivot_table_convert_indexes_ptod (const struct pivot_table *table,
1207                                   const size_t *pindexes[PIVOT_N_AXES],
1208                                   size_t dindexes[/* table->n_dimensions */])
1209 {
1210   for (size_t i = 0; i < PIVOT_N_AXES; i++)
1211     {
1212       const struct pivot_axis *axis = &table->axes[i];
1213
1214       for (size_t j = 0; j < axis->n_dimensions; j++)
1215         {
1216           const struct pivot_dimension *d = axis->dimensions[j];
1217           dindexes[d->top_index]
1218             = d->presentation_leaves[pindexes[i][j]]->data_index;
1219         }
1220     }
1221 }
1222
1223 size_t *
1224 pivot_table_enumerate_axis (const struct pivot_table *table,
1225                             enum pivot_axis_type axis_type,
1226                             const size_t *layer_indexes, bool omit_empty,
1227                             size_t *n)
1228 {
1229   const struct pivot_axis *axis = &table->axes[axis_type];
1230   if (!axis->n_dimensions)
1231     {
1232       size_t *enumeration = xnmalloc (2, sizeof *enumeration);
1233       enumeration[0] = 0;
1234       enumeration[1] = SIZE_MAX;
1235       if (n)
1236         *n = 1;
1237       return enumeration;
1238     }
1239   else if (!axis->extent)
1240     {
1241       size_t *enumeration = xmalloc (sizeof *enumeration);
1242       *enumeration = SIZE_MAX;
1243       if (n)
1244         *n = 0;
1245       return enumeration;
1246     }
1247
1248   size_t *enumeration = xnmalloc (xsum (xtimes (axis->extent,
1249                                                 axis->n_dimensions), 1),
1250                                   sizeof *enumeration);
1251   size_t *p = enumeration;
1252   size_t *dindexes = XCALLOC (table->n_dimensions, size_t);
1253
1254   size_t *axis_indexes;
1255   PIVOT_AXIS_FOR_EACH (axis_indexes, axis)
1256     {
1257       if (omit_empty)
1258         {
1259           enum pivot_axis_type axis2_type
1260             = pivot_axis_type_transpose (axis_type);
1261
1262           size_t *axis2_indexes;
1263           PIVOT_AXIS_FOR_EACH (axis2_indexes, &table->axes[axis2_type])
1264             {
1265               const size_t *pindexes[PIVOT_N_AXES];
1266               pindexes[PIVOT_AXIS_LAYER] = layer_indexes;
1267               pindexes[axis_type] = axis_indexes;
1268               pindexes[axis2_type] = axis2_indexes;
1269               pivot_table_convert_indexes_ptod (table, pindexes, dindexes);
1270               if (pivot_table_get (table, dindexes))
1271                 goto found;
1272             }
1273           continue;
1274
1275         found:
1276           free (axis2_indexes);
1277         }
1278
1279       memcpy (p, axis_indexes, axis->n_dimensions * sizeof *p);
1280       p += axis->n_dimensions;
1281     }
1282   if (omit_empty && p == enumeration)
1283     {
1284       PIVOT_AXIS_FOR_EACH (axis_indexes, axis)
1285         {
1286           memcpy (p, axis_indexes, axis->n_dimensions * sizeof *p);
1287           p += axis->n_dimensions;
1288         }
1289     }
1290   *p = SIZE_MAX;
1291   if (n)
1292     *n = (p - enumeration) / axis->n_dimensions;
1293
1294   free (dindexes);
1295   return enumeration;
1296 }
1297
1298 static const struct pivot_cell *
1299 pivot_table_lookup_cell (const struct pivot_table *table,
1300                           const size_t *dindexes)
1301 {
1302   unsigned int hash = pivot_cell_hash_indexes (dindexes, table->n_dimensions);
1303   return pivot_table_lookup_cell__ (table, dindexes, hash);
1304 }
1305
1306 const struct pivot_value *
1307 pivot_table_get (const struct pivot_table *table, const size_t *dindexes)
1308 {
1309   const struct pivot_cell *cell = pivot_table_lookup_cell (table, dindexes);
1310   return cell ? cell->value : NULL;
1311 }
1312
1313 struct pivot_value *
1314 pivot_table_get_rw (struct pivot_table *table, const size_t *dindexes)
1315 {
1316   struct pivot_cell *cell = pivot_table_insert_cell (table, dindexes);
1317   if (!cell->value)
1318     cell->value = pivot_value_new_user_text ("", -1);
1319   return cell->value;
1320 }
1321
1322 static void
1323 distribute_extra_depth (struct pivot_category *category, size_t extra_depth)
1324 {
1325   if (pivot_category_is_group (category) && category->n_subs)
1326     for (size_t i = 0; i < category->n_subs; i++)
1327       distribute_extra_depth (category->subs[i], extra_depth);
1328   else
1329     category->extra_depth += extra_depth;
1330 }
1331
1332 static void
1333 pivot_category_assign_label_depth (struct pivot_category *category,
1334                                    bool dimension_labels_in_corner)
1335 {
1336   category->extra_depth = 0;
1337
1338   if (pivot_category_is_group (category))
1339     {
1340       size_t depth = 0;
1341       for (size_t i = 0; i < category->n_subs; i++)
1342         {
1343           pivot_category_assign_label_depth (category->subs[i], false);
1344           depth = MAX (depth, category->subs[i]->label_depth);
1345         }
1346
1347       for (size_t i = 0; i < category->n_subs; i++)
1348         {
1349           struct pivot_category *sub = category->subs[i];
1350
1351           size_t extra_depth = depth - sub->label_depth;
1352           if (extra_depth)
1353             distribute_extra_depth (sub, extra_depth);
1354
1355           sub->label_depth = depth;
1356         }
1357
1358       category->show_label_in_corner = (category->show_label
1359                                         && dimension_labels_in_corner);
1360       category->label_depth
1361         = (category->show_label && !category->show_label_in_corner
1362            ? depth + 1 : depth);
1363     }
1364   else
1365     category->label_depth = 1;
1366 }
1367
1368 static bool
1369 pivot_axis_assign_label_depth (struct pivot_table *table,
1370                              enum pivot_axis_type axis_type,
1371                              bool dimension_labels_in_corner)
1372 {
1373   struct pivot_axis *axis = &table->axes[axis_type];
1374   bool any_label_shown_in_corner = false;
1375   axis->label_depth = 0;
1376   axis->extent = 1;
1377   for (size_t i = 0; i < axis->n_dimensions; i++)
1378     {
1379       struct pivot_dimension *d = axis->dimensions[i];
1380       pivot_category_assign_label_depth (d->root, dimension_labels_in_corner);
1381       d->label_depth = d->hide_all_labels ? 0 : d->root->label_depth;
1382       axis->label_depth += d->label_depth;
1383       axis->extent *= d->n_leaves;
1384
1385       if (d->root->show_label_in_corner)
1386         any_label_shown_in_corner = true;
1387     }
1388   return any_label_shown_in_corner;
1389 }
1390
1391 void
1392 pivot_table_assign_label_depth (struct pivot_table *table)
1393 {
1394   pivot_axis_assign_label_depth (table, PIVOT_AXIS_COLUMN, false);
1395   if (pivot_axis_assign_label_depth (
1396         table, PIVOT_AXIS_ROW, (table->look->row_labels_in_corner
1397                                 && !table->corner_text))
1398       && table->axes[PIVOT_AXIS_COLUMN].label_depth == 0)
1399     table->axes[PIVOT_AXIS_COLUMN].label_depth = 1;
1400   pivot_axis_assign_label_depth (table, PIVOT_AXIS_LAYER, false);
1401 }
1402 \f
1403 /* Footnotes. */
1404
1405 \f
1406 \f
1407 static void
1408 indent (int indentation)
1409 {
1410   for (int i = 0; i < indentation * 2; i++)
1411     putchar (' ');
1412 }
1413
1414 static void
1415 pivot_value_dump (const struct pivot_value *value)
1416 {
1417   char *s = pivot_value_to_string (value, SETTINGS_VALUE_SHOW_DEFAULT,
1418                                    SETTINGS_VALUE_SHOW_DEFAULT);
1419   fputs (s, stdout);
1420   free (s);
1421 }
1422
1423 static void
1424 pivot_table_dump_value (const struct pivot_value *value, const char *name,
1425                       int indentation)
1426 {
1427   if (value)
1428     {
1429       indent (indentation);
1430       printf ("%s: ", name);
1431       pivot_value_dump (value);
1432       putchar ('\n');
1433     }
1434 }
1435
1436 static void
1437 pivot_table_dump_string (const char *string, const char *name, int indentation)
1438 {
1439   if (string)
1440     {
1441       indent (indentation);
1442       printf ("%s: %s\n", name, string);
1443     }
1444 }
1445
1446 static void
1447 pivot_category_dump (const struct pivot_category *c, int indentation)
1448 {
1449   indent (indentation);
1450   printf ("%s \"", pivot_category_is_leaf (c) ? "leaf" : "group");
1451   pivot_value_dump (c->name);
1452   printf ("\" ");
1453
1454   if (pivot_category_is_leaf (c))
1455     printf ("data_index=%zu\n", c->data_index);
1456   else
1457     {
1458       printf (" (label %s)", c->show_label ? "shown" : "hidden");
1459       printf ("\n");
1460
1461       for (size_t i = 0; i < c->n_subs; i++)
1462         pivot_category_dump (c->subs[i], indentation + 1);
1463     }
1464 }
1465
1466 void
1467 pivot_dimension_dump (const struct pivot_dimension *d, int indentation)
1468 {
1469   indent (indentation);
1470   printf ("%s dimension %zu (where 0=innermost), label_depth=%d:\n",
1471           pivot_axis_type_to_string (d->axis_type), d->level, d->label_depth);
1472
1473   pivot_category_dump (d->root, indentation + 1);
1474 }
1475
1476 static void
1477 table_area_style_dump (enum pivot_area area, const struct table_area_style *a,
1478                        int indentation)
1479 {
1480   indent (indentation);
1481   printf ("%s: ", pivot_area_to_string (area));
1482   font_style_dump (&a->font_style);
1483   putchar (' ');
1484   cell_style_dump (&a->cell_style);
1485   putchar ('\n');
1486 }
1487
1488 static void
1489 table_border_style_dump (enum pivot_border border,
1490                          const struct table_border_style *b, int indentation)
1491 {
1492   indent (indentation);
1493   printf ("%s: %s ", pivot_border_to_string (border),
1494           table_stroke_to_string (b->stroke));
1495   cell_color_dump (&b->color);
1496   putchar ('\n');
1497 }
1498
1499 static char ***
1500 compose_headings (const struct pivot_axis *axis,
1501                   const size_t *column_enumeration,
1502                   enum settings_value_show show_values,
1503                   enum settings_value_show show_variables)
1504 {
1505   if (!axis->n_dimensions || !axis->extent || !axis->label_depth)
1506     return NULL;
1507
1508   char ***headings = xnmalloc (axis->label_depth, sizeof *headings);
1509   for (size_t i = 0; i < axis->label_depth; i++)
1510     headings[i] = xcalloc (axis->extent, sizeof **headings);
1511
1512   const size_t *indexes;
1513   size_t column = 0;
1514   PIVOT_ENUMERATION_FOR_EACH (indexes, column_enumeration, axis)
1515     {
1516       int row = axis->label_depth - 1;
1517       for (int dim_index = 0; dim_index < axis->n_dimensions; dim_index++)
1518         {
1519           const struct pivot_dimension *d = axis->dimensions[dim_index];
1520           if (d->hide_all_labels)
1521             continue;
1522           for (const struct pivot_category *c
1523                  = d->presentation_leaves[indexes[dim_index]];
1524                c;
1525                c = c->parent)
1526             {
1527               if (pivot_category_is_leaf (c) || (c->show_label
1528                                                  && !c->show_label_in_corner))
1529                 {
1530                   headings[row][column] = pivot_value_to_string (
1531                     c->name, show_values, show_variables);
1532                   if (!*headings[row][column])
1533                     headings[row][column] = xstrdup ("<blank>");
1534                   row--;
1535                 }
1536             }
1537         }
1538       column++;
1539     }
1540
1541   return headings;
1542 }
1543
1544 static void
1545 free_headings (const struct pivot_axis *axis, char ***headings)
1546 {
1547   for (size_t i = 0; i < axis->label_depth; i++)
1548     {
1549       for (size_t j = 0; j < axis->extent; j++)
1550         free (headings[i][j]);
1551       free (headings[i]);
1552     }
1553   free (headings);
1554 }
1555
1556 static void
1557 pivot_table_sizing_dump (const char *name,
1558                          const int width_ranges[2],
1559                          const struct pivot_table_sizing *s,
1560                          int indentation)
1561 {
1562   indent (indentation);
1563   printf ("%ss: min=%d, max=%d\n", name, width_ranges[0], width_ranges[1]);
1564   if (s->n_widths)
1565     {
1566       indent (indentation + 1);
1567       printf ("%s widths:", name);
1568       for (size_t i = 0; i < s->n_widths; i++)
1569         printf (" %d", s->widths[i]);
1570       printf ("\n");
1571     }
1572   if (s->n_breaks)
1573     {
1574       indent (indentation + 1);
1575       printf ("break after %ss:", name);
1576       for (size_t i = 0; i < s->n_breaks; i++)
1577         printf (" %zu", s->breaks[i]);
1578       printf ("\n");
1579     }
1580   if (s->n_keeps)
1581     {
1582       indent (indentation + 1);
1583       printf ("keep %ss together:", name);
1584       for (size_t i = 0; i < s->n_keeps; i++)
1585         printf (" [%zu,%zu]",
1586                 s->keeps[i].ofs,
1587                 s->keeps[i].ofs + s->keeps[i].n - 1);
1588       printf ("\n");
1589     }
1590 }
1591
1592 void
1593 pivot_table_dump (const struct pivot_table *table, int indentation)
1594 {
1595   if (!table)
1596     return;
1597
1598   int old_decimal = settings_get_decimal_char (FMT_COMMA);
1599   if (table->decimal == '.' || table->decimal == ',')
1600     settings_set_decimal_char (table->decimal);
1601
1602   pivot_table_dump_value (table->title, "title", indentation);
1603   pivot_table_dump_value (table->subtype, "subtype", indentation);
1604   pivot_table_dump_string (table->command_c, "command", indentation);
1605   pivot_table_dump_string (table->dataset, "dataset", indentation);
1606   pivot_table_dump_string (table->datafile, "datafile", indentation);
1607   pivot_table_dump_string (table->notes, "notes", indentation);
1608   pivot_table_dump_string (table->look->name, "table-look", indentation);
1609   if (table->date)
1610     {
1611       indent (indentation);
1612
1613       struct tm *tm = localtime (&table->date);
1614       printf ("date: %d-%02d-%02d %d:%02d:%02d\n", tm->tm_year + 1900,
1615               tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
1616               tm->tm_sec);
1617     }
1618
1619   indent (indentation);
1620   printf ("sizing:\n");
1621   pivot_table_sizing_dump ("column", table->look->width_ranges[TABLE_HORZ],
1622                            &table->sizing[TABLE_HORZ], indentation + 1);
1623   pivot_table_sizing_dump ("row", table->look->width_ranges[TABLE_VERT],
1624                            &table->sizing[TABLE_VERT], indentation + 1);
1625
1626   indent (indentation);
1627   printf ("areas:\n");
1628   for (enum pivot_area area = 0; area < PIVOT_N_AREAS; area++)
1629     table_area_style_dump (area, &table->look->areas[area], indentation + 1);
1630
1631   indent (indentation);
1632   printf ("borders:\n");
1633   for (enum pivot_border border = 0; border < PIVOT_N_BORDERS; border++)
1634     table_border_style_dump (border, &table->look->borders[border],
1635                              indentation + 1);
1636
1637   for (size_t i = 0; i < table->n_dimensions; i++)
1638     pivot_dimension_dump (table->dimensions[i], indentation);
1639
1640   /* Presentation and data indexes. */
1641   size_t *dindexes = XCALLOC (table->n_dimensions, size_t);
1642
1643   const struct pivot_axis *layer_axis = &table->axes[PIVOT_AXIS_LAYER];
1644   if (layer_axis->n_dimensions)
1645     {
1646       indent (indentation);
1647       printf ("current layer:");
1648
1649       for (size_t i = 0; i < layer_axis->n_dimensions; i++)
1650         {
1651           const struct pivot_dimension *d = layer_axis->dimensions[i];
1652           char *name = pivot_value_to_string (d->root->name,
1653                                               table->show_values,
1654                                               table->show_variables);
1655           char *value = pivot_value_to_string (
1656             d->data_leaves[table->current_layer[i]]->name,
1657             table->show_values, table->show_variables);
1658           printf (" %s=%s", name, value);
1659           free (value);
1660           free (name);
1661         }
1662
1663       putchar ('\n');
1664     }
1665
1666   size_t *layer_indexes;
1667   size_t layer_iteration = 0;
1668   PIVOT_AXIS_FOR_EACH (layer_indexes, &table->axes[PIVOT_AXIS_LAYER])
1669     {
1670       indent (indentation);
1671       printf ("layer %zu:", layer_iteration++);
1672
1673       const struct pivot_axis *layer_axis = &table->axes[PIVOT_AXIS_LAYER];
1674       for (size_t i = 0; i < layer_axis->n_dimensions; i++)
1675         {
1676           const struct pivot_dimension *d = layer_axis->dimensions[i];
1677
1678           fputs (i == 0 ? " " : ", ", stdout);
1679           pivot_value_dump (d->root->name);
1680           fputs (" =", stdout);
1681
1682           struct pivot_value **names = xnmalloc (d->n_leaves, sizeof *names);
1683           size_t n_names = 0;
1684           for (const struct pivot_category *c
1685                  = d->presentation_leaves[layer_indexes[i]];
1686                c;
1687                c = c->parent)
1688             {
1689               if (pivot_category_is_leaf (c) || c->show_label)
1690                 names[n_names++] = c->name;
1691             }
1692
1693           for (size_t i = n_names; i-- > 0;)
1694             {
1695               putchar (' ');
1696               pivot_value_dump (names[i]);
1697             }
1698           free (names);
1699         }
1700       putchar ('\n');
1701
1702       size_t *column_enumeration = pivot_table_enumerate_axis (
1703         table, PIVOT_AXIS_COLUMN, layer_indexes, table->look->omit_empty, NULL);
1704       size_t *row_enumeration = pivot_table_enumerate_axis (
1705         table, PIVOT_AXIS_ROW, layer_indexes, table->look->omit_empty, NULL);
1706
1707       char ***column_headings = compose_headings (
1708         &table->axes[PIVOT_AXIS_COLUMN], column_enumeration,
1709         table->show_values, table->show_variables);
1710       for (size_t y = 0; y < table->axes[PIVOT_AXIS_COLUMN].label_depth; y++)
1711         {
1712           indent (indentation + 1);
1713           for (size_t x = 0; x < table->axes[PIVOT_AXIS_COLUMN].extent; x++)
1714             {
1715               if (x)
1716                 fputs ("; ", stdout);
1717               if (column_headings[y][x])
1718                 fputs (column_headings[y][x], stdout);
1719             }
1720           putchar ('\n');
1721         }
1722       free_headings (&table->axes[PIVOT_AXIS_COLUMN], column_headings);
1723
1724       indent (indentation + 1);
1725       printf ("-----------------------------------------------\n");
1726
1727       char ***row_headings = compose_headings (
1728         &table->axes[PIVOT_AXIS_ROW], row_enumeration,
1729         table->show_values, table->show_variables);
1730
1731       size_t x = 0;
1732       const size_t *pindexes[PIVOT_N_AXES]
1733         = { [PIVOT_AXIS_LAYER] = layer_indexes };
1734       PIVOT_ENUMERATION_FOR_EACH (pindexes[PIVOT_AXIS_ROW], row_enumeration,
1735                                   &table->axes[PIVOT_AXIS_ROW])
1736         {
1737           indent (indentation + 1);
1738
1739           size_t i = 0;
1740           for (size_t y = 0; y < table->axes[PIVOT_AXIS_ROW].label_depth; y++)
1741             {
1742               if (i++)
1743                 fputs ("; ", stdout);
1744               if (row_headings[y][x])
1745                 fputs (row_headings[y][x], stdout);
1746             }
1747
1748           printf (" | ");
1749
1750           i = 0;
1751           PIVOT_ENUMERATION_FOR_EACH (pindexes[PIVOT_AXIS_COLUMN],
1752                                       column_enumeration,
1753                                       &table->axes[PIVOT_AXIS_COLUMN])
1754             {
1755               if (i++)
1756                 printf ("; ");
1757
1758               pivot_table_convert_indexes_ptod (table, pindexes, dindexes);
1759               const struct pivot_value *value = pivot_table_get (
1760                 table, dindexes);
1761               if (value)
1762                 pivot_value_dump (value);
1763             }
1764           printf ("\n");
1765
1766           x++;
1767         }
1768
1769       free (column_enumeration);
1770       free (row_enumeration);
1771       free_headings (&table->axes[PIVOT_AXIS_ROW], row_headings);
1772     }
1773
1774   pivot_table_dump_value (table->caption, "caption", indentation);
1775
1776   for (size_t i = 0; i < table->n_footnotes; i++)
1777     {
1778       const struct pivot_footnote *f = table->footnotes[i];
1779       indent (indentation);
1780       putchar ('[');
1781       if (f->marker)
1782         pivot_value_dump (f->marker);
1783       else
1784         printf ("%zu", f->idx);
1785       putchar (']');
1786       pivot_value_dump (f->content);
1787       putchar ('\n');
1788     }
1789
1790   free (dindexes);
1791   settings_set_decimal_char (old_decimal);
1792 }
1793 \f
1794 static const char *
1795 consume_int (const char *p, size_t *n)
1796 {
1797   *n = 0;
1798   while (c_isdigit (*p))
1799     *n = *n * 10 + (*p++ - '0');
1800   return p;
1801 }
1802
1803 static size_t
1804 pivot_format_inner_template (struct string *out, const char *template,
1805                              char escape,
1806                              struct pivot_value **values, size_t n_values,
1807                              enum settings_value_show show_values,
1808                              enum settings_value_show show_variables)
1809 {
1810   size_t args_consumed = 0;
1811   while (*template && *template != ':')
1812     {
1813       if (*template == '\\' && template[1])
1814         {
1815           ds_put_byte (out, template[1] == 'n' ? '\n' : template[1]);
1816           template += 2;
1817         }
1818       else if (*template == escape)
1819         {
1820           size_t index;
1821           template = consume_int (template + 1, &index);
1822           if (index >= 1 && index <= n_values)
1823             {
1824               pivot_value_format (values[index - 1], show_values,
1825                                   show_variables, out);
1826               args_consumed = MAX (args_consumed, index);
1827             }
1828         }
1829       else
1830         ds_put_byte (out, *template++);
1831     }
1832   return args_consumed;
1833 }
1834
1835 static const char *
1836 pivot_extract_inner_template (const char *template, const char **p)
1837 {
1838   *p = template;
1839
1840   for (;;)
1841     {
1842       if (*template == '\\' && template[1] != '\0')
1843         template += 2;
1844       else if (*template == ':')
1845         return template + 1;
1846       else if (*template == '\0')
1847         return template;
1848       else
1849         template++;
1850     }
1851 }
1852
1853 static void
1854 pivot_format_template (struct string *out, const char *template,
1855                        const struct pivot_argument *args, size_t n_args,
1856                        enum settings_value_show show_values,
1857                        enum settings_value_show show_variables)
1858 {
1859   while (*template)
1860     {
1861       if (*template == '\\' && template[1] != '\0')
1862         {
1863           ds_put_byte (out, template[1] == 'n' ? '\n' : template[1]);
1864           template += 2;
1865         }
1866       else if (*template == '^')
1867         {
1868           size_t index;
1869           template = consume_int (template + 1, &index);
1870           if (index >= 1 && index <= n_args && args[index - 1].n > 0)
1871             pivot_value_format (args[index - 1].values[0],
1872                                 show_values, show_variables, out);
1873         }
1874       else if (*template == '[')
1875         {
1876           const char *tmpl[2];
1877           template = pivot_extract_inner_template (template + 1, &tmpl[0]);
1878           template = pivot_extract_inner_template (template, &tmpl[1]);
1879           template += *template == ']';
1880
1881           size_t index;
1882           template = consume_int (template, &index);
1883           if (index < 1 || index > n_args)
1884             continue;
1885
1886           const struct pivot_argument *arg = &args[index - 1];
1887           size_t left = arg->n;
1888           while (left)
1889             {
1890               struct pivot_value **values = arg->values + (arg->n - left);
1891               int tmpl_idx = left == arg->n && *tmpl[0] != ':' ? 0 : 1;
1892               char escape = "%^"[tmpl_idx];
1893               size_t used = pivot_format_inner_template (
1894                 out, tmpl[tmpl_idx], escape, values, left,
1895                 show_values, show_variables);
1896               if (!used || used > left)
1897                 break;
1898               left -= used;
1899             }
1900         }
1901       else
1902         ds_put_byte (out, *template++);
1903     }
1904 }
1905
1906 static enum settings_value_show
1907 interpret_show (enum settings_value_show global_show,
1908                 enum settings_value_show table_show,
1909                 enum settings_value_show value_show,
1910                 bool has_label)
1911 {
1912   return (!has_label ? SETTINGS_VALUE_SHOW_VALUE
1913           : value_show != SETTINGS_VALUE_SHOW_DEFAULT ? value_show
1914           : table_show != SETTINGS_VALUE_SHOW_DEFAULT ? table_show
1915           : global_show);
1916 }
1917
1918 /* Appends a text representation of the body of VALUE to OUT.  SHOW_VALUES and
1919    SHOW_VARIABLES control whether variable and value labels are included.
1920
1921    The "body" omits subscripts and superscripts and footnotes. */
1922 bool
1923 pivot_value_format_body (const struct pivot_value *value,
1924                          enum settings_value_show show_values,
1925                          enum settings_value_show show_variables,
1926                          struct string *out)
1927 {
1928   enum settings_value_show show;
1929   bool numeric = false;
1930
1931   switch (value->type)
1932     {
1933     case PIVOT_VALUE_NUMERIC:
1934       show = interpret_show (settings_get_show_values (),
1935                              show_values,
1936                              value->numeric.show,
1937                              value->numeric.value_label != NULL);
1938       if (show & SETTINGS_VALUE_SHOW_VALUE)
1939         {
1940           char *s = data_out (&(union value) { .f = value->numeric.x },
1941                               "UTF-8", &value->numeric.format);
1942           ds_put_cstr (out, s + strspn (s, " "));
1943           free (s);
1944         }
1945       if (show & SETTINGS_VALUE_SHOW_LABEL)
1946         {
1947           if (show & SETTINGS_VALUE_SHOW_VALUE)
1948             ds_put_byte (out, ' ');
1949           ds_put_cstr (out, value->numeric.value_label);
1950         }
1951       numeric = !(show & SETTINGS_VALUE_SHOW_LABEL);
1952       break;
1953
1954     case PIVOT_VALUE_STRING:
1955       show = interpret_show (settings_get_show_values (),
1956                              show_values,
1957                              value->string.show,
1958                              value->string.value_label != NULL);
1959       if (show & SETTINGS_VALUE_SHOW_VALUE)
1960         {
1961           if (value->string.hex)
1962             {
1963               for (const uint8_t *p = CHAR_CAST (uint8_t *, value->string.s);
1964                    *p; p++)
1965                 ds_put_format (out, "%02X", *p);
1966             }
1967           else
1968             ds_put_cstr (out, value->string.s);
1969         }
1970       if (show & SETTINGS_VALUE_SHOW_LABEL)
1971         {
1972           if (show & SETTINGS_VALUE_SHOW_VALUE)
1973             ds_put_byte (out, ' ');
1974           ds_put_cstr (out, value->string.value_label);
1975         }
1976       break;
1977
1978     case PIVOT_VALUE_VARIABLE:
1979       show = interpret_show (settings_get_show_variables (),
1980                              show_variables,
1981                              value->variable.show,
1982                              value->variable.var_label != NULL);
1983       if (show & SETTINGS_VALUE_SHOW_VALUE)
1984         ds_put_cstr (out, value->variable.var_name);
1985       if (show & SETTINGS_VALUE_SHOW_LABEL)
1986         {
1987           if (show & SETTINGS_VALUE_SHOW_VALUE)
1988             ds_put_byte (out, ' ');
1989           ds_put_cstr (out, value->variable.var_label);
1990         }
1991       break;
1992
1993     case PIVOT_VALUE_TEXT:
1994       ds_put_cstr (out, value->text.local);
1995       break;
1996
1997     case PIVOT_VALUE_TEMPLATE:
1998       pivot_format_template (out, value->template.local, value->template.args,
1999                              value->template.n_args, show_values,
2000                              show_variables);
2001       break;
2002     }
2003
2004   return numeric;
2005 }
2006
2007 /* Appends a text representation of VALUE to OUT.  SHOW_VALUES and
2008    SHOW_VARIABLES control whether variable and value labels are included.
2009
2010    Subscripts and superscripts and footnotes are included. */
2011 void
2012 pivot_value_format (const struct pivot_value *value,
2013                     enum settings_value_show show_values,
2014                     enum settings_value_show show_variables,
2015                     struct string *out)
2016 {
2017   pivot_value_format_body (value, show_values, show_variables, out);
2018
2019   if (value->n_subscripts)
2020     {
2021       for (size_t i = 0; i < value->n_subscripts; i++)
2022         ds_put_format (out, "%c%s", i ? ',' : '_', value->subscripts[i]);
2023     }
2024
2025   if (value->superscript)
2026     ds_put_format (out, "^%s", value->superscript);
2027
2028   for (size_t i = 0; i < value->n_footnotes; i++)
2029     {
2030       ds_put_byte (out, '^');
2031       pivot_value_format (value->footnotes[i]->marker,
2032                           show_values, show_variables, out);
2033     }
2034 }
2035
2036 /* Returns a text representation of VALUE.  The caller must free the string,
2037    with free(). */
2038 char *
2039 pivot_value_to_string (const struct pivot_value *value,
2040                        enum settings_value_show show_values,
2041                        enum settings_value_show show_variables)
2042 {
2043   struct string s = DS_EMPTY_INITIALIZER;
2044   pivot_value_format (value, show_values, show_variables, &s);
2045   return ds_steal_cstr (&s);
2046 }
2047
2048 /* Frees the data owned by V. */
2049 void
2050 pivot_value_destroy (struct pivot_value *value)
2051 {
2052   if (value)
2053     {
2054       font_style_uninit (value->font_style);
2055       free (value->font_style);
2056       free (value->cell_style);
2057       /* Do not free the elements of footnotes because VALUE does not own
2058          them. */
2059       free (value->footnotes);
2060
2061       for (size_t i = 0; i < value->n_subscripts; i++)
2062         free (value->subscripts[i]);
2063       free (value->subscripts);
2064
2065       free (value->superscript);
2066
2067       switch (value->type)
2068         {
2069         case PIVOT_VALUE_NUMERIC:
2070           free (value->numeric.var_name);
2071           free (value->numeric.value_label);
2072           break;
2073
2074         case PIVOT_VALUE_STRING:
2075           free (value->string.s);
2076           free (value->string.var_name);
2077           free (value->string.value_label);
2078           break;
2079
2080         case PIVOT_VALUE_VARIABLE:
2081           free (value->variable.var_name);
2082           free (value->variable.var_label);
2083           break;
2084
2085         case PIVOT_VALUE_TEXT:
2086           free (value->text.local);
2087           if (value->text.c != value->text.local)
2088             free (value->text.c);
2089           if (value->text.id != value->text.local
2090               && value->text.id != value->text.c)
2091             free (value->text.id);
2092           break;
2093
2094         case PIVOT_VALUE_TEMPLATE:
2095           free (value->template.local);
2096           if (value->template.id != value->template.local)
2097             free (value->template.id);
2098           for (size_t i = 0; i < value->template.n_args; i++)
2099             pivot_argument_uninit (&value->template.args[i]);
2100           free (value->template.args);
2101           break;
2102         }
2103       free (value);
2104     }
2105 }
2106
2107 /* Sets AREA to the style to use for VALUE, with defaults coming from
2108    DEFAULT_STYLE for the parts of the style that VALUE doesn't override. */
2109 void
2110 pivot_value_get_style (struct pivot_value *value,
2111                        const struct font_style *base_font_style,
2112                        const struct cell_style *base_cell_style,
2113                        struct table_area_style *area)
2114 {
2115   font_style_copy (NULL, &area->font_style, (value->font_style
2116                                              ? value->font_style
2117                                              : base_font_style));
2118   area->cell_style = *(value->cell_style
2119                        ? value->cell_style
2120                        : base_cell_style);
2121 }
2122
2123 /* Copies AREA into VALUE's style. */
2124 void
2125 pivot_value_set_style (struct pivot_value *value,
2126                        const struct table_area_style *area)
2127 {
2128   if (value->font_style)
2129     font_style_uninit (value->font_style);
2130   else
2131     value->font_style = xmalloc (sizeof *value->font_style);
2132   font_style_copy (NULL, value->font_style, &area->font_style);
2133
2134   if (!value->cell_style)
2135     value->cell_style = xmalloc (sizeof *value->cell_style);
2136   *value->cell_style = area->cell_style;
2137 }
2138
2139 /* Frees the data owned by ARG (but not ARG itself). */
2140 void
2141 pivot_argument_uninit (struct pivot_argument *arg)
2142 {
2143   if (arg)
2144     {
2145       for (size_t i = 0; i < arg->n; i++)
2146         pivot_value_destroy (arg->values[i]);
2147       free (arg->values);
2148     }
2149 }
2150
2151 /* Creates and returns a new pivot_value whose contents is the null-terminated
2152    string TEXT.  Takes ownership of TEXT.
2153
2154    This function is for text strings provided by the user (with the exception
2155    that pivot_value_new_variable() should be used for variable names).  For
2156    strings that are part of the PSPP user interface, such as names of
2157    procedures, statistics, annotations, error messages, etc., use
2158    pivot_value_new_text(). */
2159 struct pivot_value *
2160 pivot_value_new_user_text_nocopy (char *text)
2161 {
2162   struct pivot_value *value = xmalloc (sizeof *value);
2163   *value = (struct pivot_value) {
2164     .type = PIVOT_VALUE_TEXT,
2165     .text = {
2166       .local = text,
2167       .c = text,
2168       .id = text,
2169       .user_provided = true,
2170     }
2171   };
2172   return value;
2173 }
2174
2175 /* Creates and returns a new pivot_value whose contents is the LENGTH bytes of
2176    TEXT.  Use SIZE_MAX if TEXT is null-teriminated and its length is not known
2177    in advance.
2178
2179    This function is for text strings provided by the user (with the exception
2180    that pivot_value_new_variable() should be used for variable names).  For
2181    strings that are part of the PSPP user interface, such as names of
2182    procedures, statistics, annotations, error messages, etc., use
2183    pivot_value_new_text().j
2184
2185    The caller retains ownership of TEXT.*/
2186 struct pivot_value *
2187 pivot_value_new_user_text (const char *text, size_t length)
2188 {
2189   return pivot_value_new_user_text_nocopy (
2190     xmemdup0 (text, length != SIZE_MAX ? length : strlen (text)));
2191 }
2192
2193 /* Creates and returns new pivot_value whose contents is TEXT, which should be
2194    a translatable string, but not actually translated yet, e.g. enclosed in
2195    N_().  This function is for text strings that are part of the PSPP user
2196    interface, such as names of procedures, statistics, annotations, error
2197    messages, etc.  For strings that come from the user, use
2198    pivot_value_new_user_text(). */
2199 struct pivot_value *
2200 pivot_value_new_text (const char *text)
2201 {
2202   char *c = xstrdup (text);
2203   char *local = xstrdup (gettext (c));
2204
2205   struct pivot_value *value = xmalloc (sizeof *value);
2206   *value = (struct pivot_value) {
2207     .type = PIVOT_VALUE_TEXT,
2208     .text = {
2209       .local = local,
2210       .c = c,
2211       .id = c,
2212       .user_provided = false,
2213     }
2214   };
2215   return value;
2216 }
2217
2218 /* Same as pivot_value_new_text() but its argument is a printf()-like format
2219    string. */
2220 struct pivot_value * PRINTF_FORMAT (1, 2)
2221 pivot_value_new_text_format (const char *format, ...)
2222 {
2223   va_list args;
2224   va_start (args, format);
2225   char *c = xvasprintf (format, args);
2226   va_end (args);
2227
2228   va_start (args, format);
2229   char *local = xvasprintf (gettext (format), args);
2230   va_end (args);
2231
2232   struct pivot_value *value = xmalloc (sizeof *value);
2233   *value = (struct pivot_value) {
2234     .type = PIVOT_VALUE_TEXT,
2235     .text = {
2236       .local = local,
2237       .c = c,
2238       .id = xstrdup (c),
2239       .user_provided = false,
2240     }
2241   };
2242   return value;
2243 }
2244
2245 /* Returns a new pivot_value that represents X.
2246
2247    The format to use for X is unspecified.  Usually the easiest way to specify
2248    a format is through assigning a result class to one of the categories that
2249    the pivot_value will end up in.  If that is not suitable, then the caller
2250    can use pivot_value_set_rc() or assign directly to value->numeric.format. */
2251 struct pivot_value *
2252 pivot_value_new_number (double x)
2253 {
2254   struct pivot_value *value = xmalloc (sizeof *value);
2255   *value = (struct pivot_value) {
2256     .type = PIVOT_VALUE_NUMERIC,
2257     .numeric = { .x = x, },
2258   };
2259   return value;
2260 }
2261
2262 /* Returns a new pivot_value that represents X, formatted as an integer. */
2263 struct pivot_value *
2264 pivot_value_new_integer (double x)
2265 {
2266   struct pivot_value *value = pivot_value_new_number (x);
2267   value->numeric.format = (struct fmt_spec) { FMT_F, 40, 0 };
2268   return value;
2269 }
2270
2271 /* Returns a new pivot_value that represents VALUE, formatted as for
2272    VARIABLE. */
2273 struct pivot_value *
2274 pivot_value_new_var_value (const struct variable *variable,
2275                            const union value *value)
2276 {
2277   struct pivot_value *pv = pivot_value_new_value (
2278     value, var_get_width (variable), var_get_print_format (variable),
2279     var_get_encoding (variable));
2280
2281   char *var_name = xstrdup (var_get_name (variable));
2282   if (var_is_alpha (variable))
2283     pv->string.var_name = var_name;
2284   else
2285     pv->numeric.var_name = var_name;
2286
2287   const char *label = var_lookup_value_label (variable, value);
2288   if (label)
2289     {
2290       if (var_is_alpha (variable))
2291         pv->string.value_label = xstrdup (label);
2292       else
2293         pv->numeric.value_label = xstrdup (label);
2294     }
2295
2296   return pv;
2297 }
2298
2299 /* Returns a new pivot_value that represents VALUE, with the given WIDTH,
2300    formatted with FORMAT.  For a string value, ENCODING must be its character
2301    encoding. */
2302 struct pivot_value *
2303 pivot_value_new_value (const union value *value, int width,
2304                        const struct fmt_spec *format, const char *encoding)
2305 {
2306   struct pivot_value *pv = xzalloc (sizeof *pv);
2307   if (width > 0)
2308     {
2309       char *s = recode_string (UTF8, encoding, CHAR_CAST (char *, value->s),
2310                                width);
2311       size_t n = strlen (s);
2312       while (n > 0 && s[n - 1] == ' ')
2313         s[--n] = '\0';
2314
2315       pv->type = PIVOT_VALUE_STRING;
2316       pv->string.s = s;
2317       pv->string.hex = format->type == FMT_AHEX;
2318     }
2319   else
2320     {
2321       pv->type = PIVOT_VALUE_NUMERIC;
2322       pv->numeric.x = value->f;
2323       pv->numeric.format = *format;
2324     }
2325
2326   return pv;
2327 }
2328
2329 /* Returns a new pivot_value for VARIABLE. */
2330 struct pivot_value *
2331 pivot_value_new_variable (const struct variable *variable)
2332 {
2333   struct pivot_value *value = xmalloc (sizeof *value);
2334   *value = (struct pivot_value) {
2335     .type = PIVOT_VALUE_VARIABLE,
2336     .variable = {
2337       .var_name = xstrdup (var_get_name (variable)),
2338       .var_label = xstrdup_if_nonempty (var_get_label (variable)),
2339     },
2340   };
2341   return value;
2342 }
2343
2344 /* Attaches a reference to FOOTNOTE to V. */
2345 void
2346 pivot_value_add_footnote (struct pivot_value *v,
2347                           const struct pivot_footnote *footnote)
2348 {
2349   /* Some legacy tables include numerous duplicate footnotes.  Suppress
2350      them. */
2351   for (size_t i = 0; i < v->n_footnotes; i++)
2352     if (v->footnotes[i] == footnote)
2353       return;
2354
2355   v->footnotes = xrealloc (v->footnotes,
2356                            (v->n_footnotes + 1) * sizeof *v->footnotes);
2357   v->footnotes[v->n_footnotes++] = footnote;
2358 }
2359
2360 /* If VALUE is a numeric value, and RC is a result class such as
2361    PIVOT_RC_COUNT, changes VALUE's format to the result class's. */
2362 void
2363 pivot_value_set_rc (const struct pivot_table *table, struct pivot_value *value,
2364                     const char *rc)
2365 {
2366   if (value->type == PIVOT_VALUE_NUMERIC)
2367     {
2368       const struct fmt_spec *f = pivot_table_get_format (table, rc);
2369       if (f)
2370         value->numeric.format = *f;
2371     }
2372 }
2373