]> diplodocus.org Git - nmh/blob - sbr/read_switch_multiword.c
sendsbr.c: Move interface to own file.
[nmh] / sbr / read_switch_multiword.c
1 /* read_switch_multiword.c -- get an answer from the user and return a string array
2 *
3 * This code is Copyright (c) 2002, 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 #include "read_switch_multiword.h"
10 #include "smatch.h"
11 #include "brkstring.h"
12 #include "ambigsw.h"
13 #include "print_sw.h"
14 #include "h/signals.h"
15 #include <setjmp.h>
16
17 static char ansbuf[BUFSIZ];
18 static sigjmp_buf sigenv;
19
20 /*
21 * static prototypes
22 */
23 static void intrser (int);
24
25
26 char **
27 read_switch_multiword (const char *prompt, const struct swit *ansp)
28 {
29 int i;
30 SIGNAL_HANDLER istat = NULL;
31 char *cp, **cpp;
32
33 if (sigsetjmp(sigenv, 1)) {
34 SIGNAL (SIGINT, istat);
35 return NULL;
36 }
37 istat = SIGNAL (SIGINT, intrser);
38
39 for (;;) {
40 fputs(prompt, stdout);
41 fflush (stdout);
42 cp = ansbuf;
43 while ((i = getchar ()) != '\n') {
44 if (i == EOF) {
45 /*
46 * If we get an EOF, return
47 */
48 if (feof(stdin))
49 siglongjmp (sigenv, 1);
50
51 /*
52 * For errors, if we get an EINTR that means that we got
53 * a signal and we should retry. If we get another error,
54 * then just return.
55 */
56
57 if (ferror(stdin)) {
58 if (errno == EINTR) {
59 clearerr(stdin);
60 continue;
61 }
62 fprintf(stderr, "\nError %s during read\n",
63 strerror(errno));
64 siglongjmp (sigenv, 1);
65 }
66
67 /* Just for completeness's sake... */
68 fprintf(stderr, "\nUnknown problem in getchar()\n");
69 siglongjmp(sigenv, 1);
70 }
71 if (cp < &ansbuf[sizeof ansbuf - 1])
72 *cp++ = i;
73 }
74 *cp = '\0';
75 if (ansbuf[0] == '?' || cp == ansbuf) {
76 puts("Options are:");
77 print_sw (ALL, ansp, "", stdout);
78 continue;
79 }
80 cpp = brkstring (ansbuf, " ", NULL);
81 switch (smatch (*cpp, ansp)) {
82 case AMBIGSW:
83 ambigsw (*cpp, ansp);
84 continue;
85 case UNKWNSW:
86 printf (" -%s unknown. Hit <CR> for help.\n", *cpp);
87 continue;
88 default:
89 SIGNAL (SIGINT, istat);
90 return cpp;
91 }
92 }
93 }
94
95
96 static void
97 intrser (int i)
98 {
99 NMH_UNUSED (i);
100
101 siglongjmp (sigenv, 1);
102 }