X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Ftable-paste.c;fp=src%2Foutput%2Ftable-paste.c;h=0000000000000000000000000000000000000000;hb=9a01f783f7e29b39210373ccfaeac44f364131b4;hp=05c8987ce6f891a0a888d582339bb2ff49aa9137;hpb=b8e1b562ffde66d72294214967741ab88156d7e7;p=pspp
diff --git a/src/output/table-paste.c b/src/output/table-paste.c
deleted file mode 100644
index 05c8987ce6..0000000000
--- a/src/output/table-paste.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/* PSPP - a program for statistical analysis.
- Copyright (C) 2009, 2011, 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 . */
-
-#include
-
-#include "libpspp/assertion.h"
-#include "libpspp/tower.h"
-#include "output/table-provider.h"
-
-#include "gl/minmax.h"
-#include "gl/xalloc.h"
-
-struct paste_subtable
- {
- struct tower_node node;
- struct table *table;
- };
-
-static struct paste_subtable *
-paste_subtable_cast (struct tower_node *node)
-{
- return tower_data (node, struct paste_subtable, node);
-}
-
-struct table_paste
- {
- struct table table;
- struct tower subtables;
- enum table_axis orientation;
- };
-
-static const struct table_class table_paste_class;
-
-static struct table_paste *
-table_paste_cast (const struct table *table)
-{
- assert (table->klass == &table_paste_class);
- return UP_CAST (table, struct table_paste, table);
-}
-
-static bool
-is_table_paste (const struct table *table, int orientation)
-{
- return (table->klass == &table_paste_class
- && table_paste_cast (table)->orientation == orientation);
-}
-
-static struct paste_subtable *
-paste_subtable_lookup (struct table_paste *tp, unsigned long int offset,
- unsigned long int *start)
-{
- return paste_subtable_cast (tower_lookup (&tp->subtables, offset, start));
-}
-
-/* This must be called *before* adding TABLE to TP, otherwise the test for
- whether TP is empty will not have the correct effect. */
-static void
-table_paste_increase_size (struct table_paste *tp,
- const struct table *table)
-{
- int o = tp->orientation;
- int h0, h1;
-
- tp->table.n[o] += table->n[o];
- tp->table.n[!o] = MAX (tp->table.n[!o], table->n[!o]);
-
- h0 = table->h[!o][0];
- h1 = table->h[!o][1];
- if (tower_is_empty (&tp->subtables))
- {
- tp->table.h[!o][0] = h0;
- tp->table.h[!o][1] = h1;
- }
- else
- {
- tp->table.h[!o][0] = MIN (tp->table.h[!o][0], h0);
-
- /* XXX this is not quite right */
- tp->table.h[!o][1] = MIN (tp->table.h[!o][1], h1);
- }
-}
-
-static void
-reassess_headers (struct table_paste *tp)
-{
- int o = tp->orientation;
- if (tower_is_empty (&tp->subtables))
- tp->table.h[o][0] = tp->table.h[o][1] = 0;
- else
- {
- struct paste_subtable *h0, *h1;
-
- h0 = paste_subtable_cast (tower_first (&tp->subtables));
- tp->table.h[o][0] = h0->table->h[o][0];
-
- h1 = paste_subtable_cast (tower_last (&tp->subtables));
- tp->table.h[o][1] = h1->table->h[o][1];
- }
-}
-
-static void
-table_paste_insert_subtable (struct table_paste *tp,
- struct table *table,
- struct tower_node *under)
-{
- struct paste_subtable *subtable;
-
- subtable = xmalloc (sizeof *subtable);
- table_paste_increase_size (tp, table);
- tower_insert (&tp->subtables, table->n[tp->orientation],
- &subtable->node, under);
- subtable->table = table;
- reassess_headers (tp);
-}
-
-/* Takes ownership of A and B and returns a table that consists of tables A and
- B "pasted together", that is, a table whose size is the sum of the sizes of
- A and B along the axis specified by ORIENTATION. A and B should have the
- same size along the axis opposite ORIENTATION; the handling of tables that
- have different sizes along that axis may vary.
-
- The rules at the seam between A and B are combined. The exact way in which
- they are combined is unspecified, but the method of table_rule_combine() is
- typical.
-
- If A or B is null, returns the other argument. */
-struct table *
-table_paste (struct table *a, struct table *b, enum table_axis orientation)
-{
- struct table_paste *tp;
-
- /* Handle nulls. */
- if (a == NULL)
- return b;
- if (b == NULL)
- return a;
-
- assert (a->n[!orientation] == b->n[!orientation]);
-
- /* Handle tables that know how to paste themselves. */
- if (!table_is_shared (a) && !table_is_shared (b) && a != b)
- {
- if (a->klass->paste != NULL)
- {
- struct table *new = a->klass->paste (a, b, orientation);
- if (new != NULL)
- return new;
- }
- if (b->klass->paste != NULL && a->klass != b->klass)
- {
- struct table *new = b->klass->paste (a, b, orientation);
- if (new != NULL)
- return new;
- }
- }
-
- /* Create new table_paste and insert A and B into it. */
- tp = xmalloc (sizeof *tp);
- table_init (&tp->table, &table_paste_class);
- tower_init (&tp->subtables);
- tp->orientation = orientation;
- table_paste_insert_subtable (tp, a, NULL);
- table_paste_insert_subtable (tp, b, NULL);
- return &tp->table;
-}
-
-/* Shorthand for table_paste (left, right, TABLE_HORZ). */
-struct table *
-table_hpaste (struct table *left, struct table *right)
-{
- return table_paste (left, right, TABLE_HORZ);
-}
-
-/* Shorthand for table_paste (top, bottom, TABLE_VERT). */
-struct table *
-table_vpaste (struct table *top, struct table *bottom)
-{
- return table_paste (top, bottom, TABLE_VERT);
-}
-
-static void
-table_paste_destroy (struct table *t)
-{
- struct table_paste *tp = table_paste_cast (t);
- struct tower_node *node, *next;
-
- for (node = tower_first (&tp->subtables); node != NULL; node = next)
- {
- struct paste_subtable *ps = paste_subtable_cast (node);
- table_unref (ps->table);
- next = tower_delete (&tp->subtables, node);
- free (node);
- }
- free (tp);
-}
-
-static void
-table_paste_get_cell (const struct table *t, int x, int y,
- struct table_cell *cell)
-{
- struct table_paste *tp = table_paste_cast (t);
- struct paste_subtable *ps;
- unsigned long int start;
- int d[TABLE_N_AXES];
-
- d[TABLE_HORZ] = x;
- d[TABLE_VERT] = y;
- ps = paste_subtable_lookup (tp, d[tp->orientation], &start);
- d[tp->orientation] -= start;
- table_get_cell (ps->table, d[TABLE_HORZ], d[TABLE_VERT], cell);
- cell->d[tp->orientation][0] += start;
- cell->d[tp->orientation][1] += start;
-}
-
-static int
-table_paste_get_rule (const struct table *t,
- enum table_axis axis, int x, int y,
- struct cell_color *color)
-{
- struct table_paste *tp = table_paste_cast (t);
- int h = tp->orientation == TABLE_HORZ ? x : y;
- int k = tp->orientation == TABLE_HORZ ? y : x;
- struct paste_subtable *ps;
- unsigned long int start;
-
- if (tp->orientation == axis)
- {
- int r;
-
- ps = paste_subtable_lookup (tp, h == 0 ? 0 : h - 1, &start);
- if (tp->orientation == TABLE_HORZ) /* XXX */
- r = table_get_rule (ps->table, axis, h - start, k, color);
- else
- r = table_get_rule (ps->table, axis, k, h - start, color);
- if (h == start + tower_node_get_size (&ps->node))
- {
- struct tower_node *ps2_ = tower_next (&tp->subtables, &ps->node);
- if (ps2_ != NULL)
- {
- struct paste_subtable *ps2 = paste_subtable_cast (ps2_);
- int r2;
-
- if (tp->orientation == TABLE_HORZ) /* XXX */
- r2 = table_get_rule (ps2->table, axis, 0, k, color);
- else
- r2 = table_get_rule (ps2->table, axis, k, 0, color);
- return table_rule_combine (r, r2);
- }
- }
- return r;
- }
- else
- {
- ps = paste_subtable_lookup (tp, h, &start);
- if (tp->orientation == TABLE_HORZ) /* XXX */
- return table_get_rule (ps->table, axis, h - start, k, color);
- else
- return table_get_rule (ps->table, axis, k, h - start, color);
- }
-}
-
-static struct table *
-table_paste_paste (struct table *a, struct table *b,
- enum table_axis orientation)
-{
- struct table_paste *ta, *tb;
-
- ta = is_table_paste (a, orientation) ? table_paste_cast (a) : NULL;
- tb = is_table_paste (b, orientation) ? table_paste_cast (b) : NULL;
-
- if (ta != NULL)
- {
- if (tb != NULL)
- {
- /* Append all of B's subtables onto A, then destroy B. */
- table_paste_increase_size (ta, b);
- tower_splice (&ta->subtables, NULL,
- &tb->subtables, tower_first (&tb->subtables), NULL);
- table_unref (b);
- }
- else
- {
- /* Append B to A's stack of subtables. */
- table_paste_insert_subtable (ta, b, NULL);
- }
- reassess_headers (ta);
- return a;
- }
- else if (tb != NULL)
- {
- /* Insert A at the beginning of B's stack of subtables. */
- table_paste_insert_subtable (tb, a, tower_first (&tb->subtables));
- reassess_headers (tb);
- return b;
- }
- else
- return NULL;
-}
-
-static const struct table_class table_paste_class =
- {
- table_paste_destroy,
- table_paste_get_cell,
- table_paste_get_rule,
- table_paste_paste,
- NULL, /* select */
- };