From 458d169f64134f4e0a9d9b72398666a01761fcf8 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 27 Jul 2007 22:58:02 +0000 Subject: [PATCH] Make interactive output go to the terminal (bug #17213), by causing the UI to flush output to the user when it prompts for a command. Thanks to John Darrington for review. --- config/ChangeLog | 5 ++++ config/devices | 11 ++++---- src/data/ChangeLog | 14 ++++++++++ src/data/file-name.c | 6 +++-- src/data/settings.c | 29 +++++++++++++------- src/libpspp/ChangeLog | 8 ++++++ src/libpspp/automake.mk | 4 +-- src/libpspp/getl.c | 2 +- src/output/ChangeLog | 19 ++++++++++++++ src/output/ascii.c | 48 +++++++++++++++++++++++++++------- src/output/html.c | 1 + src/output/manager.c | 12 ++++++++- src/output/manager.h | 1 + src/output/output.c | 20 +++++++++++--- src/output/output.h | 5 +++- src/output/postscript.c | 1 + src/ui/terminal/ChangeLog | 12 +++++++++ src/ui/terminal/command-line.c | 12 ++++----- src/ui/terminal/read-line.c | 6 ++++- 19 files changed, 174 insertions(+), 42 deletions(-) diff --git a/config/ChangeLog b/config/ChangeLog index 292a289f..b5f672a3 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,8 @@ +2007-07-25 Ben Pfaff + + * devices: Add an "interactive" category that defaults to + tty-ascii. Make the tty-ascii device more user-friendly. + Tue Apr 4 20:20:49 2006 Ben Pfaff * automake.mk: Fix bugs in installation targets. diff --git a/config/devices b/config/devices index 94cba3af..ab96d66d 100644 --- a/config/devices +++ b/config/devices @@ -41,16 +41,17 @@ # referenced with $var or ${var} syntax; the latter is preferred. # Preferred devices. -default=tty list -tty=#tty-ibmpc -list=list-ascii +default=list-ascii +interactive=tty-ascii # Output files. -define tty-output-file "/dev/tty" +define tty-output-file "|more" define list-output-file "pspp.list" # Generic ASCII devices -tty-ascii:ascii:screen:output-file=${tty-output-file} +tty-ascii:ascii:screen:squeeze=on headers=off top-margin=0 bottom-margin=0 \ + paginate=off length=${viewlength} width=${viewwidth} \ + output-file=${tty-output-file} list-ascii:ascii:listing:length=66 width=79 output-file=${list-output-file} raw-ascii:ascii:screen:width=9999 length=9999 output-file=${list-output-file} \ emphasis=none headers=off paginate=off squeeze=on \ diff --git a/src/data/ChangeLog b/src/data/ChangeLog index ddf6e685..32651710 100644 --- a/src/data/ChangeLog +++ b/src/data/ChangeLog @@ -1,3 +1,17 @@ +2007-07-25 Ben Pfaff + + Fix bugs related to bug #17213. + + * settings.c: Use HAVE_LIBNCURSES instead of HAVE_LIBTERMCAP, + since the former is what config.h has. Include the needed ncurses + headers. + (static var echo) Rename to `do_echo' because the original name is + the same as an ncurses identifier. + (get_termcap_viewport) Use error instead of msg. + + * file-name.c (fn_interp_vars): Fix interpolation of $VARS. + (fn_close): Don't close stdin, stdout, stderr. + 2007-07-26 John Darrington * procedure.c procedure.h: Added callbacks which get invoked whenever diff --git a/src/data/file-name.c b/src/data/file-name.c index 2ad3311a..23d7ee08 100644 --- a/src/data/file-name.c +++ b/src/data/file-name.c @@ -87,7 +87,7 @@ fn_interp_vars (struct substring src, const char *(*getenv) (const char *), else if (ss_match_char (&src, '{')) ss_get_until (&src, '}', &var_name); else - ss_get_chars (&src, MIN (1, ss_span (src, ss_cstr (CC_ALNUM))), + ss_get_chars (&src, MAX (1, ss_span (src, ss_cstr (CC_ALNUM))), &var_name); start = ds_length (&dst); @@ -305,7 +305,9 @@ fn_open (const char *fn, const char *mode) int fn_close (const char *fn, FILE *f) { - if (!strcmp (fn, "-")) + if (fileno (f) == STDIN_FILENO + || fileno (f) == STDOUT_FILENO + || fileno (f) == STDERR_FILENO) return 0; #if HAVE_POPEN else if (fn[0] == '|' || (*fn && fn[strlen (fn) - 1] == '|')) diff --git a/src/data/settings.c b/src/data/settings.c index 3e95b6b5..b14fb618 100644 --- a/src/data/settings.c +++ b/src/data/settings.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc. + Copyright (C) 1997-9, 2000, 2006, 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 @@ -24,13 +24,23 @@ #include "xalloc.h" #include +#include "error.h" + +#ifdef HAVE_LIBNCURSES +#include +#include +#endif + +#include "gettext.h" +#define _(msgid) gettext (msgid) + static int viewlength = 24; static int viewwidth = 79; static bool long_view = false; static bool safer_mode = false; -static bool echo = false; +static bool do_echo = false; static bool include = true; static int epoch = -1; @@ -121,7 +131,7 @@ set_viewwidth (int viewwidth_) viewwidth = viewwidth_; } -#if HAVE_LIBTERMCAP +#if HAVE_LIBNCURSES static void get_termcap_viewport (void) { @@ -130,7 +140,8 @@ get_termcap_viewport (void) return; else if (tgetent (term_buffer, getenv ("TERM")) <= 0) { - msg (IE, _("Could not access definition for terminal `%s'."), termtype); + error (0,0, _("could not access definition for terminal `%s'"), + getenv ("TERM")); return; } @@ -140,7 +151,7 @@ get_termcap_viewport (void) if (tgetnum ("co") > 1) viewwidth = tgetnum ("co") - 1; } -#endif /* HAVE_LIBTERMCAP */ +#endif /* HAVE_LIBNCURSES */ static void init_viewport (void) @@ -150,9 +161,9 @@ init_viewport (void) viewwidth = viewlength = -1; -#if HAVE_LIBTERMCAP +#if HAVE_LIBNCURSES get_termcap_viewport (); -#endif /* HAVE_LIBTERMCAP */ +#endif /* HAVE_LIBNCURSES */ if (viewwidth < 0 && getenv ("COLUMNS") != NULL) viewwidth = atoi (getenv ("COLUMNS")); @@ -183,14 +194,14 @@ set_safer_mode (void) bool get_echo (void) { - return echo; + return do_echo; } /* Set echo. */ void set_echo (bool echo_) { - echo = echo_; + do_echo = echo_; } /* If echo is on, whether commands from include files are echoed. */ diff --git a/src/libpspp/ChangeLog b/src/libpspp/ChangeLog index e0cebfb8..6f3ddf51 100644 --- a/src/libpspp/ChangeLog +++ b/src/libpspp/ChangeLog @@ -1,3 +1,11 @@ +2007-07-25 Ben Pfaff + + * getl.c (getl_append_source): Add source to *end* of list. + Otherwise the list ends up in reverse order. + + * automake.mk (src/libpspp/version.c): Use $HOME instead of ~ in + paths. We don't interpolate ~. + 2007-07-22 Ben Pfaff * str.h: Include xstrndup.h also. diff --git a/src/libpspp/automake.mk b/src/libpspp/automake.mk index ca6b7195..e0914c95 100644 --- a/src/libpspp/automake.mk +++ b/src/libpspp/automake.mk @@ -89,9 +89,9 @@ src/libpspp/version.c: $(top_srcdir)/AUTHORS echo "const char host_system[] = \"$(host_triplet)\";" >> $@ echo "const char build_system[] = \"$(build_triplet)\";" >> $@ echo "const char default_config_path[] =\ -\"~/.pspp:$(pkgsysconfdir)\";" >> $@ +\"\$$HOME/.pspp:$(pkgsysconfdir)\";" >> $@ echo "const char include_path[] =\ -\"./:~/.pspp/include:$(pkgdatadir)\";" >> $@ +\"./:\$$HOME/.pspp/include:$(pkgdatadir)\";" >> $@ echo "const char locale_dir[] = \"$(datadir)/locale\";" >> $@ echo "const char *const authors[] = {" >> $@ sed -e 's/^/ \"/' -e 's/$$/\",/' $(top_srcdir)/AUTHORS >> $@ diff --git a/src/libpspp/getl.c b/src/libpspp/getl.c index dbabde47..b4617122 100644 --- a/src/libpspp/getl.c +++ b/src/libpspp/getl.c @@ -94,7 +94,7 @@ getl_append_source (struct source_stream *ss, struct getl_interface *i) s->interface = i ; - ll_push_head (&ss->sources, &s->ll); + ll_push_tail (&ss->sources, &s->ll); } /* Nests source S within the current source file. */ diff --git a/src/output/ChangeLog b/src/output/ChangeLog index a5e3cf49..5b0318f7 100644 --- a/src/output/ChangeLog +++ b/src/output/ChangeLog @@ -1,3 +1,22 @@ +2007-07-25 Ben Pfaff + + Make interactive output go to the terminal (bug #17213), by + causing the UI to flush output to the user when it prompts for a + command. + + * ascii.c (ascii_open_driver): Move the file open into + ascii_open_page, so that we can re-open after a flush. + (ascii_close_driver): Close file using ascii_flush. + (ascii_open_page): Open the output file if it's not already open. + Use fn_open so that we can support pipes. + (ascii_close_page): Do nothing if output file not open. + (ascii_flush): New function. + (static var ascii_class): Add ascii_flush. + + * manager.c (som_flush): New function. + + * output.c (outp_flush): New function. + Tue Feb 20 07:03:48 2007 Ben Pfaff * html.c: Don't need to include "getlogin_r.h" anymore, because diff --git a/src/output/ascii.c b/src/output/ascii.c index 8ed4f918..f1d5a9be 100644 --- a/src/output/ascii.c +++ b/src/output/ascii.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + 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 @@ -115,6 +115,7 @@ struct ascii_driver_ext int line_cap; /* Number of lines allocated. */ }; +static void ascii_flush (struct outp_driver *); static int get_default_box_char (size_t idx); static bool handle_option (struct outp_driver *this, const char *key, const struct string *val); @@ -152,13 +153,6 @@ ascii_open_driver (struct outp_driver *this, struct substring options) if (!outp_parse_options (options, handle_option, this)) goto error; - x->file = pool_fopen (x->pool, x->file_name, "w"); - if (x->file == NULL) - { - error (0, errno, _("ascii: opening output file \"%s\""), x->file_name); - goto error; - } - this->length = x->page_length - x->top_margin - x->bottom_margin - 1; if (x->headers) this->length -= 3; @@ -226,8 +220,7 @@ ascii_close_driver (struct outp_driver *this) { struct ascii_driver_ext *x = this->ext; - if (fn_close (x->file_name, x->file) != 0) - error (0, errno, _("ascii: closing output file \"%s\""), x->file_name); + ascii_flush (this); pool_detach_file (x->pool, x->file); pool_destroy (x->pool); @@ -410,6 +403,18 @@ ascii_open_page (struct outp_driver *this) struct ascii_driver_ext *x = this->ext; int i; + if (x->file == NULL) + { + x->file = fn_open (x->file_name, "w"); + if (x->file == NULL) + { + error (0, errno, _("ascii: opening output file \"%s\""), + x->file_name); + return; + } + pool_attach_file (x->pool, x->file); + } + x->page_number++; if (this->length > x->line_cap) @@ -670,6 +675,9 @@ ascii_close_page (struct outp_driver *this) struct string out; int line_num; + if (x->file == NULL) + return; + ds_init_empty (&out); ds_put_char_multiple (&out, '\n', x->top_margin); @@ -718,6 +726,25 @@ ascii_close_page (struct outp_driver *this) ds_destroy (&out); } +/* Flushes all output to the user and lets the user deal with it. + This is applied only to output drivers that are designated as + "screen" drivers that the user is interacting with in real + time. */ +static void +ascii_flush (struct outp_driver *this) +{ + struct ascii_driver_ext *x = this->ext; + + if (x->file != NULL) + { + if (fn_close (x->file_name, x->file) != 0) + error (0, errno, _("ascii: closing output file \"%s\""), + x->file_name); + pool_detach_file (x->pool, x->file); + x->file = NULL; + } +} + static void ascii_chart_initialise (struct outp_driver *d UNUSED, struct chart *ch) { @@ -741,6 +768,7 @@ const struct outp_class ascii_class = ascii_open_page, ascii_close_page, + ascii_flush, NULL, diff --git a/src/output/html.c b/src/output/html.c index e07edec8..b938333f 100644 --- a/src/output/html.c +++ b/src/output/html.c @@ -405,6 +405,7 @@ const struct outp_class html_class = html_open_driver, html_close_driver, + NULL, NULL, NULL, diff --git a/src/output/manager.c b/src/output/manager.c index 2d16416a..0b2fdfe1 100644 --- a/src/output/manager.c +++ b/src/output/manager.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + 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 @@ -47,6 +47,16 @@ som_eject_page (void) outp_eject_page (d); } +/* Flushes output on all active devices. */ +void +som_flush (void) +{ + struct outp_driver *d; + + for (d = outp_drivers (NULL); d; d = outp_drivers (d)) + outp_flush (d); +} + /* Skip down a single line on all active devices. */ void som_blank_line (void) diff --git a/src/output/manager.h b/src/output/manager.h index ce658311..58d0c12d 100644 --- a/src/output/manager.h +++ b/src/output/manager.h @@ -114,5 +114,6 @@ void som_submit (struct som_entity *t); /* Miscellaneous. */ void som_eject_page (void); void som_blank_line (void); +void som_flush (void); #endif /* som_h */ diff --git a/src/output/output.c b/src/output/output.c index dea3e4ad..243e7cd3 100644 --- a/src/output/output.c +++ b/src/output/output.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + 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 @@ -150,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) { @@ -701,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; @@ -1143,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 diff --git a/src/output/output.h b/src/output/output.h index 32ad6cef..7215cb6c 100644 --- a/src/output/output.h +++ b/src/output/output.h @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + 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 @@ -73,6 +73,8 @@ struct outp_class void (*open_page) (struct outp_driver *); void (*close_page) (struct outp_driver *); + void (*flush) (struct outp_driver *); + /* special != 0 only. */ void (*submit) (struct outp_driver *, struct som_entity *); @@ -155,6 +157,7 @@ bool outp_get_paper_size (char *, int *h, int *v); void outp_open_page (struct outp_driver *); void outp_close_page (struct outp_driver *); void outp_eject_page (struct outp_driver *); +void outp_flush (struct outp_driver *); int outp_string_width (struct outp_driver *, const char *, enum outp_font); diff --git a/src/output/postscript.c b/src/output/postscript.c index 6046b0fd..f49970c5 100644 --- a/src/output/postscript.c +++ b/src/output/postscript.c @@ -1433,6 +1433,7 @@ const struct outp_class postscript_class = ps_open_page, ps_close_page, + NULL, ps_submit, diff --git a/src/ui/terminal/ChangeLog b/src/ui/terminal/ChangeLog index 10d7d365..a98b9244 100644 --- a/src/ui/terminal/ChangeLog +++ b/src/ui/terminal/ChangeLog @@ -1,3 +1,15 @@ +2007-07-25 Ben Pfaff + + Make interactive output go to the terminal (bug #17213), by + causing the UI to flush output to the user when it prompts for a + command. + + * command-line.c (parse_command_line): Configure interactive + output devices if appropriate. + + * read-line.c (readln_read): Flush output if this is a prompt for + the first line of a command. + 2007-06-06 Ben Pfaff Adapt case sources, sinks, and clients of procedure code to the diff --git a/src/ui/terminal/command-line.c b/src/ui/terminal/command-line.c index 9eb23d53..e152f700 100644 --- a/src/ui/terminal/command-line.c +++ b/src/ui/terminal/command-line.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + 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 @@ -42,12 +42,8 @@ #define _(msgid) gettext (msgid) #define N_(msgid) msgid -void welcome (void); static void usage (void); -char *subst_vars (char *); - - /* Parses the command line specified by ARGC and ARGV as received by main(). Returns true if normal execution should proceed, false if the command-line indicates that PSPP should exit. */ @@ -209,7 +205,11 @@ parse_command_line (int argc, char **argv, struct source_stream *ss) } if (!syntax_files || interactive_mode) - getl_append_source (ss, create_readln_source () ); + { + getl_append_source (ss, create_readln_source () ); + if (!cleared_device_defaults) + outp_configure_add ("interactive"); + } return true; } diff --git a/src/ui/terminal/read-line.c b/src/ui/terminal/read-line.c index e3618326..c6279ce9 100644 --- a/src/ui/terminal/read-line.c +++ b/src/ui/terminal/read-line.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-9, 2000 Free Software Foundation, Inc. + 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 @@ -32,6 +32,7 @@ #include #include #include +#include #include "xalloc.h" @@ -148,6 +149,9 @@ readln_read (struct string *line, enum prompt_style style) welcome (); + if (style == PROMPT_FIRST) + som_flush (); + #if HAVE_READLINE rl_attempted_completion_function = (style == PROMPT_FIRST ? complete_command_name -- 2.30.2