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/>. */
25 #include "libpspp/str.h"
28 #include <readline/readline.h>
29 #include <readline/history.h>
32 static char *history_file;
34 static char **complete_command_name (const char *, int, int);
35 static char **dont_complete (const char *, int, int);
36 static char *command_generator (const char *text, int state);
40 #include "ui/terminal/terminal-reader.h"
41 #include <sys/select.h>
43 #include <sys/types.h>
49 #include "data/settings.h"
50 #include "language/command.h"
51 #include "language/lexer/lexer.h"
52 #include "libpspp/assertion.h"
53 #include "libpspp/cast.h"
54 #include "libpspp/message.h"
55 #include "libpspp/prompt.h"
56 #include "libpspp/str.h"
57 #include "libpspp/version.h"
58 #include "output/driver.h"
59 #include "output/journal.h"
61 #include "gl/minmax.h"
62 #include "gl/xalloc.h"
65 #define _(msgid) gettext (msgid)
67 struct terminal_reader
69 struct lex_reader reader;
75 static int n_terminal_readers;
77 static void readline_init (void);
78 static void readline_done (void);
79 static bool readline_read (struct substring *, enum prompt_style);
81 /* Display a welcoming message. */
85 static bool welcomed = false;
89 fputs ("PSPP is free software and you are welcome to distribute copies of "
90 "it\nunder certain conditions; type \"show copying.\" to see the "
91 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
92 "warranty.\" for details.\n", stdout);
93 puts (announced_version);
97 static struct terminal_reader *
98 terminal_reader_cast (struct lex_reader *r)
100 return UP_CAST (r, struct terminal_reader, reader);
104 /* Older libreadline versions do not provide rl_outstream.
105 However, it is almost always going to be the same as stdout. */
106 #if ! HAVE_RL_OUTSTREAM
107 # define rl_outstream stdout
112 /* Similarly, rl_echo_signal_char is fairly recent.
113 We provide our own crude version if it is not present. */
114 #if ! HAVE_RL_ECHO_SIGNAL_CHAR
116 rl_echo_signal_char (int sig)
120 if (0 == tcgetattr (0, &t))
122 cc_t c = t.c_cc[VINTR];
124 if (c >= 0 && c <= 'Z' - 'A')
125 fprintf (rl_outstream, "^%c", 'A' + c - 1);
127 fprintf (rl_outstream, "%c", c);
131 fprintf (rl_outstream, "^C");
133 fflush (rl_outstream);
140 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
141 enum prompt_style prompt_style)
143 struct terminal_reader *r = terminal_reader_cast (r_);
146 if (r->offset >= r->s.length && !r->eof)
149 msg_ui_reset_counts ();
153 if (! readline_read (&r->s, prompt_style))
156 fprintf (rl_outstream, "\n");
160 r->eof = ss_is_empty (r->s);
163 chunk = MIN (n, r->s.length - r->offset);
164 memcpy (buf, r->s.string + r->offset, chunk);
170 terminal_reader_close (struct lex_reader *r_)
172 struct terminal_reader *r = terminal_reader_cast (r_);
175 free (r->reader.file_name);
178 if (!--n_terminal_readers)
182 static struct lex_reader_class terminal_reader_class =
184 terminal_reader_read,
185 terminal_reader_close
188 /* Creates a source which uses readln to get its line */
190 terminal_reader_create (void)
192 if (!n_terminal_readers++)
195 struct terminal_reader *r = XZALLOC (struct terminal_reader);
196 r->reader.class = &terminal_reader_class;
197 r->reader.syntax = SEG_MODE_INTERACTIVE;
198 r->reader.error = LEX_ERROR_TERMINAL;
199 r->reader.file_name = NULL;
209 readline_prompt (enum prompt_style style)
225 case PROMPT_DOCUMENT:
228 case PROMPT_DO_REPEAT:
229 return "DO REPEAT> ";
242 static bool sigint_received ;
245 A function similar to getc from stdio.
246 However this one may be interrupted by SIGINT.
247 If that happens it will return EOF and the global variable
248 sigint_received will be set to true.
251 interruptible_getc (FILE *fp)
257 struct timeval timeout = {0, 50000};
263 max_fd = (max_fd > fd) ? max_fd : fd;
266 max_fd = (max_fd > fd) ? max_fd : fd;
268 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
269 if (ret == -1 && errno != EINTR)
271 perror ("Select failed");
277 if (FD_ISSET (pfd[0], &what))
280 read (pfd[0], dummy, 1);
281 sigint_received = true;
288 /* This will not block! */
289 read (fileno (fp), &c, 1);
299 write (pfd[1], "x", 1);
300 rl_echo_signal_char (sig);
307 if (0 != pipe2 (pfd, O_NONBLOCK))
308 perror ("Cannot create pipe");
310 if (SIG_ERR == signal (SIGINT, handler))
311 perror ("Cannot add signal handler");
313 rl_catch_signals = 0;
314 rl_getc_function = interruptible_getc;
315 rl_basic_word_break_characters = "\n";
317 stifle_history (500);
318 if (history_file == NULL)
320 const char *home_dir = getenv ("HOME");
321 if (home_dir != NULL)
323 history_file = xasprintf ("%s/.pspp_history", home_dir);
324 read_history (history_file);
332 if (history_file != NULL && false == settings_get_testing_mode ())
333 write_history (history_file);
338 /* Prompt the user for a line of input and return it in LINE.
339 Returns true if the LINE should be considered valid, false otherwise.
342 readline_read (struct substring *line, enum prompt_style style)
346 rl_attempted_completion_function = (style == PROMPT_FIRST
347 ? complete_command_name
349 sigint_received = false;
350 string = readline (readline_prompt (style));
362 add_history (string);
364 end = strchr (string, '\0');
366 *line = ss_buffer (string, end - string + 1);
374 /* Returns a set of command name completions for TEXT.
375 This is of the proper form for assigning to
376 rl_attempted_completion_function. */
378 complete_command_name (const char *text, int start, int end UNUSED)
382 /* Complete command name at start of line. */
383 return rl_completion_matches (text, command_generator);
387 /* Otherwise don't do any completion. */
388 rl_attempted_completion_over = 1;
393 /* Do not do any completion for TEXT. */
395 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
397 rl_attempted_completion_over = 1;
401 /* If STATE is 0, returns the first command name matching TEXT.
402 Otherwise, returns the next command name matching TEXT.
403 Returns a null pointer when no matches are left. */
405 command_generator (const char *text, int state)
407 static const struct command *cmd;
412 name = cmd_complete (text, &cmd);
413 return xstrdup_if_nonnull (name);
416 #else /* !HAVE_READLINE */
418 static const char * the_prompt;
424 fputs (the_prompt, stdout);
431 if (SIG_ERR == signal (SIGINT, handler))
432 perror ("Cannot add signal handler");
440 /* Prompt the user for a line of input and return it in LINE.
441 Returns true if the LINE should be considered valid, false otherwise.
444 readline_read (struct substring *line, enum prompt_style style)
446 struct string string;
447 the_prompt = readline_prompt (style);
449 fputs (the_prompt, stdout);
451 ds_init_empty (&string);
452 ds_read_line (&string, stdin, SIZE_MAX);
458 #endif /* !HAVE_READLINE */