MATRIX: Implement HOLD (untested).
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 6 Nov 2021 05:58:07 +0000 (22:58 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 6 Nov 2021 05:58:07 +0000 (22:58 -0700)
src/language/stats/matrix.c

index 07179cefaf4bb97e1bb247a8c0d6d97cb268a654..3cdd0372073b7ddf31a3fc87de6f12ecfa71686d 100644 (file)
@@ -101,6 +101,7 @@ struct write_file
     struct file_handle *file;
     struct dfm_writer *writer;
     char *encoding;
+    struct u8_line *held;
   };
 
 struct matrix_state
@@ -1736,6 +1737,14 @@ write_file_destroy (struct write_file *wf)
 {
   if (wf)
     {
+      if (wf->held)
+        {
+          dfm_put_record_utf8 (wf->writer, wf->held->s.ss.string,
+                               wf->held->s.ss.length);
+          u8_line_destroy (wf->held);
+          free (wf->held);
+        }
+
       fh_unref (wf->file);
       dfm_close_writer (wf->writer);
       free (wf->encoding);
@@ -5185,7 +5194,7 @@ matrix_cmd_execute_write (struct write_command *write)
     }
 
   struct dfm_writer *writer = write_file_open (write->wf);
-  if (!writer)
+  if (!writer || !m->size1)
     {
       gsl_matrix_free (m);
       return;
@@ -5197,9 +5206,14 @@ matrix_cmd_execute_write (struct write_command *write)
     .w = write->w ? write->w : 40,
     .d = write->d
   };
-  struct u8_line line = U8_LINE_INITIALIZER;
+  struct u8_line *line = write->wf->held;
   for (size_t y = 0; y < m->size1; y++)
     {
+      if (!line)
+        {
+          line = xmalloc (sizeof *line);
+          u8_line_init (line);
+        }
       size_t nx = write->triangular ? y + 1 : m->size2;
       int x0 = write->c1;
       for (size_t x = 0; x < nx; x++)
@@ -5213,20 +5227,28 @@ matrix_cmd_execute_write (struct write_command *write)
           int width = u8_width (CHAR_CAST (const uint8_t *, s), len, UTF8);
           if (width + x0 > write->c2)
             {
-              dfm_put_record_utf8 (writer, line.s.ss.string, line.s.ss.length);
-              u8_line_clear (&line);
+              dfm_put_record_utf8 (writer, line->s.ss.string,
+                                   line->s.ss.length);
+              u8_line_clear (line);
               x0 = write->c1;
             }
-          u8_line_put (&line, x0, x0 + width, s, len);
+          u8_line_put (line, x0, x0 + width, s, len);
           free (s);
 
           x0 += write->w ? write->w : width + 1;
         }
 
-      dfm_put_record_utf8 (writer, line.s.ss.string, line.s.ss.length);
-      u8_line_clear (&line);
+      if (y + 1 >= m->size1 && write->hold)
+        break;
+      dfm_put_record_utf8 (writer, line->s.ss.string, line->s.ss.length);
+      u8_line_clear (line);
+    }
+  if (!write->hold)
+    {
+      u8_line_destroy (line);
+      line = NULL;
     }
-  u8_line_destroy (&line);
+  write->wf->held = line;
   dfm_close_writer (writer);
 
   gsl_matrix_free (m);