Commit 31c149ce 31c149ce587fd7ee7d7af90bc25bc143cc720741 by Sergey Poznyakoff

readline-related functions.

1 parent 293e836d
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
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 2, or (at your option)
7 any later version.
8
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.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #include "mail.h"
19
20 static char **ml_command_completion __P((char *cmd, int start, int end));
21 static char *ml_command_generator __P((char *text, int state));
22
23 static int _interrupt;
24
25 static RETSIGTYPE
26 sig_int(int signo)
27 {
28 if (util_find_env("quit")->set)
29 exit (0);
30 _interrupt++;
31 signal (signo, sig_int);
32 }
33
34 void
35 ml_clear_interrupt()
36 {
37 _interrupt = 0;
38 }
39
40 int
41 ml_got_interrupt()
42 {
43 int rc = _interrupt;
44 _interrupt = 0;
45 return rc;
46 }
47
48 #ifdef WITH_READLINE
49 int
50 ml_getc (FILE *stream)
51 {
52 unsigned char c;
53
54 if (read (fileno (stream), &c, 1) == 1)
55 return c;
56 return EOF;
57 }
58 #endif
59
60 void
61 ml_readline_init ()
62 {
63 if (!interactive)
64 return;
65
66 #ifdef WITH_READLINE
67 rl_readline_name = "mail";
68 rl_attempted_completion_function = (CPPFunction*)ml_command_completion;
69 rl_getc_function = ml_getc;
70 #endif
71 signal(SIGINT, sig_int);
72 }
73
74 #ifdef WITH_READLINE
75
76 static char *insert_text;
77
78 static int
79 ml_insert_hook()
80 {
81 if (insert_text)
82 rl_insert_text(insert_text);
83 return 0;
84 }
85
86 int
87 ml_reread(char *prompt, char **text)
88 {
89 char *s;
90
91 insert_text = *text;
92 rl_startup_hook = ml_insert_hook;
93 s = readline(prompt);
94 if (*text)
95 free(*text);
96 *text = s;
97 rl_startup_hook = NULL;
98 return 0;
99 }
100
101 /*
102 * readline tab completion
103 */
104 char **
105 ml_command_completion (char *cmd, int start, int end)
106 {
107 if (start == 0)
108 return completion_matches (cmd, ml_command_generator);
109 return NULL;
110 }
111
112 /*
113 * more readline
114 */
115 char *
116 ml_command_generator (char *text, int state)
117 {
118 static int i, len;
119 char *name;
120
121 if (!state)
122 {
123 i = 0;
124 len = strlen (text);
125 }
126
127 while ((name = mail_command_table[i].longname))
128 {
129 if (strlen (mail_command_table[i].shortname) > strlen(name))
130 name = mail_command_table[i].shortname;
131 i++;
132 if (strncmp (name, text, len) == 0)
133 return (strdup(name));
134 }
135
136 return NULL;
137 }
138
139 #else
140
141 int
142 ml_reread(char *prompt, char **text)
143 {
144 char *s;
145 /*FIXME*/
146 s = readline(prompt);
147 if (*text)
148 free(*text);
149 *text = s;
150 return 0;
151 }
152
153 char *
154 readline (const char *prompt)
155 {
156 char *line;
157 char *p;
158 size_t alloclen, linelen;
159
160 if (prompt)
161 {
162 fprintf (ofile, "%s", prompt);
163 fflush (ofile);
164 }
165
166 p = line = calloc (1, 255);
167 alloclen = 255;
168 linelen = 0;
169 for (;;)
170 {
171 size_t n;
172
173 p = fgets (p, alloclen - linelen, stdin);
174
175 if (p)
176 n = strlen(p);
177 else if (_interrupt)
178 {
179 free (line);
180 return NULL;
181 }
182 else
183 n = 0;
184
185 linelen += n;
186
187 /* Error. */
188 if (linelen == 0)
189 {
190 free (line);
191 return NULL;
192 }
193
194 /* Ok. */
195 if (line[linelen - 1] == '\n')
196 {
197 line[linelen - 1] = '\0';
198 return line;
199 }
200 else
201 {
202 char *tmp;
203 alloclen *= 2;
204 tmp = realloc (line, alloclen);
205 if (tmp == NULL)
206 {
207 free (line);
208 return NULL;
209 }
210 line = tmp;
211 p = line + linelen;
212 }
213 }
214 }
215 #endif
216