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