Added confidence and prediction intervals to model export
[pspp-builds.git] / src / tab.c
index 6005ec9cc72f16eee02b9ceaa02ce185effef118..4aa7f069bc0cdceb43e426ca0d938aa16bc24091 100644 (file)
--- a/src/tab.c
+++ b/src/tab.c
@@ -34,6 +34,9 @@
 #include "som.h"
 #include "var.h"
 
+#include "gettext.h"
+#define _(msgid) gettext (msgid)
+
 #include "debug-print.h"
 \f
 struct som_table_class tab_table_class;
@@ -44,7 +47,8 @@ struct som_table_class tab_table_class;
 struct tab_table *
 tab_create (int nc, int nr, int reallocable)
 {
-  void *(*alloc_func) (struct pool *, size_t);
+  void *(*alloc_func) (struct pool *, size_t n);
+  void *(*nalloc_func) (struct pool *, size_t n, size_t s);
 
   struct tab_table *t;
   
@@ -62,28 +66,29 @@ tab_create (int nc, int nr, int reallocable)
   t->nc = t->cf = nc;
   t->l = t->r = t->t = t->b = 0;
 
+  nalloc_func = reallocable ? pool_nmalloc : pool_nalloc;
   alloc_func = reallocable ? pool_malloc : pool_alloc;
 #if GLOBAL_DEBUGGING
   t->reallocable = reallocable;
 #endif
 
-  t->cc = alloc_func (t->container, nr * nc * sizeof *t->cc);
+  t->cc = nalloc_func (t->container, nr * nc, sizeof *t->cc);
   t->ct = alloc_func (t->container, nr * nc);
   memset (t->ct, TAB_EMPTY, nc * nr);
 
-  t->rh = alloc_func (t->container, nc * (nr + 1));
+  t->rh = nalloc_func (t->container, nc, nr + 1);
   memset (t->rh, 0, nc * (nr + 1));
 
-  t->hrh = alloc_func (t->container, sizeof *t->hrh * (nr + 1));
+  t->hrh = nalloc_func (t->container, nr + 1, sizeof *t->hrh);
   memset (t->hrh, 0, sizeof *t->hrh * (nr + 1));
 
   t->trh = alloc_func (t->container, nr + 1);
   memset (t->trh, 0, nr + 1);
 
-  t->rv = alloc_func (t->container, (nc + 1) * nr);
+  t->rv = nalloc_func (t->container, nr, nc + 1);
   memset (t->rv, 0, (nc + 1) * nr);
 
-  t->wrv = alloc_func (t->container, sizeof *t->wrv * (nc + 1));
+  t->wrv = nalloc_func (t->container, nc + 1, sizeof *t->wrv);
   memset (t->wrv, 0, sizeof *t->wrv * (nc + 1));
 
   t->trv = alloc_func (t->container, nc + 1);
@@ -160,7 +165,7 @@ tab_realloc (struct tab_table *t, int nc, int nr)
       unsigned char *new_ct;
       int r;
 
-      new_cc = pool_malloc (t->container, nr * nc * sizeof *new_cc);
+      new_cc = pool_nmalloc (t->container, nr * nc, sizeof *new_cc);
       new_ct = pool_malloc (t->container, nr * nc);
       for (r = 0; r < mr1; r++)
        {
@@ -176,14 +181,13 @@ tab_realloc (struct tab_table *t, int nc, int nr)
     }
   else if (nr != t->nr)
     {
-      t->cc = pool_realloc (t->container, t->cc, nr * nc * sizeof *t->cc);
+      t->cc = pool_nrealloc (t->container, t->cc, nr * nc, sizeof *t->cc);
       t->ct = pool_realloc (t->container, t->ct, nr * nc);
 
-      t->rh = pool_realloc (t->container, t->rh, nc * (nr + 1));
-      t->rv = pool_realloc (t->container, t->rv, (nc + 1) * nr);
+      t->rh = pool_nrealloc (t->container, t->rh, nc, nr + 1);
+      t->rv = pool_nrealloc (t->container, t->rv, nr, nc + 1);
       t->trh = pool_realloc (t->container, t->trh, nr + 1);
-      t->hrh = pool_realloc (t->container, t->hrh,
-                            sizeof *t->hrh * (nr + 1));
+      t->hrh = pool_nrealloc (t->container, t->hrh, nr + 1, sizeof *t->hrh);
       
       if (nr > t->nr)
        {
@@ -607,9 +611,7 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt,
   assert (r >= 0);
   assert (r < table->nr);
 
-  f.type = FMT_F;
-  f.w = w;
-  f.d = d;
+  f = make_output_format (FMT_F, w, d);
   
 #if GLOBAL_DEBUGGING
   if (c + table->col_ofs < 0 || r + table->row_ofs < 0
@@ -937,8 +939,8 @@ tabi_table (struct som_entity *table)
   tab_offset (t, 0, 0);
   
   assert (t->w == NULL && t->h == NULL);
-  t->w = pool_alloc (t->container, sizeof *t->w * t->nc);
-  t->h = pool_alloc (t->container, sizeof *t->h * t->nr);
+  t->w = pool_nalloc (t->container, t->nc, sizeof *t->w);
+  t->h = pool_nalloc (t->container, t->nr, sizeof *t->h);
 }
 
 /* Set the current output device to DRIVER. */
@@ -1137,6 +1139,45 @@ tabi_flags (unsigned *flags)
   *flags = t->flags;
 }
 
+/* Returns true if the table will fit in the given page WIDTH,
+   false otherwise. */
+static bool
+tabi_fits_width (int width) 
+{
+  int i;
+
+  for (i = t->l; i < t->nc - t->r; i++)
+    if (t->wl + t->wr + t->w[i] > width)
+      return false;
+
+  return true;
+}
+
+/* Returns true if the table will fit in the given page LENGTH,
+   false otherwise. */
+static bool
+tabi_fits_length (int length) 
+{
+  int i;
+
+  for (i = t->t; i < t->nr - t->b; i++)
+    if (t->ht + t->hb + t->h[i] > length)
+      return false;
+
+  return true;
+}
+
+/* Sets the number of header rows/columns on the left, right, top,
+   and bottom sides to HL, HR, HT, and HB, respectively. */
+static void
+tabi_set_headers (int hl, int hr, int ht, int hb)
+{
+  t->l = hl;
+  t->r = hr;
+  t->t = ht;
+  t->b = hb;
+}
+
 /* Render title for current table, with major index X and minor index
    Y.  Y may be zero, or X and Y may be zero, but X should be nonzero
    if Y is nonzero. */
@@ -1237,9 +1278,12 @@ struct som_table_class tab_table_class =
     NULL,
     tabi_cumulate,
     tabi_flags,
+    tabi_fits_width,
+    tabi_fits_length,
     
     NULL,
     NULL,
+    tabi_set_headers,
 
     tabi_title,
     tabi_render,