Omnimaga

Calculator Community => TI Calculators => Calculator C => Topic started by: compu on February 24, 2011, 01:42:29 pm

Title: vsprintf() doesn't work
Post by: compu on February 24, 2011, 01:42:29 pm
Hey, I wanted to make an on-screen console for the nspire.
Normal text output works fine, but i wanted an sprintf()-like function to output text, so I made this function:
Code: [Select]
void c_swrite(struct console *c, char* format, int len, char bgColor, char textColor, ...)
{
char buf[len];
memset(buf,'\0',sizeof(char)*len);
va_list arglist;
va_start(arglist,textColor);
vsprintf(buf,format,arglist);
c_write(c,buf,bgColor,textColor);
va_end(arglist);
}

Always when this function reaches vsprintf, the emulator crashes.

Code: [Select]
Error at PC=102F45C0: Unaligned read_word: 1800e0ed
         Backtrace:
Frame     PrvFrame Self     Return   Start
1800E0B0: 1800E0E8 1800E0B4 1106E9DC 102F4210
1800E0E8: 1109CA20 00000000 1800E934 1106E5A4

I have attached my whole source.
So, what am I doing wrong?
Title: Re: vsprintf() doesn't work
Post by: Goplat on February 24, 2011, 02:47:20 pm
Ndless's definition of va_start is not quite correct, it doesn't take into account that a 1-byte function parameter actually takes up 4 bytes on the stack.

For the time being, try using the gcc intrinsic __builtin_va_start instead.
Title: Re: vsprintf() doesn't work
Post by: compu on February 24, 2011, 02:56:10 pm
Do you mean I should do it like this:
Code: [Select]
void c_swrite(struct console *c, char* format, int len, char bgColor, char textColor, ...)
{
char buf[len];
memset(buf,'\0',sizeof(char)*len);
__builtin_va_list arglist;
__builtin_va_start(arglist,textColor);
__builtin_vsprintf(buf,format,arglist);
c_write(c,buf,bgColor,textColor);
__builtin_va_end(arglist);
}

I can compile it without any errors, but the emulator still crashes :(
Title: Re: vsprintf() doesn't work
Post by: Goplat on February 24, 2011, 03:11:50 pm
Don't use __builtin_vsprintf, that would end up trying to call an actual function called vsprintf (rather than the syscall). It looks like yagarto's gcc is annoyingly strict about how you can use a __builtin_va_list, but this still works:

   vsprintf(buf,format,*(char **)&arglist);
Title: Re: vsprintf() doesn't work
Post by: compu on February 24, 2011, 03:17:56 pm
Thanks! :D
This works fine :)
Title: Re: vsprintf() doesn't work
Post by: ExtendeD on February 25, 2011, 04:44:47 pm
Thanks, Ndless's va_* definitions are now wrappers to GCC builtin functions.