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