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