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