2 /********************************************
4 copyright 1991, Michael D. Brennan
6 This is a source file for mawk, an implementation of
7 the AWK programming language.
9 Mawk is distributed without warranty under the terms of
10 the GNU General Public License, version 2, 1991.
11 ********************************************/
15 * Revision 1.6 1996/08/11 22:07:50 mike
16 * Fix small bozo in rt_error("overflow converting ...")
18 * Revision 1.5 1995/06/18 19:17:45 mike
19 * Create a type Int which on most machines is an int, but on machines
20 * with 16bit ints, i.e., the PC is a long. This fixes implicit assumption
23 * Revision 1.4 1995/06/06 00:02:02 mike
24 * fix cast in d_to_l()
26 * Revision 1.3 1993/07/17 13:22:45 mike
27 * indent and general code cleanup
29 * Revision 1.2 1993/07/04 12:51:41 mike
30 * start on autoconfig changes
32 * Revision 5.5 1993/03/06 18:49:45 mike
33 * rm rt_overflow from check_strnum
35 * Revision 5.4 1993/02/13 21:57:20 mike
38 * Revision 5.3.1.4 1993/01/22 15:05:19 mike
39 * pow2->mpow2 for linux
41 * Revision 5.3.1.3 1993/01/22 14:18:33 mike
42 * const for strtod and ansi picky compilers
44 * Revision 5.3.1.2 1993/01/20 12:53:06 mike
47 * Revision 5.3.1.1 1993/01/15 03:33:37 mike
48 * patch3: safer double to int conversion
50 * Revision 5.3 1992/11/28 23:48:42 mike
51 * For internal conversion numeric->string, when testing
52 * if integer, use longs instead of ints so 16 and 32 bit
53 * systems behave the same
55 * Revision 5.2 1992/08/17 14:19:45 brennan
56 * patch2: After parsing, only bi_sprintf() uses string_buff.
58 * Revision 5.1 1991/12/05 07:55:41 brennan
72 int mpow2[NUM_CELL_TYPES] =
73 {1, 2, 4, 8, 16, 32, 64, 128, 256, 512} ;
91 register STRING *s = (STRING *) cp->ptr ;
93 #if FPE_TRAPS_ON /* look for overflow error */
95 cp->dval = strtod(s->str, (char **) 0) ;
96 if (errno && cp->dval != 0.0) /* ignore underflow */
97 rt_error("overflow converting %s to double", s->str) ;
99 cp->dval = strtod(s->str, (char **) 0) ;
106 /* don't need to convert, but do need to free the STRING part */
107 free_STRING(string(cp)) ;
112 bozo("cast on bad type") ;
114 cp->type = C_DOUBLE ;
132 free_STRING(string(cp)) ;
137 s = (STRING *) cp->ptr ;
139 #if FPE_TRAPS_ON /* look for overflow error */
141 cp->dval = strtod(s->str, (char **) 0) ;
142 if (errno && cp->dval != 0.0) /* ignore underflow */
143 rt_error("overflow converting %s to double", s->str) ;
145 cp->dval = strtod(s->str, (char **) 0) ;
151 bozo("cast on bad type") ;
153 cp->type = C_DOUBLE ;
166 free_STRING(string(cp)) ;
171 s = (STRING *) cp->ptr ;
173 #if FPE_TRAPS_ON /* look for overflow error */
175 cp->dval = strtod(s->str, (char **) 0) ;
176 if (errno && cp->dval != 0.0) /* ignore underflow */
177 rt_error("overflow converting %s to double", s->str) ;
179 cp->dval = strtod(s->str, (char **) 0) ;
185 bozo("cast on bad type") ;
187 cp->type = C_DOUBLE ;
201 cp->ptr = (PTR) & null_str ;
206 lval = d_to_I(cp->dval) ;
207 if (lval == cp->dval) sprintf(xbuff, INT_FMT, lval) ;
208 else sprintf(xbuff, string(CONVFMT)->str, cp->dval) ;
210 cp->ptr = (PTR) new_STRING(xbuff) ;
221 bozo("bad type on cast") ;
223 cp->type = C_STRING ;
237 cp->ptr = (PTR) & null_str ;
242 lval = d_to_I(cp->dval) ;
243 if (lval == cp->dval) sprintf(xbuff, INT_FMT, lval) ;
244 else sprintf(xbuff, string(CONVFMT)->str, cp->dval) ;
246 cp->ptr = (PTR) new_STRING(xbuff) ;
257 bozo("bad type on cast") ;
259 cp->type = C_STRING ;
268 cp->ptr = (PTR) & null_str ;
273 lval = d_to_I(cp->dval) ;
274 if (lval == cp->dval) sprintf(xbuff, INT_FMT, lval) ;
275 else sprintf(xbuff, string(CONVFMT)->str, cp->dval) ;
277 cp->ptr = (PTR) new_STRING(xbuff) ;
288 bozo("bad type on cast") ;
290 cp->type = C_STRING ;
299 if (cp->type < C_STRING) cast1_to_s(cp) ;
301 p = re_compile(string(cp)) ;
302 free_STRING(string(cp)) ;
312 static char meta[] = "^$.*+?|[]()" ;
313 static char xbuff[] = "\\X" ;
317 if (cp->type < C_STRING) cast1_to_s(cp) ;
319 if ((len = string(cp)->len) == 1)
321 if ((c = string(cp)->str[0]) == ' ')
323 free_STRING(string(cp)) ;
327 else if (strchr(meta, c))
330 free_STRING(string(cp)) ;
331 cp->ptr = (PTR) new_STRING(xbuff) ;
336 free_STRING(string(cp)) ;
344 /* input: cp-> a CELL of type C_MBSTRN (maybe strnum)
345 test it -- casting it to the appropriate type
346 which is C_STRING or C_STRNUM
354 register unsigned char *s, *q ;
356 cp->type = C_STRING ; /* assume not C_STRNUM */
357 s = (unsigned char *) string(cp)->str ;
358 q = s + string(cp)->len ;
359 while (scan_code[*s] == SC_SPACE) s++ ;
362 while (scan_code[q[-1]] == SC_SPACE) q-- ;
363 if (scan_code[q[-1]] != SC_DIGIT &&
367 switch (scan_code[*s])
376 cp->dval = strtod((char *) s, &test) ;
377 /* make overflow pure string */
378 if (errno && cp->dval != 0.0) return ;
380 cp->dval = strtod((char *) s, &test) ;
383 if ((char *) q <= test) cp->type = C_STRNUM ;
384 /* <= instead of == , for some buggy strtod
389 /* cast a CELL to a replacement cell */
395 register STRING *sval ;
397 if (cp->type < C_STRING) cast1_to_s(cp) ;
398 sval = (STRING *) cp->ptr ;
400 cellcpy(cp, repl_compile(sval)) ;
405 /* convert a double to Int (this is not as simple as a
406 cast because the results are undefined if it won't fit).
407 Truncate large values to +Max_Int or -Max_Int
408 Send nans to -Max_Int
415 if (d >= Max_Int) return Max_Int ;
416 if (d > -Max_Int) return (Int) d ;