added hcl_truncfpdevcal().
fixed bugs in sprintf
This commit is contained in:
parent
16b96e49bc
commit
6ed4d2e705
@ -990,6 +990,13 @@ hcl_oop_t hcl_divnums (
|
|||||||
hcl_oop_t y
|
hcl_oop_t y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
hcl_oop_t hcl_truncfpdecval (
|
||||||
|
hcl_t* hcl,
|
||||||
|
hcl_oop_t iv, /* integer */
|
||||||
|
hcl_ooi_t cs, /* current scale */
|
||||||
|
hcl_ooi_t ns /* new scale */
|
||||||
|
);
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
/* comp.c */
|
/* comp.c */
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
85
lib/logfmt.c
85
lib/logfmt.c
@ -520,7 +520,7 @@ static int put_prch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len)
|
|||||||
|
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
seglen = (len > HCL_COUNTOF(str))? len = HCL_COUNTOF(str): len;
|
seglen = (len > HCL_COUNTOF(str))? HCL_COUNTOF(str): len;
|
||||||
for (i = 0; i < seglen; i++) str[i] = ch;
|
for (i = 0; i < seglen; i++) str[i] = ch;
|
||||||
|
|
||||||
n = put_prcs (hcl, mask, str, seglen);
|
n = put_prcs (hcl, mask, str, seglen);
|
||||||
@ -949,24 +949,55 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t
|
|||||||
case 'i': /* signed conversion */
|
case 'i': /* signed conversion */
|
||||||
base = 10;
|
base = 10;
|
||||||
sign = 1;
|
sign = 1;
|
||||||
goto number;
|
goto print_integer;
|
||||||
case 'o':
|
case 'o':
|
||||||
base = 8;
|
base = 8;
|
||||||
goto number;
|
goto print_integer;
|
||||||
case 'u':
|
case 'u':
|
||||||
base = 10;
|
base = 10;
|
||||||
goto number;
|
goto print_integer;
|
||||||
case 'X':
|
case 'X':
|
||||||
base = 16;
|
base = 16;
|
||||||
goto number;
|
goto print_integer;
|
||||||
case 'x':
|
case 'x':
|
||||||
base = -16;
|
base = -16;
|
||||||
goto number;
|
goto print_integer;
|
||||||
case 'b':
|
case 'b':
|
||||||
base = 2;
|
base = 2;
|
||||||
goto number;
|
goto print_integer;
|
||||||
/* end of integer conversions */
|
/* end of integer conversions */
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
{
|
||||||
|
const hcl_ooch_t* nsptr;
|
||||||
|
hcl_oow_t nslen;
|
||||||
|
hcl_oow_t scale = 0;
|
||||||
|
|
||||||
|
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
|
||||||
|
if (HCL_OOP_IS_CHAR(arg))
|
||||||
|
{
|
||||||
|
arg = HCL_SMOOI_TO_OOP(HCL_OOP_TO_CHAR(arg));
|
||||||
|
}
|
||||||
|
else if (HCL_IS_FPDEC(hcl, arg))
|
||||||
|
{
|
||||||
|
hcl_oop_fpdec_t fa = (hcl_oop_fpdec_t)arg;
|
||||||
|
scale = HCL_OOP_TO_SMOOI(fa->scale);
|
||||||
|
arg = fa->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hcl_inttostr(hcl, arg, 10, -1))
|
||||||
|
{
|
||||||
|
HCL_LOG1 (hcl, HCL_LOG_WARN | HCL_LOG_UNTYPED, "unable to convert integer %O to string \n", arg);
|
||||||
|
goto invalid_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsptr = hcl->inttostr.xbuf.ptr;
|
||||||
|
nslen = hcl->inttostr.xbuf.len;
|
||||||
|
|
||||||
|
PRINT_OOCS (nsptr, nslen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'C':
|
case 'C':
|
||||||
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
|
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
|
||||||
@ -1022,24 +1053,55 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t
|
|||||||
if (hcl_outfmtobj(hcl, (data->mask | HCL_LOG_PREFER_JSON), arg, outbfmt) <= -1) goto oops;
|
if (hcl_outfmtobj(hcl, (data->mask | HCL_LOG_PREFER_JSON), arg, outbfmt) <= -1) goto oops;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
number:
|
print_integer:
|
||||||
{
|
{
|
||||||
const hcl_ooch_t* nsptr;
|
const hcl_ooch_t* nsptr;
|
||||||
hcl_oow_t nslen;
|
hcl_oow_t nslen;
|
||||||
|
|
||||||
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
|
GET_NEXT_ARG_TO (hcl, nargs, &arg_state, arg);
|
||||||
if (HCL_OOP_IS_CHAR(arg)) arg = HCL_SMOOI_TO_OOP(HCL_OOP_TO_CHAR(arg));
|
if (HCL_OOP_IS_CHAR(arg))
|
||||||
|
{
|
||||||
|
arg = HCL_SMOOI_TO_OOP(HCL_OOP_TO_CHAR(arg));
|
||||||
|
}
|
||||||
|
else if (HCL_IS_FPDEC(hcl, arg))
|
||||||
|
{
|
||||||
|
hcl_oop_t nv;
|
||||||
|
hcl_oop_fpdec_t fa = (hcl_oop_fpdec_t)arg;
|
||||||
|
|
||||||
|
/* the given number for integer output is a fixed-point decimal.
|
||||||
|
* i will drop all digits after the fixed point */
|
||||||
|
hcl_pushtmp (hcl, &arg);
|
||||||
|
nv = hcl_truncfpdecval(hcl, fa->value, HCL_OOP_TO_SMOOI(fa->scale), 0);
|
||||||
|
hcl_poptmp (hcl);
|
||||||
|
if (!nv)
|
||||||
|
{
|
||||||
|
HCL_LOG1 (hcl, HCL_LOG_WARN | HCL_LOG_UNTYPED, "unable to truncate a fixed-point number %O to an integer for output\n", arg);
|
||||||
|
goto invalid_format;
|
||||||
|
}
|
||||||
|
|
||||||
|
arg = nv;
|
||||||
|
}
|
||||||
|
|
||||||
if (!hcl_inttostr(hcl, arg, base, -1))
|
if (!hcl_inttostr(hcl, arg, base, -1))
|
||||||
{
|
{
|
||||||
/*hcl_seterrbfmt (hcl, HCL_EINVAL, "not a valid number - %O", arg);
|
/*hcl_seterrbfmt (hcl, HCL_EINVAL, "not a valid number - %O", arg);
|
||||||
goto oops;*/
|
goto oops;*/
|
||||||
|
HCL_LOG1 (hcl, HCL_LOG_WARN | HCL_LOG_UNTYPED, "unable to convert integer %O to string \n", arg);
|
||||||
goto invalid_format;
|
goto invalid_format;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsptr = hcl->inttostr.xbuf.ptr;
|
nsptr = hcl->inttostr.xbuf.ptr;
|
||||||
nslen = hcl->inttostr.xbuf.len;
|
nslen = hcl->inttostr.xbuf.len;
|
||||||
|
|
||||||
|
if (nsptr[0] == '-')
|
||||||
|
{
|
||||||
|
/* a negative number was given. i must skip the minus sign
|
||||||
|
* added by hcl_inttostr() for a negative number. */
|
||||||
|
HCL_ASSERT (hcl, (HCL_OOP_IS_SMOOI(arg) && HCL_OOP_TO_SMOOI(arg) < 0) || HCL_IS_NBIGINT(hcl,arg));
|
||||||
|
nsptr++;
|
||||||
|
nslen--;
|
||||||
|
}
|
||||||
|
|
||||||
extra = nslen;
|
extra = nslen;
|
||||||
if (sign && ((HCL_OOP_IS_SMOOI(arg) && HCL_OOP_TO_SMOOI(arg) < 0) || HCL_IS_NBIGINT(hcl,arg))) neg = 1;
|
if (sign && ((HCL_OOP_IS_SMOOI(arg) && HCL_OOP_TO_SMOOI(arg) < 0) || HCL_IS_NBIGINT(hcl,arg))) neg = 1;
|
||||||
|
|
||||||
@ -1175,7 +1237,7 @@ int hcl_logfmtst (hcl_t* hcl, hcl_ooi_t nargs)
|
|||||||
* -------------------------------------------------------------------------- */
|
* -------------------------------------------------------------------------- */
|
||||||
static int put_sprcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len)
|
static int put_sprcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len)
|
||||||
{
|
{
|
||||||
if (hcl->sprintf.xbuf.len >= hcl->sprintf.xbuf.capa)
|
if (len > hcl->sprintf.xbuf.capa - hcl->sprintf.xbuf.len)
|
||||||
{
|
{
|
||||||
hcl_ooch_t* tmp;
|
hcl_ooch_t* tmp;
|
||||||
hcl_oow_t newcapa;
|
hcl_oow_t newcapa;
|
||||||
@ -1197,7 +1259,7 @@ static int put_sprcs (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hcl_oow_t len
|
|||||||
|
|
||||||
static int put_sprch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len)
|
static int put_sprch (hcl_t* hcl, int mask, hcl_ooch_t ch, hcl_oow_t len)
|
||||||
{
|
{
|
||||||
if (hcl->sprintf.xbuf.len >= hcl->sprintf.xbuf.capa)
|
if (len > hcl->sprintf.xbuf.capa - hcl->sprintf.xbuf.len)
|
||||||
{
|
{
|
||||||
hcl_ooch_t* tmp;
|
hcl_ooch_t* tmp;
|
||||||
hcl_oow_t newcapa;
|
hcl_oow_t newcapa;
|
||||||
@ -1288,6 +1350,7 @@ hcl_ooi_t hcl_sproutufmt (hcl_t* hcl, int mask, const hcl_uch_t* fmt, ...)
|
|||||||
int hcl_sprintfmtst (hcl_t* hcl, hcl_ooi_t nargs)
|
int hcl_sprintfmtst (hcl_t* hcl, hcl_ooi_t nargs)
|
||||||
{
|
{
|
||||||
hcl_fmtout_t fo;
|
hcl_fmtout_t fo;
|
||||||
|
|
||||||
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
|
HCL_MEMSET (&fo, 0, HCL_SIZEOF(fo));
|
||||||
fo.putch = put_sprch;
|
fo.putch = put_sprch;
|
||||||
fo.putcs = put_sprcs;
|
fo.putcs = put_sprcs;
|
||||||
|
@ -96,7 +96,7 @@ static hcl_ooi_t equalize_scale (hcl_t* hcl, hcl_oop_t* x, hcl_oop_t* y)
|
|||||||
return xs;
|
return xs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hcl_oop_t truncate (hcl_t* hcl, hcl_oop_t iv, hcl_ooi_t cs, hcl_ooi_t ns)
|
hcl_oop_t hcl_truncfpdecval (hcl_t* hcl, hcl_oop_t iv, hcl_ooi_t cs, hcl_ooi_t ns)
|
||||||
{
|
{
|
||||||
/* this function truncates an existing fixed-point decimal.
|
/* this function truncates an existing fixed-point decimal.
|
||||||
* it doesn't create a new object */
|
* it doesn't create a new object */
|
||||||
@ -218,7 +218,7 @@ hcl_oop_t hcl_mulnums (hcl_t* hcl, hcl_oop_t x, hcl_oop_t y)
|
|||||||
* equal to or less than HCL_SMOOI_MAX */
|
* equal to or less than HCL_SMOOI_MAX */
|
||||||
HCL_ASSERT (hcl, ns > 0 && ns <= HCL_SMOOI_MAX);
|
HCL_ASSERT (hcl, ns > 0 && ns <= HCL_SMOOI_MAX);
|
||||||
|
|
||||||
nv = truncate(hcl, nv, cs, ns);
|
nv = hcl_truncfpdecval(hcl, nv, cs, ns);
|
||||||
if (!nv) return HCL_NULL;
|
if (!nv) return HCL_NULL;
|
||||||
|
|
||||||
return hcl_makefpdec(hcl, nv, ns);
|
return hcl_makefpdec(hcl, nv, ns);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user