Add tty and listing devices that use VT100 (and xterm) line-drawing
[pspp-builds.git] / src / output / output.c
index a63f1171a446e0a42fb5c1f691a8adada0078f68..3f1dd904b4746131a395c6d34b14e87b062463f2 100644 (file)
@@ -1,21 +1,18 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
+/* PSPP - a program for statistical analysis.
+   Copyright (C) 1997-9, 2000, 2007 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 the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
+   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
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
 
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA. */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
 
 #include <config.h>
 #include "output.h"
@@ -70,12 +67,12 @@ static struct outp_names *outp_configure_vec;
 /* A list of driver classes. */
 struct outp_driver_class_list
   {
-    struct outp_class *class;
+    const struct outp_class *class;
     struct outp_driver_class_list *next;
   };
 
-struct outp_driver_class_list *outp_class_list;
-struct outp_driver *outp_driver_list;
+static struct outp_driver_class_list *outp_class_list;
+static struct outp_driver *outp_driver_list;
 
 char *outp_title;
 char *outp_subtitle;
@@ -91,7 +88,7 @@ static void configure_driver (const struct substring, const struct substring,
 
 /* Add a class to the class list. */
 static void
-add_class (struct outp_class *class)
+add_class (const struct outp_class *class)
 {
   struct outp_driver_class_list *new_list = xmalloc (sizeof *new_list);
 
@@ -153,8 +150,8 @@ add_name (char *bp, char *ep, int source)
   outp_configure_vec = n;
 }
 
-/* Checks that outp_configure_vec is empty, bitches & clears it if it
-   isn't. */
+/* Checks that outp_configure_vec is empty, complains and clears
+   it if it isn't. */
 static void
 check_configure_vec (void)
 {
@@ -227,7 +224,6 @@ outp_init (void)
 {
   extern struct outp_class ascii_class;
   extern struct outp_class postscript_class;
-  extern struct outp_class html_class;
 
   char def[] = "default";
 
@@ -254,7 +250,7 @@ delete_macros (void)
 }
 
 static void
-init_default_drivers (void) 
+init_default_drivers (void)
 {
   error (0, 0, _("using default output driver configuration"));
   configure_driver (ss_cstr ("list"),
@@ -279,8 +275,7 @@ outp_read_devices (void)
   init_fn = fn_search_path (fn_getenv_default ("STAT_OUTPUT_INIT_FILE",
                                               "devices"),
                            fn_getenv_default ("STAT_OUTPUT_INIT_PATH",
-                                              config_path),
-                           NULL);
+                                              config_path));
 
   ds_init_empty (&line);
 
@@ -342,10 +337,10 @@ exit:
   ds_destroy (&line);
   delete_macros ();
 
-  if (result) 
+  if (result)
     {
-      if (outp_driver_list == NULL) 
-        error (0, 0, _("no active output drivers")); 
+      if (outp_driver_list == NULL)
+        error (0, 0, _("no active output drivers"));
     }
   else
     error (0, 0, _("error reading device definition file"));
@@ -405,7 +400,7 @@ outp_configure_macro (char *bp)
       free (d);
       return;
     }
-  
+
   if (*ep == '=')
     ep++;
   while (isspace ((unsigned char) *ep))
@@ -440,10 +435,10 @@ destroy_list (struct outp_driver ** dl)
 void
 outp_done (void)
 {
-  struct outp_driver_class_list *n = outp_class_list ; 
+  struct outp_driver_class_list *n = outp_class_list ;
   destroy_list (&outp_driver_list);
 
-  while (n) 
+  while (n)
     {
       struct outp_driver_class_list *next = n->next;
       free(n);
@@ -453,7 +448,7 @@ outp_done (void)
 
   free (outp_title);
   outp_title = NULL;
-  
+
   free (outp_subtitle);
   outp_subtitle = NULL;
 }
@@ -492,7 +487,7 @@ get_option_token (struct substring *s, const char *driver_name,
                   struct string *token)
 {
   int c;
-  
+
   ds_clear (token);
   c = ss_get_char (s);
   if (c == EOF)
@@ -510,7 +505,7 @@ get_option_token (struct substring *s, const char *driver_name,
           c = ss_get_char (s);
           if (c == quote)
             break;
-          else if (c == EOF) 
+          else if (c == EOF)
             {
               error (0, 0,
                      _("reached end of options inside quoted string "
@@ -567,7 +562,7 @@ get_option_token (struct substring *s, const char *driver_name,
                 case '7':
                   out = c - '0';
                   while (ss_first (*s) >= '0' && ss_first (*s) <= '7')
-                    out = c * 8 + (ss_get_char (s) - '0');
+                    out = out * 8 + (ss_get_char (s) - '0');
                   break;
                 case 'x':
                 case 'X':
@@ -592,7 +587,7 @@ get_option_token (struct substring *s, const char *driver_name,
             }
         }
     }
-  else 
+  else
     {
       for (;;)
         {
@@ -604,7 +599,7 @@ get_option_token (struct substring *s, const char *driver_name,
           ss_advance (s, 1);
         }
     }
-  
+
   return 1;
 }
 
@@ -624,7 +619,7 @@ outp_parse_options (struct substring options,
       ss_ltrim (&left, ss_cstr (CC_SPACES));
       if (ss_is_empty (left))
         break;
-      
+
       if (!get_option_token (&left, driver->name, &key))
         break;
 
@@ -644,7 +639,7 @@ outp_parse_options (struct substring options,
       ok = callback (driver, ds_cstr (&key), &value);
     }
   while (ok);
-  
+
   ds_destroy (&key);
   ds_destroy (&value);
 
@@ -686,7 +681,7 @@ configure_driver (struct substring driver_name, struct substring class_name,
              (int) ss_length (class_name), ss_data (class_name));
       return;
     }
-  
+
   /* Parse device type. */
   device = 0;
   while (ss_tokenize (device_type, ss_cstr (CC_SPACES), &save_idx, &token))
@@ -706,7 +701,7 @@ configure_driver (struct substring driver_name, struct substring class_name,
   d->class = c->class;
   d->name = ss_xstrdup (driver_name);
   d->page_open = false;
-  d->device = OUTP_DEV_NONE;
+  d->device = device;
   d->cp_x = d->cp_y = 0;
   d->ext = NULL;
   d->prc = NULL;
@@ -749,7 +744,7 @@ configure_driver_line (struct substring line_)
   fn_interp_vars (line_, find_defn_value, &line);
 
   save_idx = 0;
-  for (i = 0; i < 4; i++) 
+  for (i = 0; i < 4; i++)
     {
       struct substring *token = &tokens[i];
       ds_separate (&line, ss_cstr (i < 3 ? ":" : ""), &save_idx, token);
@@ -797,7 +792,7 @@ destroy_driver (struct outp_driver *d)
    code and stores subcategory in *SUBCAT on success.  Returns -1
    on failure. */
 int
-outp_match_keyword (const char *s, struct outp_option *tab, int *subcat)
+outp_match_keyword (const char *s, const struct outp_option *tab, int *subcat)
 {
   for (; tab->keyword != NULL; tab++)
     if (!strcmp (s, tab->keyword))
@@ -960,7 +955,7 @@ internal_get_paper_size (char *size, int *h, int *v)
       error (0, 0, _("trailing garbage `%s' on paper size `%s'"), tail, size);
       return false;
     }
-  
+
   return true;
 }
 
@@ -1004,7 +999,7 @@ outp_get_paper_size (char *size, int *h, int *v)
       error (0, 0, _("paper size name cannot be empty"));
       return 0;
     }
-  
+
   ep++;
   if (*ep)
     *ep = 0;
@@ -1012,8 +1007,7 @@ outp_get_paper_size (char *size, int *h, int *v)
   pprsz_fn = fn_search_path (fn_getenv_default ("STAT_OUTPUT_PAPERSIZE_FILE",
                                                "papersize"),
                             fn_getenv_default ("STAT_OUTPUT_INIT_PATH",
-                                               config_path),
-                            NULL);
+                                               config_path));
 
   ds_init_empty (&line);
 
@@ -1076,7 +1070,7 @@ exit:
 
   if (!result)
     error (0, 0, _("error reading paper size definition file"));
-  
+
   return result;
 }
 
@@ -1115,9 +1109,9 @@ outp_enable_device (int enable, int device)
 
 /* Opens a page on driver D (if one is not open). */
 void
-outp_open_page (struct outp_driver *d) 
+outp_open_page (struct outp_driver *d)
 {
-  if (!d->page_open) 
+  if (!d->page_open)
     {
       d->cp_x = d->cp_y = 0;
 
@@ -1129,9 +1123,9 @@ outp_open_page (struct outp_driver *d)
 
 /* Closes the page on driver D (if one is open). */
 void
-outp_close_page (struct outp_driver *d) 
+outp_close_page (struct outp_driver *d)
 {
-  if (d->page_open) 
+  if (d->page_open)
     {
       if (d->class->close_page != NULL)
         d->class->close_page (d);
@@ -1149,6 +1143,18 @@ outp_eject_page (struct outp_driver *d)
   outp_open_page (d);
 }
 
+/* Flushes output to screen devices, so that the user can see
+   output that doesn't fill up an entire page. */
+void
+outp_flush (struct outp_driver *d)
+{
+  if (d->device & OUTP_DEV_SCREEN && d->class->flush != NULL)
+    {
+      outp_close_page (d);
+      d->class->flush (d);
+    }
+}
+
 /* Returns the width of string S, in device units, when output on
    device D. */
 int
@@ -1156,7 +1162,7 @@ outp_string_width (struct outp_driver *d, const char *s, enum outp_font font)
 {
   struct outp_text text;
   int width;
-  
+
   text.font = font;
   text.justification = OUTP_LEFT;
   text.string = ss_cstr (s);