]> diplodocus.org Git - nmh/blob - sbr/read_switch_multiword_via_readline.c
new.c: Order two return statements to match comment.
[nmh] / sbr / read_switch_multiword_via_readline.c
1 /* read_switch_multiword_via_readline.c -- get an answer from the user, with readline
2 *
3 * This code is Copyright (c) 2012, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h>
9
10 #ifdef READLINE_SUPPORT
11 #include <readline/readline.h>
12 #include <readline/history.h>
13
14 static struct swit *rl_cmds;
15
16 static char *nmh_command_generator(const char *, int);
17 static char **nmh_completion(const char *, int, int);
18 static void initialize_readline(void);
19
20 static char ansbuf[BUFSIZ];
21
22 /*
23 * getans, but with readline support
24 */
25
26 char **
27 read_switch_multiword_via_readline(char *prompt, struct swit *ansp)
28 {
29 char *ans, **cpp;
30
31 initialize_readline();
32 rl_cmds = ansp;
33
34 for (;;) {
35 ans = readline(prompt);
36 /*
37 * If we get an EOF, return
38 */
39
40 if (ans == NULL)
41 return NULL;
42
43 if (ans[0] == '?' || ans[0] == '\0') {
44 puts("Options are:");
45 print_sw(ALL, ansp, "", stdout);
46 free(ans);
47 continue;
48 }
49 add_history(ans);
50 strncpy(ansbuf, ans, sizeof(ansbuf));
51 ansbuf[sizeof(ansbuf) - 1] = '\0';
52 free(ans);
53
54 cpp = brkstring(ansbuf, " ", NULL);
55 switch (smatch(*cpp, ansp)) {
56 case AMBIGSW:
57 ambigsw(*cpp, ansp);
58 continue;
59 case UNKWNSW:
60 printf(" -%s unknown. Hit <CR> for help.\n", *cpp);
61 continue;
62 default:
63 return cpp;
64 }
65 }
66 }
67
68 static void
69 initialize_readline(void)
70 {
71 rl_readline_name = "Nmh";
72 rl_attempted_completion_function = nmh_completion;
73 }
74
75 static char **
76 nmh_completion(const char *text, int start, int end)
77 {
78 NMH_UNUSED (end);
79
80 if (start == 0)
81 return rl_completion_matches(text, nmh_command_generator);
82
83 return NULL;
84 }
85
86 static char *
87 nmh_command_generator(const char *text, int state)
88 {
89 static int list_index, len;
90 char *name, *p;
91 char buf[256];
92
93 if (!state) {
94 list_index = 0;
95 len = strlen(text);
96 }
97
98 while ((name = rl_cmds[list_index].sw)) {
99 list_index++;
100 strncpy(buf, name, sizeof(buf));
101 buf[sizeof(buf) - 1] = '\0';
102 p = *brkstring(buf, " ", NULL);
103 if (strncmp(p, text, len) == 0)
104 return strdup(p);
105 }
106
107 return NULL;
108 }
109 #endif /* READLINE_SUPPORT */