Memory leak patrol.
[pspp-builds.git] / src / output / table.c
index 42361702b5de1164a4ccc0cceb06761bb2788054..a7dc4817f0f946a46fc73ce0f2713490810bbc5b 100644 (file)
@@ -23,8 +23,8 @@
 #include <stdarg.h>
 #include <limits.h>
 #include <stdlib.h>
-#include <libpspp/message.h>
 #include <libpspp/alloc.h>
+#include <libpspp/assertion.h>
 #include <libpspp/compiler.h>
 #include <data/format.h>
 #include <libpspp/magic.h>
@@ -59,7 +59,7 @@ tab_create (int nc, int nr, int reallocable UNUSED)
   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;
@@ -72,15 +72,9 @@ tab_create (int nc, int nr, int reallocable UNUSED)
   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;
@@ -93,6 +87,7 @@ void
 tab_destroy (struct tab_table *t)
 {
   assert (t != NULL);
+  free (t->title);
   pool_destroy (t->container);
 }
 
@@ -144,7 +139,7 @@ tab_realloc (struct tab_table *t, int nc, int nr)
       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;
 
@@ -312,7 +307,7 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
              x2, t->col_ofs, x2 + t->col_ofs,
              y2, t->row_ofs, y2 + t->row_ofs,
              t->nc, t->nr);
-      abort ();
+      NOT_REACHED ();
     }
 #endif
 
@@ -373,23 +368,16 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v,
     }
 }
 
-/* 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
@@ -401,7 +389,7 @@ tab_title (struct tab_table *t, const char *title, ...)
 
   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);
 }
 
@@ -436,7 +424,6 @@ tab_natural_width (struct tab_table *t, struct outp_driver *d, int c)
          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;
@@ -449,10 +436,10 @@ tab_natural_width (struct tab_table *t, struct outp_driver *d, int c)
 
   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; 
     }
   
   {
@@ -489,7 +476,6 @@ tab_natural_height (struct tab_table *t, struct outp_driver *d, int r)
          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];
@@ -547,7 +533,7 @@ tab_value (struct tab_table *table, int c, int r, unsigned char opt,
 #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);
@@ -597,7 +583,7 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt,
   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);
 }
@@ -632,7 +618,7 @@ tab_text (struct tab_table *table, int c, int r, unsigned opt, const char *text,
 #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);
 }
@@ -684,14 +670,14 @@ tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2,
     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);
 
@@ -703,7 +689,7 @@ tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2,
        
        for (x = x1; x < x2; x++)
          {
-           ls_init (cc++, (char *) j, 0);
+           *cc++ = ss_buffer ((char *) j, 0);
            *ct++ = opt;
          }
        
@@ -716,7 +702,7 @@ tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2,
 /* 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);
   
@@ -817,15 +803,15 @@ tab_offset (struct tab_table *t, int col, int row)
 
   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
 
@@ -867,6 +853,8 @@ tabi_table (struct som_entity *table)
   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
@@ -884,7 +872,7 @@ rule_to_spacing_type (unsigned char type)
     case TAL_2:
       return OUTP_L_DOUBLE;
     default:
-      abort ();
+      NOT_REACHED ();
     }
 }
 
@@ -1170,10 +1158,11 @@ tabi_title (int x, int y)
   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;
   
@@ -1182,7 +1171,7 @@ tabi_title (int x, int y)
 
     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;
@@ -1269,7 +1258,7 @@ translate_justification (unsigned int opt)
     case TAB_CENTER:
       return OUTP_CENTER;
     default:
-      abort ();
+      NOT_REACHED ();
     }
 }
 
@@ -1288,7 +1277,7 @@ rule_to_draw_type (unsigned char type)
     case TAL_2:
       return OUTP_L_DOUBLE;
     default:
-      abort ();
+      NOT_REACHED ();
     }
 }
 
@@ -1394,7 +1383,7 @@ render_cell (int x, int y, int c, int r, int c1, int r1)
 {
   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))
     {
@@ -1414,7 +1403,7 @@ render_cell (int x, int y, int c, int r, int c1, int r1)
   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)
         {