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