#include "output/pivot-table.h"
+#include <math.h>
#include <stdlib.h>
#include "data/data-out.h"
#define _(msgid) gettext (msgid)
#define N_(msgid) msgid
-static const struct fmt_spec *pivot_table_get_format (
- const struct pivot_table *, const char *s);
+static void pivot_table_use_rc (const struct pivot_table *, const char *s,
+ struct fmt_spec *, bool *honor_small);
\f
/* Pivot table display styling. */
static void
pivot_category_set_rc (struct pivot_category *category, const char *s)
{
- const struct fmt_spec *format = pivot_table_get_format (
- category->dimension->table, s);
- if (format)
- category->format = *format;
+ if (!s)
+ return;
+
+ pivot_table_use_rc (category->dimension->table, s,
+ &category->format, &category->honor_small);
/* Ensure that the category itself, in addition to the cells within it, takes
the format. (It's kind of rare for a category to have a numeric format
though.) */
struct pivot_value *name = category->name;
if (name->type == PIVOT_VALUE_NUMERIC && !name->numeric.format.w)
- name->numeric.format = format ? *format : *settings_get_format ();
+ pivot_table_use_rc (category->dimension->table, s,
+ &name->numeric.format, &name->numeric.honor_small);
}
static void
return NULL;
}
-static const struct fmt_spec *
-pivot_table_get_format (const struct pivot_table *table, const char *s)
+static void
+pivot_table_use_rc (const struct pivot_table *table, const char *s,
+ struct fmt_spec *format, bool *honor_small)
{
- if (!s)
- return NULL;
- else if (!strcmp (s, PIVOT_RC_OTHER))
- return settings_get_format ();
- else if (!strcmp (s, PIVOT_RC_COUNT) && !overridden_count_format)
- return &table->weight_format;
- else
+ if (s)
{
- const struct result_class *rc = pivot_result_class_find (s);
- return rc ? &rc->format : NULL;
+ if (!strcmp (s, PIVOT_RC_OTHER))
+ {
+ *format = *settings_get_format ();
+ *honor_small = true;
+ }
+ else if (!strcmp (s, PIVOT_RC_COUNT) && !overridden_count_format)
+ {
+ *format = table->weight_format;
+ *honor_small = false;
+ }
+ else
+ {
+ const struct result_class *rc = pivot_result_class_find (s);
+ if (rc)
+ {
+ *format = rc->format;
+ *honor_small = false;
+ }
+ else
+ {
+ printf ("unknown class %s\n", s);
+ }
+ }
}
}
table->subtype = subtype ? pivot_value_new_text (subtype) : NULL;
table->command_c = output_get_command_name ();
table->look = pivot_table_look_ref (pivot_table_look_get_default ());
+ table->settings = fmt_settings_copy (settings_get_fmt_settings ());
+ table->small = settings_get_small ();
hmap_init (&table->cells);
if (pivot_category_is_leaf (old))
{
+ assert (new->data_index < new_dimension->n_leaves);
new->dimension->data_leaves[new->data_index] = new;
+
+ assert (new->presentation_index < new_dimension->n_leaves);
new->dimension->presentation_leaves[new->presentation_index] = new;
}
[TABLE_VERT] = clone_sizing (&old->sizing[TABLE_VERT]),
},
- .epoch = old->epoch,
- .decimal = old->decimal,
+ .settings = fmt_settings_copy (&old->settings),
.grouping = old->grouping,
- .ccs = {
- [0] = xstrdup_if_nonnull (old->ccs[0]),
- [1] = xstrdup_if_nonnull (old->ccs[1]),
- [2] = xstrdup_if_nonnull (old->ccs[2]),
- [3] = xstrdup_if_nonnull (old->ccs[3]),
- [4] = xstrdup_if_nonnull (old->ccs[4]),
- },
.small = old->small,
.command_local = xstrdup_if_nonnull (old->command_local),
for (int i = 0; i < TABLE_N_AXES; i++)
pivot_table_sizing_uninit (&table->sizing[i]);
- for (int i = 0; i < sizeof table->ccs / sizeof *table->ccs; i++)
- free (table->ccs[i]);
+ fmt_settings_uninit (&table->settings);
free (table->command_local);
free (table->command_c);
if (c->format.w)
{
value->numeric.format = c->format;
+ value->numeric.honor_small = c->honor_small;
goto done;
}
}
}
value->numeric.format = *settings_get_format ();
+ value->numeric.honor_small = true;
done:;
}
}
static void
-pivot_value_dump (const struct pivot_value *value)
+pivot_value_dump (const struct pivot_value *value,
+ const struct pivot_table *pt)
{
- char *s = pivot_value_to_string_defaults (value);
+ char *s = pivot_value_to_string (value, pt);
fputs (s, stdout);
free (s);
}
static void
pivot_table_dump_value (const struct pivot_value *value, const char *name,
- int indentation)
+ const struct pivot_table *pt, int indentation)
{
if (value)
{
indent (indentation);
printf ("%s: ", name);
- pivot_value_dump (value);
+ pivot_value_dump (value, pt);
putchar ('\n');
}
}
}
static void
-pivot_category_dump (const struct pivot_category *c, int indentation)
+pivot_category_dump (const struct pivot_category *c,
+ const struct pivot_table *pt, int indentation)
{
indent (indentation);
printf ("%s \"", pivot_category_is_leaf (c) ? "leaf" : "group");
- pivot_value_dump (c->name);
+ pivot_value_dump (c->name, pt);
printf ("\" ");
if (pivot_category_is_leaf (c))
printf ("\n");
for (size_t i = 0; i < c->n_subs; i++)
- pivot_category_dump (c->subs[i], indentation + 1);
+ pivot_category_dump (c->subs[i], pt, indentation + 1);
}
}
void
-pivot_dimension_dump (const struct pivot_dimension *d, int indentation)
+pivot_dimension_dump (const struct pivot_dimension *d,
+ const struct pivot_table *pt, int indentation)
{
indent (indentation);
printf ("%s dimension %zu (where 0=innermost), label_depth=%d:\n",
pivot_axis_type_to_string (d->axis_type), d->level, d->label_depth);
- pivot_category_dump (d->root, indentation + 1);
+ pivot_category_dump (d->root, pt, indentation + 1);
}
static void
pivot_table_assign_label_depth (CONST_CAST (struct pivot_table *, table));
- int old_decimal = settings_get_decimal_char (FMT_COMMA);
- if (table->decimal == '.' || table->decimal == ',')
- settings_set_decimal_char (table->decimal);
-
- pivot_table_dump_value (table->title, "title", indentation);
- pivot_table_dump_value (table->subtype, "subtype", indentation);
+ pivot_table_dump_value (table->title, "title", table, indentation);
+ pivot_table_dump_value (table->subtype, "subtype", table, indentation);
pivot_table_dump_string (table->command_c, "command", indentation);
pivot_table_dump_string (table->dataset, "dataset", indentation);
pivot_table_dump_string (table->datafile, "datafile", indentation);
indentation + 1);
for (size_t i = 0; i < table->n_dimensions; i++)
- pivot_dimension_dump (table->dimensions[i], indentation);
+ pivot_dimension_dump (table->dimensions[i], table, indentation);
/* Presentation and data indexes. */
size_t *dindexes = XCALLOC (table->n_dimensions, size_t);
const struct pivot_dimension *d = layer_axis->dimensions[i];
fputs (i == 0 ? " " : ", ", stdout);
- pivot_value_dump (d->root->name);
+ pivot_value_dump (d->root->name, table);
fputs (" =", stdout);
struct pivot_value **names = xnmalloc (d->n_leaves, sizeof *names);
for (size_t i = n_names; i-- > 0;)
{
putchar (' ');
- pivot_value_dump (names[i]);
+ pivot_value_dump (names[i], table);
}
free (names);
}
const struct pivot_value *value = pivot_table_get (
table, dindexes);
if (value)
- pivot_value_dump (value);
+ pivot_value_dump (value, table);
}
printf ("\n");
free_headings (&table->axes[PIVOT_AXIS_ROW], row_headings);
}
- pivot_table_dump_value (table->caption, "caption", indentation);
+ pivot_table_dump_value (table->caption, "caption", table, indentation);
for (size_t i = 0; i < table->n_footnotes; i++)
{
indent (indentation);
putchar ('[');
if (f->marker)
- pivot_value_dump (f->marker);
+ pivot_value_dump (f->marker, table);
else
printf ("%zu", f->idx);
putchar (']');
- pivot_value_dump (f->content);
+ pivot_value_dump (f->content, table);
putchar ('\n');
}
free (dindexes);
- settings_set_decimal_char (old_decimal);
}
\f
static const char *
value->numeric.value_label != NULL);
if (show & SETTINGS_VALUE_SHOW_VALUE)
{
+ const struct fmt_spec *f = &value->numeric.format;
+ const struct fmt_spec *format
+ = (f->type == FMT_F
+ && value->numeric.honor_small
+ && value->numeric.x != 0
+ && fabs (value->numeric.x) < pt->small
+ ? &(struct fmt_spec) { .type = FMT_E, .w = 40, .d = f->d }
+ : f);
+
char *s = data_out (&(union value) { .f = value->numeric.x },
- "UTF-8", &value->numeric.format);
+ "UTF-8", format, &pt->settings);
ds_put_cstr (out, s + strspn (s, " "));
free (s);
}
font_style_copy (NULL, new->font_style, old->font_style);
}
if (old->cell_style)
- new->font_style = xmemdup (old->font_style, sizeof *new->font_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);
case PIVOT_VALUE_TEXT:
new->text.local = xstrdup (old->text.local);
new->text.c = (old->text.c == old->text.local ? new->text.local
- : xstrdup (old->text.c));
+ : xstrdup_if_nonnull (old->text.c));
new->text.id = (old->text.id == old->text.local ? new->text.local
: old->text.id == old->text.c ? new->text.c
- : xstrdup (old->text.id));
+ : xstrdup_if_nonnull (old->text.id));
break;
case PIVOT_VALUE_TEMPLATE:
const char *rc)
{
if (value->type == PIVOT_VALUE_NUMERIC)
- {
- const struct fmt_spec *f = pivot_table_get_format (table, rc);
- if (f)
- value->numeric.format = *f;
- }
+ pivot_table_use_rc (table, rc,
+ &value->numeric.format, &value->numeric.honor_small);
}