This is a weird question, but is there a standard way to manipulate the contents of a va_list before passing it to another function? For instance, suppose I have two functions, sum and vsum:
int vsum(int n, va_list ap) { int total = 0; for (int i = 0; i < n; ++i) { total += va_arg(n, int); return total; } int sum(int n, ...) { va_list ap; va_start(ap, n); int total = vsum(n, ap); va_end(ap); return total; } If I call sum as sum(4, 1, 2, 3, 4), I expect to get the result 10. Now let's suppose that instead of calling vsum directly, sum calls an intermediate function, vsum_stub which does the following:
int vsum_stub(int n, va_list ap) { va_list temp_ap; va_copy(temp_ap, ap); for (int i = 0; i < n; ++i) { int *arg = &va_arg(ap, int); *arg += 2; } va_end(temp_ap); return vsum(n, ap); } Now when I call sum(4, 1, 2, 3, 4), I should get back the result 20, since vsum_stub increments all of the values in the va_list by 2. This doesn't compile of course since you can't take the address of the result of va_arg. Is there another way to do this though? I'm working in C99.
Background:
I'm working on a library that does some pointer translation so that data may be stored on the heap in a more efficient format. Programs are compiled with a custom transformation which converts calls to library functions like printf to my own stub functions (e.g., hc_printf). hc_printf needs to translate any pointer arguments (strings intended for %s) before passing the arguments to the real printf function.
Edit: Here's a code example. Let's say we have a string foo. foo is dynamically allocated with a modified version of malloc which returns a fake pointer. The compiler modifies the program so that it can deal with fake pointers. So this works:
char *foo = fake_malloc(4); fake_strcpy(foo, "foo"); I want to write a fake_vprintf function like this (in pseudocode):
int fake_vprintf(const char *format, va_list args) { for each pointer argument p in args translate p to q, a real pointer to contiguous memory replace p with q in args } return vprintf(format, args); } The program would call fake_vprintf just like the original vprintf using the fake pointer. fake_vprintf translates the fake pointer to a real pointer that the real vprintf can use.
int *arg = &va_arg(ap, int);actually beint *arg = va_arg(ap, int *);?vsum_stubtakes in a list ofint *. Anyway do you think the code I posted is of any help?