pspp-output: Add new --nth-commands option.
[pspp] / src / output / table.c
index d6b0d73dc1686727d9c70852019ec05c054b6da1..31348a46a70d53b32aa6c3e7fdd8cd9bb2c5eea4 100644 (file)
@@ -176,7 +176,7 @@ struct table *
 table_from_string (const char *text)
 {
   struct table *t = table_create (1, 1, 0, 0, 0, 0);
-  t->styles[0] = xmalloc (sizeof *t->styles[0]);
+  t->styles[0] = pool_alloc (t->container, sizeof *t->styles[0]);
   *t->styles[0] = (struct area_style) {
     AREA_STYLE_INITIALIZER__,
     .cell_style.halign = TABLE_HALIGN_LEFT,
@@ -580,14 +580,11 @@ add_joined_cell (struct table *table, int x1, int y1, int x2, int y2,
              x1, y1, x2, y2);
 
   struct table_cell *cell = pool_alloc (table->container, sizeof *cell);
-  cell->d[TABLE_HORZ][0] = x1;
-  cell->d[TABLE_VERT][0] = y1;
-  cell->d[TABLE_HORZ][1] = ++x2;
-  cell->d[TABLE_VERT][1] = ++y2;
-  cell->options = opt;
-  cell->footnotes = NULL;
-  cell->n_footnotes = 0;
-  cell->style = NULL;
+  *cell = (struct table_cell) {
+    .d = { [TABLE_HORZ] = { x1, ++x2 },
+           [TABLE_VERT] = { y1, ++y2 } },
+    .options = opt,
+  };
 
   void **cc = &table->cc[x1 + y1 * table_nc (table)];
   unsigned short *ct = &table->ct[x1 + y1 * table_nc (table)];
@@ -620,9 +617,57 @@ table_joint_text (struct table *table, int x1, int y1, int x2, int y2,
     add_joined_cell (table, x1, y1, x2, y2, opt)->text = s;
 }
 
+static struct table_cell *
+get_joined_cell (struct table *table, int x, int y)
+{
+  int index = x + y * table_nc (table);
+  unsigned short opt = table->ct[index];
+  struct table_cell *cell;
+
+  if (opt & TAB_JOIN)
+    cell = table->cc[index];
+  else
+    {
+      char *text = table->cc[index];
+
+      cell = add_joined_cell (table, x, y, x, y, table->ct[index]);
+      cell->text = text ? text : pool_strdup (table->container, "");
+    }
+  return cell;
+}
+
+/* Sets the subscripts for column X, row Y in TABLE. */
+void
+table_add_subscripts (struct table *table, int x, int y,
+                      char **subscripts, size_t n_subscripts)
+{
+  struct table_cell *cell = get_joined_cell (table, x, y);
+
+  cell->n_subscripts = n_subscripts;
+  cell->subscripts = pool_nalloc (table->container, n_subscripts,
+                                  sizeof *cell->subscripts);
+  for (size_t i = 0; i < n_subscripts; i++)
+    cell->subscripts[i] = pool_strdup (table->container, subscripts[i]);
+}
+
+/* Sets the superscript for column X, row Y in TABLE. */
+void
+table_add_superscript (struct table *table, int x, int y,
+                       const char *superscript)
+{
+  get_joined_cell (table, x, y)->superscript
+    = pool_strdup (table->container, superscript);
+}
+
+/* Create a footnote in TABLE with MARKER (e.g. "a") as its marker and CONTENT
+   as its content.  The footnote will be styled as STYLE, which is mandatory.
+   IDX must uniquely identify the footnote within TABLE.
+
+   Returns the new footnote.  The return value is the only way to get to the
+   footnote later, so it is important for the caller to remember it. */
 struct footnote *
 table_create_footnote (struct table *table, size_t idx, const char *content,
-                     const char *marker, struct area_style *style)
+                       const char *marker, struct area_style *style)
 {
   assert (style);
 
@@ -634,25 +679,15 @@ table_create_footnote (struct table *table, size_t idx, const char *content,
   return f;
 }
 
+/* Attaches a reference to footnote F to the cell at column X, row Y in
+   TABLE. */
 void
 table_add_footnote (struct table *table, int x, int y,
                     const struct footnote *f)
 {
   assert (f->style);
 
-  int index = x + y * table_nc (table);
-  unsigned short opt = table->ct[index];
-  struct table_cell *cell;
-
-  if (opt & TAB_JOIN)
-    cell = table->cc[index];
-  else
-    {
-      char *text = table->cc[index];
-
-      cell = add_joined_cell (table, x, y, x, y, table->ct[index]);
-      cell->text = text ? text : pool_strdup (table->container, "");
-    }
+  struct table_cell *cell = get_joined_cell (table, x, y);
 
   cell->footnotes = pool_realloc (
     table->container, cell->footnotes,
@@ -661,27 +696,17 @@ table_add_footnote (struct table *table, int x, int y,
   cell->footnotes[cell->n_footnotes++] = f;
 }
 
+/* Overrides the style for column X, row Y in TABLE with STYLE.
+   Does not make a copy of STYLE, so it should either be allocated from
+   TABLE->container or have a lifetime that will outlive TABLE. */
 void
 table_add_style (struct table *table, int x, int y,
                  const struct area_style *style)
 {
-  int index = x + y * table_nc (table);
-  unsigned short opt = table->ct[index];
-  struct table_cell *cell;
-
-  if (opt & TAB_JOIN)
-    cell = table->cc[index];
-  else
-    {
-      char *text = table->cc[index];
-
-      cell = add_joined_cell (table, x, y, x, y, table->ct[index]);
-      cell->text = text ? text : pool_strdup (table->container, "");
-    }
-
-  cell->style = style;
+  get_joined_cell (table, x, y)->style = style;
 }
 
+/* Returns true if column C, row R has no contents, otherwise false. */
 bool
 table_cell_is_empty (const struct table *table, int c, int r)
 {