pspdev / psptoolchain-allegrex

This program will automatically build and install an Allegrex compiler which is used in the creation of homebrew software for the Sony PlayStation® Portable videogame system.
MIT License
10 stars 9 forks source link

Build newlib with support for C99 formatters such as %zu. #20

Closed suicvne closed 1 year ago

suicvne commented 1 year ago

Submitting this PR to add --enable-newlib-io-c99-formats to the default list of configure options, which adds support for C99 formatters such as %zu. This eases the burden of homebrew developers working on ports as they no longer need to change or write special cases to remove %zu formatters from their code.

Consider the following sample program:

#include <stdio.h>
#include <pspdebug.h>
#include <pspkernel.h>

// PSP module definition not required
// unless building formal EBOOT.PBP or PRX/KPRX.
PSP_MODULE_INFO("Hello World PSP", 0, 1, 0);

#define TEST_LOG(...) \
{\
        pspDebugScreenPrintf(__VA_ARGS__);\
        printf(__VA_ARGS__);\
}\

int main(void)
{

    TEST_LOG("Hello World!\n");
    TEST_LOG("Formatter: %zu\n", (size_t)42069);
    TEST_LOG("Formatter: %p\n", (uintptr_t)0xdeadbeef);
    TEST_LOG("Goodbye world...\n");

    while(1)
    {}

    return 0;
}

Compiling the toolchain normally will produce the following output from PPSSPP and from a real PSP: image

Compiling the toolchain WITH the flag will result in the following correct behavior: image

Recently, we also needed to patch this configure flag into the Dreamcast toolchain compilation options, as it's not enabled there either.

suicvne commented 1 year ago

NOTE: It's also worth noting you can test this by setting --enable-newlib-io-c99-formats in the environment variable TARG_XTRA_OPTS before running the general pspdev/build-all.sh script.


cd ~/git/pspdev
TARG_XTRA_OPTS=--enable-newlib-io-c99-formats ./build-all.sh
diamant3 commented 1 year ago

I tested it with my psp using this code and it worked perfectly!👍🏼

#include <pspkernel.h>
#include <pspdebug.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define TEST_LOG(...) \
{\
        pspDebugScreenPrintf(__VA_ARGS__);\
        printf(__VA_ARGS__);\
}\

PSP_MODULE_INFO("C99-formatters", 0, 1, 1);
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER);
int done = 0;

int exit_callback(int arg1, int arg2, void *common)
{
    done = 1;
    return 0;
}

int CallbackThread(SceSize args, void *argp)
{
    int cbid;

    cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    sceKernelRegisterExitCallback(cbid);
    sceKernelSleepThreadCB();

    return 0;
}

int SetupCallbacks(void)
{
    int thid = 0;

    thid = sceKernelCreateThread("update_thread", CallbackThread,
                     0x11, 0xFA0, 0, 0);
    if(thid >= 0)
    {
        sceKernelStartThread(thid, 0, 0);
    }

    return thid;
}

int main(void)
{
    pspDebugScreenInit();
    SetupCallbacks();

    while(!done){
        pspDebugScreenSetXY(0, 2);

                TEST_LOG("Characters: %c %c \n", 'a', 65);
                TEST_LOG("Decimals: %d %ld\n", 1977, 650000L);
                TEST_LOG("Preceding with blanks: %10d \n", 1977);
                TEST_LOG("Preceding with zeros: %010d \n", 1977);
                TEST_LOG("Some different radices: %d %x %o %#x %#o \n", 100, 100, 100, 100, 100);
                TEST_LOG("floats: %4.2f %+.0e %E \n", 3.1416, 3.1416, 3.1416);
                TEST_LOG("Width trick: %*d \n", 5, 10);
                TEST_LOG("%s \n", "A string");
                TEST_LOG("Formatter: %zu\n", (size_t)42069);
                TEST_LOG("Formatter: %p\n", (uintptr_t)0xdeadbeef);
    }

    sceKernelExitGame();
    return 0;
}
sharkwouter commented 1 year ago

Thanks, this seems like a cool addition! I'll let the automated builds run and merge it after.