+static void
+ctables_add_category_occurrences (const struct variable *var,
+ struct hmap *occurrences,
+ const struct ctables_categories *cats)
+{
+ const struct val_labs *val_labs = var_get_value_labels (var);
+
+ for (size_t i = 0; i < cats->n_cats; i++)
+ {
+ const struct ctables_category *c = &cats->cats[i];
+ switch (c->type)
+ {
+ case CCT_NUMBER:
+ ctables_add_occurrence (var, &(const union value) { .f = c->number },
+ occurrences);
+ break;
+
+ case CCT_STRING:
+ abort (); /* XXX */
+
+ case CCT_RANGE:
+ assert (var_is_numeric (var));
+ for (const struct val_lab *vl = val_labs_first (val_labs); vl;
+ vl = val_labs_next (val_labs, vl))
+ if (vl->value.f >= c->range[0] && vl->value.f <= c->range[1])
+ ctables_add_occurrence (var, &vl->value, occurrences);
+ break;
+
+ case CCT_MISSING:
+ for (const struct val_lab *vl = val_labs_first (val_labs); vl;
+ vl = val_labs_next (val_labs, vl))
+ if (var_is_value_missing (var, &vl->value))
+ ctables_add_occurrence (var, &vl->value, occurrences);
+ break;
+
+ case CCT_OTHERNM:
+ for (const struct val_lab *vl = val_labs_first (val_labs); vl;
+ vl = val_labs_next (val_labs, vl))
+ ctables_add_occurrence (var, &vl->value, occurrences);
+ break;
+
+ case CCT_SUBTOTAL:
+ case CCT_HSUBTOTAL:
+ case CCT_TOTAL:
+ break;
+
+ case CCT_VALUE:
+ case CCT_LABEL:
+ case CCT_FUNCTION:
+ for (const struct val_lab *vl = val_labs_first (val_labs); vl;
+ vl = val_labs_next (val_labs, vl))
+ if (c->include_missing || !var_is_value_missing (var, &vl->value))
+ ctables_add_occurrence (var, &vl->value, occurrences);
+ break;
+ }
+ }
+}
+
+static void
+ctables_section_recurse_add_empty_categories (
+ struct ctables_section *s,
+ const struct ctables_category *cats[PIVOT_N_AXES][10], struct ccase *c,
+ enum pivot_axis_type a, size_t a_idx)
+{
+ if (a >= PIVOT_N_AXES)
+ {
+
+ }
+ else if (!s->nests[a] || idx >= s->nests[a]->n)
+ {
+
+
+ }
+ else
+ {
+
+ for (size_t i = 0; i < s->nests[a]->n; i++)
+
+ }
+}
+
+static void
+ctables_section_add_empty_categories (struct ctables_section *s)
+{
+ bool show_empty = false;
+ for (size_t a = 0; a < PIVOT_N_AXES; a++)
+ if (s->nests[a])
+ for (size_t k = 0; k < s->nests[a]->n; k++)
+ if (k != s->nests[a]->scale_idx)
+ {
+ const struct variable *var = s->nests[a]->vars[k];
+ const struct ctables_categories *cats = s->table->categories[
+ var_get_dict_index (var)];
+ if (cats->show_empty)
+ {
+ show_empty = true;
+ ctables_add_category_occurrences (var, &s->occurrences[a][k], cats);
+ }
+ }
+ if (!show_empty)
+ return;
+
+ const struct ctables_category *cats[PIVOT_N_AXES][10]; /* XXX */
+ struct ccase *c = case_create (dict_get_proto (s->table->ctables->dict));
+ ctables_section_recurse_add_empty_categories (s, c, cats, a, 0);
+}
+