Fully implement arbitrary delimiters on DATA LIST, extending the half
[pspp-builds.git] / src / print.c
index 7d5b73b8cc75a81fc38916b761d142d40737c16a..b3098d673a1bc5b6ac8dacf2df493156fb47a312 100644 (file)
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA. */
 
+/* FIXME: seems like a lot of code duplication with data-list.c. */
+
 #include <config.h>
-#include <assert.h>
+#include "error.h"
 #include <stdlib.h>
 #include "alloc.h"
 #include "command.h"
@@ -32,8 +34,6 @@
 #include "tab.h"
 #include "var.h"
 
-#include "debug-print.h"
-
 /* Describes what to do when an output field is encountered. */
 enum
   {
@@ -96,16 +96,12 @@ static struct prt_out_spec *next;
 static int nrec;
 
 static int internal_cmd_print (int flags);
-static int print_trns_proc (struct trns_header *, struct ccase *);
-static void print_trns_free (struct trns_header *);
+static trns_proc_func print_trns_proc;
+static trns_free_func print_trns_free;
 static int parse_specs (void);
 static void dump_table (void);
 static void append_var_spec (struct prt_out_spec *spec);
 static void alloc_line (void);
-
-#if DEBUGGING
-void debug_print (void);
-#endif
 \f
 /* Basic parsing. */
 
@@ -113,7 +109,6 @@ void debug_print (void);
 int
 cmd_print (void)
 {
-  lex_match_id ("PRINT");
   return internal_cmd_print (PRT_PRINT);
 }
 
@@ -121,7 +116,6 @@ cmd_print (void)
 int
 cmd_print_eject (void)
 {
-  lex_match_id ("EJECT");
   return internal_cmd_print (PRT_PRINT | PRT_EJECT);
 }
 
@@ -129,7 +123,6 @@ cmd_print_eject (void)
 int
 cmd_write (void)
 {
-  lex_match_id ("WRITE");
   return internal_cmd_print (PRT_WRITE);
 }
 
@@ -192,6 +185,9 @@ internal_cmd_print (int f)
   if (!parse_specs ())
     goto lossage;
   
+  if (prt.handle != NULL && !dfm_open_for_writing (prt.handle))
+    goto lossage;
+
   /* Output the variable table if requested. */
   if (table)
     dump_table ();
@@ -205,10 +201,6 @@ internal_cmd_print (int f)
   memcpy (trns, &prt, sizeof *trns);
   add_transformation ((struct trns_header *) trns);
 
-#if 0 && DEBUGGING
-  debug_print ();
-#endif
-
   return CMD_SUCCESS;
 
  lossage:
@@ -346,7 +338,7 @@ parse_string_argument (void)
 {
   fx.spec.type = PRT_CONST;
   fx.spec.fc = fx.sc - 1;
-  fx.spec.u.c = xstrdup (ds_value (&tokstr));
+  fx.spec.u.c = xstrdup (ds_c_str (&tokstr));
   lex_get ();
 
   /* Parse the included column range. */
@@ -717,7 +709,7 @@ dump_fmt_list (struct fmt_list * f)
 static struct fmt_list *
 fixed_parse_fortran (void)
 {
-  struct fmt_list *head;
+  struct fmt_list *head = NULL;
   struct fmt_list *fl = NULL;
 
   lex_get ();                  /* skip opening parenthesis */
@@ -785,7 +777,6 @@ static void
 dump_table (void)
 {
   struct prt_out_spec *spec;
-  const char *filename;
   struct tab_table *t;
   int recno;
   int nspec;
@@ -839,13 +830,12 @@ dump_table (void)
        assert (0);
       }
 
-  filename = fh_handle_name (prt.handle);
-  tab_title (t, 1, (prt.handle != NULL
-                   ? _("Writing %3d records to file %s.")
-                   : _("Writing %3d records to the listing file.")),
-            recno, filename);
+  if (prt.handle != NULL)
+    tab_title (t, 1, _("Writing %d record(s) to file %s."),
+               recno, handle_get_filename (prt.handle));
+  else
+    tab_title (t, 1, _("Writing %d record(s) to the listing file."), recno);
   tab_submit (t);
-  fh_handle_name (NULL);
 }
 
 /* PORTME: The number of characters in a line terminator. */
@@ -886,8 +876,9 @@ alloc_line (void)
          pot_w = i->fc + 1;
          break;
        case PRT_ERROR:
+        default:
          assert (0);
-         break;
+          abort ();
        }
       if (pot_w > w)
        w = pot_w;
@@ -900,7 +891,8 @@ alloc_line (void)
 
 /* Performs the transformation inside print_trns T on case C. */
 static int
-print_trns_proc (struct trns_header * trns, struct ccase * c)
+print_trns_proc (struct trns_header * trns, struct ccase * c,
+                 int case_num UNUSED)
 {
   /* Transformation. */
   struct print_trns *t = (struct print_trns *) trns;
@@ -934,7 +926,7 @@ print_trns_proc (struct trns_header * trns, struct ccase * c)
        else
          {
            if ((t->options & PRT_CMD_MASK) == PRT_PRINT
-               || t->handle->mode != FH_MD_BINARY)
+               || handle_get_mode (t->handle) != MODE_BINARY)
              {
                /* PORTME: Line ends. */
 #ifdef __MSDOS__
@@ -958,14 +950,7 @@ print_trns_proc (struct trns_header * trns, struct ccase * c)
        break;
 
       case PRT_VAR:
-       if (i->u.v.v->type == NUMERIC)
-         data_out (&buf[i->fc], &i->u.v.f, &c->data[i->u.v.v->fv]);
-       else
-         {
-           union value t;
-           t.c = c->data[i->u.v.v->fv].s;
-           data_out (&buf[i->fc], &i->u.v.f, &t);
-         }
+        data_out (&buf[i->fc], &i->u.v.f, &c->data[i->u.v.v->fv]);
        len = i->fc + i->u.v.f.w;
        break;
 
@@ -1022,8 +1007,8 @@ struct print_space_trns
 }
 print_space_trns;
 
-static int print_space_trns_proc (struct trns_header *, struct ccase *);
-static void print_space_trns_free (struct trns_header *);
+static trns_proc_func print_space_trns_proc;
+static trns_free_func print_space_trns_free;
 
 int
 cmd_print_space (void)
@@ -1032,23 +1017,12 @@ cmd_print_space (void)
   struct file_handle *handle;
   struct expression *e;
 
-  lex_match_id ("SPACE");
   if (lex_match_id ("OUTFILE"))
     {
       lex_match ('=');
 
-      if (token == T_ID)
-       handle = fh_get_handle_by_name (tokid);
-      else if (token == T_STRING)
-       handle = fh_get_handle_by_filename (tokid);
-      else
-       {
-         msg (SE, _("A file name or handle was expected in the "
-                    "OUTFILE subcommand."));
-         return CMD_FAILURE;
-       }
-      
-      if (!handle)
+      handle = fh_parse_file_handle ();
+      if (handle == NULL)
        return CMD_FAILURE;
       lex_get ();
     }
@@ -1057,7 +1031,7 @@ cmd_print_space (void)
 
   if (token != '.')
     {
-      e = expr_parse (PXP_NUMERIC);
+      e = expr_parse (EXPR_NUMERIC);
       if (token != '.')
        {
          expr_free (e);
@@ -1068,6 +1042,12 @@ cmd_print_space (void)
   else
     e = NULL;
 
+  if (handle != NULL && !dfm_open_for_writing (handle))
+    {
+      expr_free (e);
+      return CMD_FAILURE;
+    }
+
   t = xmalloc (sizeof *t);
   t->h.proc = print_space_trns_proc;
   if (e)
@@ -1082,7 +1062,8 @@ cmd_print_space (void)
 }
 
 static int
-print_space_trns_proc (struct trns_header * trns, struct ccase * c)
+print_space_trns_proc (struct trns_header * trns, struct ccase * c,
+                       int case_num UNUSED)
 {
   struct print_space_trns *t = (struct print_space_trns *) trns;
   int n;
@@ -1091,7 +1072,7 @@ print_space_trns_proc (struct trns_header * trns, struct ccase * c)
     {
       union value v;
 
-      expr_evaluate (t->e, c, &v);
+      expr_evaluate (t->e, c, case_num, &v);
       n = v.f;
       if (n < 0)
        {
@@ -1131,45 +1112,3 @@ print_space_trns_free (struct trns_header * trns)
 {
   expr_free (((struct print_space_trns *) trns)->e);
 }
-\f
-/* Debugging code. */
-
-#if 0 && DEBUGGING
-void
-debug_print (void)
-{
-  struct prt_out_spec *p;
-
-  if (prt.handle == NULL)
-    {
-      printf ("PRINT");
-      if (prt.eject)
-       printf (" EJECT");
-    }
-  else
-    printf ("WRITE OUTFILE=%s", handle_name (prt.handle));
-  printf (" MAX_WIDTH=%d", prt.max_width);
-  printf (" /");
-  for (p = prt.spec; p; p = p->next)
-    switch (p->type)
-      {
-      case PRT_ERROR:
-       printf (_("<ERROR>"));
-       break;
-      case PRT_NEWLINE:
-       printf ("\n /");
-       break;
-      case PRT_CONST:
-       printf (" \"%s\" %d-%d", p->u.c, p->fc + 1, p->fc + strlen (p->u.c));
-       break;
-      case PRT_VAR:
-       printf (" %s %d %d-%d (%s)", p->u.v.v->name, p->u.v.v->fv, p->fc + 1,
-               p->fc + p->u.v.v->print.w, fmt_to_string (&p->u.v.v->print));
-       break;
-      case PRT_SPACE:
-       printf (" \" \" %d", p->fc + 1);
-       break;
-      }
-  printf (".\n");
-}
-#endif /* DEBUGGING */