ascii: Print syntax in output single-spaced.
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 23 Apr 2011 05:29:19 +0000 (22:29 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 23 Apr 2011 05:29:19 +0000 (22:29 -0700)
When SET PRINTBACK=ON was in effect, the ASCII output driver would
put a blank line between successive lines of syntax, because each line
was output separately.  This commit fixes that, by causing the output
core to combine successive syntax output items into a single item that
contains multiple lines of text.  This was essentially what the HTML
output driver was doing anyhow, so putting this into the core also
allows removing the corresponding logic from the HTML driver.

src/language/lexer/lexer.c
src/output/driver.c
src/output/html.c
tests/output/ascii.at

index 9a27d867b98cb87e15420671819ab24ccd1ca1fa..686aafd0d4c99fecc640828f2567a99fb414868c 100644 (file)
@@ -1324,6 +1324,7 @@ lex_source_get__ (const struct lex_source *src_)
       const char *newline;
       const char *line;
       size_t line_len;
+      char *syntax;
 
       line = &src->buffer[src->journal_pos - src->tail];
       newline = rawmemchr (line, '\n');
@@ -1331,8 +1332,12 @@ lex_source_get__ (const struct lex_source *src_)
       if (line_len > 0 && line[line_len - 1] == '\r')
         line_len--;
 
-      text_item_submit (text_item_create_nocopy (TEXT_ITEM_SYNTAX,
-                                                 xmemdup0 (line, line_len)));
+      syntax = malloc (line_len + 2);
+      memcpy (syntax, line, line_len);
+      syntax[line_len] = '\n';
+      syntax[line_len + 1] = '\0';
+
+      text_item_submit (text_item_create_nocopy (TEXT_ITEM_SYNTAX, syntax));
 
       src->journal_pos += newline - line + 1;
     }
index 0da3e6a0f6549b6fb6f3dd99edf19c7c6ffb884b..c0a525edae2f4963c3b34067c8c8f474b5b1a017 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2007, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 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
@@ -50,6 +50,9 @@ static const struct output_driver_factory *factories[];
 /* Drivers currently registered with output_driver_register(). */
 static struct llx_list drivers = LLX_INITIALIZER (drivers);
 
+/* TEXT_ITEM_SYNTAX being accumulated until another kind of output arrives. */
+static struct string deferred_syntax = DS_EMPTY_INITIALIZER;
+
 void
 output_close (void)
 {
@@ -69,10 +72,8 @@ output_get_supported_formats (struct string_set *formats)
     string_set_insert (formats, (*fp)->extension);
 }
 
-/* Submits ITEM to the configured output drivers, and transfers ownership to
-   the output subsystem. */
-void
-output_submit (struct output_item *item)
+static void
+output_submit__ (struct output_item *item)
 {
   struct llx *llx, *next;
 
@@ -104,6 +105,40 @@ output_submit (struct output_item *item)
   output_item_unref (item);
 }
 
+static void
+flush_deferred_syntax (void)
+{
+  if (!ds_is_empty (&deferred_syntax))
+    {
+      char *syntax = ds_steal_cstr (&deferred_syntax);
+      output_submit__ (text_item_super (
+                         text_item_create_nocopy (TEXT_ITEM_SYNTAX, syntax)));
+    }
+}
+
+static bool
+is_syntax_item (const struct output_item *item)
+{
+  return (is_text_item (item)
+          && text_item_get_type (to_text_item (item)) == TEXT_ITEM_SYNTAX);
+}
+
+/* Submits ITEM to the configured output drivers, and transfers ownership to
+   the output subsystem. */
+void
+output_submit (struct output_item *item)
+{
+  if (is_syntax_item (item))
+    {
+      ds_put_cstr (&deferred_syntax, text_item_get_text (to_text_item (item)));
+      output_item_unref (item);
+      return;
+    }
+
+  flush_deferred_syntax ();
+  output_submit__ (item);
+}
+
 /* Flushes output to screen devices, so that the user can see
    output that doesn't fill up an entire page. */
 void
@@ -111,6 +146,7 @@ output_flush (void)
 {
   struct llx *llx;
 
+  flush_deferred_syntax ();
   for (llx = llx_head (&drivers); llx != llx_null (&drivers);
        llx = llx_next (llx))
     {
index 5aec959c740a16a69888d9f5da76ad2d56778528..45c9a1ef730762df544128f488f227568d082517 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2009, 2010, 2011 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
@@ -55,8 +55,6 @@ struct html_driver
     char *command_name;
     FILE *file;
     size_t chart_cnt;
-
-    bool in_syntax;
   };
 
 static const struct output_driver_class html_driver_class;
@@ -200,11 +198,6 @@ html_destroy (struct output_driver *driver)
 
   if (html->file != NULL)
     {
-      if (html->in_syntax)
-        {
-          fprintf (html->file, "</PRE>\n");
-          html->in_syntax = false;
-        }
       fprintf (html->file,
                "</BODY>\n"
                "</HTML>\n"
@@ -217,13 +210,6 @@ html_destroy (struct output_driver *driver)
   free (html);
 }
 
-static bool
-is_syntax_item (const struct output_item *item)
-{
-  return (is_text_item (item)
-          && text_item_get_type (to_text_item (item)) == TEXT_ITEM_SYNTAX);
-}
-
 static void
 html_submit (struct output_driver *driver,
              const struct output_item *output_item)
@@ -232,12 +218,6 @@ html_submit (struct output_driver *driver,
 
   output_driver_track_current_command (output_item, &html->command_name);
 
-  if (html->in_syntax && !is_syntax_item (output_item))
-    {
-      fprintf (html->file, "</PRE>\n");
-      html->in_syntax = false;
-    }
-
   if (is_table_item (output_item))
     {
       struct table_item *table_item = to_table_item (output_item);
@@ -291,14 +271,9 @@ html_submit (struct output_driver *driver,
           break;
 
         case TEXT_ITEM_SYNTAX:
-          if (!html->in_syntax)
-            {
-              fprintf (html->file, "<PRE class=\"syntax\">");
-              html->in_syntax = true;
-            }
-          else
-            putc ('\n', html->file);
+          fprintf (html->file, "<PRE class=\"syntax\">");
           escape_string (html->file, s, strlen (s), " ");
+          fprintf (html->file, "</PRE>\n");
           break;
 
         case TEXT_ITEM_PARAGRAPH:
index 3c9243e7d2b09bacea503881041f9f1c069d18dd..df1263eb012b761daf611394b3766d8070677913 100644 (file)
@@ -539,3 +539,47 @@ AT_CHECK([render-test --box=unicode input], [0], [dnl
 ╰─┴───╯
 ])
 AT_CLEANUP
+
+AT_SETUP([ASCII driver syntax printback])
+AT_DATA([ascii.sps], [dnl
+SET PRINTBACK=ON.
+DATA LIST LIST /x * y * a (a23).
+BEGIN DATA.
+1 11 One
+2 22 Two
+3 33 Three
+END DATA.
+
+REGRESSION
+/VARIABLES= a
+/DEPENDENT= x y
+/STATISTICS=COEFF R ANOVA.
+])
+AT_CHECK([pspp ascii.sps], [1], [dnl
+SET PRINTBACK=ON.
+
+DATA LIST LIST /x * y * a (a23).
+
+Reading free-form data from INLINE.
++--------+------+
+|Variable|Format|
+#========#======#
+|x       |F8.0  |
+|y       |F8.0  |
+|a       |A23   |
++--------+------+
+
+BEGIN DATA.
+1 11 One
+2 22 Two
+3 33 Three
+END DATA.
+
+REGRESSION
+/VARIABLES= a
+/DEPENDENT= x y
+/STATISTICS=COEFF R ANOVA.
+
+ascii.sps:12: error: REGRESSION: REGRESSION requires numeric variables.
+])
+AT_CLEANUP