88edb62031c5227b304bb62a761704d25a03b47c
[pspp] / src / output / pivot-table.h
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 #ifndef OUTPUT_PIVOT_TABLE_H
18 #define OUTPUT_PIVOT_TABLE_H 1
19
20 #include <stdint.h>
21 #include <time.h>
22 #include "data/format.h"
23 #include "data/settings.h"
24 #include "libpspp/compiler.h"
25 #include "libpspp/hmap.h"
26 #include "output/table.h"
27
28 struct pivot_value;
29 struct variable;
30 union value;
31
32 /* Pivot tables.
33
34    Pivot tables are PSPP's primary form of output.  They are analogous to the
35    pivot tables you might be familiar with from spreadsheets and databases.
36    See https://en.wikipedia.org/wiki/Pivot_table for a brief introduction to
37    the overall concept of a pivot table.
38
39    In PSPP, the most important internal pieces of a pivot table are:
40
41    - Title.  Every pivot table has a title that is displayed above it.  It also
42      has an optional caption (displayed below it) and corner text (displayed in
43      the upper left corner).
44
45    - Dimensions.  A dimension consists of zero or more categories.  A category
46      has a label, such as "df" or "Asymp. Sig." or 123 or a variable name.  The
47      categories are the leaves of a tree whose non-leaf nodes form groups of
48      categories.  The tree always has a root group whose label is the name of
49      the dimension.
50
51    - Axes.  A table has three axes: column, row, and layer.  Each dimension is
52      assigned to an axis, and each axis has zero or more dimensions.  When an
53      axis has more than one dimension, they are ordered from innermost to
54      outermost.
55
56    - Data.  A table's data consists of zero or more cells.  Each cell maps from
57      a category for each dimension to a value, which is commonly a number but
58      could also be a variable name or an arbitrary text string.
59
60    Creating a pivot table usually consists of the following steps:
61
62    1. Create the table with pivot_table_create(), passing in the title.
63
64    2. Optionally, set the format to use for "count" values with
65       pivot_table_set_weight_var() or pivot_table_set_weight_format().
66
67    3. Create each dimension with pivot_dimension_create() and populate it with
68       categories and, possibly, with groups that contain the categories.  This
69       call also assigns the dimension to an axis.
70
71       In simple cases, only a call to pivot_dimension_create() is needed.
72       Other functions such as pivot_category_create_group() can be used for
73       hierarchies of categories.
74
75       Sometimes it's easier to create categories in tandem with inserting data,
76       for example by adding a category for a variable just before inserting the
77       first cell for that variable.  In that case, creating categories and
78       inserting data can be interleaved.
79
80    4. Insert data.  For each cell, supply the category indexes, which are
81       assigned starting from 0 in the order in which the categories were
82       created in step 2, and the value to go in the cell.  If the table has a
83       small, fixed number of dimensions, functions like, e.g.
84       pivot_table_put3() for 3 dimensions, can be used.  The general function
85       pivot_table_put() works for other cases.
86
87    5. Output the table for user consumption.  Use pivot_table_submit(). */
88 \f
89 /* Pivot table display styling. */
90
91 /* Areas of a pivot table for styling purposes. */
92 enum pivot_area
93   {
94     PIVOT_AREA_TITLE,
95     PIVOT_AREA_CAPTION,
96     PIVOT_AREA_FOOTER,          /* Footnotes. */
97     PIVOT_AREA_CORNER,          /* Top-left corner. */
98     PIVOT_AREA_COLUMN_LABELS,
99     PIVOT_AREA_ROW_LABELS,
100     PIVOT_AREA_DATA,
101     PIVOT_AREA_LAYERS,          /* Layer indication. */
102     PIVOT_N_AREAS
103   };
104
105 const char *pivot_area_to_string (enum pivot_area);
106
107 /* Table borders for styling purposes. */
108 enum pivot_border
109   {
110     PIVOT_BORDER_TITLE,
111
112     /* Outer frame. */
113     PIVOT_BORDER_OUTER_LEFT,
114     PIVOT_BORDER_OUTER_TOP,
115     PIVOT_BORDER_OUTER_RIGHT,
116     PIVOT_BORDER_OUTER_BOTTOM,
117
118     /* Inner frame. */
119     PIVOT_BORDER_INNER_LEFT,
120     PIVOT_BORDER_INNER_TOP,
121     PIVOT_BORDER_INNER_RIGHT,
122     PIVOT_BORDER_INNER_BOTTOM,
123
124     /* Data area. */
125     PIVOT_BORDER_DATA_LEFT,
126     PIVOT_BORDER_DATA_TOP,
127
128     /* Dimensions. */
129     PIVOT_BORDER_DIM_ROW_HORZ,
130     PIVOT_BORDER_DIM_ROW_VERT,
131     PIVOT_BORDER_DIM_COL_HORZ,
132     PIVOT_BORDER_DIM_COL_VERT,
133
134     /* Categories. */
135     PIVOT_BORDER_CAT_ROW_HORZ,
136     PIVOT_BORDER_CAT_ROW_VERT,
137     PIVOT_BORDER_CAT_COL_HORZ,
138     PIVOT_BORDER_CAT_COL_VERT,
139
140     PIVOT_N_BORDERS
141   };
142
143 const char *pivot_border_to_string (enum pivot_border);
144
145 /* Sizing for rows or columns of a rendered table.  The comments below talk
146    about columns and their widths but they apply equally to rows and their
147    heights. */
148 struct pivot_table_sizing
149   {
150     /* Specific column widths, in 1/96" units. */
151     int *widths;
152     size_t n_widths;
153
154     /* Specific page breaks: 0-based columns after which a page break must
155        occur, e.g. a value of 1 requests a break after the second column. */
156     size_t *breaks;
157     size_t n_breaks;
158
159     /* Keeps: columns to keep together on a page if possible. */
160     struct pivot_keep *keeps;
161     size_t n_keeps;
162   };
163
164 void pivot_table_sizing_uninit (struct pivot_table_sizing *);
165
166 /* A set of columns to keep together on a page if possible, e.g. ofs=1, n=10
167    requests keeping together the 2nd through 11th columns. */
168 struct pivot_keep
169   {
170     size_t ofs;                 /* 0-based first column. */
171     size_t n;                   /* Number of columns. */
172   };
173 \f
174 /* Axes. */
175
176 enum pivot_axis_type
177   {
178     PIVOT_AXIS_LAYER,
179     PIVOT_AXIS_ROW,
180     PIVOT_AXIS_COLUMN,
181
182     PIVOT_N_AXES
183   };
184
185 const char *pivot_axis_type_to_string (enum pivot_axis_type);
186
187 /* An axis within a pivot table. */
188 struct pivot_axis
189   {
190     /* dimensions[0] is the innermost dimension,
191        dimensions[1] is the next outer dimension,
192        ...
193        dimensions[n_dimensions - 1] is the outermost dimension. */
194     struct pivot_dimension **dimensions;
195     size_t n_dimensions;
196
197     /* The number of rows or columns along the axis,
198        that is, the product of dimension[*]->n_leaves.
199        It is 0 if any dimension has 0 leaves. */
200     size_t extent;
201
202     /* Sum of dimensions[*]->label_depth. */
203     size_t label_depth;
204   };
205
206 /* Successively assigns to INDEXES (which should be a "size_t *") each of the
207    combinations of the categories in AXIS's dimensions, in lexicographic order
208    with the innermost dimension iterating most quickly.
209
210    The value assigned to INDEXES is dynamically allocated.  If the client
211    breaks out of the loop prematurely, it needs to free it with free(). */
212 #define PIVOT_AXIS_FOR_EACH(INDEXES, AXIS)                              \
213   for ((INDEXES) = NULL;                                                \
214        ((INDEXES) = pivot_axis_iterator_next (INDEXES, AXIS)) != NULL;)
215 size_t *pivot_axis_iterator_next (size_t *indexes, const struct pivot_axis *);
216 \f
217 /* Dimensions.
218
219    A pivot_dimension identifies the categories associated with a single
220    dimension within a multidimensional pivot table.
221
222    A dimension contains a collection of categories, which are the leaves in a
223    tree of groups.
224
225    (A dimension or a group can contain zero categories, but this is unusual.
226    If a dimension contains no categories, then its table cannot contain any
227    data.)
228 */
229 struct pivot_dimension
230   {
231     /* table->axes[axis_type]->dimensions[level] == dimension. */
232     struct pivot_table *table;
233     enum pivot_axis_type axis_type;
234     size_t level;               /* 0 for innermost dimension within axis. */
235
236     /* table->dimensions[top_index] == dimension. */
237     size_t top_index;
238
239     /* Hierarchy of categories within the dimension.  The groups and categories
240        are sorted in the order that should be used for display.  This might be
241        different from the original order produced for output if the user
242        adjusted it.
243
244        The root must always be a group, although it is allowed to have no
245        subcategories. */
246     struct pivot_category *root;
247
248     /* All of the leaves reachable via the root.
249
250        The indexing for presentation_leaves is presentation order, thus
251        presentation_leaves[i]->presentation_index == i.  This order is the same
252        as would be produced by an in-order traversal of the groups.  It is the
253        order into which the user reordered or sorted the categories.
254
255        The indexing for data_leaves is that used for idx[] in struct
256        pivot_cell, thus data_leaves[i]->data_index == i.  This might differ
257        from what an in-order traversal of 'root' would yield, if the user
258        reordered categories. */
259     struct pivot_category **data_leaves;
260     struct pivot_category **presentation_leaves;
261     size_t n_leaves, allocated_leaves;
262
263     /* Display. */
264     bool hide_all_labels;
265
266     /* Number of rows or columns needed to express the labels. */
267     int label_depth;
268   };
269
270 struct pivot_dimension *pivot_dimension_create (
271   struct pivot_table *, enum pivot_axis_type, const char *name, ...)
272   SENTINEL (0);
273 #define pivot_dimension_create(...) \
274   pivot_dimension_create(__VA_ARGS__, NULL_SENTINEL)
275 struct pivot_dimension *pivot_dimension_create__ (struct pivot_table *,
276                                                   enum pivot_axis_type,
277                                                   struct pivot_value *name);
278
279 void pivot_dimension_destroy (struct pivot_dimension *);
280
281 void pivot_dimension_dump (const struct pivot_dimension *,
282                            const struct pivot_table *, int indentation);
283 \f
284 /* A pivot_category is a leaf (a category) or a group:
285
286    - For a leaf, neither index is SIZE_MAX.
287
288    - For a group, both indexes are SIZE_MAX.
289
290    Do not use 'subs' or 'n_subs' to determine whether a category is a group,
291    because a group may (pathologically) have no leaves. */
292 struct pivot_category
293   {
294     struct pivot_value *name;
295     struct pivot_category *parent;
296     struct pivot_dimension *dimension;
297     size_t label_depth, extra_depth;
298
299     /* Groups only.
300
301        If show_label is true, then the group itself has a row (or a column)
302        giving the group's name.  Otherwise, the group's own name is not
303        displayed. */
304     struct pivot_category **subs; /* Child categories or groups. */
305     size_t n_subs, allocated_subs;
306     bool show_label;            /* Display a label for the group itself? */
307     bool show_label_in_corner;
308
309     /* Leaf only. */
310     size_t group_index;        /* In ->parent->subs[]. */
311     size_t data_index;         /* In ->dimension->data_leaves[]. */
312     size_t presentation_index; /* In ->dimension->presentation_leaves[]. */
313     struct fmt_spec format;    /* Default format for values in this category. */
314     bool honor_small;          /* Honor pivot_table 'small' setting? */
315   };
316
317 static inline bool
318 pivot_category_is_group (const struct pivot_category *category)
319 {
320   return category->data_index == SIZE_MAX;
321 }
322
323 static inline bool
324 pivot_category_is_leaf (const struct pivot_category *category)
325 {
326   return !pivot_category_is_group (category);
327 }
328
329 /* Creating leaf categories. */
330 int pivot_category_create_leaves (struct pivot_category *parent, ...)
331   SENTINEL (0);
332 #define pivot_category_create_leaves(...) \
333   pivot_category_create_leaves(__VA_ARGS__, NULL_SENTINEL)
334
335 int pivot_category_create_leaf (
336   struct pivot_category *parent, struct pivot_value *name);
337 int pivot_category_create_leaf_rc (
338   struct pivot_category *parent, struct pivot_value *name, const char *rc);
339
340 /* Creating category groups. */
341 struct pivot_category *pivot_category_create_group (
342   struct pivot_category *parent, const char *name, ...) SENTINEL (0);
343 #define pivot_category_create_group(...) \
344   pivot_category_create_group(__VA_ARGS__, NULL_SENTINEL)
345 struct pivot_category *pivot_category_create_group__ (
346   struct pivot_category *parent, struct pivot_value *name);
347
348 void pivot_category_destroy (struct pivot_category *);
349
350 /* Pivot result classes.
351
352    These are used to mark leaf categories as having particular types of data,
353    to set their numeric formats.  The formats that actually get used for these
354    classes are in the result_classes[] global array in pivot-table.c, except
355    that PIVOT_RC_OTHER comes from settings_get_format() and PIVOT_RC_COUNT
356    should come from the weight variable in the dataset's dictionary. */
357 #define PIVOT_RC_OTHER ("RC_OTHER")
358 #define PIVOT_RC_INTEGER ("RC_INTEGER")
359 #define PIVOT_RC_CORRELATION ("RC_CORRELATIONS")
360 #define PIVOT_RC_SIGNIFICANCE ("RC_SIGNIFICANCE")
361 #define PIVOT_RC_PERCENT ("RC_PERCENT")
362 #define PIVOT_RC_RESIDUAL ("RC_RESIDUAL")
363 #define PIVOT_RC_COUNT ("RC_COUNT")
364
365 bool pivot_result_class_change (const char *, const struct fmt_spec *);
366 bool is_pivot_result_class (const char *);
367 \f
368 /* Styling for a pivot table.
369
370    The division between this and the style information in struct pivot_table
371    seems fairly arbitrary.  The ultimate reason for the division is simply
372    because that's how SPSS documentation and file formats do it. */
373 struct pivot_table_look
374   {
375     /* Reference count.  A pivot_table_look may be shared between multiple
376        owners, indicated by a reference count greater than 1.  When this is the
377        case, the pivot_table must not be modified. */
378     int ref_cnt;
379
380     char *name;                 /* May be null. */
381
382     /* General properties. */
383     bool omit_empty;
384     bool row_labels_in_corner;
385     int width_ranges[TABLE_N_AXES][2];      /* In 1/96" units. */
386
387     /* Footnote display settings. */
388     bool show_numeric_markers;
389     bool footnote_marker_superscripts;
390
391     /* Styles. */
392     struct table_area_style areas[PIVOT_N_AREAS];
393     struct table_border_style borders[PIVOT_N_BORDERS];
394
395     /* Print settings. */
396     bool print_all_layers;
397     bool paginate_layers;
398     bool shrink_to_fit[TABLE_N_AXES];
399     bool top_continuation, bottom_continuation;
400     char *continuation;
401     size_t n_orphan_lines;
402   };
403
404 const struct pivot_table_look *pivot_table_look_get_default (void);
405 void pivot_table_look_set_default (const struct pivot_table_look *);
406
407 char *pivot_table_look_read (const char *, struct pivot_table_look **)
408   WARN_UNUSED_RESULT;
409
410 const struct pivot_table_look *pivot_table_look_builtin_default (void);
411 struct pivot_table_look *pivot_table_look_new_builtin_default (void);
412 struct pivot_table_look *pivot_table_look_ref (
413   const struct pivot_table_look *);
414 void pivot_table_look_unref (struct pivot_table_look *);
415 struct pivot_table_look *pivot_table_look_unshare (struct pivot_table_look *);
416 \f
417 /* A pivot table.  See the top of this file for more information. */
418 struct pivot_table
419   {
420     /* Reference count.  A pivot_table may be shared between multiple owners,
421        indicated by a reference count greater than 1.  When this is the case,
422        the pivot_table must not be modified. */
423     int ref_cnt;
424
425     /* Styling. */
426     struct pivot_table_look *look;
427
428     /* Display settings. */
429     bool rotate_inner_column_labels;
430     bool rotate_outer_row_labels;
431     bool show_grid_lines;
432     bool show_title;
433     bool show_caption;
434     size_t *current_layer; /* axes[PIVOT_AXIS_LAYER].n_dimensions elements. */
435     enum settings_value_show show_values;
436     enum settings_value_show show_variables;
437     struct fmt_spec weight_format;
438
439     /* Column and row sizing and page breaks.
440        sizing[TABLE_HORZ] is for columns, sizing[TABLE_VERT] is for rows. */
441     struct pivot_table_sizing sizing[TABLE_N_AXES];
442
443     /* Format settings. */
444     struct fmt_settings settings;
445     char grouping;              /* Usually '.' or ','. */
446     double small;
447
448     /* Command information. */
449     char *command_local;        /* May be NULL. */
450     char *command_c;            /* May be NULL. */
451     char *language;             /* May be NULL. */
452     char *locale;               /* May be NULL. */
453
454     /* Source information. */
455     char *dataset;              /* May be NULL. */
456     char *datafile;             /* May be NULL. */
457     time_t date;                /* May be 0 if unknown. */
458
459     /* Footnotes. */
460     struct pivot_footnote **footnotes;
461     size_t n_footnotes, allocated_footnotes;
462
463     /* Titles. */
464     struct pivot_value *title;
465     struct pivot_value *subtype;  /* Same as spv_item's subtype. */
466     struct pivot_value *corner_text;
467     struct pivot_value *caption;
468     char *notes;                /* Shown as tooltip. */
469
470     /* Dimensions. */
471     struct pivot_dimension **dimensions;
472     size_t n_dimensions;
473
474     /* Allocation of dimensions to rows, columns, and layers. */
475     struct pivot_axis axes[PIVOT_N_AXES];
476
477     struct hmap cells;          /* Contains "struct pivot_cell"s. */
478   };
479
480 /* Creating and destroy pivot tables. */
481 struct pivot_table *pivot_table_create (const char *title);
482 struct pivot_table *pivot_table_create__ (struct pivot_value *title,
483                                           const char *subtype);
484 struct pivot_table *pivot_table_create_for_text (struct pivot_value *title,
485                                                  struct pivot_value *content);
486
487 struct pivot_table *pivot_table_ref (const struct pivot_table *);
488 struct pivot_table *pivot_table_unshare (struct pivot_table *);
489 void pivot_table_unref (struct pivot_table *);
490 bool pivot_table_is_shared (const struct pivot_table *);
491
492 /* Titles. */
493 void pivot_table_set_title (struct pivot_table *, struct pivot_value *);
494 void pivot_table_set_subtype (struct pivot_table *, struct pivot_value *);
495 void pivot_table_set_corner_text (struct pivot_table *, struct pivot_value *);
496 void pivot_table_set_caption (struct pivot_table *, struct pivot_value *);
497
498 /* Axes. */
499 void pivot_table_swap_axes (struct pivot_table *,
500                             enum pivot_axis_type, enum pivot_axis_type);
501 void pivot_table_transpose (struct pivot_table *);
502 void pivot_table_move_dimension (struct pivot_table *,
503                                  struct pivot_dimension *,
504                                  enum pivot_axis_type, size_t ofs);
505
506 /* Styling. */
507 const struct pivot_table_look *pivot_table_get_look (
508   const struct pivot_table *);
509 void pivot_table_set_look (struct pivot_table *,
510                            const struct pivot_table_look *);
511
512 /* Format of PIVOT_RC_COUNT cells. */
513 void pivot_table_set_weight_var (struct pivot_table *,
514                                  const struct variable *);
515 void pivot_table_set_weight_format (struct pivot_table *,
516                                     const struct fmt_spec *);
517
518 /* Query. */
519 bool pivot_table_is_empty (const struct pivot_table *);
520
521 /* Output. */
522 void pivot_table_submit (struct pivot_table *);
523
524 /* Data cells. */
525 void pivot_table_put (struct pivot_table *, const size_t *dindexes, size_t n,
526                       struct pivot_value *);
527 void pivot_table_put1 (struct pivot_table *, size_t idx1,
528                        struct pivot_value *);
529 void pivot_table_put2 (struct pivot_table *, size_t idx1, size_t idx2,
530                        struct pivot_value *);
531 void pivot_table_put3 (struct pivot_table *, size_t idx1, size_t idx2,
532                        size_t idx3, struct pivot_value *);
533 void pivot_table_put4 (struct pivot_table *, size_t idx1, size_t idx2,
534                        size_t idx3, size_t idx4, struct pivot_value *);
535
536 const struct pivot_value *pivot_table_get (const struct pivot_table *,
537                                            const size_t *dindexes);
538
539 struct pivot_value *pivot_table_get_rw (struct pivot_table *,
540                                         const size_t *dindexes);
541
542 bool pivot_table_delete (struct pivot_table *, const size_t *dindexes);
543
544 /* Footnotes.
545
546    Use pivot_table_create_footnote() to create a footnote.
547    Use pivot_value_add_footnote() to add a reference to a footnote. */
548 struct pivot_footnote
549   {
550     size_t idx;
551     struct pivot_value *content;
552     struct pivot_value *marker;
553     bool show;
554   };
555
556 struct pivot_footnote *pivot_table_create_footnote (
557   struct pivot_table *, struct pivot_value *content);
558 struct pivot_footnote *pivot_table_create_footnote__ (
559   struct pivot_table *, size_t idx,
560   struct pivot_value *marker, struct pivot_value *content);
561
562 void pivot_footnote_format_marker (const struct pivot_footnote *,
563                                    const struct pivot_table *,
564                                    struct string *);
565 char *pivot_footnote_marker_string (const struct pivot_footnote *,
566                                     const struct pivot_table *);
567
568 void pivot_footnote_destroy (struct pivot_footnote *);
569
570 /* Internals. */
571 void pivot_table_convert_indexes_ptod (const struct pivot_table *,
572                                        const size_t *pindexes[PIVOT_N_AXES],
573                                        size_t *dindexes);
574 size_t *pivot_table_enumerate_axis (const struct pivot_table *,
575                                     enum pivot_axis_type,
576                                     const size_t *layer_indexes,
577                                     bool omit_empty, size_t *n);
578 #define PIVOT_ENUMERATION_FOR_EACH(INDEXES, ENUMERATION, AXIS)  \
579   for ((INDEXES) = (ENUMERATION); *(INDEXES) != SIZE_MAX;       \
580        (INDEXES) += MAX (1, (AXIS)->n_dimensions))
581
582 void pivot_table_assign_label_depth (struct pivot_table *);
583
584 void pivot_table_dump (const struct pivot_table *, int indentation);
585 \f
586 /* pivot_value. */
587
588 enum ATTRIBUTE ((packed)) pivot_value_type
589   {
590     PIVOT_VALUE_NUMERIC,          /* A value of a numeric variable. */
591     PIVOT_VALUE_STRING,           /* A value of a string variable. */
592     PIVOT_VALUE_VARIABLE,         /* Name of a variable. */
593     PIVOT_VALUE_TEXT,             /* Text. */
594     PIVOT_VALUE_TEMPLATE,         /* Templated text. */
595   };
596
597 /* A pivot_value is the content of a single pivot table cell.  A pivot_value is
598    also a pivot table's title, caption, footnote marker and contents, and so
599    on.
600
601    A given pivot_value is one of:
602
603    1. A number resulting from a calculation (PIVOT_VALUE_NUMERIC).  Use
604       pivot_value_new_number() to create such a pivot_value.
605
606       A numeric pivot_value has an associated display format (usually an F or
607       PCT format).  This format can be set directly on the pivot_value, but
608       that is not usually the easiest way.  Instead, it is usually true that
609       all of the values in a single category should have the same format
610       (e.g. all "Significance" values might use format F40.3), so PSPP makes
611       it easy to set the default format for a category while creating the
612       category.  See pivot_dimension_create() for more details.
613
614       For numbers that should be displayed as integers,
615       pivot_value_new_integer() can occasionally be a useful special case.
616
617    2. A numeric or string value obtained from data (PIVOT_VALUE_NUMERIC or
618       PIVOT_VALUE_STRING).  If such a value corresponds to a variable, then the
619       variable's name can be attached to the pivot_value.  If the value has a
620       value label, then that can also be attached.  When a label is present,
621       the user can control whether to show the value or the label or both.
622
623       Use pivot_value_new_var_value() to create pivot_values of these kinds.
624
625    3. A variable name (PIVOT_VALUE_VARIABLE).  The variable label, if any, can
626       be attached too, and again the user can control whether to show the value
627       or the label or both.
628
629    4. A text string (PIVOT_VALUE_TEXT).  The value stores the string in English
630       and translated into the output language (localized).  Use
631       pivot_value_new_text() or pivot_value_new_text_format() for those cases.
632       In some cases, only an English or a localized version is available for
633       one reason or another, although this is regrettable; in those cases, use
634       pivot_value_new_user_text() or pivot_value_new_user_text_nocopy().
635
636    (There is also a PIVOT_VALUE_TEMPLATE but PSPP does not yet create these
637    itself.)
638
639
640    Footnotes
641    =========
642
643    A pivot_value may reference any number of footnotes.  Use
644    pivot_value_add_footnote() to add a footnote reference.  The footnotes being
645    referenced must first be created with pivot_table_create_footnote().
646
647
648    Styling
649    =======
650
651    A pivot_value can have specific font and cell styles.  Only the user should
652    add these.
653 */
654 struct pivot_value
655   {
656     struct pivot_value_ex *ex;
657     union
658       {
659         enum pivot_value_type type;
660
661         /* PIVOT_VALUE_NUMERIC. */
662         struct
663           {
664             enum pivot_value_type type;
665             enum settings_value_show show; /* Show value or label or both? */
666             struct fmt_spec format;   /* Format to display 'x'. */
667             bool honor_small;         /* Honor value of pivot table 'small'? */
668             double x;                 /* The numeric value. */
669             char *var_name;           /* May be NULL. */
670             char *value_label;        /* May be NULL. */
671           }
672         numeric;
673
674         /* PIVOT_VALUE_STRING. */
675         struct
676           {
677             enum pivot_value_type type;
678             enum settings_value_show show; /* Show value or label or both? */
679             bool hex;                 /* Display in hex? */
680             char *s;                  /* The string value. */
681             char *var_name;           /* May be NULL. */
682             char *value_label;        /* May be NULL. */
683           }
684         string;
685
686         /* PIVOT_VALUE_VARIABLE. */
687         struct
688           {
689             enum pivot_value_type type;
690             enum settings_value_show show; /* Show name or label or both? */
691             char *var_name;
692             char *var_label;          /* May be NULL. */
693           }
694         variable;
695
696         /* PIVOT_VALUE_TEXT. */
697         struct
698           {
699             enum pivot_value_type type;
700
701             /* 'local', 'c', and 'id' must all be nonnull, but they are allowed
702                to be the same pointer. */
703             bool user_provided;
704             char *local;              /* Localized. */
705             char *c;                  /* English. */
706             char *id;                 /* Identifier. */
707           }
708         text;
709
710         /* PIVOT_VALUE_TEMPLATE. */
711         struct
712           {
713             enum pivot_value_type type;
714
715             /* Arguments.
716
717                The odd ordering in this struct reduces the overall size
718                of struct pivot_value. */
719             unsigned int n_args;
720             struct pivot_argument *args;
721
722             /* Both 'local' and 'id' must be nonnull, but they are allowed to
723                be the same pointer. */
724             char *local;              /* Localized. */
725             char *id;                 /* Identifier. */
726           }
727         template;
728       };
729   };
730
731 /* Life cycle. */
732 struct pivot_value *pivot_value_clone (const struct pivot_value *);
733 void pivot_value_destroy (struct pivot_value *);
734
735 /* Numbers resulting from calculations. */
736 struct pivot_value *pivot_value_new_number (double);
737 struct pivot_value *pivot_value_new_integer (double);
738
739 /* Values from data. */
740 struct pivot_value *pivot_value_new_var_value (
741   const struct variable *, const union value *);
742 struct pivot_value *pivot_value_new_value (const union value *, int width,
743                                            const struct fmt_spec *,
744                                            const char *encoding);
745
746 /* Values from variable names. */
747 struct pivot_value *pivot_value_new_variable (const struct variable *);
748 struct pivot_value *pivot_value_new_variable__ (const char *name,
749                                                 const char *label);
750
751 /* Values from text strings. */
752 struct pivot_value *pivot_value_new_text (const char *);
753 struct pivot_value *pivot_value_new_text_format (const char *, ...)
754 #if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__>= 4) || __GNUC__ > 4)
755   __attribute__((format(gnu_printf, 1, 2)));
756 #else
757   __attribute__((format(__printf__, 1, 2)));
758 #endif
759
760 struct pivot_value *pivot_value_new_user_text (const char *, size_t length);
761 struct pivot_value *pivot_value_new_user_text_nocopy (char *);
762
763 /* Footnotes. */
764 void pivot_value_add_footnote (struct pivot_value *, const struct pivot_footnote *);
765 void pivot_value_sort_footnotes (struct pivot_value *);
766
767 /* Numeric formats. */
768 void pivot_value_set_rc (const struct pivot_table *, struct pivot_value *,
769                          const char *rc);
770
771 /* Converting a pivot_value to a string for display. */
772 char *pivot_value_to_string (const struct pivot_value *,
773                              const struct pivot_table *);
774 char *pivot_value_to_string_defaults (const struct pivot_value *);
775 bool pivot_value_format (const struct pivot_value *,
776                          const struct pivot_table *, struct string *);
777 bool pivot_value_format_body (const struct pivot_value *,
778                               const struct pivot_table *,
779                               struct string *);
780
781 /* Styling. */
782 void pivot_value_get_style (struct pivot_value *,
783                             const struct font_style *base_font_style,
784                             const struct cell_style *base_cell_style,
785                             struct table_area_style *);
786 void pivot_value_set_style (struct pivot_value *,
787                             const struct table_area_style *);
788 void pivot_value_set_font_style (struct pivot_value *,
789                                  const struct font_style *);
790 void pivot_value_set_cell_style (struct pivot_value *,
791                                  const struct cell_style *);
792
793 /* Template arguments. */
794 struct pivot_argument
795   {
796     size_t n;
797     struct pivot_value **values;
798   };
799
800 void pivot_argument_uninit (struct pivot_argument *);
801 void pivot_argument_copy (struct pivot_argument *,
802                           const struct pivot_argument *);
803 \f
804 /* Extra styling for a pivot_value.
805
806    This is logically part of pivot_value itself.  It is broken into a separate
807    structure to save memory because it is rarely used. */
808 struct pivot_value_ex
809   {
810     struct font_style *font_style;
811     struct cell_style *cell_style;
812
813     char **subscripts;
814     size_t n_subscripts;
815
816     size_t *footnote_indexes;
817     size_t n_footnotes;
818   };
819
820 static inline const struct pivot_value_ex *
821 pivot_value_ex (const struct pivot_value *value)
822 {
823   static const struct pivot_value_ex empty_ex = { .font_style = NULL };
824   return value->ex ? value->ex : &empty_ex;
825 }
826
827 struct pivot_value_ex *pivot_value_ex_rw (struct pivot_value *);
828 struct pivot_value_ex *pivot_value_ex_clone (const struct pivot_value_ex *);
829 void pivot_value_ex_destroy (struct pivot_value_ex *);
830 \f
831 /* One piece of data within a pivot table. */
832 struct pivot_cell
833   {
834     struct hmap_node hmap_node; /* In struct pivot_table's 'cells' hmap. */
835     struct pivot_value *value;
836     unsigned int idx[];         /* One index per table dimension. */
837   };
838
839 #endif /* output/pivot-table.h */