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 struct terminal_reader *r;
194 if (!n_terminal_readers++)
197 r = xzalloc (sizeof *r);
198 r->reader.class = &terminal_reader_class;
199 r->reader.syntax = SEG_MODE_INTERACTIVE;
200 r->reader.error = LEX_ERROR_TERMINAL;
201 r->reader.file_name = NULL;
211 readline_prompt (enum prompt_style style)
227 case PROMPT_DOCUMENT:
230 case PROMPT_DO_REPEAT:
231 return "DO REPEAT> ";
244 static bool sigint_received ;
247 A function similar to getc from stdio.
248 However this one may be interrupted by SIGINT.
249 If that happens it will return EOF and the global variable
250 sigint_received will be set to true.
253 interruptible_getc (FILE *fp)
259 struct timeval timeout = {0, 50000};
265 max_fd = (max_fd > fd) ? max_fd : fd;
268 max_fd = (max_fd > fd) ? max_fd : fd;
270 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
271 if (ret == -1 && errno != EINTR)
273 perror ("Select failed");
279 if (FD_ISSET (pfd[0], &what))
282 read (pfd[0], dummy, 1);
283 sigint_received = true;
290 /* This will not block! */
291 read (fileno (fp), &c, 1);
301 write (pfd[1], "x", 1);
302 rl_echo_signal_char (sig);
309 if (0 != pipe2 (pfd, O_NONBLOCK))
310 perror ("Cannot create pipe");
312 if (SIG_ERR == signal (SIGINT, handler))
313 perror ("Cannot add signal handler");
315 rl_catch_signals = 0;
316 rl_getc_function = interruptible_getc;
317 rl_basic_word_break_characters = "\n";
319 stifle_history (500);
320 if (history_file == NULL)
322 const char *home_dir = getenv ("HOME");
323 if (home_dir != NULL)
325 history_file = xasprintf ("%s/.pspp_history", home_dir);
326 read_history (history_file);
334 if (history_file != NULL && false == settings_get_testing_mode ())
335 write_history (history_file);
340 /* Prompt the user for a line of input and return it in LINE.
341 Returns true if the LINE should be considered valid, false otherwise.
344 readline_read (struct substring *line, enum prompt_style style)
348 rl_attempted_completion_function = (style == PROMPT_FIRST
349 ? complete_command_name
351 sigint_received = false;
352 string = readline (readline_prompt (style));
364 add_history (string);
366 end = strchr (string, '\0');
368 *line = ss_buffer (string, end - string + 1);
376 /* Returns a set of command name completions for TEXT.
377 This is of the proper form for assigning to
378 rl_attempted_completion_function. */
380 complete_command_name (const char *text, int start, int end UNUSED)
384 /* Complete command name at start of line. */
385 return rl_completion_matches (text, command_generator);
389 /* Otherwise don't do any completion. */
390 rl_attempted_completion_over = 1;
395 /* Do not do any completion for TEXT. */
397 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
399 rl_attempted_completion_over = 1;
403 /* If STATE is 0, returns the first command name matching TEXT.
404 Otherwise, returns the next command name matching TEXT.
405 Returns a null pointer when no matches are left. */
407 command_generator (const char *text, int state)
409 static const struct command *cmd;
414 name = cmd_complete (text, &cmd);
415 return xstrdup_if_nonnull (name);
418 #else /* !HAVE_READLINE */
420 static const char * the_prompt;
426 fputs (the_prompt, stdout);
433 if (SIG_ERR == signal (SIGINT, handler))
434 perror ("Cannot add signal handler");
442 /* Prompt the user for a line of input and return it in LINE.
443 Returns true if the LINE should be considered valid, false otherwise.
446 readline_read (struct substring *line, enum prompt_style style)
448 struct string string;
449 the_prompt = readline_prompt (style);
451 fputs (the_prompt, stdout);
453 ds_init_empty (&string);
454 ds_read_line (&string, stdin, SIZE_MAX);
460 #endif /* !HAVE_READLINE */