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