]> diplodocus.org Git - nmh/blob - sbr/read_switch_multiword.c
d66bd254a85e6241104076401569352ab0a15228
[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 "print_sw.h"
10 #include "h/signals.h"
11 #include <setjmp.h>
12
13 static char ansbuf[BUFSIZ];
14 static sigjmp_buf sigenv;
15
16 /*
17 * static prototypes
18 */
19 static void intrser (int);
20
21
22 char **
23 read_switch_multiword (const char *prompt, const struct swit *ansp)
24 {
25 int i;
26 SIGNAL_HANDLER istat = NULL;
27 char *cp, **cpp;
28
29 if (sigsetjmp(sigenv, 1)) {
30 SIGNAL (SIGINT, istat);
31 return NULL;
32 }
33 istat = SIGNAL (SIGINT, intrser);
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 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 }
62
63 /* Just for completeness's sake... */
64 fprintf(stderr, "\nUnknown problem in getchar()\n");
65 siglongjmp(sigenv, 1);
66 }
67 if (cp < &ansbuf[sizeof ansbuf - 1])
68 *cp++ = i;
69 }
70 *cp = '\0';
71 if (ansbuf[0] == '?' || cp == ansbuf) {
72 puts("Options are:");
73 print_sw (ALL, ansp, "", stdout);
74 continue;
75 }
76 cpp = brkstring (ansbuf, " ", NULL);
77 switch (smatch (*cpp, ansp)) {
78 case AMBIGSW:
79 ambigsw (*cpp, ansp);
80 continue;
81 case UNKWNSW:
82 printf (" -%s unknown. Hit <CR> for help.\n", *cpp);
83 continue;
84 default:
85 SIGNAL (SIGINT, istat);
86 return cpp;
87 }
88 }
89 }
90
91
92 static void
93 intrser (int i)
94 {
95 NMH_UNUSED (i);
96
97 siglongjmp (sigenv, 1);
98 }