Initial revision
[mmh] / sbr / getans.c
1
2 /*
3  * getans.c -- get an answer from the user and return a string array
4  *
5  * $Id$
6  */
7
8 #include <h/mh.h>
9 #include <h/signals.h>
10 #include <setjmp.h>
11 #include <signal.h>
12
13 static char ansbuf[BUFSIZ];
14 static jmp_buf sigenv;
15
16 /*
17  * static prototypes
18  */
19 static RETSIGTYPE intrser (int);
20
21
22 char **
23 getans (char *prompt, struct swit *ansp)
24 {
25     int i;
26     SIGNAL_HANDLER istat;
27     char *cp, **cpp;
28
29     if (!(setjmp (sigenv))) {
30         istat = SIGNAL (SIGINT, intrser);
31     } else {
32         SIGNAL (SIGINT, istat);
33         return NULL;
34     }
35
36     for (;;) {
37         printf ("%s", prompt);
38         fflush (stdout);
39         cp = ansbuf;
40         while ((i = getchar ()) != '\n') {
41             if (i == EOF)
42                 longjmp (sigenv, 1);
43             if (cp < &ansbuf[sizeof ansbuf - 1])
44                 *cp++ = i;
45         }
46         *cp = '\0';
47         if (ansbuf[0] == '?' || cp == ansbuf) {
48             printf ("Options are:\n");
49             print_sw (ALL, ansp, "");
50             continue;
51         }
52         cpp = brkstring (ansbuf, " ", NULL);
53         switch (smatch (*cpp, ansp)) {
54             case AMBIGSW: 
55                 ambigsw (*cpp, ansp);
56                 continue;
57             case UNKWNSW: 
58                 printf (" -%s unknown. Hit <CR> for help.\n", *cpp);
59                 continue;
60             default: 
61                 SIGNAL (SIGINT, istat);
62                 return cpp;
63         }
64     }
65 }
66
67
68 static RETSIGTYPE
69 intrser (int i)
70 {
71     /*
72      * should this be siglongjmp?
73      */
74     longjmp (sigenv, 1);
75 }