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);
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
117 /* Similarly, rl_echo_signal_char is fairly recent.
118 We provide our own crude version if it is not present. */
119 #if ! HAVE_RL_ECHO_SIGNAL_CHAR
121 rl_echo_signal_char (int sig)
125 if (0 == tcgetattr (0, &t))
127 cc_t c = t.c_cc[VINTR];
129 if (c >= 0 && c <= 'Z' - 'A')
130 fprintf (rl_outstream, "^%c", 'A' + c - 1);
132 fprintf (rl_outstream, "%c", c);
136 fprintf (rl_outstream, "^C");
138 fflush (rl_outstream);
144 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
145 enum prompt_style prompt_style)
147 struct terminal_reader *r = terminal_reader_cast (r_);
150 if (r->offset >= r->s.length && !r->eof)
153 msg_ui_reset_counts ();
157 if (! readline_read (&r->s, prompt_style))
160 fprintf (rl_outstream, "\n");
164 r->eof = ss_is_empty (r->s);
166 /* Check whether the size of the window has changed, so that
167 the output drivers can adjust their settings as needed. We
168 only do this for the first line of a command, as it's
169 possible that the output drivers are actually in use
170 afterward, and we don't want to confuse them in the middle
172 if (prompt_style == PROMPT_FIRST)
173 terminal_check_size ();
176 chunk = MIN (n, r->s.length - r->offset);
177 memcpy (buf, r->s.string + r->offset, chunk);
183 terminal_reader_close (struct lex_reader *r_)
185 struct terminal_reader *r = terminal_reader_cast (r_);
188 free (r->reader.file_name);
191 if (!--n_terminal_readers)
195 static struct lex_reader_class terminal_reader_class =
197 terminal_reader_read,
198 terminal_reader_close
201 /* Creates a source which uses readln to get its line */
203 terminal_reader_create (void)
205 struct terminal_reader *r;
207 if (!n_terminal_readers++)
210 r = xzalloc (sizeof *r);
211 r->reader.class = &terminal_reader_class;
212 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
213 r->reader.error = LEX_ERROR_TERMINAL;
214 r->reader.file_name = NULL;
224 readline_prompt (enum prompt_style style)
240 case PROMPT_DOCUMENT:
243 case PROMPT_DO_REPEAT:
244 return "DO REPEAT> ";
253 static bool sigint_received ;
260 write (pfd[1], "x", 1);
261 rl_echo_signal_char (sig);
266 A function similar to getc from stdio.
267 However this one may be interrupted by SIGINT.
268 If that happens it will return EOF and the global variable
269 sigint_received will be set to true.
272 interruptible_getc (FILE *fp)
278 struct timeval timeout = {0, 50000};
284 max_fd = (max_fd > fd) ? max_fd : fd;
287 max_fd = (max_fd > fd) ? max_fd : fd;
289 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
290 if ( ret == -1 && errno != EINTR)
292 perror ("Select failed");
298 if (FD_ISSET (pfd[0], &what))
301 read (pfd[0], dummy, 1);
302 sigint_received = true;
309 /* This will not block! */
310 read (fileno (fp), &c, 1);
322 if ( 0 != pipe2 (pfd, O_NONBLOCK))
323 perror ("Cannot create pipe");
325 if ( SIG_ERR == signal (SIGINT, handler))
326 perror ("Cannot add signal handler");
328 rl_catch_signals = 0;
329 rl_getc_function = interruptible_getc;
330 rl_basic_word_break_characters = "\n";
332 stifle_history (500);
333 if (history_file == NULL)
335 const char *home_dir = getenv ("HOME");
336 if (home_dir != NULL)
338 history_file = xasprintf ("%s/.pspp_history", home_dir);
339 read_history (history_file);
347 if (history_file != NULL && false == settings_get_testing_mode () )
348 write_history (history_file);
353 /* Prompt the user for a line of input and return it in LINE.
354 Returns true if the LINE should be considered valid, false otherwise.
357 readline_read (struct substring *line, enum prompt_style style)
361 rl_attempted_completion_function = (style == PROMPT_FIRST
362 ? complete_command_name
364 sigint_received = false;
365 string = readline (readline_prompt (style));
377 add_history (string);
379 end = strchr (string, '\0');
381 *line = ss_buffer (string, end - string + 1);
389 /* Returns a set of command name completions for TEXT.
390 This is of the proper form for assigning to
391 rl_attempted_completion_function. */
393 complete_command_name (const char *text, int start, int end UNUSED)
397 /* Complete command name at start of line. */
398 return rl_completion_matches (text, command_generator);
402 /* Otherwise don't do any completion. */
403 rl_attempted_completion_over = 1;
408 /* Do not do any completion for TEXT. */
410 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
412 rl_attempted_completion_over = 1;
416 /* If STATE is 0, returns the first command name matching TEXT.
417 Otherwise, returns the next command name matching TEXT.
418 Returns a null pointer when no matches are left. */
420 command_generator (const char *text, int state)
422 static const struct command *cmd;
427 name = cmd_complete (text, &cmd);
428 return name ? xstrdup (name) : NULL;
431 #else /* !HAVE_READLINE */
444 readline_read (struct substring *line, enum prompt_style style)
446 struct string string;
447 const char *prompt = readline_prompt (style);
449 fputs (prompt, stdout);
451 ds_init_empty (&string);
452 ds_read_line (&string, stdin, SIZE_MAX);
458 #endif /* !HAVE_READLINE */