X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fpivot-table.c;h=272ccc9e34849dca95a9d133712d219b2a3e0b75;hb=fcd81b62b80e6e7bb0f5527b246522e74a96354e;hp=3878b888e51842df6ee63d1ef7d239d640c3a51e;hpb=dc23d73ba6a44d3b962c3cafa3b797af14b9db4a;p=pspp diff --git a/src/output/pivot-table.c b/src/output/pivot-table.c index 3878b888e5..272ccc9e34 100644 --- a/src/output/pivot-table.c +++ b/src/output/pivot-table.c @@ -62,7 +62,7 @@ pivot_area_to_string (enum pivot_area area) } } -const struct area_style * +const struct table_area_style * pivot_area_get_default_style (enum pivot_area area) { #define STYLE(BOLD, H, V, L, R, T, B) { \ @@ -80,8 +80,8 @@ pivot_area_get_default_style (enum pivot_area area) .typeface = (char *) "Sans Serif", \ }, \ } - static const struct area_style default_area_styles[PIVOT_N_AREAS] = { - [PIVOT_AREA_TITLE] = STYLE( true, CENTER, CENTER, 8,11,1,8), + static const struct table_area_style default_area_styles[PIVOT_N_AREAS] = { + [PIVOT_AREA_TITLE] = STYLE(true, CENTER, CENTER, 8,11,1,8), [PIVOT_AREA_CAPTION] = STYLE(false, LEFT, TOP, 8,11,1,1), [PIVOT_AREA_FOOTER] = STYLE(false, LEFT, TOP, 11, 8,2,3), [PIVOT_AREA_CORNER] = STYLE(false, LEFT, BOTTOM, 8,11,1,1), @@ -193,6 +193,80 @@ pivot_table_sizing_uninit (struct pivot_table_sizing *sizing) } } +/* Pivot table looks. */ + +void +pivot_table_look_init (struct pivot_table_look *look) +{ + memset (look, 0, sizeof *look); + + look->omit_empty = false; + look->row_labels_in_corner = true; + look->width_ranges[TABLE_HORZ][0] = 36; + look->width_ranges[TABLE_HORZ][1] = 72; + look->width_ranges[TABLE_VERT][0] = 36; + look->width_ranges[TABLE_VERT][1] = 120; + + for (size_t i = 0; i < PIVOT_N_AREAS; i++) + table_area_style_copy (NULL, &look->areas[i], + pivot_area_get_default_style (i)); + + static const enum table_stroke default_strokes[PIVOT_N_BORDERS] = { + [PIVOT_BORDER_TITLE] = TABLE_STROKE_NONE, + [PIVOT_BORDER_OUTER_LEFT] = TABLE_STROKE_NONE, + [PIVOT_BORDER_OUTER_TOP] = TABLE_STROKE_NONE, + [PIVOT_BORDER_OUTER_RIGHT] = TABLE_STROKE_NONE, + [PIVOT_BORDER_OUTER_BOTTOM] = TABLE_STROKE_NONE, + [PIVOT_BORDER_INNER_LEFT] = TABLE_STROKE_THICK, + [PIVOT_BORDER_INNER_TOP] = TABLE_STROKE_THICK, + [PIVOT_BORDER_INNER_RIGHT] = TABLE_STROKE_THICK, + [PIVOT_BORDER_INNER_BOTTOM] = TABLE_STROKE_THICK, + [PIVOT_BORDER_DATA_LEFT] = TABLE_STROKE_THICK, + [PIVOT_BORDER_DATA_TOP] = TABLE_STROKE_THICK, + [PIVOT_BORDER_DIM_ROW_HORZ] = TABLE_STROKE_SOLID, + [PIVOT_BORDER_DIM_ROW_VERT] = TABLE_STROKE_NONE, + [PIVOT_BORDER_DIM_COL_HORZ] = TABLE_STROKE_SOLID, + [PIVOT_BORDER_DIM_COL_VERT] = TABLE_STROKE_SOLID, + [PIVOT_BORDER_CAT_ROW_HORZ] = TABLE_STROKE_NONE, + [PIVOT_BORDER_CAT_ROW_VERT] = TABLE_STROKE_NONE, + [PIVOT_BORDER_CAT_COL_HORZ] = TABLE_STROKE_SOLID, + [PIVOT_BORDER_CAT_COL_VERT] = TABLE_STROKE_SOLID, + }; + for (size_t i = 0; i < PIVOT_N_BORDERS; i++) + look->borders[i] = (struct table_border_style) { + .stroke = default_strokes[i], + .color = CELL_COLOR_BLACK, + }; +} + +void +pivot_table_look_uninit (struct pivot_table_look *look) +{ + free (look->name); + + for (size_t i = 0; i < PIVOT_N_AREAS; i++) + table_area_style_uninit (&look->areas[i]); + + free (look->continuation); +} + +static char * +xstrdup_if_nonempty (const char *s) +{ + return s && s[0] ? xstrdup (s) : NULL; +} + +void +pivot_table_look_copy (struct pivot_table_look *dst, + const struct pivot_table_look *src) +{ + *dst = *src; + dst->name = xstrdup_if_nonempty (src->name); + for (size_t i = 0; i < PIVOT_N_AREAS; i++) + table_area_style_copy (NULL, &dst->areas[i], &src->areas[i]); + dst->continuation = xstrdup_if_nonempty (src->continuation); +} + /* Axes. */ /* Returns the name of AXIS_TYPE. */ @@ -704,48 +778,11 @@ pivot_table_create__ (struct pivot_value *title, const char *subtype) table->show_caption = true; table->weight_format = (struct fmt_spec) { FMT_F, 40, 0 }; table->title = title; - table->subtype = pivot_value_new_text (subtype); + table->subtype = subtype ? pivot_value_new_text (subtype) : NULL; + table->command_c = output_get_command_name (); - const char *command_id = output_get_command_name (); - table->command_c = command_id ? xstrdup (command_id) : NULL; + pivot_table_look_init (&table->look); - table->sizing[TABLE_HORZ].range[0] = 50; - table->sizing[TABLE_HORZ].range[1] = 72; - table->sizing[TABLE_VERT].range[0] = 36; - table->sizing[TABLE_VERT].range[1] = 120; - - for (size_t i = 0; i < PIVOT_N_AREAS; i++) - area_style_copy (NULL, &table->areas[i], pivot_area_get_default_style (i)); - - /* Set default border styles. */ - static const enum table_stroke default_strokes[PIVOT_N_BORDERS] = { - [PIVOT_BORDER_TITLE] = TABLE_STROKE_NONE, - [PIVOT_BORDER_OUTER_LEFT] = TABLE_STROKE_NONE, - [PIVOT_BORDER_OUTER_TOP] = TABLE_STROKE_NONE, - [PIVOT_BORDER_OUTER_RIGHT] = TABLE_STROKE_NONE, - [PIVOT_BORDER_OUTER_BOTTOM] = TABLE_STROKE_NONE, - [PIVOT_BORDER_INNER_LEFT] = TABLE_STROKE_THICK, - [PIVOT_BORDER_INNER_TOP] = TABLE_STROKE_THICK, - [PIVOT_BORDER_INNER_RIGHT] = TABLE_STROKE_THICK, - [PIVOT_BORDER_INNER_BOTTOM] = TABLE_STROKE_THICK, - [PIVOT_BORDER_DATA_LEFT] = TABLE_STROKE_THICK, - [PIVOT_BORDER_DATA_TOP] = TABLE_STROKE_THICK, - [PIVOT_BORDER_DIM_ROW_HORZ] = TABLE_STROKE_SOLID, - [PIVOT_BORDER_DIM_ROW_VERT] = TABLE_STROKE_NONE, - [PIVOT_BORDER_DIM_COL_HORZ] = TABLE_STROKE_SOLID, - [PIVOT_BORDER_DIM_COL_VERT] = TABLE_STROKE_SOLID, - [PIVOT_BORDER_CAT_ROW_HORZ] = TABLE_STROKE_NONE, - [PIVOT_BORDER_CAT_ROW_VERT] = TABLE_STROKE_NONE, - [PIVOT_BORDER_CAT_COL_HORZ] = TABLE_STROKE_SOLID, - [PIVOT_BORDER_CAT_COL_VERT] = TABLE_STROKE_SOLID, - }; - for (size_t i = 0; i < PIVOT_N_BORDERS; i++) - table->borders[i] = (struct table_border_style) { - .stroke = default_strokes[i], - .color = CELL_COLOR_BLACK, - }; - - table->row_labels_in_corner = true; hmap_init (&table->cells); return table; @@ -794,13 +831,11 @@ pivot_table_unref (struct pivot_table *table) return; free (table->current_layer); - free (table->table_look); + pivot_table_look_uninit (&table->look); for (int i = 0; i < TABLE_N_AXES; i++) pivot_table_sizing_uninit (&table->sizing[i]); - free (table->continuation); - for (int i = 0; i < sizeof table->ccs / sizeof *table->ccs; i++) free (table->ccs[i]); @@ -821,9 +856,6 @@ pivot_table_unref (struct pivot_table *table) pivot_value_destroy (table->corner_text); pivot_value_destroy (table->caption); - for (size_t i = 0; i < PIVOT_N_AREAS; i++) - area_style_uninit (&table->areas[i]); - for (size_t i = 0; i < table->n_dimensions; i++) pivot_dimension_destroy (table->dimensions[i]); free (table->dimensions); @@ -852,6 +884,20 @@ pivot_table_is_shared (const struct pivot_table *table) return table->ref_cnt > 1; } +const struct pivot_table_look * +pivot_table_get_look (const struct pivot_table *table) +{ + return &table->look; +} + +void +pivot_table_set_look (struct pivot_table *table, + const struct pivot_table_look *look) +{ + pivot_table_look_uninit (&table->look); + pivot_table_look_copy (&table->look, look); +} + /* Sets the format used for PIVOT_RC_COUNT cells to the one used for variable WV, which should be the weight variable for the dictionary whose data or statistics are being put into TABLE. @@ -1057,7 +1103,7 @@ pivot_table_create_footnote__ (struct pivot_table *table, size_t idx, struct pivot_footnote *f = xmalloc (sizeof *f); f->idx = table->n_footnotes; f->marker = pivot_make_default_footnote_marker ( - f->idx, table->show_numeric_markers); + f->idx, table->look.show_numeric_markers); f->content = NULL; f->show = true; @@ -1140,7 +1186,7 @@ pivot_table_enumerate_axis (const struct pivot_table *table, axis->n_dimensions), 1), sizeof *enumeration); size_t *p = enumeration; - size_t *dindexes = xcalloc (table->n_dimensions, sizeof *dindexes); + size_t *dindexes = XCALLOC (table->n_dimensions, size_t); size_t *axis_indexes; PIVOT_AXIS_FOR_EACH (axis_indexes, axis) @@ -1276,7 +1322,7 @@ pivot_table_assign_label_depth (struct pivot_table *table) { pivot_axis_assign_label_depth (table, PIVOT_AXIS_COLUMN, false); if (pivot_axis_assign_label_depth ( - table, PIVOT_AXIS_ROW, (table->row_labels_in_corner + table, PIVOT_AXIS_ROW, (table->look.row_labels_in_corner && !table->corner_text)) && table->axes[PIVOT_AXIS_COLUMN].label_depth == 0) table->axes[PIVOT_AXIS_COLUMN].label_depth = 1; @@ -1357,8 +1403,8 @@ pivot_dimension_dump (const struct pivot_dimension *d, int indentation) } static void -area_style_dump (enum pivot_area area, const struct area_style *a, - int indentation) +table_area_style_dump (enum pivot_area area, const struct table_area_style *a, + int indentation) { indent (indentation); printf ("%s: ", pivot_area_to_string (area)); @@ -1437,11 +1483,13 @@ free_headings (const struct pivot_axis *axis, char ***headings) } static void -pivot_table_sizing_dump (const char *name, const struct pivot_table_sizing *s, +pivot_table_sizing_dump (const char *name, + const int width_ranges[2], + const struct pivot_table_sizing *s, int indentation) { indent (indentation); - printf ("%ss: min=%d, max=%d\n", name, s->range[0], s->range[1]); + printf ("%ss: min=%d, max=%d\n", name, width_ranges[0], width_ranges[1]); if (s->n_widths) { indent (indentation + 1); @@ -1485,36 +1533,40 @@ pivot_table_dump (const struct pivot_table *table, int indentation) pivot_table_dump_string (table->dataset, "dataset", indentation); pivot_table_dump_string (table->datafile, "datafile", indentation); pivot_table_dump_string (table->notes, "notes", indentation); - pivot_table_dump_string (table->table_look, "table-look", indentation); + pivot_table_dump_string (table->look.name, "table-look", indentation); if (table->date) { indent (indentation); - char buf[26]; - printf ("date: %s", ctime_r (&table->date, buf)); + + struct tm *tm = localtime (&table->date); + printf ("date: %d-%02d-%02d %d:%02d:%02d\n", tm->tm_year + 1900, + tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, + tm->tm_sec); } indent (indentation); printf ("sizing:\n"); - pivot_table_sizing_dump ("column", &table->sizing[TABLE_HORZ], - indentation + 1); - pivot_table_sizing_dump ("row", &table->sizing[TABLE_VERT], - indentation + 1); + pivot_table_sizing_dump ("column", table->look.width_ranges[TABLE_HORZ], + &table->sizing[TABLE_HORZ], indentation + 1); + pivot_table_sizing_dump ("row", table->look.width_ranges[TABLE_VERT], + &table->sizing[TABLE_VERT], indentation + 1); indent (indentation); printf ("areas:\n"); for (enum pivot_area area = 0; area < PIVOT_N_AREAS; area++) - area_style_dump (area, &table->areas[area], indentation + 1); + table_area_style_dump (area, &table->look.areas[area], indentation + 1); indent (indentation); printf ("borders:\n"); for (enum pivot_border border = 0; border < PIVOT_N_BORDERS; border++) - table_border_style_dump (border, &table->borders[border], indentation + 1); + table_border_style_dump (border, &table->look.borders[border], + indentation + 1); for (size_t i = 0; i < table->n_dimensions; i++) pivot_dimension_dump (table->dimensions[i], indentation); /* Presentation and data indexes. */ - size_t *dindexes = xcalloc (table->n_dimensions, sizeof *dindexes); + size_t *dindexes = XCALLOC (table->n_dimensions, size_t); const struct pivot_axis *layer_axis = &table->axes[PIVOT_AXIS_LAYER]; if (layer_axis->n_dimensions) @@ -1567,7 +1619,7 @@ pivot_table_dump (const struct pivot_table *table, int indentation) names[n_names++] = c->name; } - for (size_t i = n_names; i-- > 0; ) + for (size_t i = n_names; i-- > 0;) { putchar (' '); pivot_value_dump (names[i]); @@ -1577,9 +1629,9 @@ pivot_table_dump (const struct pivot_table *table, int indentation) putchar ('\n'); size_t *column_enumeration = pivot_table_enumerate_axis ( - table, PIVOT_AXIS_COLUMN, layer_indexes, table->omit_empty, NULL); + table, PIVOT_AXIS_COLUMN, layer_indexes, table->look.omit_empty, NULL); size_t *row_enumeration = pivot_table_enumerate_axis ( - table, PIVOT_AXIS_ROW, layer_indexes, table->omit_empty, NULL); + table, PIVOT_AXIS_ROW, layer_indexes, table->look.omit_empty, NULL); char ***column_headings = compose_headings ( &table->axes[PIVOT_AXIS_COLUMN], column_enumeration, @@ -1891,7 +1943,7 @@ pivot_value_format (const struct pivot_value *value, enum settings_value_show show_variables, struct string *out) { - pivot_value_format_body ( value, show_values, show_variables, out); + pivot_value_format_body (value, show_values, show_variables, out); if (value->n_subscripts) { @@ -1985,21 +2037,22 @@ pivot_value_destroy (struct pivot_value *value) DEFAULT_STYLE for the parts of the style that VALUE doesn't override. */ void pivot_value_get_style (struct pivot_value *value, - const struct area_style *default_style, - struct area_style *area) + const struct font_style *base_font_style, + 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 - : &default_style->font_style)); - area->cell_style = (value->cell_style - ? *value->cell_style - : default_style->cell_style); + : base_font_style)); + area->cell_style = *(value->cell_style + ? value->cell_style + : base_cell_style); } /* Copies AREA into VALUE's style. */ void pivot_value_set_style (struct pivot_value *value, - const struct area_style *area) + const struct table_area_style *area) { if (value->font_style) font_style_uninit (value->font_style); @@ -2118,12 +2171,6 @@ pivot_value_new_text_format (const char *format, ...) return value; } -static char * -xstrdup_if_nonempty (const char *s) -{ - return s && s[0] ? xstrdup (s) : NULL; -} - /* Returns a new pivot_value that represents X. The format to use for X is unspecified. Usually the easiest way to specify @@ -2228,6 +2275,12 @@ void pivot_value_add_footnote (struct pivot_value *v, const struct pivot_footnote *footnote) { + /* Some legacy tables include numerous duplicate footnotes. Suppress + them. */ + for (size_t i = 0; i < v->n_footnotes; i++) + if (v->footnotes[i] == footnote) + return; + v->footnotes = xrealloc (v->footnotes, (v->n_footnotes + 1) * sizeof *v->footnotes); v->footnotes[v->n_footnotes++] = footnote;