/* PSPP - computes sample statistics.
- Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
- Written by Ben Pfaff <blp@gnu.org>.
+ Copyright (C) 1997-9, 2000, 2006 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
02110-1301, USA. */
#include <config.h>
+
#include "table.h"
+
#include <ctype.h>
#include <stdarg.h>
#include <limits.h>
#include <stdlib.h>
-#include <libpspp/message.h>
+
+#include "output.h"
+#include "manager.h"
+
+#include <data/data-out.h>
+#include <data/format.h>
+#include <data/value.h>
#include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
#include <libpspp/compiler.h>
-#include <data/format.h>
#include <libpspp/magic.h>
#include <libpspp/misc.h>
-#include "minmax.h"
-#include "output.h"
#include <libpspp/pool.h>
-#include "manager.h"
-#include <data/variable.h>
+
+#include "minmax.h"
#include "gettext.h"
#define _(msgid) gettext (msgid)
-
-#include <libpspp/debug-print.h>
\f
-struct som_table_class tab_table_class;
+const struct som_table_class tab_table_class;
static char *command_name;
/* Returns the font to use for a cell with the given OPTIONS. */
t = pool_create_container (struct tab_table, container);
t->col_style = TAB_COL_NONE;
t->col_group = 0;
- ls_null (&t->title);
+ t->title = NULL;
t->flags = SOMF_NONE;
t->nr = nr;
t->nc = t->cf = nc;
t->rh = pool_nmalloc (t->container, nc, nr + 1);
memset (t->rh, 0, nc * (nr + 1));
- t->hrh = pool_nmalloc (t->container, nr + 1, sizeof *t->hrh);
- memset (t->hrh, 0, sizeof *t->hrh * (nr + 1));
-
t->rv = pool_nmalloc (t->container, nr, nc + 1);
memset (t->rv, UCHAR_MAX, nr * (nc + 1));
- t->wrv = pool_nmalloc (t->container, nc + 1, sizeof *t->wrv);
- memset (t->wrv, 0, sizeof *t->wrv * (nc + 1));
-
t->dim = NULL;
t->w = t->h = NULL;
t->col_ofs = t->row_ofs = 0;
tab_destroy (struct tab_table *t)
{
assert (t != NULL);
+ free (t->title);
pool_destroy (t->container);
}
if (nc > t->cf)
{
- int mr1 = min (nr, t->nr);
- int mc1 = min (nc, t->nc);
+ int mr1 = MIN (nr, t->nr);
+ int mc1 = MIN (nc, t->nc);
- struct fixed_string *new_cc;
+ struct substring *new_cc;
unsigned char *new_ct;
int r;
y += t->row_ofs;
assert (y >= 0);
- assert (y < t->nr);
+ assert (y <= t->nr);
assert (x2 >= x1 );
assert (x1 >= 0 );
assert (x2 < t->nc);
x2, t->col_ofs, x2 + t->col_ofs,
y2, t->row_ofs, y2 + t->row_ofs,
t->nc, t->nr);
- abort ();
+ NOT_REACHED ();
}
#endif
}
}
-/* Formats text TEXT and arguments ARGS as indicated in OPT and sets
- the resultant string into S in TABLE's pool. */
-static void
-text_format (struct tab_table *table, int opt, const char *text, va_list args,
- struct fixed_string *s)
+/* Formats text TEXT and arguments ARGS as indicated in OPT in
+ TABLE's pool and returns the resultant string. */
+static struct substring
+text_format (struct tab_table *table, int opt, const char *text, va_list args)
{
- char *tmp = NULL;
-
- assert (table != NULL && text != NULL && s != NULL);
-
- if (opt & TAT_PRINTF)
- text = tmp = xvasprintf (text, args);
+ assert (table != NULL && text != NULL);
- ls_create_buffer (s, text, strlen (text));
- pool_register (table->container, free, s->string);
-
- free (tmp);
+ return ss_cstr (opt & TAT_PRINTF
+ ? pool_vasprintf (table->container, text, args)
+ : pool_strdup (table->container, text));
}
/* Set the title of table T to TITLE, which is formatted as if
assert (t != NULL && title != NULL);
va_start (args, title);
- text_format (t, TAT_PRINTF, title, args, &t->title);
+ t->title = xvasprintf (title, args);
va_end (args);
}
continue;
text.string = t->cc[c + r * t->cf];
- assert (!ls_null_p (&text.string));
text.justification = OUTP_LEFT;
text.font = options_to_font (opt);
text.h = text.v = INT_MAX;
if (width == 0)
{
- width = d->prop_em_width * 8;
-#if DEBUGGING
- printf ("warning: table column %d contains no data.\n", c);
-#endif
+ /* FIXME: This is an ugly kluge to compensate for the fact
+ that we don't let joined cells contribute to column
+ widths. */
+ width = d->prop_em_width * 8;
}
{
continue;
text.string = t->cc[c + r * t->cf];
- assert (!ls_null_p (&text.string));
text.justification = OUTP_LEFT;
text.font = options_to_font (opt);
text.h = t->w[c];
#endif
contents = pool_alloc (table->container, f->w);
- ls_init (&table->cc[c + r * table->cf], contents, f->w);
+ table->cc[c + r * table->cf] = ss_buffer (contents, f->w);
table->ct[c + r * table->cf] = opt;
- data_out (contents, f, v);
+ data_out (v, f, contents);
}
/* Sets cell (C,R) in TABLE, with options OPT, to have value VAL
assert (r >= 0);
assert (r < table->nr);
- f = make_output_format (FMT_F, w, d);
+ f = fmt_for_output (FMT_F, w, d);
#if DEBUGGING
if (c + table->col_ofs < 0 || r + table->row_ofs < 0
#endif
double_value.f = val;
- data_out (buf, &f, &double_value);
+ data_out (&double_value, &f, buf);
cp = buf;
while (isspace ((unsigned char) *cp) && cp < &buf[w])
f.w = w - (cp - buf);
contents = pool_alloc (table->container, f.w);
- ls_init (&table->cc[c + r * table->cf], contents, f.w);
+ table->cc[c + r * table->cf] = ss_buffer (contents, f.w);
table->ct[c + r * table->cf] = opt;
memcpy (contents, cp, f.w);
}
#endif
va_start (args, text);
- text_format (table, opt, text, args, &table->cc[c + r * table->cf]);
+ table->cc[c + r * table->cf] = text_format (table, opt, text, args);
table->ct[c + r * table->cf] = opt;
va_end (args);
}
va_list args;
va_start (args, text);
- text_format (table, opt, text, args, &j->contents);
+ j->contents = text_format (table, opt, text, args);
va_end (args);
}
opt |= TAB_JOIN;
{
- struct fixed_string *cc = &table->cc[x1 + y1 * table->cf];
+ struct substring *cc = &table->cc[x1 + y1 * table->cf];
unsigned char *ct = &table->ct[x1 + y1 * table->cf];
const int ofs = table->cf - (x2 - x1);
for (x = x1; x < x2; x++)
{
- ls_init (cc++, (char *) j, 0);
+ *cc++ = ss_buffer ((char *) j, 0);
*ct++ = opt;
}
/* Sets cell (C,R) in TABLE, with options OPT, to contents STRING. */
void
tab_raw (struct tab_table *table, int c, int r, unsigned opt,
- struct fixed_string *string)
+ struct substring *string)
{
assert (table != NULL && string != NULL);
assert (t != NULL);
#if DEBUGGING
- if (row < -1 || row >= t->nr)
+ if (row < -1 || row > t->nr)
{
printf ("tab_offset(): row=%d in %d-row table\n", row, t->nr);
- abort ();
+ NOT_REACHED ();
}
- if (col < -1 || col >= t->nc)
+ if (col < -1 || col > t->nc)
{
printf ("tab_offset(): col=%d in %d-column table\n", col, t->nc);
- abort ();
+ NOT_REACHED ();
}
#endif
\f
static struct tab_table *t;
static struct outp_driver *d;
-int tab_hit;
+static int tab_hit;
/* Set the current table to TABLE. */
static void
assert (t->w == NULL && t->h == NULL);
t->w = pool_nalloc (t->container, t->nc, sizeof *t->w);
t->h = pool_nalloc (t->container, t->nr, sizeof *t->h);
+ t->hrh = pool_nmalloc (t->container, t->nr + 1, sizeof *t->hrh);
+ t->wrv = pool_nmalloc (t->container, t->nc + 1, sizeof *t->wrv);
}
/* Returns the line style to use for spacing purposes for a rule
case TAL_2:
return OUTP_L_DOUBLE;
default:
- abort ();
+ NOT_REACHED ();
}
}
if (command_name != NULL)
cp = spprintf (cp, " %s", command_name);
cp = stpcpy (cp, ". ");
- if (!ls_empty_p (&t->title))
+ if (t->title != NULL)
{
- memcpy (cp, ls_c_str (&t->title), ls_length (&t->title));
- cp += ls_length (&t->title);
+ size_t length = strlen (t->title);
+ memcpy (cp, t->title, length);
+ cp += length;
}
*cp = 0;
text.font = OUTP_PROPORTIONAL;
text.justification = OUTP_LEFT;
- ls_init (&text.string, buf, cp - buf);
+ text.string = ss_buffer (buf, cp - buf);
text.h = d->width;
text.v = d->font_height;
text.x = 0;
y = render_rows (y, c0, c1, (t->nr - t->b) * 2, t->nr * 2 + 1);
}
-struct som_table_class tab_table_class =
+const struct som_table_class tab_table_class =
{
tabi_table,
tabi_driver,
case TAB_CENTER:
return OUTP_CENTER;
default:
- abort ();
+ NOT_REACHED ();
}
}
case TAL_2:
return OUTP_L_DOUBLE;
default:
- abort ();
+ NOT_REACHED ();
}
}
{
const int index = c + (r * t->cf);
unsigned char type = t->ct[index];
- struct fixed_string *content = &t->cc[index];
+ struct substring *content = &t->cc[index];
if (!(type & TAB_JOIN))
{
else
{
struct tab_joined_cell *j
- = (struct tab_joined_cell *) ls_c_str (content);
+ = (struct tab_joined_cell *) ss_data (*content);
if (j->hit != tab_hit)
{