3 * getansreadline.c -- get an answer from the user, with readline
5 * This code is Copyright (c) 2012, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
11 #include <h/signals.h>
16 #ifdef READLINE_SUPPORT
17 #include <readline/readline.h>
18 #include <readline/history.h>
20 static struct swit *rl_cmds;
22 static char *nmh_command_generator(const char *, int);
23 static char **nmh_completion(const char *, int, int);
24 static void initialize_readline(void);
26 static char ansbuf[BUFSIZ];
28 static sigjmp_buf sigenv;
33 static void intrser (int);
37 getans (char *prompt, struct swit *ansp)
40 SIGNAL_HANDLER istat = NULL;
43 if (!(sigsetjmp(sigenv, 1))) {
44 istat = SIGNAL (SIGINT, intrser);
46 SIGNAL (SIGINT, istat);
51 printf ("%s", prompt);
54 while ((i = getchar ()) != '\n') {
57 * If we get an EOF, return
60 siglongjmp (sigenv, 1);
63 * For errors, if we get an EINTR that means that we got
64 * a signal and we should retry. If we get another error,
68 else if (ferror(stdin)) {
73 fprintf(stderr, "\nError %s during read\n",
75 siglongjmp (sigenv, 1);
78 * Just for completeness's sake ...
81 fprintf(stderr, "\nUnknown problem in getchar()\n");
82 siglongjmp (sigenv, 1);
85 if (cp < &ansbuf[sizeof ansbuf - 1])
89 if (ansbuf[0] == '?' || cp == ansbuf) {
90 printf ("Options are:\n");
91 print_sw (ALL, ansp, "", stdout);
94 cpp = brkstring (ansbuf, " ", NULL);
95 switch (smatch (*cpp, ansp)) {
100 printf (" -%s unknown. Hit <CR> for help.\n", *cpp);
103 SIGNAL (SIGINT, istat);
116 * should this be siglongjmp?
118 siglongjmp (sigenv, 1);
123 * getans, but with readline support
127 getans_via_readline(char *prompt, struct swit *ansp)
131 initialize_readline();
135 ans = readline(prompt);
137 * If we get an EOF, return
143 if (ans[0] == '?' || ans[0] == '\0') {
144 printf("Options are:\n");
145 print_sw(ALL, ansp, "", stdout);
150 strncpy(ansbuf, ans, sizeof(ansbuf));
151 ansbuf[sizeof(ansbuf) - 1] = '\0';
152 cpp = brkstring(ansbuf, " ", NULL);
153 switch (smatch(*cpp, ansp)) {
158 printf(" -%s unknown. Hit <CR> for help.\n", *cpp);
169 initialize_readline(void)
171 rl_readline_name = "Nmh";
172 rl_attempted_completion_function = nmh_completion;
176 nmh_completion(const char *text, int start, int end)
182 matches = (char **) NULL;
185 matches = rl_completion_matches(text, nmh_command_generator);
191 nmh_command_generator(const char *text, int state)
193 static int list_index, len;
202 while ((name = rl_cmds[list_index].sw)) {
204 strncpy(buf, name, sizeof(buf));
205 buf[sizeof(buf) - 1] = '\0';
206 p = *brkstring(buf, " ", NULL);
207 if (strncmp(p, text, len) == 0)
213 #endif /* READLINE_SUPPORT */