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;
44 #include "ui/terminal/terminal-reader.h"
45 #include <sys/select.h>
47 #include <sys/types.h>
54 #include "data/settings.h"
55 #include "language/command.h"
56 #include "language/lexer/lexer.h"
57 #include "libpspp/assertion.h"
58 #include "libpspp/cast.h"
59 #include "libpspp/message.h"
60 #include "libpspp/prompt.h"
61 #include "libpspp/str.h"
62 #include "libpspp/version.h"
63 #include "output/driver.h"
64 #include "output/journal.h"
65 #include "ui/terminal/terminal.h"
67 #include "gl/minmax.h"
68 #include "gl/xalloc.h"
71 #define _(msgid) gettext (msgid)
73 struct terminal_reader
75 struct lex_reader reader;
81 static int n_terminal_readers;
83 static void readline_init (void);
84 static void readline_done (void);
85 static bool readline_read (struct substring *, enum prompt_style);
87 /* Display a welcoming message. */
91 static bool welcomed = false;
95 fputs ("PSPP is free software and you are welcome to distribute copies of "
96 "it\nunder certain conditions; type \"show copying.\" to see the "
97 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
98 "warranty.\" for details.\n", stdout);
99 puts (announced_version);
103 static struct terminal_reader *
104 terminal_reader_cast (struct lex_reader *r)
106 return UP_CAST (r, struct terminal_reader, reader);
110 /* Older libreadline versions do not provide rl_outstream.
111 However, it is almost always going to be the same as stdout. */
112 #if ! HAVE_RL_OUTSTREAM
113 # define rl_outstream stdout
118 /* Similarly, rl_echo_signal_char is fairly recent.
119 We provide our own crude version if it is not present. */
120 #if ! HAVE_RL_ECHO_SIGNAL_CHAR
122 rl_echo_signal_char (int sig)
126 if (0 == tcgetattr (0, &t))
128 cc_t c = t.c_cc[VINTR];
130 if (c >= 0 && c <= 'Z' - 'A')
131 fprintf (rl_outstream, "^%c", 'A' + c - 1);
133 fprintf (rl_outstream, "%c", c);
137 fprintf (rl_outstream, "^C");
139 fflush (rl_outstream);
146 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
147 enum prompt_style prompt_style)
149 struct terminal_reader *r = terminal_reader_cast (r_);
152 if (r->offset >= r->s.length && !r->eof)
155 msg_ui_reset_counts ();
159 if (! readline_read (&r->s, prompt_style))
162 fprintf (rl_outstream, "\n");
166 r->eof = ss_is_empty (r->s);
168 /* Check whether the size of the window has changed, so that
169 the output drivers can adjust their settings as needed. We
170 only do this for the first line of a command, as it's
171 possible that the output drivers are actually in use
172 afterward, and we don't want to confuse them in the middle
174 if (prompt_style == PROMPT_FIRST)
175 terminal_check_size ();
178 chunk = MIN (n, r->s.length - r->offset);
179 memcpy (buf, r->s.string + r->offset, chunk);
185 terminal_reader_close (struct lex_reader *r_)
187 struct terminal_reader *r = terminal_reader_cast (r_);
190 free (r->reader.file_name);
193 if (!--n_terminal_readers)
197 static struct lex_reader_class terminal_reader_class =
199 terminal_reader_read,
200 terminal_reader_close
203 /* Creates a source which uses readln to get its line */
205 terminal_reader_create (void)
207 struct terminal_reader *r;
209 if (!n_terminal_readers++)
212 r = xzalloc (sizeof *r);
213 r->reader.class = &terminal_reader_class;
214 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
215 r->reader.error = LEX_ERROR_TERMINAL;
216 r->reader.file_name = NULL;
226 readline_prompt (enum prompt_style style)
242 case PROMPT_DOCUMENT:
245 case PROMPT_DO_REPEAT:
246 return "DO REPEAT> ";
256 static bool sigint_received ;
259 A function similar to getc from stdio.
260 However this one may be interrupted by SIGINT.
261 If that happens it will return EOF and the global variable
262 sigint_received will be set to true.
265 interruptible_getc (FILE *fp)
271 struct timeval timeout = {0, 50000};
277 max_fd = (max_fd > fd) ? max_fd : fd;
280 max_fd = (max_fd > fd) ? max_fd : fd;
282 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
283 if ( ret == -1 && errno != EINTR)
285 perror ("Select failed");
291 if (FD_ISSET (pfd[0], &what))
294 read (pfd[0], dummy, 1);
295 sigint_received = true;
302 /* This will not block! */
303 read (fileno (fp), &c, 1);
313 write (pfd[1], "x", 1);
314 rl_echo_signal_char (sig);
321 if ( 0 != pipe2 (pfd, O_NONBLOCK))
322 perror ("Cannot create pipe");
324 if ( SIG_ERR == signal (SIGINT, handler))
325 perror ("Cannot add signal handler");
327 rl_catch_signals = 0;
328 rl_getc_function = interruptible_getc;
329 rl_basic_word_break_characters = "\n";
331 stifle_history (500);
332 if (history_file == NULL)
334 const char *home_dir = getenv ("HOME");
335 if (home_dir != NULL)
337 history_file = xasprintf ("%s/.pspp_history", home_dir);
338 read_history (history_file);
346 if (history_file != NULL && false == settings_get_testing_mode () )
347 write_history (history_file);
352 /* Prompt the user for a line of input and return it in LINE.
353 Returns true if the LINE should be considered valid, false otherwise.
356 readline_read (struct substring *line, enum prompt_style style)
360 rl_attempted_completion_function = (style == PROMPT_FIRST
361 ? complete_command_name
363 sigint_received = false;
364 string = readline (readline_prompt (style));
376 add_history (string);
378 end = strchr (string, '\0');
380 *line = ss_buffer (string, end - string + 1);
388 /* Returns a set of command name completions for TEXT.
389 This is of the proper form for assigning to
390 rl_attempted_completion_function. */
392 complete_command_name (const char *text, int start, int end UNUSED)
396 /* Complete command name at start of line. */
397 return rl_completion_matches (text, command_generator);
401 /* Otherwise don't do any completion. */
402 rl_attempted_completion_over = 1;
407 /* Do not do any completion for TEXT. */
409 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
411 rl_attempted_completion_over = 1;
415 /* If STATE is 0, returns the first command name matching TEXT.
416 Otherwise, returns the next command name matching TEXT.
417 Returns a null pointer when no matches are left. */
419 command_generator (const char *text, int state)
421 static const struct command *cmd;
426 name = cmd_complete (text, &cmd);
427 return name ? xstrdup (name) : NULL;
430 #else /* !HAVE_READLINE */
443 readline_read (struct substring *line, enum prompt_style style)
445 struct string string;
446 const char *prompt = readline_prompt (style);
448 fputs (prompt, stdout);
450 ds_init_empty (&string);
451 ds_read_line (&string, stdin, SIZE_MAX);
457 #endif /* !HAVE_READLINE */