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 */