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