You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA. */
-/* AIX requires this to be the first thing in the file. */
#include <config.h>
-#if __GNUC__
-#define alloca __builtin_alloca
-#else
-#if HAVE_ALLOCA_H
-#include <alloca.h>
-#else
-#ifdef _AIX
-#pragma alloca
-#else
-#ifndef alloca /* predefined by HP cc +Olibcalls */
-char *alloca ();
-#endif
-#endif
-#endif
-#endif
-
#include "tab.h"
#include <ctype.h>
-#include <assert.h>
#include <stdarg.h>
#include <limits.h>
#include <stdlib.h>
+#include "error.h"
#include "alloc.h"
#include "command.h"
#include "format.h"
\f
struct som_table_class tab_table_class;
-#if DEBUGGING
-#define DEFFIRST(NAME, LABEL) LABEL,
-#define DEFTAB(NAME, LABEL) LABEL,
-/*
-static const char *tab_names[] =
- {
-#include "tab.def"
- };
-*/
-#undef DEFFIRST
-#undef DEFTAB
-#endif
-
/* Creates a table with NC columns and NR rows. If REALLOCABLE is
nonzero then the table's size can be increased later; otherwise,
its size can only be reduced. */
{
assert (t != NULL);
pool_destroy (t->container);
+ t=0;
}
/* Sets the width and height of a table, in columns and rows,
int mr1 = min (nr, t->nr);
int mc1 = min (nc, t->nc);
- struct len_string *new_cc;
+ struct fixed_string *new_cc;
unsigned char *new_ct;
int r;
tab_headers (struct tab_table *table, int l, int r, int t, int b)
{
assert (table != NULL);
+ assert (l < table->nc);
+ assert (r < table->nc);
+ assert (t < table->nr);
+ assert (b < table->nr);
+
+
table->l = l;
table->r = r;
table->t = t;
int y;
assert (t != NULL);
+
#if GLOBAL_DEBUGGING
if (x + t->col_ofs < 0 || x + t->col_ofs > t->nc
|| y1 + t->row_ofs < 0 || y1 + t->row_ofs >= t->nr
y1 += t->row_ofs;
y2 += t->row_ofs;
+ assert (x > 0);
+ assert (x < t->nc);
+ assert (y1 >= 0);
+ assert (y2 >= y1);
+ assert (y2 <= t->nr);
+
if (style != -1)
{
if ((style & TAL_SPACING) == 0)
int x;
assert (t != NULL);
-#if GLOBAL_DEBUGGING
- if (x1 + t->col_ofs < 0 || x1 + t->col_ofs >= t->nc
- || x2 + t->col_ofs < 0 || x2 + t->col_ofs >= t->nc
- || y + t->row_ofs < 0 || y + t->row_ofs > t->nr)
- {
- printf (_("bad hline: x=(%d+%d=%d,%d+%d=%d) y=%d+%d=%d "
- "in table size (%d,%d)\n"),
- x1, t->col_ofs, x1 + t->col_ofs,
- x2, t->col_ofs, x2 + t->col_ofs,
- y, t->row_ofs, y + t->row_ofs,
- t->nc, t->nr);
- return;
- }
-#endif
x1 += t->col_ofs;
x2 += t->col_ofs;
y += t->row_ofs;
+ assert (y >= 0);
+ assert (y < t->nr);
+ assert (x2 >= x1 );
+ assert (x1 >= 0 );
+ assert (x2 < t->nc);
+
if (style != -1)
{
if ((style & TAL_SPACING) == 0)
int x1, int y1, int x2, int y2)
{
assert (t != NULL);
+
#if GLOBAL_DEBUGGING
if (x1 + t->col_ofs < 0 || x1 + t->col_ofs >= t->nc
|| x2 + t->col_ofs < 0 || x2 + t->col_ofs >= t->nc
y1 += t->row_ofs;
y2 += t->row_ofs;
+ assert (x2 >= x1);
+ assert (y2 >= y1);
+ assert (x1 >= 0);
+ assert (y1 >= 0);
+ assert (x2 < t->nc);
+ assert (y2 < t->nr);
+
if (f_h != -1)
{
int x;
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 len_string *s)
+ struct fixed_string *s)
{
int len;
else
len = strlen (text);
- ls_create_buffer (table->container, s, text, len);
+ ls_create_buffer (s, text, len);
+ pool_register (table->container, free, s->string);
if (opt & TAT_PRINTF)
local_free (text);
const union value *v, const struct fmt_spec *f)
{
char *contents;
- union value temp_val;
assert (table != NULL && v != NULL && f != NULL);
#if GLOBAL_DEBUGGING
ls_init (&table->cc[c + r * table->cf], contents, f->w);
table->ct[c + r * table->cf] = opt;
- if (formats[f->type].cat & FCAT_STRING)
- {
- temp_val.c = (char *) v->s;
- v = &temp_val;
- }
data_out (contents, f, v);
}
char buf[40], *cp;
struct fmt_spec f;
+ union value double_value;
assert (table != NULL && w <= 40);
+ assert (c >= 0);
+ assert (c < table->nc);
+ assert (r >= 0);
+ assert (r < table->nr);
+
f.type = FMT_F;
f.w = w;
f.d = d;
}
#endif
- data_out (buf, &f, (union value *) &val);
+ double_value.f = val;
+ data_out (buf, &f, &double_value);
+
cp = buf;
while (isspace ((unsigned char) *cp) && cp < &buf[w])
cp++;
va_list args;
assert (table != NULL && text != NULL);
+
+ assert (c >= 0 );
+ assert (r >= 0 );
+ assert (c < table->nc);
+ assert (r < table->nr);
+
+
#if GLOBAL_DEBUGGING
if (c + table->col_ofs < 0 || r + table->row_ofs < 0
|| c + table->col_ofs >= table->nc
struct tab_joined_cell *j;
assert (table != NULL && text != NULL);
+
+ assert (x1 + table->col_ofs >= 0);
+ assert (y1 + table->row_ofs >= 0);
+ assert (y2 >= y1);
+ assert (x2 >= x1);
+ assert (y2 + table->row_ofs < table->nr);
+ assert (x2 + table->col_ofs < table->nc);
+
#if GLOBAL_DEBUGGING
if (x1 + table->col_ofs < 0 || x1 + table->col_ofs >= table->nc
|| y1 + table->row_ofs < 0 || y1 + table->row_ofs >= table->nr
opt |= TAB_JOIN;
{
- struct len_string *cc = &table->cc[x1 + y1 * table->cf];
+ struct fixed_string *cc = &table->cc[x1 + y1 * table->cf];
unsigned char *ct = &table->ct[x1 + y1 * table->cf];
const int ofs = table->cf - (x2 - x1);
/* 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 len_string *string)
+ struct fixed_string *string)
{
assert (table != NULL && string != NULL);
{
if (!d->page_open)
d->class->open_page (d);
-
- d->class->text_set_font_by_name (d, "FIXED");
+
+ if (d->class->text_set_font_by_name != NULL)
+ d->class->text_set_font_by_name (d, "FIXED");
+ else
+ {
+ /* FIXME */
+ }
}
}
struct outp_driver *d;
for (d = outp_drivers (NULL); d; d = outp_drivers (d))
- d->class->text_set_font_by_name (d, "PROP");
+ if (d->class->text_set_font_by_name != NULL)
+ d->class->text_set_font_by_name (d, "PROP");
+ else
+ {
+ /* FIXME */
+ }
}
if (options & TAT_PRINTF)
void
tab_submit (struct tab_table *t)
{
- struct som_table s;
+ struct som_entity s;
assert (t != NULL);
s.class = &tab_table_class;
s.ext = t;
+ s.type = SOM_TABLE;
som_submit (&s);
tab_destroy (t);
}
/* Set the current table to TABLE. */
static void
-tabi_table (struct som_table *table)
+tabi_table (struct som_entity *table)
{
assert (table != NULL);
+ assert (table->type == SOM_TABLE);
+
t = table->ext;
tab_offset (t, 0, 0);
cp = stpcpy (cp, ". ");
if (!ls_empty_p (&t->title))
{
- memcpy (cp, ls_value (&t->title), ls_length (&t->title));
+ memcpy (cp, ls_c_str (&t->title), ls_length (&t->title));
cp += ls_length (&t->title);
}
*cp = 0;
static int render_strip (int x, int y, int r, int c1, int c2, int r1, int r2);
-/* Execute BODY for each value of X from A to B exclusive. */
-#define UNROLL_LOOP(X, A, B, BODY) \
- do \
- { \
- for (X = A; X < B; X++) \
- { \
- BODY \
- } \
- } \
- while (0)
-
-/* Execute PREP, then BODY for each specified value of X: A1...A2, B1...B2,
- C1...C2, in each case not including the second value. */
-#define UNROLL_3_LOOPS(X, A1, A2, B1, B2, C1, C2, BODY) \
- do \
- { \
- UNROLL_LOOP (X, A1, A2, BODY); \
- UNROLL_LOOP (X, B1, B2, BODY); \
- UNROLL_LOOP (X, C1, C2, BODY); \
- } \
- while (0)
-
/* Draws the table region in rectangle (X1,Y1)-(X2,Y2), where column
X2 and row Y2 are not included in the rectangle, at the current
position on the current output device. Draws headers as well. */
static void
tabi_render (int x1, int y1, int x2, int y2)
{
- int y, r;
+ int i, y;
+ int ranges[3][2];
tab_hit++;
+
y = d->cp_y;
if (!(t->flags & SOMF_NO_TITLE))
y += d->font_height;
- UNROLL_3_LOOPS (r, 0, t->t * 2 + 1, y1 * 2 + 1, y2 * 2,
- (t->nr - t->b) * 2, t->nr * 2 + 1,
-
- int x = d->cp_x;
- x += render_strip (x, y, r, 0, t->l * 2 + 1, y1, y2);
- x += render_strip (x, y, r, x1 * 2 + 1, x2 * 2, y1, y2);
- x += render_strip (x, y, r, (t->nc - t->r) * 2,
- t->nc * 2 + 1, y1, y2);
- y += (r & 1) ? t->h[r / 2] : t->hrh[r / 2];
- );
+
+ /* Top headers. */
+ ranges[0][0] = 0;
+ ranges[0][1] = t->t * 2 + 1;
+
+ /* Requested rows. */
+ ranges[1][0] = y1 * 2 + 1;
+ ranges[1][1] = y2 * 2;
+
+ /* Bottom headers. */
+ ranges[2][0] = (t->nr - t->b) * 2;
+ ranges[2][1] = t->nr * 2 + 1;
+
+ for (i = 0; i < 3; i++)
+ {
+ int r;
+
+ for (r = ranges[i][0]; r < ranges[i][1]; r++)
+ {
+ int x = d->cp_x;
+ x += render_strip (x, y, r, 0, t->l * 2 + 1, y1, y2);
+ x += render_strip (x, y, r, x1 * 2 + 1, x2 * 2, y1, y2);
+ x += render_strip (x, y, r, (t->nc - t->r) * 2,
+ t->nc * 2 + 1, y1, y2);
+ y += (r & 1) ? t->h[r / 2] : t->hrh[r / 2];
+ }
+ }
}
struct som_table_class tab_table_class =
FIXME: Doesn't use r1? Huh? */
static int
-render_strip (int x, int y, int r, int c1, int c2, int r1 unused, int r2)
+render_strip (int x, int y, int r, int c1, int c2, int r1 UNUSED, int r2)
{
int x_origin = x;
}
} else {
struct tab_joined_cell *j =
- (struct tab_joined_cell *) ls_value (&t->cc[index]);
+ (struct tab_joined_cell *) ls_c_str (&t->cc[index]);
if (j->hit != tab_hit)
{
j->hit = tab_hit;
- if (j->x1 == c / 2 && j->y1 == r / 2
- && j->x2 <= c2 && j->y2 <= r2)
+ if (j->x1 == c / 2 && j->y1 == r / 2)
{
struct outp_text text;
int c;
for (c = j->x1, text.h = -t->wrv[j->x2];
- c < j->x2; c++)
- text.h += t->w[c] + t->wrv[c + 1];
+ c < j->x2 && c < c2 / 2; c++)
+ text.h += t->w[c] + t->wrv[c + 1];
}
{
int r;
for (r = j->y1, text.v = -t->hrh[j->y2];
- r < j->y2; r++)
+ r < j->y2 && r < r2 / 2; r++)
text.v += t->h[r] + t->hrh[r + 1];
}
d->class->text_draw (d, &text);