]> diplodocus.org Git - nmh/blob - sbr/getans.c
Make the test suite work on systems other than Linux. Still needs work.
[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 <h/m_setjmp.h>
13 #include <signal.h>
14 #include <errno.h>
15
16 static char ansbuf[BUFSIZ];
17 static sigjmp_buf sigenv;
18
19 /*
20 * static prototypes
21 */
22 static void intrser (int);
23
24
25 char **
26 getans (char *prompt, struct swit *ansp)
27 {
28 int i;
29 SIGNAL_HANDLER istat = NULL;
30 char *cp, **cpp;
31
32 if (!(sigsetjmp(sigenv, 1))) {
33 istat = SIGNAL (SIGINT, intrser);
34 } else {
35 SIGNAL (SIGINT, istat);
36 return NULL;
37 }
38
39 for (;;) {
40 printf ("%s", prompt);
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 else 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 } else {
66 /*
67 * Just for completeness's sake ...
68 */
69
70 fprintf(stderr, "\nUnknown problem in getchar()\n");
71 siglongjmp (sigenv, 1);
72 }
73 }
74 if (cp < &ansbuf[sizeof ansbuf - 1])
75 *cp++ = i;
76 }
77 *cp = '\0';
78 if (ansbuf[0] == '?' || cp == ansbuf) {
79 printf ("Options are:\n");
80 print_sw (ALL, ansp, "", stdout);
81 continue;
82 }
83 cpp = brkstring (ansbuf, " ", NULL);
84 switch (smatch (*cpp, ansp)) {
85 case AMBIGSW:
86 ambigsw (*cpp, ansp);
87 continue;
88 case UNKWNSW:
89 printf (" -%s unknown. Hit <CR> for help.\n", *cpp);
90 continue;
91 default:
92 SIGNAL (SIGINT, istat);
93 return cpp;
94 }
95 }
96 }
97
98
99 static void
100 intrser (int i)
101 {
102 NMH_UNUSED (i);
103
104 /*
105 * should this be siglongjmp?
106 */
107 siglongjmp (sigenv, 1);
108 }