From 5d8fa2ae8c6e7d890570585aedec66bd51630814 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 22 Apr 2011 22:29:19 -0700 Subject: [PATCH 1/1] ascii: Print syntax in output single-spaced. 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 | 9 ++++++-- src/output/driver.c | 46 +++++++++++++++++++++++++++++++++----- src/output/html.c | 31 +++---------------------- tests/output/ascii.at | 44 ++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 35 deletions(-) diff --git a/src/language/lexer/lexer.c b/src/language/lexer/lexer.c index 9a27d867..686aafd0 100644 --- a/src/language/lexer/lexer.c +++ b/src/language/lexer/lexer.c @@ -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; } diff --git a/src/output/driver.c b/src/output/driver.c index 0da3e6a0..c0a525ed 100644 --- a/src/output/driver.c +++ b/src/output/driver.c @@ -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)) { diff --git a/src/output/html.c b/src/output/html.c index 5aec959c..45c9a1ef 100644 --- a/src/output/html.c +++ b/src/output/html.c @@ -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, "\n"); - html->in_syntax = false; - } fprintf (html->file, "\n" "\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, "\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, "
");
-              html->in_syntax = true;
-            }
-          else
-            putc ('\n', html->file);
+          fprintf (html->file, "
");
           escape_string (html->file, s, strlen (s), " ");
+          fprintf (html->file, "
\n"); break; case TEXT_ITEM_PARAGRAPH: diff --git a/tests/output/ascii.at b/tests/output/ascii.at index 3c9243e7..df1263eb 100644 --- a/tests/output/ascii.at +++ b/tests/output/ascii.at @@ -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 -- 2.30.2