+++ /dev/null
-/* PSPP - a program for statistical analysis.
- Copyright (C) 2009, 2011, 2013, 2014 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-
-#include <string.h>
-
-#include "libpspp/assertion.h"
-#include "libpspp/tower.h"
-#include "output/table-provider.h"
-
-#include "gl/minmax.h"
-#include "gl/xalloc.h"
-
-/* This file uses TABLE_HORZ and TABLE_VERT enough to warrant abbreviating. */
-#define H TABLE_HORZ
-#define V TABLE_VERT
-
-struct table_stomp
- {
- struct table table;
- struct table *subtable;
- };
-
-static const struct table_class table_stomp_class;
-
-static struct table_stomp *
-table_stomp_cast (const struct table *table)
-{
- assert (table->klass == &table_stomp_class);
- return UP_CAST (table, struct table_stomp, table);
-}
-
-/* Returns a new table based on SUBTABLE with exactly one row. Each cell in
- that row consists of the contents of all of the rows stacked together into a
- single cell. So, for example, if SUBTABLE has one column and three rows,
- then the returned table has one column and one row, and the single cell in
- the returned table has all of the content of the three cells in
- SUBTABLE.
-
- SUBTABLE should have the same column structure in every row, i.e. don't
- stomp a table that has rows with differently joined cells. */
-struct table *
-table_stomp (struct table *subtable)
-{
- struct table_stomp *ts;
-
- if (subtable->n[V] == 1)
- return subtable;
-
- ts = xmalloc (sizeof *ts);
- table_init (&ts->table, &table_stomp_class);
- ts->table.n[H] = subtable->n[H];
- ts->table.n[V] = 1;
- ts->subtable = subtable;
- return &ts->table;
-}
-
-static void
-table_stomp_destroy (struct table *t)
-{
- struct table_stomp *ts = table_stomp_cast (t);
-
- table_unref (ts->subtable);
- free (ts);
-}
-
-struct table_stomp_subcells
- {
- struct cell_contents *contents;
-
- size_t n_subcells;
- struct table_cell subcells[];
- };
-
-static void
-table_stomp_free_cell (void *sc_)
-{
- struct table_stomp_subcells *sc = sc_;
- size_t i;
-
- for (i = 0; i < sc->n_subcells; i++)
- table_cell_free (&sc->subcells[i]);
- free (sc->contents);
- free (sc);
-}
-
-static void
-table_stomp_get_cell (const struct table *t, int x, int y UNUSED,
- struct table_cell *cell)
-{
- struct table_stomp *ts = table_stomp_cast (t);
- size_t n_rows = ts->subtable->n[V];
- struct table_stomp_subcells *sc;
- size_t row;
- size_t ofs;
- size_t i;
-
- sc = xzalloc (sizeof *sc + n_rows * sizeof *sc->subcells);
- sc->n_subcells = 0;
-
- cell->n_contents = 0;
- for (row = 0; row < n_rows; )
- {
- struct table_cell *subcell = &sc->subcells[sc->n_subcells++];
-
- table_get_cell (ts->subtable, x, row, subcell);
- cell->n_contents += subcell->n_contents;
- row = subcell->d[V][1];
- }
-
- cell->d[H][0] = sc->subcells[0].d[H][0];
- cell->d[V][0] = 0;
- cell->d[H][1] = sc->subcells[0].d[H][1];
- cell->d[V][1] = 1;
-
- sc->contents = xmalloc (cell->n_contents * sizeof *cell->contents);
- cell->contents = sc->contents;
-
- ofs = 0;
- for (i = 0; i < sc->n_subcells; i++)
- {
- struct table_cell *subcell = &sc->subcells[i];
-
- memcpy (&sc->contents[ofs], subcell->contents,
- subcell->n_contents * sizeof *subcell->contents);
- ofs += subcell->n_contents;
- }
-
- cell->destructor = table_stomp_free_cell;
- cell->destructor_aux = sc;
-}
-
-static int
-table_stomp_get_rule (const struct table *t,
- enum table_axis axis, int x, int y,
- struct cell_color *color)
-{
- struct table_stomp *ts = table_stomp_cast (t);
-
- return table_get_rule (ts->subtable, axis, x,
- axis == H || y == 0 ? y : ts->subtable->n[V],
- color);
-}
-
-static const struct table_class table_stomp_class =
- {
- table_stomp_destroy,
- table_stomp_get_cell,
- table_stomp_get_rule,
- NULL, /* paste */
- NULL, /* select */
- };