libc/stdio: Support "long long" type if CONFIG_HAVE_LONG_LONG is enabled

but just format the low 32bits if CONFIG_LIBC_LONG_LONG isn't enabled to
avoid to expand the code space to much.
Note: the size will increase 192 bytes on stm32_tiny:nsh.
Before the change:
   text    data     bss     dec     hex filename
  41444     184    1656   43284    a914 nuttx
After the change:
   text    data     bss     dec     hex filename
  41636     184    1656   43476    a9d4 nuttx

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
This commit is contained in:
Xiang Xiao 2022-07-14 03:29:37 +08:00 committed by Petro Karashchenko
parent f9e3ef3464
commit 63cb11cc72
2 changed files with 31 additions and 17 deletions

View File

@ -215,7 +215,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
int base = 10;
char tmp[MAXLN];
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
FAR unsigned long long *plonglong = NULL;
#endif
FAR unsigned long *plong = NULL;
@ -317,7 +317,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
else if (fmt_char(fmt) == 'j')
{
/* Same as long long if available. Otherwise, long. */
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
modifier = LL_MOD;
#else
modifier = L_MOD;
@ -569,7 +569,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
*plong = 0;
break;
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
case LL_MOD:
plonglong = va_arg(ap, FAR unsigned long long *);
*plonglong = 0;
@ -596,7 +596,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
bool stopconv;
int errsave;
unsigned long tmplong = 0;
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
unsigned long long tmplonglong = 0;
#endif
/* Copy the real string into a temporary working buffer. */
@ -815,7 +815,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
switch (modifier)
{
#ifndef CONFIG_LIBC_LONG_LONG
#ifndef CONFIG_HAVE_LONG_LONG
case LL_MOD:
#endif
case HH_MOD:
@ -832,15 +832,23 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
}
break;
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
case LL_MOD:
if (sign)
{
# ifdef CONFIG_LIBC_LONG_LONG
tmplonglong = strtoll(tmp, &endptr, base);
# else
tmplonglong = strtol(tmp, &endptr, base);
# endif
}
else
{
# ifdef CONFIG_LIBC_LONG_LONG
tmplonglong = strtoull(tmp, &endptr, base);
# else
tmplonglong = strtoul(tmp, &endptr, base);
# endif
}
break;
#endif
@ -878,7 +886,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
*pint = (unsigned int)tmplong;
break;
#ifndef CONFIG_LIBC_LONG_LONG
#ifndef CONFIG_HAVE_LONG_LONG
case L_MOD:
#endif
default:
@ -886,7 +894,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
*plong = tmplong;
break;
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
case LL_MOD:
linfo("Return %lld to %p\n", tmplonglong,
plonglong);
@ -1141,7 +1149,7 @@ int lib_vscanf(FAR struct lib_instream_s *obj, FAR int *lastc,
*plong = (unsigned long)nchars;
break;
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
case LL_MOD:
plonglong = va_arg(ap, FAR unsigned long long *);
*plonglong = (unsigned long long)nchars;

View File

@ -131,7 +131,7 @@ struct arg_s
{
unsigned int u;
unsigned long ul;
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
unsigned long long ull;
#endif
double d;
@ -414,7 +414,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream,
/* The only known cases that the default will be hit are
* (1) the eZ80 which has sizeof(size_t) = 3 which is the
* same as the sizeof(int). And (2) if
* CONFIG_LIBC_LONG_LONG
* CONFIG_HAVE_LONG_LONG
* is not enabled and sizeof(size_t) is equal to
* sizeof(unsigned long long). This latter case is an
* error.
@ -431,7 +431,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream,
c = 'l';
break;
#if defined(CONFIG_LIBC_LONG_LONG) && ULLONG_MAX != ULONG_MAX
#if defined(CONFIG_HAVE_LONG_LONG) && ULLONG_MAX != ULONG_MAX
case sizeof(unsigned long long):
c = 'l';
flags |= FL_LONG;
@ -445,7 +445,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream,
{
/* Same as long long if available. Otherwise, long. */
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
flags |= FL_REPD_TYPE;
#endif
flags |= FL_LONG;
@ -493,7 +493,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream,
flags &= ~(FL_LONG | FL_REPD_TYPE);
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
if (sizeof(void *) == sizeof(unsigned long long))
{
flags |= (FL_LONG | FL_REPD_TYPE);
@ -963,7 +963,7 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream,
if (c == 'd' || c == 'i')
{
#ifndef CONFIG_LIBC_LONG_LONG
#ifndef CONFIG_HAVE_LONG_LONG
long x;
#else
long long x;
@ -1040,13 +1040,16 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream,
}
else
{
#if !defined(CONFIG_LIBC_LONG_LONG) && defined(CONFIG_HAVE_LONG_LONG)
DEBUGASSERT(x >= 0 && x <= ULONG_MAX);
#endif
c = __ultoa_invert(x, (FAR char *)buf, 10) - (FAR char *)buf;
}
}
else
{
int base;
#ifndef CONFIG_LIBC_LONG_LONG
#ifndef CONFIG_HAVE_LONG_LONG
unsigned long x;
#else
unsigned long long x;
@ -1212,6 +1215,9 @@ static int vsprintf_internal(FAR struct lib_outstream_s *stream,
}
else
{
#if !defined(CONFIG_LIBC_LONG_LONG) && defined(CONFIG_HAVE_LONG_LONG)
DEBUGASSERT(x <= ULONG_MAX);
#endif
c = __ultoa_invert(x, (FAR char *)buf, base) - (FAR char *)buf;
}
@ -1345,7 +1351,7 @@ int lib_vsprintf(FAR struct lib_outstream_s *stream,
switch (arglist[i].type)
{
case TYPE_LONG_LONG:
#ifdef CONFIG_LIBC_LONG_LONG
#ifdef CONFIG_HAVE_LONG_LONG
arglist[i].value.ull = va_arg(ap, unsigned long long);
break;
#endif