Page 1 of 1

problem in passing varable number argument to another functi

Posted: Sun Jan 15, 2006 1:21 pm
by asammoud
hello every one
this is my first time to ask in this great forum....
so.... in brief
I'm writing an OS "unix clone" ,and i started with the print functions....
the main two parts in this function is :tk_printf and tk_sprintf
the two function prototype:

1-int tk_printf(const char*, ...);
printf() calls sprintf() to format the pre-formatted string containing unlimited arguments then prints the ouptput of sprintf() on the standard output. returns the number of characters printed on the standard output not including the trailing '\0' used to end output to strings or a negative value if an output error occurs.

2-int tk_sprintf(char*,const char*, ...);
sprintf() formats the pre-formatted string containing unlimited arguments and prints it in a buffer. the 1st parameter is a pointer to the buffer which will contain the formatted string, the 2nd parameter is a pointer to a constant string containing the pre-formatted string, the remaining parameters is the list of arguments as passed in the pre-formatted string.the pre-formatted string uses the same format specifies as the libc printf() function.

i'm using the va_list in the sprintf function to deal with the arguments...
the problem is that when i pass the string from the tk_printf to the tk_sprintf function the va_list in the sprintf can't locate the arguments.

the code of tk_printf function:


int tk_printf(const char* nformatted,...)
{
char buffer[256];
int index=0,num_printed,check,char_num=0,nf_index=0;

num_printed=tk_sprintf(buffer,nformatted);

for(index=0,check=0;num_printed>index;index++,check++)
{
putchar(buffer[index]); /*using the putchar of libc until i write the tk_putchar*/
}

if(num_printed!=check)
return(-1);

return (num_printed);
}
???

Re:problem in passing varable number argument to another fun

Posted: Sun Jan 15, 2006 1:36 pm
by Candy
You aren't passing along the unknown arguments as well. It's pretty hard to do that, but you would need to to make it work.

Re:problem in passing varable number argument to another fun

Posted: Sun Jan 15, 2006 2:10 pm
by Assembler
Hi,

I caught the bug.
u can pass paramters of a function to another.
it's something related to internal of c language itself.
this is because the parameter is passed to function on its stack, so
if u want to pass the parameters of a function to another one, u
should send it all parameter one follows the other not just a pointer
to the first parameter. This should work.
but it seems that it was my mistake since sprintf() is not used in
printf(), ur sprintf() has no problem, it should be used alone to
format a string however printf() uses vsprintf() where printf() passes
va_list to the vsprintf() or (vsnprintf() if u passed the number of
character).
but remember u can't use va_start or va_end macros in vsprintf(), the
printf() has to do so, start the arguments list call vsprintf()
passing the parameters to it, after vsprintf() returns, the printf()
must end the argument list.
i think now every thing is clear.
u can consult the manual pages for better clearifications.
>man vsprintf
where vsprintf() should be defined as follows:
int vsprintf(char *buf, const char *fmt, va_list args);
where vsprintf() just call vsnprintf() passing every thing besides the
number of string to format.
here is the vsprintf() from linux-2.6.11 source code:

Code: Select all

int vsprintf(char *buf, const char *fmt, va_list args)
{
       return vsnprintf(buf, (~0U)>>1, fmt, args);
}
the strange but interresting thing that the sprintf() itself just
calls the vsprintf() to do the actuall work and the vsprintf() calles
vsnprintf().
here is the sprintf() from linux-2.6.11:

Code: Select all

int sprintf(char * buf, const char *fmt, ...)
{
       va_list args;
       int i;

       va_start(args, fmt);
       i=vsprintf(buf,fmt,args);
       va_end(args);
       return i;
}
every thing should be clear now.
the bone function is vsnprintf().
vsprintf() calles vsnprintf()
sprintf() calles vsprintf() which calles vsnprintf()
printf() calles vsprintf() which calles vsnprintf()

However in linux since there is no printf() there is printk() which
have extra format specifiers as : <0> ...
so printk() is implemented by vprintk()
this code from linux-2.6.11

Code: Select all

asmlinkage int printk(const char *fmt, ...)
{
       va_list args;
       int r;

       va_start(args, fmt);
       r = vprintk(fmt, args);
       va_end(args);

       return r;
}
i hope i made things clear for you now ;-)

Re:problem in passing varable number argument to another fun

Posted: Sun Jan 15, 2006 2:44 pm
by asammoud
thanx a lot assembler