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