1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011, 2013 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
27 #include <readline/readline.h>
28 #include <readline/history.h>
31 static char *history_file;
33 static char **complete_command_name (const char *, int, int);
34 static char **dont_complete (const char *, int, int);
35 static char *command_generator (const char *text, int state);
37 static const bool have_readline = true;
40 static const bool have_readline = false;
45 #include "ui/terminal/terminal-reader.h"
46 #include <sys/select.h>
48 #include <sys/types.h>
55 #include "data/settings.h"
56 #include "language/command.h"
57 #include "language/lexer/lexer.h"
58 #include "libpspp/assertion.h"
59 #include "libpspp/cast.h"
60 #include "libpspp/message.h"
61 #include "libpspp/prompt.h"
62 #include "libpspp/str.h"
63 #include "libpspp/version.h"
64 #include "output/driver.h"
65 #include "output/journal.h"
66 #include "ui/terminal/terminal.h"
68 #include "gl/minmax.h"
69 #include "gl/xalloc.h"
72 #define _(msgid) gettext (msgid)
74 struct terminal_reader
76 struct lex_reader reader;
82 static int n_terminal_readers;
84 static void readline_init (void);
85 static void readline_done (void);
86 static bool readline_read (struct substring *, enum prompt_style);
88 /* Display a welcoming message. */
92 static bool welcomed = false;
96 fputs ("PSPP is free software and you are welcome to distribute copies of "
97 "it\nunder certain conditions; type \"show copying.\" to see the "
98 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
99 "warranty.\" for details.\n", stdout);
104 static struct terminal_reader *
105 terminal_reader_cast (struct lex_reader *r)
107 return UP_CAST (r, struct terminal_reader, reader);
111 /* Older libreadline versions do not provide rl_outstream.
112 However, it is almost always going to be the same as stdout. */
113 #if ! HAVE_RL_OUTSTREAM
114 # define rl_outstream stdout
119 /* Similarly, rl_echo_signal_char is fairly recent.
120 We provide our own crude version if it is not present. */
121 #if ! HAVE_RL_ECHO_SIGNAL_CHAR
123 rl_echo_signal_char (int sig)
127 if (0 == tcgetattr (0, &t))
129 cc_t c = t.c_cc[VINTR];
131 if (c >= 0 && c <= 'Z' - 'A')
132 fprintf (rl_outstream, "^%c", 'A' + c - 1);
134 fprintf (rl_outstream, "%c", c);
138 fprintf (rl_outstream, "^C");
140 fflush (rl_outstream);
147 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
148 enum prompt_style prompt_style)
150 struct terminal_reader *r = terminal_reader_cast (r_);
153 if (r->offset >= r->s.length && !r->eof)
156 msg_ui_reset_counts ();
160 if (! readline_read (&r->s, prompt_style))
163 fprintf (rl_outstream, "\n");
167 r->eof = ss_is_empty (r->s);
169 /* Check whether the size of the window has changed, so that
170 the output drivers can adjust their settings as needed. We
171 only do this for the first line of a command, as it's
172 possible that the output drivers are actually in use
173 afterward, and we don't want to confuse them in the middle
175 if (prompt_style == PROMPT_FIRST)
176 terminal_check_size ();
179 chunk = MIN (n, r->s.length - r->offset);
180 memcpy (buf, r->s.string + r->offset, chunk);
186 terminal_reader_close (struct lex_reader *r_)
188 struct terminal_reader *r = terminal_reader_cast (r_);
191 free (r->reader.file_name);
194 if (!--n_terminal_readers)
198 static struct lex_reader_class terminal_reader_class =
200 terminal_reader_read,
201 terminal_reader_close
204 /* Creates a source which uses readln to get its line */
206 terminal_reader_create (void)
208 struct terminal_reader *r;
210 if (!n_terminal_readers++)
213 r = xzalloc (sizeof *r);
214 r->reader.class = &terminal_reader_class;
215 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
216 r->reader.error = LEX_ERROR_TERMINAL;
217 r->reader.file_name = NULL;
227 readline_prompt (enum prompt_style style)
243 case PROMPT_DOCUMENT:
246 case PROMPT_DO_REPEAT:
247 return "DO REPEAT> ";
256 static bool sigint_received ;
260 A function similar to getc from stdio.
261 However this one may be interrupted by SIGINT.
262 If that happens it will return EOF and the global variable
263 sigint_received will be set to true.
266 interruptible_getc (FILE *fp)
272 struct timeval timeout = {0, 50000};
278 max_fd = (max_fd > fd) ? max_fd : fd;
281 max_fd = (max_fd > fd) ? max_fd : fd;
283 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
284 if ( ret == -1 && errno != EINTR)
286 perror ("Select failed");
292 if (FD_ISSET (pfd[0], &what))
295 read (pfd[0], dummy, 1);
296 sigint_received = true;
303 /* This will not block! */
304 read (fileno (fp), &c, 1);
318 write (pfd[1], "x", 1);
319 rl_echo_signal_char (sig);
326 if ( 0 != pipe2 (pfd, O_NONBLOCK))
327 perror ("Cannot create pipe");
329 if ( SIG_ERR == signal (SIGINT, handler))
330 perror ("Cannot add signal handler");
332 rl_catch_signals = 0;
333 rl_getc_function = interruptible_getc;
334 rl_basic_word_break_characters = "\n";
336 stifle_history (500);
337 if (history_file == NULL)
339 const char *home_dir = getenv ("HOME");
340 if (home_dir != NULL)
342 history_file = xasprintf ("%s/.pspp_history", home_dir);
343 read_history (history_file);
351 if (history_file != NULL && false == settings_get_testing_mode () )
352 write_history (history_file);
357 /* Prompt the user for a line of input and return it in LINE.
358 Returns true if the LINE should be considered valid, false otherwise.
361 readline_read (struct substring *line, enum prompt_style style)
365 rl_attempted_completion_function = (style == PROMPT_FIRST
366 ? complete_command_name
368 sigint_received = false;
369 string = readline (readline_prompt (style));
381 add_history (string);
383 end = strchr (string, '\0');
385 *line = ss_buffer (string, end - string + 1);
393 /* Returns a set of command name completions for TEXT.
394 This is of the proper form for assigning to
395 rl_attempted_completion_function. */
397 complete_command_name (const char *text, int start, int end UNUSED)
401 /* Complete command name at start of line. */
402 return rl_completion_matches (text, command_generator);
406 /* Otherwise don't do any completion. */
407 rl_attempted_completion_over = 1;
412 /* Do not do any completion for TEXT. */
414 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
416 rl_attempted_completion_over = 1;
420 /* If STATE is 0, returns the first command name matching TEXT.
421 Otherwise, returns the next command name matching TEXT.
422 Returns a null pointer when no matches are left. */
424 command_generator (const char *text, int state)
426 static const struct command *cmd;
431 name = cmd_complete (text, &cmd);
432 return name ? xstrdup (name) : NULL;
435 #else /* !HAVE_READLINE */
448 readline_read (struct substring *line, enum prompt_style style)
450 struct string string;
451 const char *prompt = readline_prompt (style);
453 fputs (prompt, stdout);
455 ds_init_empty (&string);
456 ds_read_line (&string, stdin, SIZE_MAX);
462 #endif /* !HAVE_READLINE */