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;
157 #include <readline/readline.h>
158 #include <readline/history.h>
160 static char *history_file;
162 static char **complete_command_name (const char *, int, int);
163 static char **dont_complete (const char *, int, int);
164 static char *command_generator (const char *text, int state);
169 rl_basic_word_break_characters = "\n";
171 stifle_history (500);
172 if (history_file == NULL)
174 const char *home_dir = getenv ("HOME");
175 if (home_dir != NULL)
177 history_file = xasprintf ("%s/.pspp_history", home_dir);
178 read_history (history_file);
186 if (history_file != NULL && false == settings_get_testing_mode () )
187 write_history (history_file);
193 readline_prompt (enum prompt_style style)
209 case PROMPT_DOCUMENT:
212 case PROMPT_DO_REPEAT:
213 return "DO REPEAT> ";
219 static struct substring
220 readline_read (enum prompt_style style)
224 rl_attempted_completion_function = (style == PROMPT_FIRST
225 ? complete_command_name
227 string = readline (readline_prompt (style));
233 add_history (string);
235 end = strchr (string, '\0');
237 return ss_buffer (string, end - string + 1);
243 /* Returns a set of command name completions for TEXT.
244 This is of the proper form for assigning to
245 rl_attempted_completion_function. */
247 complete_command_name (const char *text, int start, int end UNUSED)
251 /* Complete command name at start of line. */
252 return rl_completion_matches (text, command_generator);
256 /* Otherwise don't do any completion. */
257 rl_attempted_completion_over = 1;
262 /* Do not do any completion for TEXT. */
264 dont_complete (const char *text UNUSED, int start UNUSED, int end UNUSED)
266 rl_attempted_completion_over = 1;
270 /* If STATE is 0, returns the first command name matching TEXT.
271 Otherwise, returns the next command name matching TEXT.
272 Returns a null pointer when no matches are left. */
274 command_generator (const char *text, int state)
276 static const struct command *cmd;
281 name = cmd_complete (text, &cmd);
282 return name ? xstrdup (name) : NULL;
284 #else /* !HAVE_READLINE */
295 static struct substring
296 readline_read (enum prompt_style style)
298 const char *prompt = prompt_get (style);
301 fputs (prompt, stdout);
303 ds_init_empty (&line);
304 ds_read_line (&line, stdin, SIZE_MAX);
308 #endif /* !HAVE_READLINE */