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>
30 static char *history_file;
32 static char **complete_command_name (const char *, int, int);
33 static char **dont_complete (const char *, int, int);
34 static char *command_generator (const char *text, int state);
36 static const bool have_readline = true;
39 static const bool have_readline = false;
44 #include "ui/terminal/terminal-reader.h"
45 #include <sys/select.h>
47 #include <sys/types.h>
54 #include "data/file-name.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.
114 #if HAVE_RL_OUTSTREAM
115 # define rl_outstream stdout
119 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
120 enum prompt_style prompt_style)
122 struct terminal_reader *r = terminal_reader_cast (r_);
125 if (r->offset >= r->s.length && !r->eof)
128 msg_ui_reset_counts ();
132 if (! readline_read (&r->s, prompt_style))
135 fprintf (rl_outstream, "\n");
139 r->eof = ss_is_empty (r->s);
141 /* Check whether the size of the window has changed, so that
142 the output drivers can adjust their settings as needed. We
143 only do this for the first line of a command, as it's
144 possible that the output drivers are actually in use
145 afterward, and we don't want to confuse them in the middle
147 if (prompt_style == PROMPT_FIRST)
148 terminal_check_size ();
151 chunk = MIN (n, r->s.length - r->offset);
152 memcpy (buf, r->s.string + r->offset, chunk);
158 terminal_reader_close (struct lex_reader *r_)
160 struct terminal_reader *r = terminal_reader_cast (r_);
163 free (r->reader.file_name);
166 if (!--n_terminal_readers)
170 static struct lex_reader_class terminal_reader_class =
172 terminal_reader_read,
173 terminal_reader_close
176 /* Creates a source which uses readln to get its line */
178 terminal_reader_create (void)
180 struct terminal_reader *r;
182 if (!n_terminal_readers++)
185 r = xzalloc (sizeof *r);
186 r->reader.class = &terminal_reader_class;
187 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
188 r->reader.error = LEX_ERROR_TERMINAL;
189 r->reader.file_name = NULL;
199 readline_prompt (enum prompt_style style)
215 case PROMPT_DOCUMENT:
218 case PROMPT_DO_REPEAT:
219 return "DO REPEAT> ";
228 static bool sigint_received ;
235 write (pfd[1], "x", 1);
236 rl_echo_signal_char (sig);
241 A function similar to getc from stdio.
242 However this one may be interrupted by SIGINT.
243 If that happens it will return EOF and the global variable
244 sigint_received will be set to true.
247 interruptible_getc (FILE *fp)
253 struct timeval timeout = {0, 50000};
259 max_fd = (max_fd > fd) ? max_fd : fd;
262 max_fd = (max_fd > fd) ? max_fd : fd;
264 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
265 if ( ret == -1 && errno != EINTR)
267 perror ("Select failed");
273 if (FD_ISSET (pfd[0], &what))
276 read (pfd[0], dummy, 1);
277 sigint_received = true;
284 /* This will not block! */
285 read (fileno (fp), &c, 1);
297 if ( 0 != pipe2 (pfd, O_NONBLOCK))
298 perror ("Cannot create pipe");
300 if ( SIG_ERR == signal (SIGINT, handler))
301 perror ("Cannot add signal handler");
303 rl_catch_signals = 0;
304 rl_getc_function = interruptible_getc;
305 rl_basic_word_break_characters = "\n";
307 stifle_history (500);
308 if (history_file == NULL)
310 const char *home_dir = getenv ("HOME");
311 if (home_dir != NULL)
313 history_file = xasprintf ("%s/.pspp_history", home_dir);
314 read_history (history_file);
322 if (history_file != NULL && false == settings_get_testing_mode () )
323 write_history (history_file);
328 /* Prompt the user for a line of input and return it in LINE.
329 Returns true if the LINE should be considered valid, false otherwise.
332 readline_read (struct substring *line, enum prompt_style style)
336 rl_attempted_completion_function = (style == PROMPT_FIRST
337 ? complete_command_name
339 sigint_received = false;
340 string = readline (readline_prompt (style));
352 add_history (string);
354 end = strchr (string, '\0');
356 *line = ss_buffer (string, end - string + 1);
364 /* Returns a set of command name completions for TEXT.
365 This is of the proper form for assigning to
366 rl_attempted_completion_function. */
368 complete_command_name (const char *text, int start, int end UNUSED)
372 /* Complete command name at start of line. */
373 return rl_completion_matches (text, command_generator);
377 /* Otherwise don't do any completion. */
378 rl_attempted_completion_over = 1;
383 /* Do not do any completion for TEXT. */
385 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
387 rl_attempted_completion_over = 1;
391 /* If STATE is 0, returns the first command name matching TEXT.
392 Otherwise, returns the next command name matching TEXT.
393 Returns a null pointer when no matches are left. */
395 command_generator (const char *text, int state)
397 static const struct command *cmd;
402 name = cmd_complete (text, &cmd);
403 return name ? xstrdup (name) : NULL;
406 #else /* !HAVE_READLINE */
419 readline_read (struct substring *line, enum prompt_style style)
421 struct string string;
422 const char *prompt = readline_prompt (style);
424 fputs (prompt, stdout);
426 ds_init_empty (&string);
427 ds_read_line (&string, stdin, SIZE_MAX);
433 #endif /* !HAVE_READLINE */