enhanced hcl_inttostr() to accept a negative radix to produce lower-case alphabetic digits

This commit is contained in:
hyung-hwan 2018-02-28 15:57:19 +00:00
parent ed729adc2e
commit 09302470f7
5 changed files with 50 additions and 47 deletions

View File

@ -40,7 +40,8 @@
#define IS_SIGN_DIFF(x,y) (((x) ^ (y)) < 0) #define IS_SIGN_DIFF(x,y) (((x) ^ (y)) < 0)
/* digit character array */ /* digit character array */
static char _digitc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static char _digitc_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static char _digitc_lower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/* exponent table */ /* exponent table */
static hcl_uint8_t _exp_tab[] = static hcl_uint8_t _exp_tab[] =
@ -3761,6 +3762,19 @@ oops_einval:
static hcl_oow_t oow_to_text (hcl_t* hcl, hcl_oow_t w, int radix, hcl_ooch_t* buf) static hcl_oow_t oow_to_text (hcl_t* hcl, hcl_oow_t w, int radix, hcl_ooch_t* buf)
{ {
hcl_ooch_t* ptr; hcl_ooch_t* ptr;
const char* _digitc;
if (radix < 0)
{
_digitc = _digitc_lower;
radix = -radix;
}
else
{
_digitc = _digitc_upper;
}
HCL_ASSERT (hcl, radix >= 2 && radix <= 36); HCL_ASSERT (hcl, radix >= 2 && radix <= 36);
ptr = buf; ptr = buf;
@ -3955,6 +3969,18 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
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;
const char* _digitc;
int orgradix = radix;
if (radix < 0)
{
_digitc = _digitc_lower;
radix = -radix;
}
else
{
_digitc = _digitc_upper;
}
HCL_ASSERT (hcl, radix >= 2 && radix <= 36); HCL_ASSERT (hcl, radix >= 2 && radix <= 36);
if (!hcl_isint(hcl,num)) goto oops_einval; if (!hcl_isint(hcl,num)) goto oops_einval;
@ -3980,7 +4006,7 @@ 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;
} }
xlen = oow_to_text(hcl, w, radix, xbuf); xlen = oow_to_text(hcl, w, orgradix, xbuf);
if (v < 0) xbuf[xlen++] = '-'; if (v < 0) xbuf[xlen++] = '-';
reverse_string (xbuf, xlen); reverse_string (xbuf, xlen);
@ -4144,7 +4170,7 @@ hcl_oop_t hcl_inttostr (hcl_t* hcl, hcl_oop_t num, int radix, int ngc)
#else #else
# error UNSUPPORTED LIW BIT SIZE # error UNSUPPORTED LIW BIT SIZE
#endif #endif
seglen = oow_to_text (hcl, w, radix, &xbuf[xlen]); seglen = oow_to_text (hcl, w, orgradix, &xbuf[xlen]);
xlen += seglen; xlen += seglen;
if (r == a) break; /* reached the last block */ if (r == a) break; /* reached the last block */

View File

@ -1063,6 +1063,10 @@ int hcl_outfmtobj (
hcl_outbfmt_t outbfmt hcl_outbfmt_t outbfmt
); );
int hcl_printfmt (
hcl_t* hcl,
hcl_ooi_t nargs
);
#if defined(__cplusplus) #if defined(__cplusplus)
} }

View File

@ -1,28 +0,0 @@
/*
* $Id$
*
Copyright (c) 2016-2018 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "hcl-prv.h"

View File

@ -724,6 +724,9 @@ void hcl_seterrufmtv (hcl_t* hcl, hcl_errnum_t errnum, const hcl_uch_t* fmt, va_
* -------------------------------------------------------------------------- */ * -------------------------------------------------------------------------- */
#if 1 #if 1
#if 0
static int put_formatted_chars (hcl_t* hcl, int mask, const hcl_ooch_t ch, hcl_oow_t len) static int put_formatted_chars (hcl_t* hcl, int mask, const hcl_ooch_t ch, hcl_oow_t len)
{ {
/* TODO: better error handling, buffering. /* TODO: better error handling, buffering.
@ -766,12 +769,12 @@ static int put_formatted_string (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hc
if (n == 0) return 0; /* eof. stop printing */ if (n == 0) return 0; /* eof. stop printing */
return 1; /* success */ return 1; /* success */
} }
#endif
#define PRINT_OOCH(c,n) do { \ #define PRINT_OOCH(c,n) do { \
if (n > 0) { \ if (n > 0) { \
int xx; \ int xx; \
if ((xx = put_formatted_chars(hcl, data->mask, c, n)) <= -1) goto oops; \ if ((xx = put_prch(hcl, data->mask, c, n)) <= -1) goto oops; \
if (xx == 0) goto done; \ if (xx == 0) goto done; \
data->count += n; \ data->count += n; \
} \ } \
@ -780,7 +783,7 @@ static int put_formatted_string (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hc
#define PRINT_OOCS(ptr,len) do { \ #define PRINT_OOCS(ptr,len) do { \
if (len > 0) { \ if (len > 0) { \
int xx; \ int xx; \
if ((xx = put_formatted_string(hcl, data->mask, ptr, len)) <= -1) goto oops; \ if ((xx = put_prcs(hcl, data->mask, ptr, len)) <= -1) goto oops; \
if (xx == 0) goto done; \ if (xx == 0) goto done; \
data->count += len; \ data->count += len; \
} \ } \
@ -789,8 +792,9 @@ static int put_formatted_string (hcl_t* hcl, int mask, const hcl_ooch_t* ptr, hc
static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t* data) static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t* data)
{ {
hcl_oop_char_t fmtoop; hcl_oop_char_t fmtoop;
hcl_ooch_t* fmt, * fmtend;
const hcl_ooch_t* checkpoint, * percent;
//hcl_bch_t nbuf[MAXNBUF], bch;
int n, base, neg, sign; int n, base, neg, sign;
hcl_ooi_t tmp, width, precision; hcl_ooi_t tmp, width, precision;
hcl_ooch_t ch, padc, ooch; hcl_ooch_t ch, padc, ooch;
@ -798,9 +802,6 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t
hcl_uintmax_t num = 0; hcl_uintmax_t num = 0;
int stop = 0; int stop = 0;
hcl_ooch_t* fmt, * fmtend;
const hcl_ooch_t* checkpoint, * percent;
hcl_oop_t arg; hcl_oop_t arg;
hcl_ooi_t argidx = 0; hcl_ooi_t argidx = 0;
@ -833,7 +834,6 @@ static HCL_INLINE int print_formatted (hcl_t* hcl, hcl_ooi_t nargs, hcl_fmtout_t
neg = 0; sign = 0; neg = 0; sign = 0;
lm_flag = 0; lm_dflag = 0; flagc = 0; lm_flag = 0; lm_dflag = 0; flagc = 0;
//sprintn = sprintn_lower;
reswitch: reswitch:
switch (ch = *fmt++) switch (ch = *fmt++)
@ -963,10 +963,11 @@ reswitch:
base = 10; base = 10;
goto number; goto number;
case 'X': case 'X':
//sprintn = sprintn_upper; /* TODO: handle this */
case 'x':
base = 16; base = 16;
goto number; goto number;
case 'x':
base = -16;
goto number;
case 'b': case 'b':
base = 2; base = 2;
goto number; goto number;
@ -979,7 +980,6 @@ reswitch:
/* zeropad must not take effect for 'c' */ /* zeropad must not take effect for 'c' */
if (flagc & FLAGC_ZEROPAD) padc = ' '; if (flagc & FLAGC_ZEROPAD) padc = ' ';
//bch = HCL_SIZEOF(hcl_bch_t) < HCL_SIZEOF(int)? va_arg(ap, int): va_arg(ap, hcl_bch_t);
arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++; arg = HCL_STACK_GETARG(hcl, nargs, argidx); argidx++;
if (!HCL_OOP_IS_CHAR(arg)) if (!HCL_OOP_IS_CHAR(arg))
{ {
@ -1116,7 +1116,7 @@ reswitch:
PRINT_OOCH (padc, width); PRINT_OOCH (padc, width);
} }
//while (*nbufp) PRINT_OOCH (*nbufp--, 1); /* output actual digits */ /*while (*nbufp) PRINT_OOCH (*nbufp--, 1);*/ /* output actual digits */
PRINT_OOCS (nsptr, nslen); PRINT_OOCS (nsptr, nslen);
if ((flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0) if ((flagc & FLAGC_LEFTADJ) && width > 0 && (width -= tmp) > 0)
@ -1158,10 +1158,11 @@ oops:
return -1; return -1;
} }
int hcl_print_formatted (hcl_t* hcl, hcl_ooi_t nargs) int hcl_printfmt (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));
return print_formatted(hcl, nargs, &fo); return print_formatted(hcl, nargs, &fo);
} }
#endif #endif

View File

@ -394,7 +394,7 @@ static hcl_pfrc_t pf_printf (hcl_t* hcl, hcl_mod_t* mod, hcl_ooi_t nargs)
return HCL_PF_SUCCESS; return HCL_PF_SUCCESS;
} }
if (hcl_print_formatted(hcl, nargs) <= -1) if (hcl_printfmt(hcl, nargs) <= -1)
{ {
HCL_STACK_SETRETTOERRNUM (hcl, nargs); HCL_STACK_SETRETTOERRNUM (hcl, nargs);
} }