stdlib: fix atoi()/strto*() pulling in the entirety of scanf

This was due to the few base __scanf() functions, used by strto*() and
co. to share their framework with scanf() specifiers, being in the main
scanf() file. Not sure why it ended up pulling the entire file even with
LTO, but now that it's separate there's no issue anymore.

Pulling in the entirety of scanf() is mostly expensive because it
contains specifiers(), including strtod(), which itself computes on
floating point numbers, leading to many libm functions being linked in,
some of them with their internal data tables.

In the end you'd call atoi() and get a 24-kB size increase.
Which is not great :)
This commit is contained in:
Lephenixnoir 2024-11-19 12:33:26 +01:00
parent c16a1a3be6
commit 09610f59de
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495
3 changed files with 38 additions and 34 deletions

View file

@ -60,7 +60,7 @@ if(FXLIBC_PIC)
add_compile_options(-fpic)
endif()
if(FXLIBC_LTO)
add_compile_options(-flto)
add_compile_options(-flto -ffat-lto-objects)
# Generate the archive with gcc-ar instead of ar as it will load the LTO
# plugin which is required to generate a usable archive.
set(CMAKE_C_ARCHIVE_CREATE "${CMAKE_C_COMPILER_AR} qcs <TARGET> <OBJECTS>")
@ -157,6 +157,7 @@ set(SOURCES
src/stdio/rewind.c
src/stdio/scanf.c
src/stdio/scanf/scan.c
src/stdio/scanf/scan_base.c
src/stdio/setbuf.c
src/stdio/setvbuf.c
src/stdio/snprintf.c

View file

@ -27,39 +27,6 @@
- TODO: Maximum field width for floating-point is mostly untested and likely
has bugs when the field ends in the middle of the number. */
void __scanf_start(struct __scanf_input *in)
{
if(in->fp)
in->buffer = fgetc(in->fp);
else {
in->buffer = (*in->str ? *in->str : EOF);
in->str += (in->buffer != EOF);
}
}
int __scanf_fetch(struct __scanf_input *in)
{
if(in->fp)
return fgetc(in->fp);
int c = *in->str;
if(c == 0)
return EOF;
in->str++;
return c;
}
void __scanf_end(struct __scanf_input *in)
{
if(in->buffer == EOF)
return;
if(in->fp)
ungetc(in->buffer, in->fp);
else
in->str--;
}
static void __skip_spaces(struct __scanf_input *in)
{
while(isspace(__scanf_peek(in)))

View file

@ -0,0 +1,36 @@
#include "../stdio_p.h"
#include "../../stdlib/stdlib_p.h"
#include <stdio.h>
void __scanf_start(struct __scanf_input *in)
{
if(in->fp)
in->buffer = fgetc(in->fp);
else {
in->buffer = (*in->str ? *in->str : EOF);
in->str += (in->buffer != EOF);
}
}
int __scanf_fetch(struct __scanf_input *in)
{
if(in->fp)
return fgetc(in->fp);
int c = *in->str;
if(c == 0)
return EOF;
in->str++;
return c;
}
void __scanf_end(struct __scanf_input *in)
{
if(in->buffer == EOF)
return;
if(in->fp)
ungetc(in->buffer, in->fp);
else
in->str--;
}