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>
30 static char *history_file;
32 static char **complete_command_name (const char *, int, int);
33 static char **dont_complete (const char *, int, int);
34 static char *command_generator (const char *text, int state);
36 static const bool have_readline = true;
39 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/file-name.h"
55 #include "data/settings.h"
56 #include "language/command.h"
57 #include "language/lexer/lexer.h"
58 #include "libpspp/assertion.h"
59 #include "libpspp/cast.h"
60 #include "libpspp/message.h"
61 #include "libpspp/prompt.h"
62 #include "libpspp/str.h"
63 #include "libpspp/version.h"
64 #include "output/driver.h"
65 #include "output/journal.h"
66 #include "ui/terminal/terminal.h"
68 #include "gl/minmax.h"
69 #include "gl/xalloc.h"
72 #define _(msgid) gettext (msgid)
74 struct terminal_reader
76 struct lex_reader reader;
82 static int n_terminal_readers;
84 static void readline_init (void);
85 static void readline_done (void);
86 static bool readline_read (struct substring *, enum prompt_style);
88 /* Display a welcoming message. */
92 static bool welcomed = false;
96 fputs ("PSPP is free software and you are welcome to distribute copies of "
97 "it\nunder certain conditions; type \"show copying.\" to see the "
98 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
99 "warranty.\" for details.\n", stdout);
104 static struct terminal_reader *
105 terminal_reader_cast (struct lex_reader *r)
107 return UP_CAST (r, struct terminal_reader, reader);
111 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
112 enum prompt_style prompt_style)
114 struct terminal_reader *r = terminal_reader_cast (r_);
117 if (r->offset >= r->s.length && !r->eof)
120 msg_ui_reset_counts ();
124 if (! readline_read (&r->s, prompt_style))
127 fprintf (rl_outstream, "\n");
131 r->eof = ss_is_empty (r->s);
133 /* Check whether the size of the window has changed, so that
134 the output drivers can adjust their settings as needed. We
135 only do this for the first line of a command, as it's
136 possible that the output drivers are actually in use
137 afterward, and we don't want to confuse them in the middle
139 if (prompt_style == PROMPT_FIRST)
140 terminal_check_size ();
143 chunk = MIN (n, r->s.length - r->offset);
144 memcpy (buf, r->s.string + r->offset, chunk);
150 terminal_reader_close (struct lex_reader *r_)
152 struct terminal_reader *r = terminal_reader_cast (r_);
155 free (r->reader.file_name);
158 if (!--n_terminal_readers)
162 static struct lex_reader_class terminal_reader_class =
164 terminal_reader_read,
165 terminal_reader_close
168 /* Creates a source which uses readln to get its line */
170 terminal_reader_create (void)
172 struct terminal_reader *r;
174 if (!n_terminal_readers++)
177 r = xzalloc (sizeof *r);
178 r->reader.class = &terminal_reader_class;
179 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
180 r->reader.error = LEX_ERROR_TERMINAL;
181 r->reader.file_name = NULL;
191 readline_prompt (enum prompt_style style)
207 case PROMPT_DOCUMENT:
210 case PROMPT_DO_REPEAT:
211 return "DO REPEAT> ";
220 static bool sigint_received ;
227 write (pfd[1], "x", 1);
228 rl_echo_signal_char (sig);
233 A function similar to getc from stdio.
234 However this one may be interrupted by SIGINT.
235 If that happens it will return EOF and the global variable
236 sigint_received will be set to true.
239 interruptible_getc (FILE *fp)
245 struct timeval timeout = {0, 50000};
251 max_fd = (max_fd > fd) ? max_fd : fd;
254 max_fd = (max_fd > fd) ? max_fd : fd;
256 ret = select (max_fd + 1, &what, NULL, NULL, &timeout);
257 if ( ret == -1 && errno != EINTR)
259 perror ("Select failed");
265 if (FD_ISSET (pfd[0], &what))
268 read (pfd[0], dummy, 1);
269 sigint_received = true;
276 /* This will not block! */
277 read (fileno (fp), &c, 1);
289 if ( 0 != pipe2 (pfd, O_NONBLOCK))
290 perror ("Cannot create pipe");
292 if ( SIG_ERR == signal (SIGINT, handler))
293 perror ("Cannot add signal handler");
295 rl_catch_signals = 0;
296 rl_getc_function = interruptible_getc;
297 rl_basic_word_break_characters = "\n";
299 stifle_history (500);
300 if (history_file == NULL)
302 const char *home_dir = getenv ("HOME");
303 if (home_dir != NULL)
305 history_file = xasprintf ("%s/.pspp_history", home_dir);
306 read_history (history_file);
314 if (history_file != NULL && false == settings_get_testing_mode () )
315 write_history (history_file);
320 /* Prompt the user for a line of input and return it in LINE.
321 Returns true if the LINE should be considered valid, false otherwise.
324 readline_read (struct substring *line, enum prompt_style style)
328 rl_attempted_completion_function = (style == PROMPT_FIRST
329 ? complete_command_name
331 sigint_received = false;
332 string = readline (readline_prompt (style));
344 add_history (string);
346 end = strchr (string, '\0');
348 *line = ss_buffer (string, end - string + 1);
356 /* Returns a set of command name completions for TEXT.
357 This is of the proper form for assigning to
358 rl_attempted_completion_function. */
360 complete_command_name (const char *text, int start, int end UNUSED)
364 /* Complete command name at start of line. */
365 return rl_completion_matches (text, command_generator);
369 /* Otherwise don't do any completion. */
370 rl_attempted_completion_over = 1;
375 /* Do not do any completion for TEXT. */
377 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
379 rl_attempted_completion_over = 1;
383 /* If STATE is 0, returns the first command name matching TEXT.
384 Otherwise, returns the next command name matching TEXT.
385 Returns a null pointer when no matches are left. */
387 command_generator (const char *text, int state)
389 static const struct command *cmd;
394 name = cmd_complete (text, &cmd);
395 return name ? xstrdup (name) : NULL;
398 #else /* !HAVE_READLINE */
411 readline_read (struct substring *line, enum prompt_style style)
413 struct string string;
414 const char *prompt = readline_prompt (style);
416 fputs (prompt, stdout);
418 ds_init_empty (&string);
419 ds_read_line (&string, stdin, SIZE_MAX);
425 #endif /* !HAVE_READLINE */