1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2009, 2011, 2013, 2014 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include "libpspp/assertion.h"
22 #include "libpspp/tower.h"
23 #include "output/table-provider.h"
25 #include "gl/minmax.h"
26 #include "gl/xalloc.h"
28 /* This file uses TABLE_HORZ and TABLE_VERT enough to warrant abbreviating. */
35 struct table *subtable;
38 static const struct table_class table_stomp_class;
40 static struct table_stomp *
41 table_stomp_cast (const struct table *table)
43 assert (table->klass == &table_stomp_class);
44 return UP_CAST (table, struct table_stomp, table);
47 /* Returns a new table based on SUBTABLE with exactly one row. Each cell in
48 that row consists of the contents of all of the rows stacked together into a
49 single cell. So, for example, if SUBTABLE has one column and three rows,
50 then the returned table has one column and one row, and the single cell in
51 the returned table has all of the content of the three cells in
54 SUBTABLE should have the same column structure in every row, i.e. don't
55 stomp a table that has rows with differently joined cells. */
57 table_stomp (struct table *subtable)
59 struct table_stomp *ts;
61 if (subtable->n[V] == 1)
64 ts = xmalloc (sizeof *ts);
65 table_init (&ts->table, &table_stomp_class);
66 ts->table.n[H] = subtable->n[H];
68 ts->subtable = subtable;
73 table_stomp_destroy (struct table *t)
75 struct table_stomp *ts = table_stomp_cast (t);
77 table_unref (ts->subtable);
81 struct table_stomp_subcells
83 struct cell_contents *contents;
86 struct table_cell subcells[];
90 table_stomp_free_cell (void *sc_)
92 struct table_stomp_subcells *sc = sc_;
95 for (i = 0; i < sc->n_subcells; i++)
96 table_cell_free (&sc->subcells[i]);
102 table_stomp_get_cell (const struct table *t, int x, int y UNUSED,
103 struct table_cell *cell)
105 struct table_stomp *ts = table_stomp_cast (t);
106 size_t n_rows = ts->subtable->n[V];
107 struct table_stomp_subcells *sc;
112 sc = xzalloc (sizeof *sc + n_rows * sizeof *sc->subcells);
115 cell->n_contents = 0;
116 for (row = 0; row < n_rows; )
118 struct table_cell *subcell = &sc->subcells[sc->n_subcells++];
120 table_get_cell (ts->subtable, x, row, subcell);
121 cell->n_contents += subcell->n_contents;
122 row = subcell->d[V][1];
125 cell->d[H][0] = sc->subcells[0].d[H][0];
127 cell->d[H][1] = sc->subcells[0].d[H][1];
130 sc->contents = xmalloc (cell->n_contents * sizeof *cell->contents);
131 cell->contents = sc->contents;
134 for (i = 0; i < sc->n_subcells; i++)
136 struct table_cell *subcell = &sc->subcells[i];
138 memcpy (&sc->contents[ofs], subcell->contents,
139 subcell->n_contents * sizeof *subcell->contents);
140 ofs += subcell->n_contents;
143 cell->destructor = table_stomp_free_cell;
144 cell->destructor_aux = sc;
148 table_stomp_get_rule (const struct table *t,
149 enum table_axis axis, int x, int y,
150 struct cell_color *color)
152 struct table_stomp *ts = table_stomp_cast (t);
154 return table_get_rule (ts->subtable, axis, x,
155 axis == H || y == 0 ? y : ts->subtable->n[V],
159 static const struct table_class table_stomp_class =
162 table_stomp_get_cell,
163 table_stomp_get_rule,