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