From 5ce9c6ba1502e623ec6723a8273da77e5858b8d4 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 8 Mar 2021 18:18:48 -0800 Subject: [PATCH] pivot-table: Reduce size of struct pivot_value from 80 bytes to 40. --- src/output/cairo-fsm.c | 18 ++-- src/output/html.c | 14 +-- src/output/odt.c | 4 +- src/output/output-item.c | 16 +-- src/output/pivot-output.c | 5 +- src/output/pivot-table.c | 162 ++++++++++++++++++---------- src/output/pivot-table.h | 37 +++++-- src/output/spv/spv-legacy-decoder.c | 15 +-- src/output/spv/spv-light-decoder.c | 21 ++-- src/output/spv/spv-writer.c | 23 ++-- src/output/spv/spv.c | 3 +- src/output/table.c | 5 +- src/output/tex.c | 14 +-- tests/output/pivot-table-test.c | 32 +++--- 14 files changed, 223 insertions(+), 146 deletions(-) diff --git a/src/output/cairo-fsm.c b/src/output/cairo-fsm.c index d71f4d0b02..bedf3147ea 100644 --- a/src/output/cairo-fsm.c +++ b/src/output/cairo-fsm.c @@ -742,23 +742,23 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, PANGO_UNDERLINE_SINGLE)); } - const struct pivot_value *value = cell->value; - if (value->n_footnotes || value->n_subscripts) + const struct pivot_value_ex *ex = pivot_value_ex (cell->value); + if (ex->n_footnotes || ex->n_subscripts) { size_t subscript_ofs = ds_length (&body); - for (size_t i = 0; i < value->n_subscripts; i++) + for (size_t i = 0; i < ex->n_subscripts; i++) { if (i) ds_put_byte (&body, ','); - ds_put_cstr (&body, value->subscripts[i]); + ds_put_cstr (&body, ex->subscripts[i]); } size_t footnote_ofs = ds_length (&body); size_t n_footnotes = 0; - for (size_t i = 0; i < value->n_footnotes; i++) + for (size_t i = 0; i < ex->n_footnotes; i++) { const struct pivot_footnote *f - = pt->footnotes[value->footnote_indexes[i]]; + = pt->footnotes[ex->footnote_indexes[i]]; if (f->show) { if (n_footnotes++) @@ -769,7 +769,7 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, /* Allow footnote markers to occupy the right margin. That way, numbers in the column are still aligned. */ - if (value->n_footnotes && halign == TABLE_HALIGN_RIGHT) + if (ex->n_footnotes && halign == TABLE_HALIGN_RIGHT) { /* Measure the width of the footnote marker, so we know how much we need to make room for. */ @@ -804,10 +804,10 @@ xr_layout_cell_text (struct xr_fsm *xr, const struct table_cell *cell, PANGO_ATTR_INDEX_TO_TEXT_END); add_attr (attrs, pango_attr_scale_new (PANGO_SCALE_SMALL), subscript_ofs, PANGO_ATTR_INDEX_TO_TEXT_END); - if (value->n_subscripts) + if (ex->n_subscripts) add_attr (attrs, pango_attr_rise_new (-3000), subscript_ofs, footnote_ofs - subscript_ofs); - if (value->n_footnotes) + if (ex->n_footnotes) { bool superscript = pt->look->footnote_marker_superscripts; add_attr (attrs, pango_attr_rise_new (superscript ? 3000 : -3000), diff --git a/src/output/html.c b/src/output/html.c index cbb8e90c6e..60ca95e28d 100644 --- a/src/output/html.c +++ b/src/output/html.c @@ -587,26 +587,26 @@ html_put_table_cell (struct html_driver *html, const struct pivot_table *pt, escape_string (html->file, s, " ", "
"); ds_destroy (&body); - if (cell->value->n_subscripts) + const struct pivot_value_ex *ex = pivot_value_ex (cell->value); + if (ex->n_subscripts) { fputs ("", html->file); - for (size_t i = 0; i < cell->value->n_subscripts; i++) + for (size_t i = 0; i < ex->n_subscripts; i++) { if (i) putc (',', html->file); - escape_string (html->file, cell->value->subscripts[i], - " ", "
"); + escape_string (html->file, ex->subscripts[i], " ", "
"); } fputs ("
", html->file); } - if (cell->value->n_footnotes > 0) + if (ex->n_footnotes > 0) { fputs ("", html->file); size_t n_footnotes = 0; - for (size_t i = 0; i < cell->value->n_footnotes; i++) + for (size_t i = 0; i < ex->n_footnotes; i++) { const struct pivot_footnote *f - = pt->footnotes[cell->value->footnote_indexes[i]]; + = pt->footnotes[ex->footnote_indexes[i]]; if (f->show) { if (n_footnotes++ > 0) diff --git a/src/output/odt.c b/src/output/odt.c index ed70ecbb4c..9fadc5d26a 100644 --- a/src/output/odt.c +++ b/src/output/odt.c @@ -446,8 +446,8 @@ write_table_item_cell (struct odt_driver *odt, xmlTextWriterWriteString (odt->content_wtr, _xml (ds_cstr (&body))); ds_destroy (&body); - write_footnotes (odt, pt, cell->value->footnote_indexes, - cell->value->n_footnotes); + const struct pivot_value_ex *ex = pivot_value_ex (cell->value); + write_footnotes (odt, pt, ex->footnote_indexes, ex->n_footnotes); } static void diff --git a/src/output/output-item.c b/src/output/output-item.c index a46fdf8020..25cffe4600 100644 --- a/src/output/output-item.c +++ b/src/output/output-item.c @@ -586,14 +586,15 @@ text_item_create_value (enum text_item_subtype subtype, { if (subtype == TEXT_ITEM_SYNTAX || subtype == TEXT_ITEM_LOG) { - if (!value->font_style) + struct pivot_value_ex *ex = pivot_value_ex_rw (value); + if (!ex->font_style) { - value->font_style = xmalloc (sizeof *value->font_style); - *value->font_style = (struct font_style) FONT_STYLE_INITIALIZER; + ex->font_style = xmalloc (sizeof *value->ex->font_style); + *ex->font_style = (struct font_style) FONT_STYLE_INITIALIZER; } - free (value->font_style->typeface); - value->font_style->typeface = xstrdup ("Monospaced"); + free (ex->font_style->typeface); + ex->font_style->typeface = xstrdup ("Monospaced"); } struct output_item *item = xzalloc (sizeof *item); @@ -652,8 +653,9 @@ text_item_append (struct output_item *dst, const struct output_item *src) if (ds != ss || (ds != TEXT_ITEM_SYNTAX && ds != TEXT_ITEM_LOG) || strcmp (output_item_get_label (dst), output_item_get_label (src)) - || !nullable_font_style_equal (dc->font_style, sc->font_style) - || (dc->font_style && dc->font_style->markup) + || !nullable_font_style_equal (dc->ex ? dc->ex->font_style : NULL, + sc->ex ? sc->ex->font_style : NULL) + || (dc->ex && dc->ex->font_style && dc->ex->font_style->markup) || sc->type != PIVOT_VALUE_TEXT || dc->type != PIVOT_VALUE_TEXT) return false; diff --git a/src/output/pivot-output.c b/src/output/pivot-output.c index 2fa664bffa..a170b6ee71 100644 --- a/src/output/pivot-output.c +++ b/src/output/pivot-output.c @@ -394,9 +394,10 @@ add_references (const struct pivot_table *pt, const struct table *table, if (x == cell.d[H][0] && y == cell.d[V][0]) { - for (size_t i = 0; i < cell.value->n_footnotes; i++) + const struct pivot_value_ex *ex = pivot_value_ex (cell.value); + for (size_t i = 0; i < ex->n_footnotes; i++) { - size_t idx = cell.value->footnote_indexes[i]; + size_t idx = ex->footnote_indexes[i]; assert (idx < pt->n_footnotes); if (!refs[idx] && pt->footnotes[idx]->show) diff --git a/src/output/pivot-table.c b/src/output/pivot-table.c index ad146a58ba..8314407721 100644 --- a/src/output/pivot-table.c +++ b/src/output/pivot-table.c @@ -2411,7 +2411,7 @@ pivot_value_format_body (const struct pivot_value *value, break; case PIVOT_VALUE_TEXT: - if (value->font_style && value->font_style->markup) + if (value->ex && value->ex->font_style && value->ex->font_style->markup) get_text_from_markup (value->text.local, out); else ds_put_cstr (out, value->text.local); @@ -2440,21 +2440,25 @@ pivot_value_format (const struct pivot_value *value, { bool numeric = pivot_value_format_body (value, pt, out); - if (value->n_subscripts) + const struct pivot_value_ex *ex = value->ex; + if (ex) { - for (size_t i = 0; i < value->n_subscripts; i++) - ds_put_format (out, "%c%s", i ? ',' : '_', value->subscripts[i]); - } + if (ex->n_subscripts) + { + for (size_t i = 0; i < ex->n_subscripts; i++) + ds_put_format (out, "%c%s", i ? ',' : '_', ex->subscripts[i]); + } - for (size_t i = 0; i < value->n_footnotes; i++) - { - ds_put_byte (out, '['); + for (size_t i = 0; i < ex->n_footnotes; i++) + { + ds_put_byte (out, '['); - size_t idx = value->footnote_indexes[i]; - const struct pivot_footnote *f = pt->footnotes[idx]; - pivot_footnote_format_marker (f, pt, out); + size_t idx = ex->footnote_indexes[i]; + const struct pivot_footnote *f = pt->footnotes[idx]; + pivot_footnote_format_marker (f, pt, out); - ds_put_byte (out, ']'); + ds_put_byte (out, ']'); + } } return numeric; @@ -2489,22 +2493,8 @@ pivot_value_clone (const struct pivot_value *old) return NULL; struct pivot_value *new = xmemdup (old, sizeof *new); - if (old->font_style) - { - new->font_style = xmalloc (sizeof *new->font_style); - font_style_copy (NULL, new->font_style, old->font_style); - } - if (old->cell_style) - new->cell_style = xmemdup (old->cell_style, sizeof *new->cell_style); - if (old->n_subscripts) - { - new->subscripts = xnmalloc (old->n_subscripts, sizeof *new->subscripts); - for (size_t i = 0; i < old->n_subscripts; i++) - new->subscripts[i] = xstrdup (old->subscripts[i]); - } - if (old->n_footnotes) - new->footnote_indexes = xmemdup ( - old->footnote_indexes, old->n_footnotes * sizeof *new->footnote_indexes); + if (old->ex) + new->ex = pivot_value_ex_clone (old->ex); switch (new->type) { @@ -2557,15 +2547,7 @@ pivot_value_destroy (struct pivot_value *value) { if (value) { - font_style_uninit (value->font_style); - free (value->font_style); - free (value->cell_style); - free (value->footnote_indexes); - - for (size_t i = 0; i < value->n_subscripts; i++) - free (value->subscripts[i]); - free (value->subscripts); - + pivot_value_ex_destroy (value->ex); switch (value->type) { case PIVOT_VALUE_NUMERIC: @@ -2617,12 +2599,10 @@ pivot_value_get_style (struct pivot_value *value, const struct cell_style *base_cell_style, struct table_area_style *area) { - font_style_copy (NULL, &area->font_style, (value->font_style - ? value->font_style - : base_font_style)); - area->cell_style = *(value->cell_style - ? value->cell_style - : base_cell_style); + const struct pivot_value_ex *ex = pivot_value_ex (value); + font_style_copy (NULL, &area->font_style, + ex->font_style ? ex->font_style : base_font_style); + area->cell_style = *(ex->cell_style ? ex->cell_style : base_cell_style); } /* Copies AREA into VALUE's style. */ @@ -2638,20 +2618,22 @@ void pivot_value_set_font_style (struct pivot_value *value, const struct font_style *font_style) { - if (value->font_style) - font_style_uninit (value->font_style); + struct pivot_value_ex *ex = pivot_value_ex_rw (value); + if (ex->font_style) + font_style_uninit (ex->font_style); else - value->font_style = xmalloc (sizeof *value->font_style); - font_style_copy (NULL, value->font_style, font_style); + ex->font_style = xmalloc (sizeof *ex->font_style); + font_style_copy (NULL, ex->font_style, font_style); } void pivot_value_set_cell_style (struct pivot_value *value, const struct cell_style *cell_style) { - if (!value->cell_style) - value->cell_style = xmalloc (sizeof *value->cell_style); - *value->cell_style = *cell_style; + struct pivot_value_ex *ex = pivot_value_ex_rw (value); + if (!ex->cell_style) + ex->cell_style = xmalloc (sizeof *ex->cell_style); + *ex->cell_style = *cell_style; } void @@ -2879,15 +2861,18 @@ void pivot_value_add_footnote (struct pivot_value *v, const struct pivot_footnote *footnote) { + struct pivot_value_ex *ex = pivot_value_ex_rw (v); + /* Some legacy tables include numerous duplicate footnotes. Suppress them. */ - for (size_t i = 0; i < v->n_footnotes; i++) - if (v->footnote_indexes[i] == footnote->idx) + for (size_t i = 0; i < ex->n_footnotes; i++) + if (ex->footnote_indexes[i] == footnote->idx) return; - v->footnote_indexes = xrealloc ( - v->footnote_indexes, (v->n_footnotes + 1) * sizeof *v->footnote_indexes); - v->footnote_indexes[v->n_footnotes++] = footnote->idx; + ex->footnote_indexes = xrealloc ( + ex->footnote_indexes, + (ex->n_footnotes + 1) * sizeof *ex->footnote_indexes); + ex->footnote_indexes[ex->n_footnotes++] = footnote->idx; pivot_value_sort_footnotes (v); } @@ -2908,9 +2893,9 @@ compare_footnote_indexes (const void *a_, const void *b_) void pivot_value_sort_footnotes (struct pivot_value *v) { - if (v->n_footnotes > 1) - qsort (v->footnote_indexes, v->n_footnotes, sizeof *v->footnote_indexes, - compare_footnote_indexes); + if (v->ex && v->ex->n_footnotes > 1) + qsort (v->ex->footnote_indexes, v->ex->n_footnotes, + sizeof *v->ex->footnote_indexes, compare_footnote_indexes); } /* If VALUE is a numeric value, and RC is a result class such as @@ -2923,4 +2908,65 @@ pivot_value_set_rc (const struct pivot_table *table, struct pivot_value *value, pivot_table_use_rc (table, rc, &value->numeric.format, &value->numeric.honor_small); } + +/* pivot_value_ex. */ + +struct pivot_value_ex * +pivot_value_ex_rw (struct pivot_value *value) +{ + if (!value->ex) + value->ex = xzalloc (sizeof *value->ex); + return value->ex; +} + +struct pivot_value_ex * +pivot_value_ex_clone (const struct pivot_value_ex *old) +{ + struct font_style *font_style = NULL; + if (old->font_style) + { + font_style = xmalloc (sizeof *font_style); + font_style_copy (NULL, font_style, old->font_style); + } + char **subscripts = NULL; + if (old->n_subscripts) + { + subscripts = xnmalloc (old->n_subscripts, sizeof *subscripts); + for (size_t i = 0; i < old->n_subscripts; i++) + subscripts[i] = xstrdup (old->subscripts[i]); + } + + struct pivot_value_ex *new = xmalloc (sizeof *new); + *new = (struct pivot_value_ex) { + .font_style = font_style, + .cell_style = (old->cell_style + ? xmemdup (old->cell_style, sizeof *new->cell_style) + : NULL), + .subscripts = subscripts, + .n_subscripts = old->n_subscripts, + .footnote_indexes = ( + old->n_footnotes + ? xmemdup (old->footnote_indexes, + old->n_footnotes * sizeof *new->footnote_indexes) + : NULL), + .n_footnotes = old->n_footnotes + }; + return new; +} + +void +pivot_value_ex_destroy (struct pivot_value_ex *ex) +{ + if (ex) + { + font_style_uninit (ex->font_style); + free (ex->font_style); + free (ex->cell_style); + free (ex->footnote_indexes); + + for (size_t i = 0; i < ex->n_subscripts; i++) + free (ex->subscripts[i]); + free (ex->subscripts); + } +} diff --git a/src/output/pivot-table.h b/src/output/pivot-table.h index 0d6e333b06..eb78325428 100644 --- a/src/output/pivot-table.h +++ b/src/output/pivot-table.h @@ -647,15 +647,7 @@ enum ATTRIBUTE ((packed)) pivot_value_type */ struct pivot_value { - struct font_style *font_style; - struct cell_style *cell_style; - - char **subscripts; - size_t n_subscripts; - - size_t *footnote_indexes; - size_t n_footnotes; - + struct pivot_value_ex *ex; union { enum pivot_value_type type; @@ -801,6 +793,33 @@ void pivot_argument_uninit (struct pivot_argument *); void pivot_argument_copy (struct pivot_argument *, const struct pivot_argument *); +/* Extra styling for a pivot_value. + + This is logically part of pivot_value itself. It is broken into a separate + structure to save memory because it is rarely used. */ +struct pivot_value_ex + { + struct font_style *font_style; + struct cell_style *cell_style; + + char **subscripts; + size_t n_subscripts; + + size_t *footnote_indexes; + size_t n_footnotes; + }; + +static inline const struct pivot_value_ex * +pivot_value_ex (const struct pivot_value *value) +{ + static const struct pivot_value_ex empty_ex = { .font_style = NULL }; + return value->ex ? value->ex : &empty_ex; +} + +struct pivot_value_ex *pivot_value_ex_rw (struct pivot_value *); +struct pivot_value_ex *pivot_value_ex_clone (const struct pivot_value_ex *); +void pivot_value_ex_destroy (struct pivot_value_ex *); + /* One piece of data within a pivot table. */ struct pivot_cell { diff --git a/src/output/spv/spv-legacy-decoder.c b/src/output/spv/spv-legacy-decoder.c index d8ddb82e31..f5b50e2502 100644 --- a/src/output/spv/spv-legacy-decoder.c +++ b/src/output/spv/spv-legacy-decoder.c @@ -1427,11 +1427,11 @@ apply_styles_to_value (struct pivot_table *table, { if (sf) { - if (sf->reset > 0) + if (sf->reset > 0 && value->ex) { - free (value->footnote_indexes); - value->footnote_indexes = NULL; - value->n_footnotes = 0; + free (value->ex->footnote_indexes); + value->ex->footnote_indexes = NULL; + value->ex->n_footnotes = 0; } struct fmt_spec format = { .w = 0 }; @@ -1476,11 +1476,12 @@ apply_styles_to_value (struct pivot_table *table, } if (fg || bg) { + const struct pivot_value_ex *ex = pivot_value_ex (value); struct table_area_style area; pivot_value_get_style ( value, - value->font_style ? value->font_style : &base_area_style->font_style, - value->cell_style ? value->cell_style : &base_area_style->cell_style, + ex->font_style ? ex->font_style : &base_area_style->font_style, + ex->cell_style ? ex->cell_style : &base_area_style->cell_style, &area); decode_spvdx_style_incremental (fg, bg, &area); pivot_value_set_style (value, &area); @@ -1996,7 +1997,7 @@ decode_spvdx_table (const struct spvdx_visualization *v, const char *subtype, if (value->type == PIVOT_VALUE_NUMERIC && value->numeric.x == SYSMIS - && !value->n_footnotes) + && !pivot_value_ex (value)->n_footnotes) { /* Apparently, system-missing values are just empty cells? */ pivot_value_destroy (value); diff --git a/src/output/spv/spv-light-decoder.c b/src/output/spv/spv-light-decoder.c index fb0dd18d6a..e58d423d67 100644 --- a/src/output/spv/spv-light-decoder.c +++ b/src/output/spv/spv-light-decoder.c @@ -393,17 +393,19 @@ decode_spvlb_value (const struct pivot_table *table, { if (vm->n_subscripts) { - out->n_subscripts = vm->n_subscripts; - out->subscripts = xnmalloc (vm->n_subscripts, - sizeof *out->subscripts); + struct pivot_value_ex *ex = pivot_value_ex_rw (out); + ex->n_subscripts = vm->n_subscripts; + ex->subscripts = xnmalloc (vm->n_subscripts, sizeof *ex->subscripts); for (size_t i = 0; i < vm->n_subscripts; i++) - out->subscripts[i] = to_utf8 (vm->subscripts[i], encoding); + ex->subscripts[i] = to_utf8 (vm->subscripts[i], encoding); } if (vm->n_refs) { - out->footnote_indexes = xnmalloc (vm->n_refs, - sizeof *out->footnote_indexes); + struct pivot_value_ex *ex = pivot_value_ex_rw (out); + ex->footnote_indexes = xnmalloc (vm->n_refs, + sizeof *ex->footnote_indexes); + for (size_t i = 0; i < vm->n_refs; i++) { uint16_t idx = vm->refs[i]; @@ -414,18 +416,19 @@ decode_spvlb_value (const struct pivot_table *table, idx, table->n_footnotes); } - out->footnote_indexes[out->n_footnotes++] = idx; + ex->footnote_indexes[ex->n_footnotes++] = idx; } pivot_value_sort_footnotes (out); } if (vm->style_pair) { + struct pivot_value_ex *ex = pivot_value_ex_rw (out); error = decode_spvlb_font_style (vm->style_pair->font_style, - encoding, &out->font_style); + encoding, &ex->font_style); if (!error) error = decode_spvlb_cell_style (vm->style_pair->cell_style, - &out->cell_style); + &ex->cell_style); if (error) { pivot_value_destroy (out); diff --git a/src/output/spv/spv-writer.c b/src/output/spv/spv-writer.c index 2e24a33e9b..bb37a05e24 100644 --- a/src/output/spv/spv-writer.c +++ b/src/output/spv/spv-writer.c @@ -558,20 +558,25 @@ static void put_value_mod (struct buf *buf, const struct pivot_value *value, const char *template) { - if (value->n_footnotes || value->n_subscripts - || template || value->font_style || value->cell_style) + if ((value->ex + && (value->ex->n_footnotes + || value->ex->n_subscripts + || value->ex->font_style + || value->ex->cell_style)) + || template) { + const struct pivot_value_ex *ex = pivot_value_ex (value); put_byte (buf, 0x31); /* Footnotes. */ - put_u32 (buf, value->n_footnotes); - for (size_t i = 0; i < value->n_footnotes; i++) - put_u16 (buf, value->footnote_indexes[i]); + put_u32 (buf, ex->n_footnotes); + for (size_t i = 0; i < ex->n_footnotes; i++) + put_u16 (buf, ex->footnote_indexes[i]); /* Subscripts. */ - put_u32 (buf, value->n_subscripts); - for (size_t i = 0; i < value->n_subscripts; i++) - put_string (buf, value->subscripts[i]); + put_u32 (buf, ex->n_subscripts); + for (size_t i = 0; i < ex->n_subscripts; i++) + put_string (buf, ex->subscripts[i]); /* Template and style. */ uint32_t v3_start = start_count (buf); @@ -585,7 +590,7 @@ put_value_mod (struct buf *buf, const struct pivot_value *value, put_string (buf, template); } end_count_u32 (buf, template_string_start); - put_style_pair (buf, value->font_style, value->cell_style); + put_style_pair (buf, ex->font_style, ex->cell_style); end_count_u32 (buf, v3_start); } else diff --git a/src/output/spv/spv.c b/src/output/spv/spv.c index 9b0fe17a21..2e5dd07b2b 100644 --- a/src/output/spv/spv.c +++ b/src/output/spv/spv.c @@ -282,9 +282,9 @@ decode_container_text (const struct spvsx_container_text *ct) { struct font_style *font_style = xmalloc (sizeof *font_style); char *text = decode_embedded_html (ct->html->node_.raw, font_style); + struct pivot_value *value = xmalloc (sizeof *value); *value = (struct pivot_value) { - .font_style = font_style, .text = { .type = PIVOT_VALUE_TEXT, .local = text, @@ -293,6 +293,7 @@ decode_container_text (const struct spvsx_container_text *ct) .user_provided = true, }, }; + pivot_value_ex_rw (value)->font_style = font_style; struct output_item *item = text_item_create_value (TEXT_ITEM_LOG, value, NULL); diff --git a/src/output/table.c b/src/output/table.c index bf22d2da5a..09ed509e35 100644 --- a/src/output/table.c +++ b/src/output/table.c @@ -527,12 +527,13 @@ table_get_cell (const struct table *t, int x, int y, struct table_cell *cell) else { const struct pivot_value *v = cc ? cc : &empty_value; + const struct pivot_value_ex *ex = pivot_value_ex (v); *cell = (struct table_cell) { .d = { [H] = { x, x + 1 }, [V] = { y, y + 1 } }, .options = opt, .value = v, - .font_style = v->font_style ? v->font_style : &style->font_style, - .cell_style = v->cell_style ? v->cell_style : &style->cell_style, + .font_style = ex->font_style ? ex->font_style : &style->font_style, + .cell_style = ex->cell_style ? ex->cell_style : &style->cell_style, }; } diff --git a/src/output/tex.c b/src/output/tex.c index 800aa726d9..698abaa453 100644 --- a/src/output/tex.c +++ b/src/output/tex.c @@ -393,13 +393,12 @@ tex_submit (struct output_driver *driver, const struct output_item *item) static void tex_put_footnote_markers (struct tex_driver *tex, const struct pivot_table *pt, - const size_t *footnote_indexes, - size_t n_footnotes) + const struct pivot_value_ex *ex) { size_t n_visible = 0; - for (size_t i = 0; i < n_footnotes; i++) + for (size_t i = 0; i < ex->n_footnotes; i++) { - const struct pivot_footnote *f = pt->footnotes[footnote_indexes[i]]; + const struct pivot_footnote *f = pt->footnotes[ex->footnote_indexes[i]]; if (f->show) { if (!n_visible++) @@ -423,9 +422,7 @@ tex_put_table_cell (struct tex_driver *tex, const struct pivot_table *pt, tex_escape_string (tex, ds_cstr (&s), false); ds_destroy (&s); - tex_put_footnote_markers (tex, pt, - cell->value->footnote_indexes, - cell->value->n_footnotes); + tex_put_footnote_markers (tex, pt, pivot_value_ex (cell->value)); } static void @@ -549,8 +546,7 @@ tex_output_table_layer (struct tex_driver *tex, const struct pivot_table *pt, tex_escape_string (tex, ds_cstr (&s), true); ds_destroy (&s); - tex_put_footnote_markers (tex, pt, cell.value->footnote_indexes, - cell.value->n_footnotes); + tex_put_footnote_markers (tex, pt, pivot_value_ex (cell.value)); if (halign == TABLE_HALIGN_CENTER || halign == TABLE_HALIGN_RIGHT) { shipout (&tex->token_list, "}"); diff --git a/tests/output/pivot-table-test.c b/tests/output/pivot-table-test.c index 98336b2563..18e7d0499f 100644 --- a/tests/output/pivot-table-test.c +++ b/tests/output/pivot-table-test.c @@ -598,16 +598,16 @@ read_value_option (struct lexer *lexer, const struct pivot_table *pt, if (lex_match_id (lexer, "SUBSCRIPTS")) { lex_match (lexer, T_EQUALS); - size_t allocated_subscripts = value->n_subscripts; + + struct pivot_value_ex *ex = pivot_value_ex_rw (value); + size_t allocated_subscripts = ex->n_subscripts; while (lex_token (lexer) == T_STRING) { - if (value->n_subscripts >= allocated_subscripts) - value->subscripts = x2nrealloc (value->subscripts, - &allocated_subscripts, - sizeof *value->subscripts); + if (ex->n_subscripts >= allocated_subscripts) + ex->subscripts = x2nrealloc (ex->subscripts, &allocated_subscripts, + sizeof *ex->subscripts); - value->subscripts[value->n_subscripts++] = xstrdup ( - lex_tokcstr (lexer)); + ex->subscripts[ex->n_subscripts++] = xstrdup (lex_tokcstr (lexer)); lex_get (lexer); } return; @@ -617,12 +617,13 @@ read_value_option (struct lexer *lexer, const struct pivot_table *pt, { lex_match (lexer, T_EQUALS); - if (!value->font_style) + struct pivot_value_ex *ex = pivot_value_ex_rw (value); + if (!ex->font_style) { - value->font_style = xmalloc (sizeof *value->font_style); - font_style_copy (NULL, value->font_style, &base_style->font_style); + ex->font_style = xmalloc (sizeof *ex->font_style); + font_style_copy (NULL, ex->font_style, &base_style->font_style); } - read_font_style (lexer, value->font_style); + read_font_style (lexer, ex->font_style); return; } @@ -630,12 +631,13 @@ read_value_option (struct lexer *lexer, const struct pivot_table *pt, { lex_match (lexer, T_EQUALS); - if (!value->cell_style) + struct pivot_value_ex *ex = pivot_value_ex_rw (value); + if (!ex->cell_style) { - value->cell_style = xmalloc (sizeof *value->cell_style); - *value->cell_style = base_style->cell_style; + ex->cell_style = xmalloc (sizeof *ex->cell_style); + *ex->cell_style = base_style->cell_style; } - read_cell_style (lexer, value->cell_style); + read_cell_style (lexer, ex->cell_style); return; } -- 2.30.2