enhanced hcl_inttostr() to keep results in the temporary buffer when ngc is negative.
changed the integer printing function to utilize this change in print.c
This commit is contained in:
parent
46a4bd1561
commit
2a0551df2d
81
lib/bigint.c
81
lib/bigint.c
@ -3954,7 +3954,6 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
|
|||||||
hcl_liw_t* t = HCL_NULL;
|
hcl_liw_t* t = HCL_NULL;
|
||||||
hcl_ooch_t* xbuf = HCL_NULL;
|
hcl_ooch_t* xbuf = HCL_NULL;
|
||||||
hcl_oow_t xlen = 0, seglen, reqcapa;
|
hcl_oow_t xlen = 0, seglen, reqcapa;
|
||||||
hcl_oop_t s;
|
|
||||||
|
|
||||||
HCL_ASSERT (hcl, radix >= 2 && radix <= 36);
|
HCL_ASSERT (hcl, radix >= 2 && radix <= 36);
|
||||||
|
|
||||||
@ -3963,19 +3962,36 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
|
|||||||
|
|
||||||
if (v)
|
if (v)
|
||||||
{
|
{
|
||||||
/* Use a static buffer for simple conversion as the largest
|
/* The largest buffer is required for radix 2.
|
||||||
* size is known. The largest buffer is required for radix 2.
|
|
||||||
* For a binary conversion(radix 2), the number of bits is
|
* For a binary conversion(radix 2), the number of bits is
|
||||||
* the maximum number of digits that can be produced. +1 is
|
* the maximum number of digits that can be produced. +1 is
|
||||||
* needed for the sign. */
|
* needed for the sign. */
|
||||||
hcl_ooch_t buf[HCL_OOW_BITS + 1];
|
|
||||||
hcl_oow_t len;
|
|
||||||
|
|
||||||
len = oow_to_text(hcl, w, radix, buf);
|
reqcapa = HCL_OOW_BITS + 1;
|
||||||
if (v < 0) buf[len++] = '-';
|
if (hcl->inttostr.xbuf.capa < reqcapa)
|
||||||
|
{
|
||||||
|
xbuf = (hcl_ooch_t*)hcl_reallocmem(hcl, hcl->inttostr.xbuf.ptr, reqcapa);
|
||||||
|
if (!xbuf) return HCL_NULL;
|
||||||
|
hcl->inttostr.xbuf.capa = reqcapa;
|
||||||
|
hcl->inttostr.xbuf.ptr = xbuf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xbuf = hcl->inttostr.xbuf.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
reverse_string (buf, len);
|
xlen = oow_to_text(hcl, w, radix, xbuf);
|
||||||
return hcl_makestring(hcl, buf, len, ngc);
|
if (v < 0) xbuf[xlen++] = '-';
|
||||||
|
|
||||||
|
reverse_string (xbuf, xlen);
|
||||||
|
if (ngc < 0)
|
||||||
|
{
|
||||||
|
/* special case. don't create a new object.
|
||||||
|
* the caller can use the data left in hcl->inttostr.xbuf */
|
||||||
|
hcl->inttostr.xbuf.len = xlen;
|
||||||
|
return hcl->_nil;
|
||||||
|
}
|
||||||
|
return hcl_makestring(hcl, xbuf, xlen, ngc);
|
||||||
}
|
}
|
||||||
|
|
||||||
as = HCL_OBJ_GET_SIZE(num);
|
as = HCL_OBJ_GET_SIZE(num);
|
||||||
@ -3990,10 +4006,6 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
|
|||||||
xlen = as * ((HCL_LIW_BITS + exp) / exp) + 1;
|
xlen = as * ((HCL_LIW_BITS + exp) / exp) + 1;
|
||||||
xpos = xlen;
|
xpos = xlen;
|
||||||
|
|
||||||
#if 0
|
|
||||||
xbuf = (hcl_ooch_t*)hcl_allocmem(hcl, HCL_SIZEOF(*xbuf) * xlen);
|
|
||||||
if (!xbuf) return HCL_NULL;
|
|
||||||
#else
|
|
||||||
reqcapa = HCL_SIZEOF(*xbuf) * xlen;
|
reqcapa = HCL_SIZEOF(*xbuf) * xlen;
|
||||||
if (hcl->inttostr.xbuf.capa < reqcapa)
|
if (hcl->inttostr.xbuf.capa < reqcapa)
|
||||||
{
|
{
|
||||||
@ -4006,7 +4018,6 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
|
|||||||
{
|
{
|
||||||
xbuf = hcl->inttostr.xbuf.ptr;
|
xbuf = hcl->inttostr.xbuf.ptr;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
acc = 0;
|
acc = 0;
|
||||||
accbits = 0;
|
accbits = 0;
|
||||||
@ -4038,27 +4049,20 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
|
|||||||
HCL_ASSERT (hcl, xpos >= 1);
|
HCL_ASSERT (hcl, xpos >= 1);
|
||||||
if (HCL_IS_NBIGINT(hcl, num)) xbuf[--xpos] = '-';
|
if (HCL_IS_NBIGINT(hcl, num)) xbuf[--xpos] = '-';
|
||||||
|
|
||||||
s = hcl_makestring(hcl, &xbuf[xpos], xlen - xpos, ngc);
|
if (ngc < 0)
|
||||||
#if 0
|
{
|
||||||
hcl_freemem (hcl, xbuf);
|
/* special case. don't create a new object.
|
||||||
#endif
|
* the caller can use the data left in hcl->inttostr.xbuf */
|
||||||
return s;
|
HCL_MEMMOVE (&xbuf[0], &xbuf[xpos], HCL_SIZEOF(*xbuf) * (xlen - xpos));
|
||||||
|
hcl->inttostr.xbuf.len = xlen - xpos;
|
||||||
|
return hcl->_nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hcl_makestring(hcl, &xbuf[xpos], xlen - xpos, ngc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do it in a hard way for other cases */
|
/* Do it in a hard way for other cases */
|
||||||
/* TODO: migrate these buffers into hcl_t? */
|
|
||||||
/* TODO: find an optimial buffer size */
|
/* TODO: find an optimial buffer size */
|
||||||
#if 0
|
|
||||||
xbuf = (hcl_ooch_t*)hcl_allocmem (hcl, HCL_SIZEOF(*xbuf) * (as * HCL_LIW_BITS + 1));
|
|
||||||
if (!xbuf) return HCL_NULL;
|
|
||||||
|
|
||||||
t = (hcl_liw_t*)hcl_callocmem(hcl, HCL_SIZEOF(*t) * as * 3);
|
|
||||||
if (!t)
|
|
||||||
{
|
|
||||||
hcl_freemem (hcl, xbuf);
|
|
||||||
return HCL_NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
reqcapa = HCL_SIZEOF(*xbuf) * (as * HCL_LIW_BITS + 1);
|
reqcapa = HCL_SIZEOF(*xbuf) * (as * HCL_LIW_BITS + 1);
|
||||||
if (hcl->inttostr.xbuf.capa < reqcapa)
|
if (hcl->inttostr.xbuf.capa < reqcapa)
|
||||||
{
|
{
|
||||||
@ -4084,7 +4088,6 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
|
|||||||
{
|
{
|
||||||
t = hcl->inttostr.t.ptr;
|
t = hcl->inttostr.t.ptr;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (HCL_LIW_BITS == HCL_OOW_BITS)
|
#if (HCL_LIW_BITS == HCL_OOW_BITS)
|
||||||
b[0] = hcl->bigint[radix].multiplier; /* block divisor */
|
b[0] = hcl->bigint[radix].multiplier; /* block divisor */
|
||||||
@ -4157,13 +4160,15 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
|
|||||||
|
|
||||||
if (HCL_IS_NBIGINT(hcl, num)) xbuf[xlen++] = '-';
|
if (HCL_IS_NBIGINT(hcl, num)) xbuf[xlen++] = '-';
|
||||||
reverse_string (xbuf, xlen);
|
reverse_string (xbuf, xlen);
|
||||||
s = hcl_makestring(hcl, xbuf, xlen, ngc);
|
if (ngc < 0)
|
||||||
|
{
|
||||||
|
/* special case. don't create a new object.
|
||||||
|
* the caller can use the data left in hcl->inttostr.xbuf */
|
||||||
|
hcl->inttostr.xbuf.len = xlen;
|
||||||
|
return hcl->_nil;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
return hcl_makestring(hcl, xbuf, xlen, ngc);
|
||||||
hcl_freemem (hcl, t);
|
|
||||||
hcl_freemem (hcl, xbuf);
|
|
||||||
#endif
|
|
||||||
return s;
|
|
||||||
|
|
||||||
oops_einval:
|
oops_einval:
|
||||||
hcl_seterrnum (hcl, HCL_EINVAL);
|
hcl_seterrnum (hcl, HCL_EINVAL);
|
||||||
|
@ -970,6 +970,15 @@ hcl_oop_t hcl_strtoint (
|
|||||||
int radix
|
int radix
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hcl_inttostr() function converts an integer object to a string object
|
||||||
|
* printed in the given radix. If ngc is 0, it creates a normal string object
|
||||||
|
* managed by object memory manager. If ngc greater than 0, it creates a non-GC
|
||||||
|
* string object that should be destroyed with hcl_freengcobj() later. If ngc
|
||||||
|
* is less than 0, it returns hcl->_nil but keeps the result in the buffer
|
||||||
|
* pointed to by hcl->inttostr.xbuf.ptr with the length stored in
|
||||||
|
* hcl->inttostr.xbuf.len. If the function fails, it returns #HCL_NULL.
|
||||||
|
*/
|
||||||
hcl_oop_t hcl_inttostr (
|
hcl_oop_t hcl_inttostr (
|
||||||
hcl_t* hcl,
|
hcl_t* hcl,
|
||||||
hcl_oop_t num,
|
hcl_oop_t num,
|
||||||
@ -977,7 +986,6 @@ hcl_oop_t hcl_inttostr (
|
|||||||
int ngc
|
int ngc
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
/* print.c */
|
/* print.c */
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -236,6 +236,7 @@ void hcl_fini (hcl_t* hcl)
|
|||||||
hcl_freemem (hcl, hcl->inttostr.xbuf.ptr);
|
hcl_freemem (hcl, hcl->inttostr.xbuf.ptr);
|
||||||
hcl->inttostr.xbuf.ptr = HCL_NULL;
|
hcl->inttostr.xbuf.ptr = HCL_NULL;
|
||||||
hcl->inttostr.xbuf.capa = 0;
|
hcl->inttostr.xbuf.capa = 0;
|
||||||
|
hcl->inttostr.xbuf.len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hcl->inttostr.t.ptr)
|
if (hcl->inttostr.t.ptr)
|
||||||
|
@ -1017,6 +1017,7 @@ struct hcl_t
|
|||||||
{
|
{
|
||||||
hcl_uch_t* ptr;
|
hcl_uch_t* ptr;
|
||||||
hcl_oow_t capa;
|
hcl_oow_t capa;
|
||||||
|
hcl_oow_t len;
|
||||||
} xbuf;
|
} xbuf;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
18
lib/print.c
18
lib/print.c
@ -156,18 +156,16 @@ next:
|
|||||||
case HCL_BRAND_PBIGINT:
|
case HCL_BRAND_PBIGINT:
|
||||||
case HCL_BRAND_NBIGINT:
|
case HCL_BRAND_NBIGINT:
|
||||||
{
|
{
|
||||||
hcl_oop_t str;
|
hcl_oop_t tmp;
|
||||||
|
|
||||||
/* TODO: can i do this without memory allocation? */
|
/* -1 to drive hcl_inttostr() to not create a new string object.
|
||||||
str = hcl_inttostr(hcl, obj, 10, 1); /* inttostr with ngc on. not using object memory */
|
* not using the object memory. the result stays in the temporary
|
||||||
if (!str) return -1;
|
* buffer */
|
||||||
|
tmp = hcl_inttostr(hcl, obj, 10, -1);
|
||||||
|
if (!tmp) return -1;
|
||||||
|
|
||||||
if (outbfmt(hcl, mask, "%.*js", HCL_OBJ_GET_SIZE(str), HCL_OBJ_GET_CHAR_SLOT(str)) <= -1)
|
HCL_ASSERT (hcl, (hcl_oop_t)tmp == hcl->_nil);
|
||||||
{
|
if (outbfmt(hcl, mask, "%.*js", hcl->inttostr.xbuf.len, hcl->inttostr.xbuf.ptr) <= -1) return -1;
|
||||||
hcl_freengcobj (hcl, str);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
hcl_freengcobj (hcl, str);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
37
lib/read.c
37
lib/read.c
@ -195,6 +195,7 @@ static hcl_oop_t string_to_num (hcl_t* hcl, hcl_oocs_t* str, int radixed)
|
|||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (radixed)
|
if (radixed)
|
||||||
{
|
{
|
||||||
HCL_ASSERT (hcl, ptr < end);
|
HCL_ASSERT (hcl, ptr < end);
|
||||||
@ -210,10 +211,34 @@ static hcl_oop_t string_to_num (hcl_t* hcl, hcl_oocs_t* str, int radixed)
|
|||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
else base = 10;
|
else base = 10;
|
||||||
|
#else
|
||||||
|
if (radixed)
|
||||||
|
{
|
||||||
|
HCL_ASSERT (hcl, ptr < end);
|
||||||
|
|
||||||
|
if (*ptr != '#')
|
||||||
|
{
|
||||||
|
hcl_seterrnum (hcl, HCL_EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ptr++; /* skip '#' */
|
||||||
|
|
||||||
|
if (*ptr == 'x') base = 16;
|
||||||
|
else if (*ptr == 'o') base = 8;
|
||||||
|
else if (*ptr == 'b') base = 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hcl_seterrnum (hcl, HCL_EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
else base = 10;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: handle floating point numbers ... etc */
|
/* TODO: handle floating point numbers ... etc */
|
||||||
if (negsign) base = -base;
|
if (negsign) base = -base;
|
||||||
return hcl_strtoint (hcl, ptr, end - ptr, base);
|
return hcl_strtoint(hcl, ptr, end - ptr, base);
|
||||||
}
|
}
|
||||||
static HCL_INLINE int is_spacechar (hcl_ooci_t c)
|
static HCL_INLINE int is_spacechar (hcl_ooci_t c)
|
||||||
{
|
{
|
||||||
@ -1878,7 +1903,7 @@ static int read_object (hcl_t* hcl)
|
|||||||
hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
hcl_setsynerr (hcl, HCL_SYNERR_VBARBANNED, TOKEN_LOC(hcl), TOKEN_NAME(hcl));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (get_symbol_array_literal (hcl, &obj) <= -1) return -1;
|
if (get_symbol_array_literal(hcl, &obj) <= -1) return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case HCL_IOTOK_NIL:
|
case HCL_IOTOK_NIL:
|
||||||
@ -1899,12 +1924,12 @@ static int read_object (hcl_t* hcl)
|
|||||||
|
|
||||||
case HCL_IOTOK_NUMLIT:
|
case HCL_IOTOK_NUMLIT:
|
||||||
case HCL_IOTOK_RADNUMLIT:
|
case HCL_IOTOK_RADNUMLIT:
|
||||||
obj = string_to_num(hcl, TOKEN_NAME(hcl), TOKEN_TYPE(hcl) == HCL_IOTOK_RADNUMLIT);
|
obj = string_to_num(hcl, TOKEN_NAME(hcl), TOKEN_TYPE(hcl) == HCL_IOTOK_RADNUMLIT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
case HCL_IOTOK_REAL:
|
case HCL_IOTOK_REAL:
|
||||||
obj = hcl_makerealnum (hcl, HCL_IOTOK_RVAL(hcl));
|
obj = hcl_makerealnum(hcl, HCL_IOTOK_RVAL(hcl));
|
||||||
break;
|
break;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1923,7 +1948,7 @@ static int read_object (hcl_t* hcl)
|
|||||||
hcl_pfbase_t* pfbase;
|
hcl_pfbase_t* pfbase;
|
||||||
hcl_oop_t prim;
|
hcl_oop_t prim;
|
||||||
|
|
||||||
pfbase = hcl_querymod (hcl, TOKEN_NAME_PTR(hcl), TOKEN_NAME_LEN(hcl));
|
pfbase = hcl_querymod(hcl, TOKEN_NAME_PTR(hcl), TOKEN_NAME_LEN(hcl));
|
||||||
if (!pfbase)
|
if (!pfbase)
|
||||||
{
|
{
|
||||||
/* TODO switch to syntax error */
|
/* TODO switch to syntax error */
|
||||||
|
Loading…
Reference in New Issue
Block a user