1*1003ba15Sbostic /* SC A Spreadsheet Calculator
2*1003ba15Sbostic * Lexical analyser
3*1003ba15Sbostic *
4*1003ba15Sbostic * original by James Gosling, September 1982
5*1003ba15Sbostic * modifications by Mark Weiser and Bruce Israel,
6*1003ba15Sbostic * University of Maryland
7*1003ba15Sbostic *
8*1003ba15Sbostic * More mods Robert Bond, 12/86
9*1003ba15Sbostic * More mods by Alan Silverstein, 3/88, see list of changes.
10*1003ba15Sbostic * $Revision: 6.8 $
11*1003ba15Sbostic *
12*1003ba15Sbostic */
13*1003ba15Sbostic
14*1003ba15Sbostic
15*1003ba15Sbostic
16*1003ba15Sbostic #if defined(BSD42) || defined(BSD43)
17*1003ba15Sbostic #include <sys/ioctl.h>
18*1003ba15Sbostic #endif
19*1003ba15Sbostic
20*1003ba15Sbostic #ifdef IEEE_MATH
21*1003ba15Sbostic #include <ieeefp.h>
22*1003ba15Sbostic #endif /* IEEE_MATH */
23*1003ba15Sbostic
24*1003ba15Sbostic #include <curses.h>
25*1003ba15Sbostic #include <signal.h>
26*1003ba15Sbostic #include <setjmp.h>
27*1003ba15Sbostic #include "sc.h"
28*1003ba15Sbostic #include <ctype.h>
29*1003ba15Sbostic
30*1003ba15Sbostic #ifdef BSD42
31*1003ba15Sbostic #include <strings.h>
32*1003ba15Sbostic #else
33*1003ba15Sbostic #ifndef SYSIII
34*1003ba15Sbostic #include <string.h>
35*1003ba15Sbostic #endif
36*1003ba15Sbostic #endif
37*1003ba15Sbostic
38*1003ba15Sbostic #ifdef VMS
39*1003ba15Sbostic #include "gram_tab.h"
40*1003ba15Sbostic typedef union {
41*1003ba15Sbostic int ival;
42*1003ba15Sbostic double fval;
43*1003ba15Sbostic struct ent *ent;
44*1003ba15Sbostic struct enode *enode;
45*1003ba15Sbostic char *sval;
46*1003ba15Sbostic struct range_s rval;
47*1003ba15Sbostic } YYSTYPE;
48*1003ba15Sbostic extern YYSTYPE yylval;
49*1003ba15Sbostic extern int VMS_read_raw; /*sigh*/
50*1003ba15Sbostic #else /* VMS */
51*1003ba15Sbostic #include "y.tab.h"
52*1003ba15Sbostic #endif /* VMS */
53*1003ba15Sbostic
54*1003ba15Sbostic char *strtof();
55*1003ba15Sbostic
56*1003ba15Sbostic jmp_buf wakeup;
57*1003ba15Sbostic jmp_buf fpe_buf;
58*1003ba15Sbostic
59*1003ba15Sbostic struct key {
60*1003ba15Sbostic char *key;
61*1003ba15Sbostic int val;
62*1003ba15Sbostic };
63*1003ba15Sbostic
64*1003ba15Sbostic struct key experres[] = {
65*1003ba15Sbostic #include "experres.h"
66*1003ba15Sbostic 0, 0};
67*1003ba15Sbostic
68*1003ba15Sbostic struct key statres[] = {
69*1003ba15Sbostic #include "statres.h"
70*1003ba15Sbostic 0, 0};
71*1003ba15Sbostic
yylex()72*1003ba15Sbostic yylex ()
73*1003ba15Sbostic {
74*1003ba15Sbostic register char *p = line+linelim;
75*1003ba15Sbostic int ret;
76*1003ba15Sbostic while (isspace(*p)) p++;
77*1003ba15Sbostic if (*p == '\0') ret = -1;
78*1003ba15Sbostic else if (isalpha(*p)) {
79*1003ba15Sbostic char *tokenst = p;
80*1003ba15Sbostic register tokenl;
81*1003ba15Sbostic register struct key *tblp;
82*1003ba15Sbostic tokenl = 0;
83*1003ba15Sbostic /*
84*1003ba15Sbostic * This picks up either 1 or 2 alpha characters (a column) or
85*1003ba15Sbostic * tokens with at least three leading alphas and '_' or digits
86*1003ba15Sbostic * (a function or token or command or a range name)
87*1003ba15Sbostic */
88*1003ba15Sbostic while (isalpha(*p) || ((*p == '_') || isdigit(*p)) && (tokenl > 2)) {
89*1003ba15Sbostic p++;
90*1003ba15Sbostic tokenl++;
91*1003ba15Sbostic }
92*1003ba15Sbostic if (tokenl <= 2) { /* a COL is 1 or 2 char alpha
93*1003ba15Sbostic (but not pi, ln, fv, pv, if -- this should be fixed!) */
94*1003ba15Sbostic if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'i') {
95*1003ba15Sbostic ret = K_PI;
96*1003ba15Sbostic } else if (tokenl == 2 && tokenst[0] == 'l' && tokenst[1] == 'n') {
97*1003ba15Sbostic ret = K_LN;
98*1003ba15Sbostic } else if (tokenl == 2 && tokenst[0] == 'f' && tokenst[1] == 'v') {
99*1003ba15Sbostic ret = K_FV;
100*1003ba15Sbostic } else if (tokenl == 2 && tokenst[0] == 'p' && tokenst[1] == 'v') {
101*1003ba15Sbostic ret = K_PV;
102*1003ba15Sbostic } else if (tokenl == 2 && tokenst[0] == 'i' && tokenst[1] == 'f') {
103*1003ba15Sbostic ret = K_IF;
104*1003ba15Sbostic
105*1003ba15Sbostic } else {
106*1003ba15Sbostic ret = COL;
107*1003ba15Sbostic yylval.ival = atocol (tokenst, tokenl);
108*1003ba15Sbostic }
109*1003ba15Sbostic } else {
110*1003ba15Sbostic ret = WORD;
111*1003ba15Sbostic for (tblp = linelim ? experres : statres; tblp->key; tblp++)
112*1003ba15Sbostic if (((tblp->key[0]^tokenst[0])&0137)==0
113*1003ba15Sbostic && tblp->key[tokenl]==0) {
114*1003ba15Sbostic register i = 1;
115*1003ba15Sbostic while (i<tokenl && ((tokenst[i]^tblp->key[i])&0137)==0)
116*1003ba15Sbostic i++;
117*1003ba15Sbostic if (i>=tokenl) {
118*1003ba15Sbostic ret = tblp->val;
119*1003ba15Sbostic break;
120*1003ba15Sbostic }
121*1003ba15Sbostic }
122*1003ba15Sbostic if (ret==WORD) {
123*1003ba15Sbostic struct range *r;
124*1003ba15Sbostic if (r = find_range(tokenst, tokenl,
125*1003ba15Sbostic (struct ent *)0, (struct ent *)0)) {
126*1003ba15Sbostic yylval.rval.left = r->r_left;
127*1003ba15Sbostic yylval.rval.right = r->r_right;
128*1003ba15Sbostic if (r->r_is_range)
129*1003ba15Sbostic ret = RANGE;
130*1003ba15Sbostic else
131*1003ba15Sbostic ret = VAR;
132*1003ba15Sbostic } else {
133*1003ba15Sbostic linelim = p-line;
134*1003ba15Sbostic yyerror ("Unintelligible word");
135*1003ba15Sbostic }
136*1003ba15Sbostic }
137*1003ba15Sbostic }
138*1003ba15Sbostic } else if ((*p == '.') || isdigit(*p)) {
139*1003ba15Sbostic double v = 0;
140*1003ba15Sbostic int temp;
141*1003ba15Sbostic char *nstart = p;
142*1003ba15Sbostic if (*p != '.') {
143*1003ba15Sbostic do v = v*10 + (double)(*p-'0');
144*1003ba15Sbostic while (isdigit(*++p));
145*1003ba15Sbostic }
146*1003ba15Sbostic if (*p=='.' || *p == 'e' || *p == 'E') {
147*1003ba15Sbostic ret = FNUMBER;
148*1003ba15Sbostic p = strtof(nstart, &yylval.fval);
149*1003ba15Sbostic } else {
150*1003ba15Sbostic /* A NUMBER must hold at least MAXROW and MAXCOL */
151*1003ba15Sbostic /* This is consistent with a short row and col in struct ent */
152*1003ba15Sbostic if (v > (double)32767 || v < (double)-32768) {
153*1003ba15Sbostic ret = FNUMBER;
154*1003ba15Sbostic yylval.fval = v;
155*1003ba15Sbostic } else {
156*1003ba15Sbostic temp = (int)v;
157*1003ba15Sbostic if((double)temp != v) {
158*1003ba15Sbostic ret = FNUMBER;
159*1003ba15Sbostic yylval.fval = v;
160*1003ba15Sbostic } else {
161*1003ba15Sbostic ret = NUMBER;
162*1003ba15Sbostic yylval.ival = temp;
163*1003ba15Sbostic }
164*1003ba15Sbostic }
165*1003ba15Sbostic }
166*1003ba15Sbostic } else if (*p=='"') {
167*1003ba15Sbostic char *ptr;
168*1003ba15Sbostic ptr = p+1;
169*1003ba15Sbostic while(*ptr && *ptr++ != '"');
170*1003ba15Sbostic ptr = xmalloc((unsigned)(ptr-p));
171*1003ba15Sbostic yylval.sval = ptr;
172*1003ba15Sbostic p += 1;
173*1003ba15Sbostic while (*p && *p!='"') *ptr++ = *p++;
174*1003ba15Sbostic *ptr = 0;
175*1003ba15Sbostic if (*p) p += 1;
176*1003ba15Sbostic ret = STRING;
177*1003ba15Sbostic } else if (*p=='[') {
178*1003ba15Sbostic while (*p && *p!=']') p++;
179*1003ba15Sbostic if (*p) p++;
180*1003ba15Sbostic linelim = p-line;
181*1003ba15Sbostic return yylex();
182*1003ba15Sbostic } else ret = *p++;
183*1003ba15Sbostic linelim = p-line;
184*1003ba15Sbostic return ret;
185*1003ba15Sbostic }
186*1003ba15Sbostic
187*1003ba15Sbostic
188*1003ba15Sbostic /*
189*1003ba15Sbostic * Given a token string starting with a symbolic column name and its valid
190*1003ba15Sbostic * length, convert column name ("A"-"Z" or "AA"-"ZZ") to a column number (0-N).
191*1003ba15Sbostic * Never mind if the column number is illegal (too high). The procedure's name
192*1003ba15Sbostic * and function are the inverse of coltoa().
193*1003ba15Sbostic *
194*1003ba15Sbostic * Case-insensitivity is done crudely, by ignoring the 040 bit.
195*1003ba15Sbostic */
196*1003ba15Sbostic
197*1003ba15Sbostic int
atocol(string,len)198*1003ba15Sbostic atocol (string, len)
199*1003ba15Sbostic char *string;
200*1003ba15Sbostic int len;
201*1003ba15Sbostic {
202*1003ba15Sbostic register int col;
203*1003ba15Sbostic
204*1003ba15Sbostic col = (string [0] & 0137) - 'A';
205*1003ba15Sbostic
206*1003ba15Sbostic if (len == 2) /* has second char */
207*1003ba15Sbostic col = ((col + 1) * 26) + ((string [1] & 0137) - 'A');
208*1003ba15Sbostic
209*1003ba15Sbostic return (col);
210*1003ba15Sbostic }
211*1003ba15Sbostic
212*1003ba15Sbostic
213*1003ba15Sbostic #ifdef SIMPLE
214*1003ba15Sbostic
initkbd()215*1003ba15Sbostic initkbd()
216*1003ba15Sbostic {}
217*1003ba15Sbostic
kbd_again()218*1003ba15Sbostic kbd_again()
219*1003ba15Sbostic {}
220*1003ba15Sbostic
resetkbd()221*1003ba15Sbostic resetkbd()
222*1003ba15Sbostic {}
223*1003ba15Sbostic
224*1003ba15Sbostic #ifndef VMS
225*1003ba15Sbostic
nmgetch()226*1003ba15Sbostic nmgetch()
227*1003ba15Sbostic {
228*1003ba15Sbostic return (toascii(getchar()));
229*1003ba15Sbostic }
230*1003ba15Sbostic
231*1003ba15Sbostic #else /* VMS */
232*1003ba15Sbostic
nmgetch()233*1003ba15Sbostic nmgetch()
234*1003ba15Sbostic /*
235*1003ba15Sbostic This is not perfect, it doesn't move the cursor when goraw changes
236*1003ba15Sbostic over to deraw, but it works well enough since the whole sc package
237*1003ba15Sbostic is incredibly stable (loop constantly positions cursor).
238*1003ba15Sbostic
239*1003ba15Sbostic Question, why didn't the VMS people just implement cbreak?
240*1003ba15Sbostic
241*1003ba15Sbostic NOTE: During testing it was discovered that the DEBUGGER and curses
242*1003ba15Sbostic and this method of reading would collide (the screen was not updated
243*1003ba15Sbostic when continuing from screen mode in the debugger).
244*1003ba15Sbostic */
245*1003ba15Sbostic {
246*1003ba15Sbostic short c;
247*1003ba15Sbostic static int key_id=0;
248*1003ba15Sbostic int status;
249*1003ba15Sbostic #define VMScheck(a) {if (~(status = (a)) & 1) VMS_MSG (status);}
250*1003ba15Sbostic
251*1003ba15Sbostic if (VMS_read_raw) {
252*1003ba15Sbostic VMScheck(smg$read_keystroke (&stdkb->_id, &c, 0, 0, 0));
253*1003ba15Sbostic }
254*1003ba15Sbostic else
255*1003ba15Sbostic c = getchar();
256*1003ba15Sbostic
257*1003ba15Sbostic switch (c) {
258*1003ba15Sbostic case SMG$K_TRM_LEFT: c = ctl('b'); break;
259*1003ba15Sbostic case SMG$K_TRM_RIGHT: c = ctl('f'); break;
260*1003ba15Sbostic case SMG$K_TRM_UP: c = ctl('p'); break;
261*1003ba15Sbostic case SMG$K_TRM_DOWN: c = ctl('n'); break;
262*1003ba15Sbostic default: c = c & 0x7f;
263*1003ba15Sbostic }
264*1003ba15Sbostic return (c);
265*1003ba15Sbostic }
266*1003ba15Sbostic
267*1003ba15Sbostic
VMS_MSG(status)268*1003ba15Sbostic VMS_MSG (status)
269*1003ba15Sbostic int status;
270*1003ba15Sbostic /*
271*1003ba15Sbostic Routine to put out the VMS operating system error (if one occurs).
272*1003ba15Sbostic */
273*1003ba15Sbostic {
274*1003ba15Sbostic #include <descrip.h>
275*1003ba15Sbostic char errstr[81], buf[120];
276*1003ba15Sbostic $DESCRIPTOR(errdesc, errstr);
277*1003ba15Sbostic short int length;
278*1003ba15Sbostic #define err_out(msg) fprintf (stderr,msg)
279*1003ba15Sbostic
280*1003ba15Sbostic /* Check for no error or standard error */
281*1003ba15Sbostic
282*1003ba15Sbostic if (~status & 1) {
283*1003ba15Sbostic status = status & 0x8000 ? status & 0xFFFFFFF : status & 0xFFFF;
284*1003ba15Sbostic if (SYS$GETMSG(status, &length, &errdesc, 1, 0) == SS$_NORMAL) {
285*1003ba15Sbostic errstr[length] = '\0';
286*1003ba15Sbostic sprintf (buf, "<0x%x> %s", status, errdesc.dsc$a_pointer);
287*1003ba15Sbostic err_out (buf);
288*1003ba15Sbostic }
289*1003ba15Sbostic else
290*1003ba15Sbostic err_out ("System error");
291*1003ba15Sbostic }
292*1003ba15Sbostic }
293*1003ba15Sbostic #endif /* VMS */
294*1003ba15Sbostic
295*1003ba15Sbostic #else /*SIMPLE*/
296*1003ba15Sbostic
297*1003ba15Sbostic #if defined(BSD42) || defined (SYSIII) || defined(BSD43)
298*1003ba15Sbostic
299*1003ba15Sbostic #define N_KEY 4
300*1003ba15Sbostic
301*1003ba15Sbostic struct key_map {
302*1003ba15Sbostic char *k_str;
303*1003ba15Sbostic char k_val;
304*1003ba15Sbostic char k_index;
305*1003ba15Sbostic };
306*1003ba15Sbostic
307*1003ba15Sbostic struct key_map km[N_KEY];
308*1003ba15Sbostic
309*1003ba15Sbostic char keyarea[N_KEY*30];
310*1003ba15Sbostic
311*1003ba15Sbostic char *tgetstr();
312*1003ba15Sbostic char *getenv();
313*1003ba15Sbostic char *ks;
314*1003ba15Sbostic char ks_buf[20];
315*1003ba15Sbostic char *ke;
316*1003ba15Sbostic char ke_buf[20];
317*1003ba15Sbostic
318*1003ba15Sbostic #ifdef TIOCSLTC
319*1003ba15Sbostic struct ltchars old_chars, new_chars;
320*1003ba15Sbostic #endif
321*1003ba15Sbostic
322*1003ba15Sbostic char dont_use[] = {
323*1003ba15Sbostic ctl('['), ctl('a'), ctl('b'), ctl('c'), ctl('e'), ctl('f'), ctl('g'), ctl('h'),
324*1003ba15Sbostic ctl('i'), ctl('j'), ctl('l'), ctl('m'), ctl('n'), ctl('p'), ctl('q'),
325*1003ba15Sbostic ctl('r'), ctl('s'), ctl('t'), ctl('u'), ctl('v'), ctl('w'), ctl('x'),
326*1003ba15Sbostic ctl('z'), 0
327*1003ba15Sbostic };
328*1003ba15Sbostic
charout(c)329*1003ba15Sbostic charout(c)
330*1003ba15Sbostic int c;
331*1003ba15Sbostic {
332*1003ba15Sbostic (void)putchar(c);
333*1003ba15Sbostic }
334*1003ba15Sbostic
initkbd()335*1003ba15Sbostic initkbd()
336*1003ba15Sbostic {
337*1003ba15Sbostic register struct key_map *kp;
338*1003ba15Sbostic register i,j;
339*1003ba15Sbostic char *p = keyarea;
340*1003ba15Sbostic char *ktmp;
341*1003ba15Sbostic static char buf[1024]; /* Why do I have to do this again? */
342*1003ba15Sbostic
343*1003ba15Sbostic if (tgetent(buf, getenv("TERM")) <= 0)
344*1003ba15Sbostic return;
345*1003ba15Sbostic
346*1003ba15Sbostic km[0].k_str = tgetstr("kl", &p); km[0].k_val = ctl('b');
347*1003ba15Sbostic km[1].k_str = tgetstr("kr", &p); km[1].k_val = ctl('f');
348*1003ba15Sbostic km[2].k_str = tgetstr("ku", &p); km[2].k_val = ctl('p');
349*1003ba15Sbostic km[3].k_str = tgetstr("kd", &p); km[3].k_val = ctl('n');
350*1003ba15Sbostic ktmp = tgetstr("ks",&p);
351*1003ba15Sbostic if (ktmp) {
352*1003ba15Sbostic (void) strcpy(ks_buf, ktmp);
353*1003ba15Sbostic ks = ks_buf;
354*1003ba15Sbostic tputs(ks, 1, charout);
355*1003ba15Sbostic }
356*1003ba15Sbostic ktmp = tgetstr("ke",&p);
357*1003ba15Sbostic if (ktmp) {
358*1003ba15Sbostic (void) strcpy(ke_buf, ktmp);
359*1003ba15Sbostic ke = ke_buf;
360*1003ba15Sbostic }
361*1003ba15Sbostic
362*1003ba15Sbostic /* Unmap arrow keys which conflict with our ctl keys */
363*1003ba15Sbostic /* Ignore unset, longer than length 1, and 1-1 mapped keys */
364*1003ba15Sbostic
365*1003ba15Sbostic for (i = 0; i < N_KEY; i++) {
366*1003ba15Sbostic kp = &km[i];
367*1003ba15Sbostic if (kp->k_str && (kp->k_str[1] == 0) && (kp->k_str[0] != kp->k_val))
368*1003ba15Sbostic for (j = 0; dont_use[j] != 0; j++)
369*1003ba15Sbostic if (kp->k_str[0] == dont_use[j]) {
370*1003ba15Sbostic kp->k_str = (char *)0;
371*1003ba15Sbostic break;
372*1003ba15Sbostic }
373*1003ba15Sbostic }
374*1003ba15Sbostic
375*1003ba15Sbostic
376*1003ba15Sbostic #ifdef TIOCSLTC
377*1003ba15Sbostic (void)ioctl(fileno(stdin), TIOCGLTC, (char *)&old_chars);
378*1003ba15Sbostic new_chars = old_chars;
379*1003ba15Sbostic if (old_chars.t_lnextc == ctl('v'))
380*1003ba15Sbostic new_chars.t_lnextc = -1;
381*1003ba15Sbostic if (old_chars.t_rprntc == ctl('r'))
382*1003ba15Sbostic new_chars.t_rprntc = -1;
383*1003ba15Sbostic (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
384*1003ba15Sbostic #endif
385*1003ba15Sbostic }
386*1003ba15Sbostic
387*1003ba15Sbostic void
kbd_again()388*1003ba15Sbostic kbd_again()
389*1003ba15Sbostic {
390*1003ba15Sbostic if (ks)
391*1003ba15Sbostic tputs(ks, 1, charout);
392*1003ba15Sbostic
393*1003ba15Sbostic #ifdef TIOCSLTC
394*1003ba15Sbostic (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&new_chars);
395*1003ba15Sbostic #endif
396*1003ba15Sbostic }
397*1003ba15Sbostic
398*1003ba15Sbostic void
resetkbd()399*1003ba15Sbostic resetkbd()
400*1003ba15Sbostic {
401*1003ba15Sbostic if (ke)
402*1003ba15Sbostic tputs(ke, 1, charout);
403*1003ba15Sbostic
404*1003ba15Sbostic #ifdef TIOCSLTC
405*1003ba15Sbostic (void)ioctl(fileno(stdin), TIOCSLTC, (char *)&old_chars);
406*1003ba15Sbostic #endif
407*1003ba15Sbostic }
408*1003ba15Sbostic
nmgetch()409*1003ba15Sbostic nmgetch()
410*1003ba15Sbostic {
411*1003ba15Sbostic register int c;
412*1003ba15Sbostic register struct key_map *kp;
413*1003ba15Sbostic register struct key_map *biggest;
414*1003ba15Sbostic register int i;
415*1003ba15Sbostic int almost;
416*1003ba15Sbostic int maybe;
417*1003ba15Sbostic
418*1003ba15Sbostic static char dumpbuf[10];
419*1003ba15Sbostic static char *dumpindex;
420*1003ba15Sbostic
421*1003ba15Sbostic #ifdef SIGVOID
422*1003ba15Sbostic void time_out();
423*1003ba15Sbostic #else
424*1003ba15Sbostic int time_out();
425*1003ba15Sbostic #endif
426*1003ba15Sbostic
427*1003ba15Sbostic if (dumpindex && *dumpindex)
428*1003ba15Sbostic return (*dumpindex++);
429*1003ba15Sbostic
430*1003ba15Sbostic c = toascii(getchar());
431*1003ba15Sbostic biggest = 0;
432*1003ba15Sbostic almost = 0;
433*1003ba15Sbostic
434*1003ba15Sbostic for (kp = &km[0]; kp < &km[N_KEY]; kp++) {
435*1003ba15Sbostic if (!kp->k_str)
436*1003ba15Sbostic continue;
437*1003ba15Sbostic if (c == kp->k_str[kp->k_index]) {
438*1003ba15Sbostic almost = 1;
439*1003ba15Sbostic kp->k_index++;
440*1003ba15Sbostic if (kp->k_str[kp->k_index] == 0) {
441*1003ba15Sbostic c = kp->k_val;
442*1003ba15Sbostic for (kp = &km[0]; kp < &km[N_KEY]; kp++)
443*1003ba15Sbostic kp->k_index = 0;
444*1003ba15Sbostic return(c);
445*1003ba15Sbostic }
446*1003ba15Sbostic }
447*1003ba15Sbostic if (!biggest && kp->k_index)
448*1003ba15Sbostic biggest = kp;
449*1003ba15Sbostic else if (kp->k_index && biggest->k_index < kp->k_index)
450*1003ba15Sbostic biggest = kp;
451*1003ba15Sbostic }
452*1003ba15Sbostic
453*1003ba15Sbostic if (almost) {
454*1003ba15Sbostic (void) signal(SIGALRM, time_out);
455*1003ba15Sbostic (void) alarm(1);
456*1003ba15Sbostic
457*1003ba15Sbostic if (setjmp(wakeup) == 0) {
458*1003ba15Sbostic maybe = nmgetch();
459*1003ba15Sbostic (void) alarm(0);
460*1003ba15Sbostic return(maybe);
461*1003ba15Sbostic }
462*1003ba15Sbostic }
463*1003ba15Sbostic
464*1003ba15Sbostic if (biggest) {
465*1003ba15Sbostic for (i = 0; i<biggest->k_index; i++)
466*1003ba15Sbostic dumpbuf[i] = biggest->k_str[i];
467*1003ba15Sbostic if (!almost)
468*1003ba15Sbostic dumpbuf[i++] = c;
469*1003ba15Sbostic dumpbuf[i] = '\0';
470*1003ba15Sbostic dumpindex = &dumpbuf[1];
471*1003ba15Sbostic for (kp = &km[0]; kp < &km[N_KEY]; kp++)
472*1003ba15Sbostic kp->k_index = 0;
473*1003ba15Sbostic return (dumpbuf[0]);
474*1003ba15Sbostic }
475*1003ba15Sbostic
476*1003ba15Sbostic return(c);
477*1003ba15Sbostic }
478*1003ba15Sbostic
479*1003ba15Sbostic #endif
480*1003ba15Sbostic
481*1003ba15Sbostic #if defined(SYSV2) || defined(SYSV3)
482*1003ba15Sbostic
initkbd()483*1003ba15Sbostic initkbd()
484*1003ba15Sbostic {
485*1003ba15Sbostic keypad(stdscr, TRUE);
486*1003ba15Sbostic }
487*1003ba15Sbostic
488*1003ba15Sbostic void
kbd_again()489*1003ba15Sbostic kbd_again()
490*1003ba15Sbostic {
491*1003ba15Sbostic keypad(stdscr, TRUE);
492*1003ba15Sbostic }
493*1003ba15Sbostic
494*1003ba15Sbostic void
resetkbd()495*1003ba15Sbostic resetkbd()
496*1003ba15Sbostic {
497*1003ba15Sbostic keypad(stdscr, FALSE);
498*1003ba15Sbostic }
499*1003ba15Sbostic
nmgetch()500*1003ba15Sbostic nmgetch()
501*1003ba15Sbostic {
502*1003ba15Sbostic register int c;
503*1003ba15Sbostic
504*1003ba15Sbostic c = getch();
505*1003ba15Sbostic switch (c) {
506*1003ba15Sbostic case KEY_LEFT: c = ctl('b'); break;
507*1003ba15Sbostic case KEY_RIGHT: c = ctl('f'); break;
508*1003ba15Sbostic case KEY_UP: c = ctl('p'); break;
509*1003ba15Sbostic case KEY_DOWN: c = ctl('n'); break;
510*1003ba15Sbostic #ifdef KEY_C1
511*1003ba15Sbostic /* This stuff works for a wyse wy75 in ANSI mode under 5.3. Good luck. */
512*1003ba15Sbostic /* It is supposed to map the curses keypad back to the numeric equiv. */
513*1003ba15Sbostic case KEY_C1: c = '0'; break;
514*1003ba15Sbostic case KEY_A1: c = '1'; break;
515*1003ba15Sbostic case KEY_B2: c = '2'; break;
516*1003ba15Sbostic case KEY_A3: c = '3'; break;
517*1003ba15Sbostic case KEY_F(5): c = '4'; break;
518*1003ba15Sbostic case KEY_F(6): c = '5'; break;
519*1003ba15Sbostic case KEY_F(7): c = '6'; break;
520*1003ba15Sbostic case KEY_F(9): c = '7'; break;
521*1003ba15Sbostic case KEY_F(10): c = '8'; break;
522*1003ba15Sbostic case KEY_F0: c = '9'; break;
523*1003ba15Sbostic case KEY_C3: c = '.'; break;
524*1003ba15Sbostic case KEY_ENTER: c = ctl('m'); break;
525*1003ba15Sbostic #endif
526*1003ba15Sbostic default: c = toascii(c);
527*1003ba15Sbostic break;
528*1003ba15Sbostic }
529*1003ba15Sbostic return (c);
530*1003ba15Sbostic }
531*1003ba15Sbostic
532*1003ba15Sbostic #endif /* SYSV2 || SYSV3 */
533*1003ba15Sbostic
534*1003ba15Sbostic #endif /* SIMPLE */
535*1003ba15Sbostic
536*1003ba15Sbostic #ifdef SIGVOID
537*1003ba15Sbostic void
538*1003ba15Sbostic #endif
time_out(signo)539*1003ba15Sbostic time_out(signo)
540*1003ba15Sbostic int signo;
541*1003ba15Sbostic {
542*1003ba15Sbostic #ifdef IEEE_MATH
543*1003ba15Sbostic (void)fpsetsticky((fp_except)0); /* Clear exception */
544*1003ba15Sbostic #endif /* IEEE_MATH */
545*1003ba15Sbostic longjmp(wakeup, -1);
546*1003ba15Sbostic }
547*1003ba15Sbostic
548*1003ba15Sbostic #ifdef SIGVOID
549*1003ba15Sbostic void
550*1003ba15Sbostic #endif
fpe_trap(signo)551*1003ba15Sbostic fpe_trap(signo)
552*1003ba15Sbostic int signo;
553*1003ba15Sbostic {
554*1003ba15Sbostic longjmp(fpe_buf, 1);
555*1003ba15Sbostic }
556*1003ba15Sbostic
557*1003ba15Sbostic /*
558*1003ba15Sbostic * This converts a floating point number of the form
559*1003ba15Sbostic * [s]ddd[.d*][esd*] where s can be a + or - and e is E or e.
560*1003ba15Sbostic * to floating point.
561*1003ba15Sbostic * p is advanced.
562*1003ba15Sbostic */
563*1003ba15Sbostic
564*1003ba15Sbostic char *
strtof(p,res)565*1003ba15Sbostic strtof(p, res)
566*1003ba15Sbostic register char *p;
567*1003ba15Sbostic double *res;
568*1003ba15Sbostic {
569*1003ba15Sbostic double acc;
570*1003ba15Sbostic int sign;
571*1003ba15Sbostic double fpos;
572*1003ba15Sbostic int exp;
573*1003ba15Sbostic int exps;
574*1003ba15Sbostic #ifdef SIGVOID
575*1003ba15Sbostic void (*sig_save)();
576*1003ba15Sbostic #else
577*1003ba15Sbostic int (*sig_save)();
578*1003ba15Sbostic #endif
579*1003ba15Sbostic
580*1003ba15Sbostic sig_save = signal(SIGFPE, fpe_trap);
581*1003ba15Sbostic if (setjmp(fpe_buf)) {
582*1003ba15Sbostic error("Floating point exception\n");
583*1003ba15Sbostic *res = 0.0;
584*1003ba15Sbostic (void) signal(SIGFPE, sig_save);
585*1003ba15Sbostic return(p);
586*1003ba15Sbostic }
587*1003ba15Sbostic acc = 0.0;
588*1003ba15Sbostic sign = 1;
589*1003ba15Sbostic exp = 0;
590*1003ba15Sbostic exps = 1;
591*1003ba15Sbostic if (*p == '+')
592*1003ba15Sbostic p++;
593*1003ba15Sbostic else if (*p == '-') {
594*1003ba15Sbostic p++;
595*1003ba15Sbostic sign = -1;
596*1003ba15Sbostic }
597*1003ba15Sbostic while (isdigit(*p)) {
598*1003ba15Sbostic acc = acc * 10.0 + (double)(*p - '0');
599*1003ba15Sbostic p++;
600*1003ba15Sbostic }
601*1003ba15Sbostic if (*p == 'e' || *p == 'E') {
602*1003ba15Sbostic p++;
603*1003ba15Sbostic if (*p == '+')
604*1003ba15Sbostic p++;
605*1003ba15Sbostic else if (*p == '-') {
606*1003ba15Sbostic p++;
607*1003ba15Sbostic exps = -1;
608*1003ba15Sbostic }
609*1003ba15Sbostic while(isdigit(*p)) {
610*1003ba15Sbostic exp = exp * 10 + (*p - '0');
611*1003ba15Sbostic p++;
612*1003ba15Sbostic }
613*1003ba15Sbostic }
614*1003ba15Sbostic if (*p == '.') {
615*1003ba15Sbostic fpos = 1.0/10.0;
616*1003ba15Sbostic p++;
617*1003ba15Sbostic while(isdigit(*p)) {
618*1003ba15Sbostic acc += (*p - '0') * fpos;
619*1003ba15Sbostic fpos *= 1.0/10.0;
620*1003ba15Sbostic p++;
621*1003ba15Sbostic }
622*1003ba15Sbostic }
623*1003ba15Sbostic if (*p == 'e' || *p == 'E') {
624*1003ba15Sbostic exp = 0;
625*1003ba15Sbostic exps = 1;
626*1003ba15Sbostic p++;
627*1003ba15Sbostic if (*p == '+')
628*1003ba15Sbostic p++;
629*1003ba15Sbostic else if (*p == '-') {
630*1003ba15Sbostic p++;
631*1003ba15Sbostic exps = -1;
632*1003ba15Sbostic }
633*1003ba15Sbostic while(isdigit(*p)) {
634*1003ba15Sbostic exp = exp * 10 + (*p - '0');
635*1003ba15Sbostic p++;
636*1003ba15Sbostic }
637*1003ba15Sbostic }
638*1003ba15Sbostic if (exp) {
639*1003ba15Sbostic if (exps > 0)
640*1003ba15Sbostic while (exp--)
641*1003ba15Sbostic acc *= 10.0;
642*1003ba15Sbostic else
643*1003ba15Sbostic while (exp--)
644*1003ba15Sbostic acc *= 1.0/10.0;
645*1003ba15Sbostic }
646*1003ba15Sbostic if (sign > 0)
647*1003ba15Sbostic *res = acc;
648*1003ba15Sbostic else
649*1003ba15Sbostic *res = -acc;
650*1003ba15Sbostic
651*1003ba15Sbostic (void) signal(SIGFPE, sig_save);
652*1003ba15Sbostic return(p);
653*1003ba15Sbostic }
654