readline-related functions.
Showing
1 changed file
with
216 additions
and
0 deletions
mail/mailline.c
0 → 100644
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 |
-
Please register or sign in to post a comment