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