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/file-name.h"
56 #include "data/settings.h"
57 #include "language/command.h"
58 #include "language/lexer/lexer.h"
59 #include "libpspp/assertion.h"
60 #include "libpspp/cast.h"
61 #include "libpspp/message.h"
62 #include "libpspp/prompt.h"
63 #include "libpspp/str.h"
64 #include "libpspp/version.h"
65 #include "output/driver.h"
66 #include "output/journal.h"
67 #include "ui/terminal/terminal.h"
69 #include "gl/minmax.h"
70 #include "gl/xalloc.h"
73 #define _(msgid) gettext (msgid)
75 struct terminal_reader
77 struct lex_reader reader;
83 static int n_terminal_readers;
85 static void readline_init (void);
86 static void readline_done (void);
87 static bool readline_read (struct substring *, enum prompt_style);
89 /* Display a welcoming message. */
93 static bool welcomed = false;
97 fputs ("PSPP is free software and you are welcome to distribute copies of "
98 "it\nunder certain conditions; type \"show copying.\" to see the "
99 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
100 "warranty.\" for details.\n", stdout);
105 static struct terminal_reader *
106 terminal_reader_cast (struct lex_reader *r)
108 return UP_CAST (r, struct terminal_reader, reader);
112 /* Older libreadline versions do not provide rl_outstream.
113 However, it is almost always going to be the same as stdout. */
114 #if ! HAVE_RL_OUTSTREAM
115 # define rl_outstream stdout
120 /* Similarly, rl_echo_signal_char is fairly recent.
121 We provide our own crude version if it is not present. */
122 #if ! HAVE_RL_ECHO_SIGNAL_CHAR
124 rl_echo_signal_char (int sig)
128 if (0 == tcgetattr (0, &t))
130 cc_t c = t.c_cc[VINTR];
132 if (c >= 0 && c <= 'Z' - 'A')
133 fprintf (rl_outstream, "^%c", 'A' + c - 1);
135 fprintf (rl_outstream, "%c", c);
139 fprintf (rl_outstream, "^C");
141 fflush (rl_outstream);
148 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
149 enum prompt_style prompt_style)
151 struct terminal_reader *r = terminal_reader_cast (r_);
154 if (r->offset >= r->s.length && !r->eof)
157 msg_ui_reset_counts ();
161 if (! readline_read (&r->s, prompt_style))
164 fprintf (rl_outstream, "\n");
168 r->eof = ss_is_empty (r->s);
170 /* Check whether the size of the window has changed, so that
171 the output drivers can adjust their settings as needed. We
172 only do this for the first line of a command, as it's
173 possible that the output drivers are actually in use
174 afterward, and we don't want to confuse them in the middle
176 if (prompt_style == PROMPT_FIRST)
177 terminal_check_size ();
180 chunk = MIN (n, r->s.length - r->offset);
181 memcpy (buf, r->s.string + r->offset, chunk);
187 terminal_reader_close (struct lex_reader *r_)
189 struct terminal_reader *r = terminal_reader_cast (r_);
192 free (r->reader.file_name);
195 if (!--n_terminal_readers)
199 static struct lex_reader_class terminal_reader_class =
201 terminal_reader_read,
202 terminal_reader_close
205 /* Creates a source which uses readln to get its line */
207 terminal_reader_create (void)
209 struct terminal_reader *r;
211 if (!n_terminal_readers++)
214 r = xzalloc (sizeof *r);
215 r->reader.class = &terminal_reader_class;
216 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
217 r->reader.error = LEX_ERROR_TERMINAL;
218 r->reader.file_name = NULL;
228 readline_prompt (enum prompt_style style)
244 case PROMPT_DOCUMENT:
247 case PROMPT_DO_REPEAT:
248 return "DO REPEAT> ";
257 static bool sigint_received ;
264 write (pfd[1], "x", 1);
265 rl_echo_signal_char (sig);
270 A function similar to getc from stdio.
271 However this one may be interrupted by SIGINT.
272 If that happens it will return EOF and the global variable
273 sigint_received will be set to true.
276 interruptible_getc (FILE *fp)
282 struct timeval timeout = {0, 50000};
288 max_fd = (max_fd > fd) ? max_fd : fd;
291 max_fd = (max_fd > fd) ? max_fd : fd;
293 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
294 if ( ret == -1 && errno != EINTR)
296 perror ("Select failed");
302 if (FD_ISSET (pfd[0], &what))
305 read (pfd[0], dummy, 1);
306 sigint_received = true;
313 /* This will not block! */
314 read (fileno (fp), &c, 1);
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 */