Import full printf and fix fwrite implementation
Hello!
This PR imports FreeBSD's printf implementation so that all flags are now implemented.
This PR also fixes the fwrite_term implementation such that printf can be used properly.
I've tested the following calls to printf and all of them succeed:
printf("%%s\\n <- \"Bonjour!\"\n");
printf("%s\n\n", "Bonjour!");
printf("%%d\\n <- 182741\n");
printf("%d\n\n", 182741);
printf("%%llu\\n <- 9223372036854775808\n");
printf("%llu\n\n", 9223372036854775808LLU);
printf("%%c\\n <- '8'\n");
printf("%c\n\n", '8');
printf("0x%%x\\n <- 0x5f2\n");
printf("0x%x\n\n", 0x5f2);
printf("%d ls were %s %c%c 0x%x w/ val %llu", 23, "created", 'a', 't',
0x80020070, 102034818llu);
This adds a lot of code; what's the effect on binary size? Would it be feasible to have a compile-time option to disable less-commonly used formatting features to reduce code size (and probably enable it by default)?
Here's the effect on libc and a minimal G3A using printf - int main() { printf("%s", "Hello!");
| Binary | Old printf | New printf |
|---|---|---|
| libc.a | 239k | 255k |
| Minimal G3A | 32.6k | 33.8k |
That's a reasonable size increase, so I'll see what I can do in terms of compile-time options.
I've moved pretty much everything that wasn't in the old version into #ifndef PRINTF_MINIMAL blocks (PRINTF_MINIMAL is defined by default in libc).
Here's the new sizes:
| Binary | Old printf | New printf |
|---|---|---|
| libc.a | 239k | 243k |
| Minimal G3A | 32.6k | 32.95k |
That's a lot better, I'm not sure what else I could change to make it smaller, but if necessary I could probably find something.
That seems like an okay difference, since it would be more difficult to make it much smaller yet.
However, it should be possible for a user of the SDK to select minimal or full printf in their project without recompiling the libraries- that probably means we need to build two different static libraries for printf and select which one to link depending on makefile variables set by the user. We should also add some documentation describing whatever that mechanism ends up being.