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