Calling a function that expects variable arguments from a functionwith variable arguments


N

Navaneeth

I am writing a dynamically growing string buffer. The following struct
represents a string buffer.

struct strbuf {
char *buffer; /* null terminated buffer */
size_t length; /* length of the string excluding null
terminator */
size_t allocated; /* total memory allocated */
};

I have also got several functions to operate on this. The following
function takes a format and formats it using "vsnprintf" and adds to
the buffer.

int strbuf_addf(struct strbuf *string, const char *format, ...)
{
size_t space_available;
int length;
va_list args;

if(string == NULL) return 0;

space_available = get_available_space(string);
for(;;)
{
va_start(args, format);
length = vsnprintf(string->buffer + string->length,
space_available, format, args);
va_end(args);

if(length < space_available) break;

grow_buffer(string);
space_available = get_available_space(string);
}

string->length += length;

/* buffer should always contain some free space */
assert(string->length < string->allocated);

return 1;
}

This works well. Now I have a requirement where I would like to call
the above function from another function that takes variable
arguments. Prototype would be,

void print_info(const char *format, ...);

How can I call "strbuf_addf" from "print_info"?

The only way which I can think is add another method to the string
buffer which takes a "va_list". So from "print_info" & "strbuf_addf" I
can get a "va_list" and pass that. Wondering is this the correct
approach?

Any help would be great!
 
Ad

Advertisements

P

Paul N

I am writing a dynamically growing string buffer. The following struct
represents a string buffer.

struct strbuf {
    char *buffer;            /* null terminated buffer */
    size_t length;           /* length of the string excluding null
terminator */
    size_t allocated;        /* total memory allocated */

};

I have also got several functions to operate on this. The following
function takes a format and formats it using "vsnprintf" and adds to
the buffer.

int strbuf_addf(struct strbuf *string, const char *format, ...)
{
    size_t space_available;
    int length;
    va_list args;

    if(string == NULL) return 0;

    space_available = get_available_space(string);
    for(;;)
    {
        va_start(args, format);
        length = vsnprintf(string->buffer + string->length,
space_available, format, args);
        va_end(args);

        if(length < space_available) break;

        grow_buffer(string);
        space_available = get_available_space(string);
    }

    string->length += length;

    /* buffer should always contain some free space */
    assert(string->length < string->allocated);

    return 1;

}

This works well. Now I have a requirement where I would like to call
the above function from another function that takes variable
arguments. Prototype would be,

void print_info(const char *format, ...);

How can I call "strbuf_addf" from "print_info"?

The only way which I can think is add another method to the string
buffer which takes a "va_list". So from "print_info" & "strbuf_addf" I
can get a "va_list" and pass that. Wondering is this the correct
approach?

Any help would be great!

I'm not an expert but...

You can't *call* a function with a variable number of arguments. That
is to say, whenever you make a function call, there will be a fixed
number of arguments present. So when print_info calls strbuf_addf it
must send a fixed number of arguments, even if strbuf_addf can also
take a different number of arguments. So I think you are going to have
to pass the variable arguments from print_info to strbuf_addf in the
form of a va_list. From your example code it seems you already know
how to do this, or at least better than I do.

Hope that helps.
Paul.
 
Ad

Advertisements

K

Kenny McCormack

http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Constructing-Calls.html

This allows you to call a function with (a copy of) the argument list of
the current function.
Interesting...

It doesn't allow you to construct arbitrary calls. If you need that,
there's always libffi.

Yes. I'm a big fan of "avcall" (part of libffi)

--
Is God willing to prevent evil, but not able? Then he is not omnipotent.
Is he able, but not willing? Then he is malevolent.
Is he both able and willing? Then whence cometh evil?
Is he neither able nor willing? Then why call him God?
~ Epicurus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top