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)
124 if (0 == tcgetattr (0, &t))
126 cc_t c = t.c_cc[VINTR];
128 if (c >= 0 && c <= 'Z' - 'A')
129 fprintf (rl_outstream, "^%c", 'A' + c - 1);
131 fprintf (rl_outstream, "%c", c);
134 fprintf (rl_outstream, "^C");
136 fflush (rl_outstream);
142 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
143 enum prompt_style prompt_style)
145 struct terminal_reader *r = terminal_reader_cast (r_);
148 if (r->offset >= r->s.length && !r->eof)
151 msg_ui_reset_counts ();
155 if (! readline_read (&r->s, prompt_style))
158 fprintf (rl_outstream, "\n");
162 r->eof = ss_is_empty (r->s);
164 /* Check whether the size of the window has changed, so that
165 the output drivers can adjust their settings as needed. We
166 only do this for the first line of a command, as it's
167 possible that the output drivers are actually in use
168 afterward, and we don't want to confuse them in the middle
170 if (prompt_style == PROMPT_FIRST)
171 terminal_check_size ();
174 chunk = MIN (n, r->s.length - r->offset);
175 memcpy (buf, r->s.string + r->offset, chunk);
181 terminal_reader_close (struct lex_reader *r_)
183 struct terminal_reader *r = terminal_reader_cast (r_);
186 free (r->reader.file_name);
189 if (!--n_terminal_readers)
193 static struct lex_reader_class terminal_reader_class =
195 terminal_reader_read,
196 terminal_reader_close
199 /* Creates a source which uses readln to get its line */
201 terminal_reader_create (void)
203 struct terminal_reader *r;
205 if (!n_terminal_readers++)
208 r = xzalloc (sizeof *r);
209 r->reader.class = &terminal_reader_class;
210 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
211 r->reader.error = LEX_ERROR_TERMINAL;
212 r->reader.file_name = NULL;
222 readline_prompt (enum prompt_style style)
238 case PROMPT_DOCUMENT:
241 case PROMPT_DO_REPEAT:
242 return "DO REPEAT> ";
251 static bool sigint_received ;
258 write (pfd[1], "x", 1);
259 rl_echo_signal_char (sig);
264 A function similar to getc from stdio.
265 However this one may be interrupted by SIGINT.
266 If that happens it will return EOF and the global variable
267 sigint_received will be set to true.
270 interruptible_getc (FILE *fp)
276 struct timeval timeout = {0, 50000};
282 max_fd = (max_fd > fd) ? max_fd : fd;
285 max_fd = (max_fd > fd) ? max_fd : fd;
287 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
288 if ( ret == -1 && errno != EINTR)
290 perror ("Select failed");
296 if (FD_ISSET (pfd[0], &what))
299 read (pfd[0], dummy, 1);
300 sigint_received = true;
307 /* This will not block! */
308 read (fileno (fp), &c, 1);
320 if ( 0 != pipe2 (pfd, O_NONBLOCK))
321 perror ("Cannot create pipe");
323 if ( SIG_ERR == signal (SIGINT, handler))
324 perror ("Cannot add signal handler");
326 rl_catch_signals = 0;
327 rl_getc_function = interruptible_getc;
328 rl_basic_word_break_characters = "\n";
330 stifle_history (500);
331 if (history_file == NULL)
333 const char *home_dir = getenv ("HOME");
334 if (home_dir != NULL)
336 history_file = xasprintf ("%s/.pspp_history", home_dir);
337 read_history (history_file);
345 if (history_file != NULL && false == settings_get_testing_mode () )
346 write_history (history_file);
351 /* Prompt the user for a line of input and return it in LINE.
352 Returns true if the LINE should be considered valid, false otherwise.
355 readline_read (struct substring *line, enum prompt_style style)
359 rl_attempted_completion_function = (style == PROMPT_FIRST
360 ? complete_command_name
362 sigint_received = false;
363 string = readline (readline_prompt (style));
375 add_history (string);
377 end = strchr (string, '\0');
379 *line = ss_buffer (string, end - string + 1);
387 /* Returns a set of command name completions for TEXT.
388 This is of the proper form for assigning to
389 rl_attempted_completion_function. */
391 complete_command_name (const char *text, int start, int end UNUSED)
395 /* Complete command name at start of line. */
396 return rl_completion_matches (text, command_generator);
400 /* Otherwise don't do any completion. */
401 rl_attempted_completion_over = 1;
406 /* Do not do any completion for TEXT. */
408 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
410 rl_attempted_completion_over = 1;
414 /* If STATE is 0, returns the first command name matching TEXT.
415 Otherwise, returns the next command name matching TEXT.
416 Returns a null pointer when no matches are left. */
418 command_generator (const char *text, int state)
420 static const struct command *cmd;
425 name = cmd_complete (text, &cmd);
426 return name ? xstrdup (name) : NULL;
429 #else /* !HAVE_READLINE */
442 readline_read (struct substring *line, enum prompt_style style)
444 struct string string;
445 const char *prompt = readline_prompt (style);
447 fputs (prompt, stdout);
449 ds_init_empty (&string);
450 ds_read_line (&string, stdin, SIZE_MAX);
456 #endif /* !HAVE_READLINE */