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