1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2007, 2009, 2010, 2011 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/>. */
19 #include "ui/terminal/terminal-reader.h"
27 #include "data/file-name.h"
28 #include "data/settings.h"
29 #include "language/command.h"
30 #include "language/lexer/lexer.h"
31 #include "libpspp/assertion.h"
32 #include "libpspp/cast.h"
33 #include "libpspp/message.h"
34 #include "libpspp/prompt.h"
35 #include "libpspp/str.h"
36 #include "libpspp/version.h"
37 #include "output/driver.h"
38 #include "output/journal.h"
39 #include "ui/terminal/terminal.h"
41 #include "gl/minmax.h"
42 #include "gl/xalloc.h"
45 #define _(msgid) gettext (msgid)
47 struct terminal_reader
49 struct lex_reader reader;
55 static int n_terminal_readers;
57 static void readline_init (void);
58 static void readline_done (void);
59 static struct substring readline_read (enum prompt_style);
61 /* Display a welcoming message. */
65 static bool welcomed = false;
69 fputs ("PSPP is free software and you are welcome to distribute copies of "
70 "it\nunder certain conditions; type \"show copying.\" to see the "
71 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
72 "warranty.\" for details.\n", stdout);
77 static struct terminal_reader *
78 terminal_reader_cast (struct lex_reader *r)
80 return UP_CAST (r, struct terminal_reader, reader);
84 terminal_reader_read (struct lex_reader *r_, char *buf, size_t n,
85 enum prompt_style prompt_style)
87 struct terminal_reader *r = terminal_reader_cast (r_);
90 if (r->offset >= r->s.length && !r->eof)
93 msg_ui_reset_counts ();
97 r->s = readline_read (prompt_style);
99 r->eof = ss_is_empty (r->s);
101 /* Check whether the size of the window has changed, so that
102 the output drivers can adjust their settings as needed. We
103 only do this for the first line of a command, as it's
104 possible that the output drivers are actually in use
105 afterward, and we don't want to confuse them in the middle
107 if (prompt_style == PROMPT_FIRST)
108 terminal_check_size ();
111 chunk = MIN (n, r->s.length - r->offset);
112 memcpy (buf, r->s.string + r->offset, chunk);
118 terminal_reader_close (struct lex_reader *r_)
120 struct terminal_reader *r = terminal_reader_cast (r_);
123 free (r->reader.file_name);
126 if (!--n_terminal_readers)
130 static struct lex_reader_class terminal_reader_class =
132 terminal_reader_read,
133 terminal_reader_close
136 /* Creates a source which uses readln to get its line */
138 terminal_reader_create (void)
140 struct terminal_reader *r;
142 if (!n_terminal_readers++)
145 r = xzalloc (sizeof *r);
146 r->reader.class = &terminal_reader_class;
147 r->reader.syntax = LEX_SYNTAX_INTERACTIVE;
148 r->reader.error = LEX_ERROR_INTERACTIVE;
149 r->reader.file_name = NULL;
159 readline_prompt (enum prompt_style style)
175 case PROMPT_DOCUMENT:
178 case PROMPT_DO_REPEAT:
179 return "DO REPEAT> ";
187 #include <readline/readline.h>
188 #include <readline/history.h>
190 static char *history_file;
192 static char **complete_command_name (const char *, int, int);
193 static char **dont_complete (const char *, int, int);
194 static char *command_generator (const char *text, int state);
199 rl_basic_word_break_characters = "\n";
201 stifle_history (500);
202 if (history_file == NULL)
204 const char *home_dir = getenv ("HOME");
205 if (home_dir != NULL)
207 history_file = xasprintf ("%s/.pspp_history", home_dir);
208 read_history (history_file);
216 if (history_file != NULL && false == settings_get_testing_mode () )
217 write_history (history_file);
222 static struct substring
223 readline_read (enum prompt_style style)
227 rl_attempted_completion_function = (style == PROMPT_FIRST
228 ? complete_command_name
230 string = readline (readline_prompt (style));
236 add_history (string);
238 end = strchr (string, '\0');
240 return ss_buffer (string, end - string + 1);
246 /* Returns a set of command name completions for TEXT.
247 This is of the proper form for assigning to
248 rl_attempted_completion_function. */
250 complete_command_name (const char *text, int start, int end UNUSED)
254 /* Complete command name at start of line. */
255 return rl_completion_matches (text, command_generator);
259 /* Otherwise don't do any completion. */
260 rl_attempted_completion_over = 1;
265 /* Do not do any completion for TEXT. */
267 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
269 rl_attempted_completion_over = 1;
273 /* If STATE is 0, returns the first command name matching TEXT.
274 Otherwise, returns the next command name matching TEXT.
275 Returns a null pointer when no matches are left. */
277 command_generator (const char *text, int state)
279 static const struct command *cmd;
284 name = cmd_complete (text, &cmd);
285 return name ? xstrdup (name) : NULL;
287 #else /* !HAVE_READLINE */
298 static struct substring
299 readline_read (enum prompt_style style)
301 const char *prompt = readline_prompt (style);
304 fputs (prompt, stdout);
306 ds_init_empty (&line);
307 ds_read_line (&line, stdin, SIZE_MAX);
311 #endif /* !HAVE_READLINE */