X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fterminal%2Fterminal-reader.c;h=3225678e8707b28a0dba95064d93fae4abf6b6f0;hb=af8622f11c920a03269ad489617d86bfd568b287;hp=2f11279bf428af8b24a63902ef71f1db8bf83328;hpb=e2da62d735c597afeef2e0e9b36e5a4a83d7da94;p=pspp diff --git a/src/ui/terminal/terminal-reader.c b/src/ui/terminal/terminal-reader.c index 2f11279bf4..3225678e87 100644 --- a/src/ui/terminal/terminal-reader.c +++ b/src/ui/terminal/terminal-reader.c @@ -22,6 +22,7 @@ #include #include +#include "libpspp/str.h" #if HAVE_READLINE #include @@ -33,12 +34,6 @@ static char *history_file; static char **complete_command_name (const char *, int, int); static char **dont_complete (const char *, int, int); static char *command_generator (const char *text, int state); - -static const bool have_readline = true; - -#else -static const bool have_readline = false; -static int rl_end; #endif @@ -47,12 +42,10 @@ static int rl_end; #include #include -#include #include #include #include -#include "data/file-name.h" #include "data/settings.h" #include "language/command.h" #include "language/lexer/lexer.h" @@ -64,7 +57,6 @@ static int rl_end; #include "libpspp/version.h" #include "output/driver.h" #include "output/journal.h" -#include "ui/terminal/terminal.h" #include "gl/minmax.h" #include "gl/xalloc.h" @@ -98,8 +90,8 @@ welcome (void) "it\nunder certain conditions; type \"show copying.\" to see the " "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show " "warranty.\" for details.\n", stdout); - puts (stat_version); - journal_enable (); + puts (announced_version); + journal_init (); } static struct terminal_reader * @@ -108,12 +100,15 @@ terminal_reader_cast (struct lex_reader *r) return UP_CAST (r, struct terminal_reader, reader); } + /* Older libreadline versions do not provide rl_outstream. However, it is almost always going to be the same as stdout. */ #if ! HAVE_RL_OUTSTREAM # define rl_outstream stdout #endif + +#if HAVE_READLINE /* Similarly, rl_echo_signal_char is fairly recent. We provide our own crude version if it is not present. */ #if ! HAVE_RL_ECHO_SIGNAL_CHAR @@ -125,7 +120,7 @@ rl_echo_signal_char (int sig) if (0 == tcgetattr (0, &t)) { cc_t c = t.c_cc[VINTR]; - + if (c >= 0 && c <= 'Z' - 'A') fprintf (rl_outstream, "^%c", 'A' + c - 1); else @@ -136,7 +131,8 @@ rl_echo_signal_char (int sig) fprintf (rl_outstream, "^C"); fflush (rl_outstream); -} +} +#endif #endif @@ -162,15 +158,6 @@ terminal_reader_read (struct lex_reader *r_, char *buf, size_t n, } r->offset = 0; r->eof = ss_is_empty (r->s); - - /* Check whether the size of the window has changed, so that - the output drivers can adjust their settings as needed. We - only do this for the first line of a command, as it's - possible that the output drivers are actually in use - afterward, and we don't want to confuse them in the middle - of output. */ - if (prompt_style == PROMPT_FIRST) - terminal_check_size (); } chunk = MIN (n, r->s.length - r->offset); @@ -202,14 +189,12 @@ static struct lex_reader_class terminal_reader_class = struct lex_reader * terminal_reader_create (void) { - struct terminal_reader *r; - if (!n_terminal_readers++) readline_init (); - r = xzalloc (sizeof *r); + struct terminal_reader *r = XZALLOC (struct terminal_reader); r->reader.class = &terminal_reader_class; - r->reader.syntax = LEX_SYNTAX_INTERACTIVE; + r->reader.syntax = SEG_MODE_INTERACTIVE; r->reader.error = LEX_ERROR_TERMINAL; r->reader.file_name = NULL; r->s = ss_empty (); @@ -242,27 +227,21 @@ readline_prompt (enum prompt_style style) case PROMPT_DO_REPEAT: return "DO REPEAT> "; + + case PROMPT_DEFINE: + return "DEFINE> "; } NOT_REACHED (); } +#if HAVE_READLINE static int pfd[2]; static bool sigint_received ; -static void -handler (int sig) -{ - rl_end = 0; - - write (pfd[1], "x", 1); - rl_echo_signal_char (sig); -} - - -/* +/* A function similar to getc from stdio. However this one may be interrupted by SIGINT. If that happens it will return EOF and the global variable @@ -287,13 +266,13 @@ interruptible_getc (FILE *fp) max_fd = (max_fd > fd) ? max_fd : fd; FD_SET (fd, &what); ret = select (max_fd + 1, &what, NULL, NULL, &timeout); - if ( ret == -1 && errno != EINTR) + if (ret == -1 && errno != EINTR) { perror ("Select failed"); continue; } - if (ret > 0 ) + if (ret > 0) { if (FD_ISSET (pfd[0], &what)) { @@ -312,17 +291,23 @@ interruptible_getc (FILE *fp) return c; } +static void +handler (int sig) +{ + rl_end = 0; + write (pfd[1], "x", 1); + rl_echo_signal_char (sig); +} -#if HAVE_READLINE static void readline_init (void) { - if ( 0 != pipe2 (pfd, O_NONBLOCK)) + if (0 != pipe2 (pfd, O_NONBLOCK)) perror ("Cannot create pipe"); - if ( SIG_ERR == signal (SIGINT, handler)) + if (SIG_ERR == signal (SIGINT, handler)) perror ("Cannot add signal handler"); rl_catch_signals = 0; @@ -344,13 +329,13 @@ readline_init (void) static void readline_done (void) { - if (history_file != NULL && false == settings_get_testing_mode () ) + if (history_file != NULL && false == settings_get_testing_mode ()) write_history (history_file); clear_history (); free (history_file); } -/* Prompt the user for a line of input and return it in LINE. +/* Prompt the user for a line of input and return it in LINE. Returns true if the LINE should be considered valid, false otherwise. */ static bool @@ -425,14 +410,26 @@ command_generator (const char *text, int state) if (state == 0) cmd = NULL; name = cmd_complete (text, &cmd); - return name ? xstrdup (name) : NULL; + return xstrdup_if_nonnull (name); } #else /* !HAVE_READLINE */ +static const char * the_prompt; + +static void +handler (int sig) +{ + if (the_prompt) + fputs (the_prompt, stdout); + fflush (stdout); +} + static void readline_init (void) { + if (SIG_ERR == signal (SIGINT, handler)) + perror ("Cannot add signal handler"); } static void @@ -440,19 +437,22 @@ readline_done (void) { } +/* Prompt the user for a line of input and return it in LINE. + Returns true if the LINE should be considered valid, false otherwise. + */ static bool readline_read (struct substring *line, enum prompt_style style) { struct string string; - const char *prompt = readline_prompt (style); + the_prompt = readline_prompt (style); - fputs (prompt, stdout); + fputs (the_prompt, stdout); fflush (stdout); ds_init_empty (&string); ds_read_line (&string, stdin, SIZE_MAX); - + *line = string.ss; - - return false; + + return true; } #endif /* !HAVE_READLINE */