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 ;
261 A function similar to getc from stdio.
262 However this one may be interrupted by SIGINT.
263 If that happens it will return EOF and the global variable
264 sigint_received will be set to true.
267 interruptible_getc (FILE *fp)
273 struct timeval timeout = {0, 50000};
279 max_fd = (max_fd > fd) ? max_fd : fd;
282 max_fd = (max_fd > fd) ? max_fd : fd;
284 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
285 if ( ret == -1 && errno != EINTR)
287 perror ("Select failed");
293 if (FD_ISSET (pfd[0], &what))
296 read (pfd[0], dummy, 1);
297 sigint_received = true;
304 /* This will not block! */
305 read (fileno (fp), &c, 1);
319 write (pfd[1], "x", 1);
320 rl_echo_signal_char (sig);
327 if ( 0 != pipe2 (pfd, O_NONBLOCK))
328 perror ("Cannot create pipe");
330 if ( SIG_ERR == signal (SIGINT, handler))
331 perror ("Cannot add signal handler");
333 rl_catch_signals = 0;
334 rl_getc_function = interruptible_getc;
335 rl_basic_word_break_characters = "\n";
337 stifle_history (500);
338 if (history_file == NULL)
340 const char *home_dir = getenv ("HOME");
341 if (home_dir != NULL)
343 history_file = xasprintf ("%s/.pspp_history", home_dir);
344 read_history (history_file);
352 if (history_file != NULL && false == settings_get_testing_mode () )
353 write_history (history_file);
358 /* Prompt the user for a line of input and return it in LINE.
359 Returns true if the LINE should be considered valid, false otherwise.
362 readline_read (struct substring *line, enum prompt_style style)
366 rl_attempted_completion_function = (style == PROMPT_FIRST
367 ? complete_command_name
369 sigint_received = false;
370 string = readline (readline_prompt (style));
382 add_history (string);
384 end = strchr (string, '\0');
386 *line = ss_buffer (string, end - string + 1);
394 /* Returns a set of command name completions for TEXT.
395 This is of the proper form for assigning to
396 rl_attempted_completion_function. */
398 complete_command_name (const char *text, int start, int end UNUSED)
402 /* Complete command name at start of line. */
403 return rl_completion_matches (text, command_generator);
407 /* Otherwise don't do any completion. */
408 rl_attempted_completion_over = 1;
413 /* Do not do any completion for TEXT. */
415 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
417 rl_attempted_completion_over = 1;
421 /* If STATE is 0, returns the first command name matching TEXT.
422 Otherwise, returns the next command name matching TEXT.
423 Returns a null pointer when no matches are left. */
425 command_generator (const char *text, int state)
427 static const struct command *cmd;
432 name = cmd_complete (text, &cmd);
433 return name ? xstrdup (name) : NULL;
436 #else /* !HAVE_READLINE */
449 readline_read (struct substring *line, enum prompt_style style)
451 struct string string;
452 const char *prompt = readline_prompt (style);
454 fputs (prompt, stdout);
456 ds_init_empty (&string);
457 ds_read_line (&string, stdin, SIZE_MAX);
463 #endif /* !HAVE_READLINE */