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