Make minimum breaks configurable.
[pspp] / tests / output / render-test.c
index 5d8a291816d26911a07418e17660386e0c3392f5..b996e644cb10a7176954cd47cc8f97f8bf30c16a 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2009 Free Software Foundation, Inc.
+   Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include <stdio.h>
 #include <string.h>
 
-#include <libpspp/assertion.h>
-#include <libpspp/compiler.h>
-#include <output/driver.h>
-#include <output/tab.h>
-#include <output/table-item.h>
+#include "libpspp/assertion.h"
+#include "libpspp/compiler.h"
+#include "libpspp/string-map.h"
+#include "output/ascii.h"
+#include "output/driver.h"
+#include "output/tab.h"
+#include "output/table-item.h"
 
 #include "gl/error.h"
 #include "gl/progname.h"
+#include "gl/xalloc.h"
 #include "gl/xvasprintf.h"
 
 /* --transpose: Transpose the table before outputting? */
 static int transpose;
 
+/* --emphasis: ASCII driver emphasis option. */
+static char *emphasis;
+
+/* --box: ASCII driver box option. */
+static char *box;
+
+/* --draw-mode: special ASCII driver test mode. */
+static int draw_mode;
+
+/* --pdf: Also render PDF output. */
+static int render_pdf;
+
+/* ASCII driver, for ASCII driver test mode. */
+static struct output_driver *ascii_driver;
+
 static const char *parse_options (int argc, char **argv);
 static void usage (void) NO_RETURN;
 static struct table *read_table (FILE *);
+static void draw (FILE *);
 
 int
 main (int argc, char **argv)
 {
-  struct table *table;
   const char *input_file_name;
   FILE *input;
 
@@ -57,40 +75,135 @@ main (int argc, char **argv)
       if (input == NULL)
         error (1, errno, "%s: open failed", input_file_name);
     }
-  table = read_table (input);
+
+  if (!draw_mode)
+    {
+      struct table *table;
+
+      table = read_table (input);
+
+      if (transpose)
+        table = table_transpose (table);
+
+      table_item_submit (table_item_create (table, NULL));
+    }
+  else
+    draw (input);
+
   if (input != stdin)
     fclose (input);
 
-  if (transpose)
-    table = table_transpose (table);
-
-  table_item_submit (table_item_create (table, NULL));
   output_close ();
 
   return 0;
 }
 
+static void
+configure_drivers (int width, int length, int min_break)
+{
+  struct string_map options, tmp;
+  struct output_driver *driver;
+
+  string_map_init (&options);
+  string_map_insert (&options, "format", "txt");
+  string_map_insert (&options, "output-file", "-");
+  string_map_insert_nocopy (&options, xstrdup ("width"),
+                            xasprintf ("%d", width));
+  string_map_insert_nocopy (&options, xstrdup ("length"),
+                            xasprintf ("%d", length));
+  if (min_break >= 0)
+    {
+      string_map_insert_nocopy (&options, xstrdup ("min-hbreak"),
+                                xasprintf ("%d", min_break));
+      string_map_insert_nocopy (&options, xstrdup ("min-vbreak"),
+                                xasprintf ("%d", min_break));
+    }
+  if (emphasis != NULL)
+    string_map_insert (&options, "emphasis", emphasis);
+  if (box != NULL)
+    string_map_insert (&options, "box", box);
+
+  /* Render to stdout. */
+  string_map_clone (&tmp, &options);
+  ascii_driver = driver = output_driver_create (&tmp);
+  if (driver == NULL)
+    exit (EXIT_FAILURE);
+  output_driver_register (driver);
+  string_map_destroy (&tmp);
+
+  if (draw_mode)
+   {
+    string_map_destroy (&options);
+    return;
+   }
+
+  /* Render to render.txt. */
+  string_map_replace (&options, "output-file", "render.txt");
+  driver = output_driver_create (&options);
+  if (driver == NULL)
+    exit (EXIT_FAILURE);
+  output_driver_register (driver);
+
+#ifdef HAVE_CAIRO
+  if (render_pdf)
+    {
+      string_map_insert (&options, "output-file", "render.pdf");
+      string_map_insert (&options, "top-margin", "0");
+      string_map_insert (&options, "bottom-margin", "0");
+      string_map_insert (&options, "left-margin", "0");
+      string_map_insert (&options, "right-margin", "0");
+      string_map_insert_nocopy (&options, xstrdup ("paper-size"),
+                                xasprintf ("%dx%dpt", width * 5, length * 8));
+      if (min_break >= 0)
+        {
+          string_map_insert_nocopy (&options, xstrdup ("min-hbreak"),
+                                    xasprintf ("%d", min_break * 5));
+          string_map_insert_nocopy (&options, xstrdup ("min-vbreak"),
+                                    xasprintf ("%d", min_break * 8));
+        }
+      driver = output_driver_create (&options);
+      if (driver == NULL)
+        exit (EXIT_FAILURE);
+      output_driver_register (driver);
+    }
+#endif
+
+  string_map_insert (&options, "output-file", "render.odt");
+  driver = output_driver_create (&options);
+  if (driver == NULL)
+    exit (EXIT_FAILURE);
+  output_driver_register (driver);
+
+  string_map_destroy (&options);
+}
+
 static const char *
 parse_options (int argc, char **argv)
 {
-  bool configured_driver = false;
   int width = 79;
   int length = 66;
+  int min_break = -1;
 
   for (;;)
     {
       enum {
-        OPT_DRIVER = UCHAR_MAX + 1,
-        OPT_WIDTH,
+        OPT_WIDTH = UCHAR_MAX + 1,
         OPT_LENGTH,
+        OPT_MIN_BREAK,
+        OPT_EMPHASIS,
+        OPT_BOX,
         OPT_HELP
       };
       static const struct option options[] =
         {
-          {"driver", required_argument, NULL, OPT_DRIVER},
           {"width", required_argument, NULL, OPT_WIDTH},
           {"length", required_argument, NULL, OPT_LENGTH},
+          {"min-break", required_argument, NULL, OPT_MIN_BREAK},
           {"transpose", no_argument, &transpose, 1},
+          {"emphasis", required_argument, NULL, OPT_EMPHASIS},
+          {"box", required_argument, NULL, OPT_BOX},
+          {"draw-mode", no_argument, &draw_mode, 1},
+          {"pdf", no_argument, &render_pdf, 1},
           {"help", no_argument, NULL, OPT_HELP},
           {NULL, 0, NULL, 0},
         };
@@ -101,11 +214,6 @@ parse_options (int argc, char **argv)
 
       switch (c)
         {
-        case OPT_DRIVER:
-          output_configure_driver (optarg);
-          configured_driver = true;
-          break;
-
         case OPT_WIDTH:
           width = atoi (optarg);
           break;
@@ -114,6 +222,18 @@ parse_options (int argc, char **argv)
           length = atoi (optarg);
           break;
 
+        case OPT_MIN_BREAK:
+          min_break = atoi (optarg);
+          break;
+
+        case OPT_EMPHASIS:
+          emphasis = optarg;
+          break;
+
+        case OPT_BOX:
+          box = optarg;
+          break;
+
         case OPT_HELP:
           usage ();
 
@@ -130,32 +250,7 @@ parse_options (int argc, char **argv)
 
     }
 
-  if (!configured_driver)
-    {
-      char *config;
-
-#if 1
-      config = xasprintf ("ascii:ascii:listing:headers=off top-margin=0 "
-                          "bottom-margin=0 output-file=- emphasis=none "
-                          "paginate=off squeeze=on width=%d length=%d",
-                          width, length);
-      output_configure_driver (config);
-      free (config);
-
-      config = xasprintf ("ascii:ascii:listing:headers=off top-margin=0 "
-                          "bottom-margin=0 output-file=render.txt "
-                          "emphasis=none paginate=off squeeze=on");
-      output_configure_driver (config);
-      free (config);
-#endif
-
-      config = xasprintf ("pdf:cairo:listing:headers=off top-margin=0 "
-                          "bottom-margin=0 left-margin=0 right-margin=0 "
-                          "output-file=render.pdf paper-size=%dx%dpt",
-                          width * 5, length * 6);
-      output_configure_driver (config);
-      free (config);
-    }
+  configure_drivers (width, length, min_break);
 
   if (optind + 1 != argc)
     error (1, 0, "exactly one non-option argument required; "
@@ -169,7 +264,8 @@ usage (void)
   printf ("%s, to test rendering of PSPP tables\n"
           "usage: %s [OPTIONS] INPUT\n"
           "\nOptions:\n"
-          "  --driver=NAME:CLASS:DEVICE:OPTIONS  set output driver\n",
+          "  --width=WIDTH   set page width in characters\n"
+          "  --length=LINE   set page length in lines\n",
           program_name, program_name);
   exit (EXIT_SUCCESS);
 }
@@ -282,3 +378,29 @@ read_table (FILE *stream)
 
   return &tab->table;
 }
+
+static void
+draw (FILE *stream)
+{
+  char buffer[1024];
+  int line = 0;
+
+  while (fgets (buffer, sizeof buffer, stream))
+    {
+      char text[sizeof buffer];
+      int length;
+      int emph;
+      int x, y;
+
+      line++;
+      if (strchr ("#\r\n", buffer[0]))
+        continue;
+
+      if (sscanf (buffer, "%d %d %d %[^\n]", &x, &y, &emph, text) == 4)
+        ascii_test_write (ascii_driver, text, x, y, emph ? TAB_EMPH : 0);
+      else if (sscanf (buffer, "set-length %d %d", &y, &length) == 2)
+        ascii_test_set_length (ascii_driver, y, length);
+      else
+        error (1, 0, "line %d has invalid format", line);
+    }
+}