diff options
author | svn2git <svn2git@FreeBSD.org> | 1994-07-01 08:00:00 +0000 |
---|---|---|
committer | svn2git <svn2git@FreeBSD.org> | 1994-07-01 08:00:00 +0000 |
commit | 5e0e9b99dc3fc0ecd49d929db0d57c784b66f481 (patch) | |
tree | e779b5a6edddbb949b7990751b12d6f25304ba86 /gnu/usr.bin/awk/node.c | |
parent | a16f65c7d117419bd266c28a1901ef129a337569 (diff) |
Diffstat (limited to 'gnu/usr.bin/awk/node.c')
-rw-r--r-- | gnu/usr.bin/awk/node.c | 68 |
1 files changed, 51 insertions, 17 deletions
diff --git a/gnu/usr.bin/awk/node.c b/gnu/usr.bin/awk/node.c index 65ecb0ed1723..dca4ad191b9f 100644 --- a/gnu/usr.bin/awk/node.c +++ b/gnu/usr.bin/awk/node.c @@ -3,7 +3,7 @@ */ /* - * Copyright (C) 1986, 1988, 1989, 1991, 1992 the Free Software Foundation, Inc. + * Copyright (C) 1986, 1988, 1989, 1991, 1992, 1993 the Free Software Foundation, Inc. * * This file is part of GAWK, the GNU implementation of the * AWK Progamming Language. @@ -35,7 +35,7 @@ register NODE *n; register char *cpend; char save; char *ptr; - unsigned int newflags = 0; + unsigned int newflags; #ifdef DEBUG if (n == NULL) @@ -69,7 +69,8 @@ register NODE *n; if (n->flags & MAYBE_NUM) { newflags = NUMBER; n->flags &= ~MAYBE_NUM; - } + } else + newflags = 0; if (cpend - cp == 1) { if (isdigit(*cp)) { n->numbr = (AWKNUM)(*cp - '0'); @@ -101,7 +102,7 @@ register NODE *n; * (more complicated) variations on this theme didn't seem to pay off, but * systematic testing might be in order at some point */ -static char *values[] = { +static const char *values[] = { "0", "1", "2", @@ -121,7 +122,7 @@ register NODE *s; { char buf[128]; register char *sp = buf; - register long num = 0; + double val; #ifdef DEBUG if (s == NULL) cant_happen(); @@ -131,26 +132,56 @@ register NODE *s; if (s->stref != 0) ; /*cant_happen();*/ #endif - /* avoids floating point exception in DOS*/ - if ( s->numbr <= LONG_MAX && s->numbr >= -LONG_MAX) - num = (long)s->numbr; - if ((AWKNUM) num == s->numbr) { /* integral value */ + /* not an integral value, or out of range */ + if ((val = double_to_int(s->numbr)) != s->numbr + || val < LONG_MIN || val > LONG_MAX) { +#ifdef GFMT_WORKAROUND + NODE *dummy, *r; + unsigned short oflags; + extern NODE *format_tree P((const char *, int, NODE *)); + extern NODE **fmt_list; /* declared in eval.c */ + + /* create dummy node for a sole use of format_tree */ + getnode(dummy); + dummy->lnode = s; + dummy->rnode = NULL; + oflags = s->flags; + s->flags |= PERM; /* prevent from freeing by format_tree() */ + r = format_tree(CONVFMT, fmt_list[CONVFMTidx]->stlen, dummy); + s->flags = oflags; + s->stfmt = (char)CONVFMTidx; + s->stlen = r->stlen; + s->stptr = r->stptr; + freenode(r); /* Do not free_temp(r)! We want */ + freenode(dummy); /* to keep s->stptr == r->stpr. */ + + goto no_malloc; +#else + /* + * no need for a "replacement" formatting by gawk, + * just use sprintf + */ + sprintf(sp, CONVFMT, s->numbr); + s->stlen = strlen(sp); + s->stfmt = (char)CONVFMTidx; +#endif /* GFMT_WORKAROUND */ + } else { + /* integral value */ + /* force conversion to long only once */ + register long num = (long) val; if (num < NVAL && num >= 0) { - sp = values[num]; + sp = (char *) values[num]; s->stlen = 1; } else { (void) sprintf(sp, "%ld", num); s->stlen = strlen(sp); } s->stfmt = -1; - } else { - (void) sprintf(sp, CONVFMT, s->numbr); - s->stlen = strlen(sp); - s->stfmt = (char)CONVFMTidx; } - s->stref = 1; emalloc(s->stptr, char *, s->stlen + 2, "force_string"); memcpy(s->stptr, sp, s->stlen+1); +no_malloc: + s->stref = 1; s->flags |= STR; return s; } @@ -182,7 +213,8 @@ NODE *n; if (n->type == Node_val && (n->flags & STR)) { r->stref = 1; emalloc(r->stptr, char *, r->stlen + 2, "dupnode"); - memcpy(r->stptr, n->stptr, r->stlen+1); + memcpy(r->stptr, n->stptr, r->stlen); + r->stptr[r->stlen] = '\0'; } return r; } @@ -285,8 +317,10 @@ more_nodes() /* get more nodes and initialize list */ emalloc(nextfree, NODE *, NODECHUNK * sizeof(NODE), "newnode"); - for (np = nextfree; np < &nextfree[NODECHUNK - 1]; np++) + for (np = nextfree; np < &nextfree[NODECHUNK - 1]; np++) { + np->flags = 0; np->nextp = np + 1; + } np->nextp = NULL; np = nextfree; nextfree = nextfree->nextp; |