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