1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2007, 2009, 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/read-line.h"
29 #include "data/file-name.h"
30 #include "data/settings.h"
31 #include "language/command.h"
32 #include "language/prompt.h"
33 #include "libpspp/cast.h"
34 #include "libpspp/message.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/msg-ui.h"
40 #include "ui/terminal/terminal.h"
42 #include "gl/xalloc.h"
45 #define _(msgid) gettext (msgid)
48 #include <readline/readline.h>
49 #include <readline/history.h>
51 static char *history_file;
53 static char **complete_command_name (const char *, int, int);
54 static char **dont_complete (const char *, int, int);
55 #endif /* HAVE_READLINE */
60 struct getl_interface parent ;
62 bool (*interactive_func) (struct string *line,
67 static bool initialised = false;
69 /* Initialize getl. */
71 readln_initialize (void)
76 rl_basic_word_break_characters = "\n";
79 if (history_file == NULL)
81 const char *home_dir = getenv ("HOME");
84 history_file = xasprintf ("%s/.pspp_history", home_dir);
85 read_history (history_file);
93 readln_uninitialize (void)
98 if (history_file != NULL && false == settings_get_testing_mode () )
99 write_history (history_file);
107 read_interactive (struct getl_interface *s,
110 struct readln_source *is = UP_CAST (s, struct readln_source, parent);
112 return is->interactive_func (line, prompt_get_style ());
116 always_true (const struct getl_interface *s UNUSED)
121 /* Display a welcoming message. */
125 static bool welcomed = false;
129 fputs ("PSPP is free software and you are welcome to distribute copies of "
130 "it\nunder certain conditions; type \"show copying.\" to see the "
131 "conditions.\nThere is ABSOLUTELY NO WARRANTY for PSPP; type \"show "
132 "warranty.\" for details.\n", stdout);
134 readln_initialize ();
138 /* Gets a line from the user and stores it into LINE.
139 Prompts the user with PROMPT.
140 Returns true if successful, false at end of file.
143 readln_read (struct string *line, enum prompt_style style)
145 const char *prompt = prompt_get (style);
151 assert (initialised);
153 msg_ui_reset_counts ();
160 rl_attempted_completion_function = (style == PROMPT_FIRST
161 ? complete_command_name
163 string = readline (prompt);
169 add_history (string);
170 ds_assign_cstr (line, string);
175 fputs (prompt, stdout);
177 if (ds_read_line (line, stdin, SIZE_MAX))
179 ds_chomp (line, '\n');
186 /* Check whether the size of the window has changed, so that
187 the output drivers can adjust their settings as needed. We
188 only do this for the first line of a command, as it's
189 possible that the output drivers are actually in use
190 afterward, and we don't want to confuse them in the middle
192 if (style == PROMPT_FIRST)
193 terminal_check_size ();
199 readln_close (struct getl_interface *i)
204 /* Creates a source which uses readln to get its line */
205 struct getl_interface *
206 create_readln_source (void)
208 struct readln_source *rlns = xzalloc (sizeof (*rlns));
210 rlns->interactive_func = readln_read;
212 rlns->parent.interactive = always_true;
213 rlns->parent.read = read_interactive;
214 rlns->parent.close = readln_close;
216 return &rlns->parent;
221 static char *command_generator (const char *text, int state);
223 /* Returns a set of command name completions for TEXT.
224 This is of the proper form for assigning to
225 rl_attempted_completion_function. */
227 complete_command_name (const char *text, int start, int end UNUSED)
231 /* Complete command name at start of line. */
232 return rl_completion_matches (text, command_generator);
236 /* Otherwise don't do any completion. */
237 rl_attempted_completion_over = 1;
242 /* Do not do any completion for TEXT. */
244 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
246 rl_attempted_completion_over = 1;
250 /* If STATE is 0, returns the first command name matching TEXT.
251 Otherwise, returns the next command name matching TEXT.
252 Returns a null pointer when no matches are left. */
254 command_generator (const char *text, int state)
256 static const struct command *cmd;
261 name = cmd_complete (text, &cmd);
262 return name ? xstrdup (name) : NULL;
264 #endif /* HAVE_READLINE */