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);
39 #include "ui/terminal/terminal-reader.h"
40 #include <sys/select.h>
42 #include <sys/types.h>
48 #include "data/settings.h"
49 #include "language/command.h"
50 #include "language/lexer/lexer.h"
51 #include "libpspp/assertion.h"
52 #include "libpspp/cast.h"
53 #include "libpspp/message.h"
54 #include "libpspp/prompt.h"
55 #include "libpspp/str.h"
56 #include "libpspp/version.h"
57 #include "output/driver.h"
58 #include "output/journal.h"
60 #include "gl/minmax.h"
61 #include "gl/xalloc.h"
64 #define _(msgid) gettext (msgid)
66 struct terminal_reader
68 struct lex_reader reader;
74 static int n_terminal_readers;
76 static void readline_init (void);
77 static void readline_done (void);
78 static bool readline_read (struct substring *, enum prompt_style);
80 /* Display a welcoming message. */
84 static bool welcomed = false;
88 fputs ("PSPP is free software and you are welcome to distribute copies of "
89 "it\nunder certain conditions; type \"show copying.\" to see the "
90 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
91 "warranty.\" for details.\n", stdout);
92 puts (announced_version);
96 static struct terminal_reader *
97 terminal_reader_cast (struct lex_reader *r)
99 return UP_CAST (r, struct terminal_reader, reader);
103 /* Older libreadline versions do not provide rl_outstream.
104 However, it is almost always going to be the same as stdout. */
105 #if ! HAVE_RL_OUTSTREAM
106 # define rl_outstream stdout
111 /* Similarly, rl_echo_signal_char is fairly recent.
112 We provide our own crude version if it is not present. */
113 #if ! HAVE_RL_ECHO_SIGNAL_CHAR
115 rl_echo_signal_char (int sig)
119 if (0 == tcgetattr (0, &t))
121 cc_t c = t.c_cc[VINTR];
123 if (c >= 0 && c <= 'Z' - 'A')
124 fprintf (rl_outstream, "^%c", 'A' + c - 1);
126 fprintf (rl_outstream, "%c", c);
130 fprintf (rl_outstream, "^C");
132 fflush (rl_outstream);
139 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
140 enum prompt_style prompt_style)
142 struct terminal_reader *r = terminal_reader_cast (r_);
145 if (r->offset >= r->s.length && !r->eof)
148 msg_ui_reset_counts ();
152 if (! readline_read (&r->s, prompt_style))
155 fprintf (rl_outstream, "\n");
159 r->eof = ss_is_empty (r->s);
162 chunk = MIN (n, r->s.length - r->offset);
163 memcpy (buf, r->s.string + r->offset, chunk);
169 terminal_reader_close (struct lex_reader *r_)
171 struct terminal_reader *r = terminal_reader_cast (r_);
174 free (r->reader.file_name);
177 if (!--n_terminal_readers)
181 static struct lex_reader_class terminal_reader_class =
183 terminal_reader_read,
184 terminal_reader_close
187 /* Creates a source which uses readln to get its line */
189 terminal_reader_create (void)
191 struct terminal_reader *r;
193 if (!n_terminal_readers++)
196 r = xzalloc (sizeof *r);
197 r->reader.class = &terminal_reader_class;
198 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
199 r->reader.error = LEX_ERROR_TERMINAL;
200 r->reader.file_name = NULL;
210 readline_prompt (enum prompt_style style)
226 case PROMPT_DOCUMENT:
229 case PROMPT_DO_REPEAT:
230 return "DO REPEAT> ";
240 static bool sigint_received ;
243 A function similar to getc from stdio.
244 However this one may be interrupted by SIGINT.
245 If that happens it will return EOF and the global variable
246 sigint_received will be set to true.
249 interruptible_getc (FILE *fp)
255 struct timeval timeout = {0, 50000};
261 max_fd = (max_fd > fd) ? max_fd : fd;
264 max_fd = (max_fd > fd) ? max_fd : fd;
266 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
267 if (ret == -1 && errno != EINTR)
269 perror ("Select failed");
275 if (FD_ISSET (pfd[0], &what))
278 read (pfd[0], dummy, 1);
279 sigint_received = true;
286 /* This will not block! */
287 read (fileno (fp), &c, 1);
297 write (pfd[1], "x", 1);
298 rl_echo_signal_char (sig);
305 if (0 != pipe2 (pfd, O_NONBLOCK))
306 perror ("Cannot create pipe");
308 if (SIG_ERR == signal (SIGINT, handler))
309 perror ("Cannot add signal handler");
311 rl_catch_signals = 0;
312 rl_getc_function = interruptible_getc;
313 rl_basic_word_break_characters = "\n";
315 stifle_history (500);
316 if (history_file == NULL)
318 const char *home_dir = getenv ("HOME");
319 if (home_dir != NULL)
321 history_file = xasprintf ("%s/.pspp_history", home_dir);
322 read_history (history_file);
330 if (history_file != NULL && false == settings_get_testing_mode ())
331 write_history (history_file);
336 /* Prompt the user for a line of input and return it in LINE.
337 Returns true if the LINE should be considered valid, false otherwise.
340 readline_read (struct substring *line, enum prompt_style style)
344 rl_attempted_completion_function = (style == PROMPT_FIRST
345 ? complete_command_name
347 sigint_received = false;
348 string = readline (readline_prompt (style));
360 add_history (string);
362 end = strchr (string, '\0');
364 *line = ss_buffer (string, end - string + 1);
372 /* Returns a set of command name completions for TEXT.
373 This is of the proper form for assigning to
374 rl_attempted_completion_function. */
376 complete_command_name (const char *text, int start, int end UNUSED)
380 /* Complete command name at start of line. */
381 return rl_completion_matches (text, command_generator);
385 /* Otherwise don't do any completion. */
386 rl_attempted_completion_over = 1;
391 /* Do not do any completion for TEXT. */
393 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
395 rl_attempted_completion_over = 1;
399 /* If STATE is 0, returns the first command name matching TEXT.
400 Otherwise, returns the next command name matching TEXT.
401 Returns a null pointer when no matches are left. */
403 command_generator (const char *text, int state)
405 static const struct command *cmd;
410 name = cmd_complete (text, &cmd);
411 return name ? xstrdup (name) : NULL;
414 #else /* !HAVE_READLINE */
427 readline_read (struct substring *line, enum prompt_style style)
429 struct string string;
430 const char *prompt = readline_prompt (style);
432 fputs (prompt, stdout);
434 ds_init_empty (&string);
435 ds_read_line (&string, stdin, SIZE_MAX);
441 #endif /* !HAVE_READLINE */