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