Page 1 of 1

Va_*

Posted: Mon Oct 02, 2006 2:31 am
by elaverick
I'm having a bit of difficulty with va_ commands in my k_printf

My va functions are defined as follows (borrowed from another Barebones)

Code: Select all

#define __va_rounded_size( TYPE )   ( ( (sizeof(TYPE) + sizeof(int) - 1) / sizeof(int) ) * sizeof(int) )
#define va_start( AP, LASTARG )      ( AP = ((char *) &(LASTARG) + __va_rounded_size(LASTARG)) )
#define va_arg( AP, TYPE )         ( AP += __va_rounded_size(TYPE), *((TYPE *) (AP - __va_rounded_size(TYPE))) )
And I'm using them like this

Code: Select all

void SCR_Printf(const char *fmt, ...)
{
    va_list pt;
    int args = 0;
    char cur, pos = 0;
    
   while((cur = fmt[pos++]))
       if(cur == '%')
           args++;
    if(args)
        va_start(pt, args);

    while((cur = *fmt++))
        if(cur == '%')
        {
            cur = *fmt++;
            switch(cur)
            {
                case 'd':
                case 'i':
                    putint((int)va_arg(pt, int));
                    break;
                case 'c':
                    putchar((char)va_arg(pt, char));
                    break;
                case 's':
                    puts(va_arg(pt, char *));
                    break;
            }
        }
        else
            putchar(cur);
}
All the put* functions are working fine as I've unit tested each of those, but when I try to parse any va statements all I get printed is a solid right facing arrow head.

Any ideas?

Re:Va_*

Posted: Mon Oct 02, 2006 3:24 am
by wacco
The second parameter of va_start should be the last parameter your function explicitly defined. In your case;

Code: Select all

va_start(pt, fmt);

// And don't forget at the end of your function!
va_end(pt);
Furthermore I'm not entirely happy with your if(args), if I recall correctly you *have* to do the va_start / va_end combination if you declared your function that way, otherwise your compiler could make nasty mistakes. Then again, you might just get away with it ;)

For a proper example you might want to have a look on this website.

Re:Va_*

Posted: Mon Oct 02, 2006 9:58 am
by elaverick
That's great thanks. I had come across that website but I'd misunder stood how the va_start was being called for some reason. It's all working nicely now tho thank you :)

Re:Va_*

Posted: Fri Oct 06, 2006 1:11 pm
by CopperMan
Hi .

If You use a GCC to compile your code you can use builtin functions :

#define va_start(v,l)   __builtin_va_start(v,l)
#define va_end(v)   __builtin_va_end(v)
#define va_arg(v,l)   __builtin_va_arg(v,l)

typedef __builtin_va_list va_list;

Works fine for me !