Dynamic building of va_list ? 
Author Message
 Dynamic building of va_list ?

I know what I am trying is a kludge (so forgive me :-).

I am interfacing with existing C code that uses sprintf to build output
strings. There is existing logic to generate a format string (that I do not
want to reinvent). However, the existing C code makes manual calls to
sprintf with specific numbers of arguments. I would like to generalize this
setup using vsprintf and building the va_list dynamically at run-time (I do
not know how many parameters will be in the list - but I could set an
arbitrary max). Does anyone know of a portable way of implementing this?

Thanks in advance
pth
--



Sat, 06 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?


Quote:
>I know what I am trying is a kludge (so forgive me :-).

>I am interfacing with existing C code that uses sprintf to build output
>strings. There is existing logic to generate a format string (that I do not
>want to reinvent). However, the existing C code makes manual calls to
>sprintf with specific numbers of arguments. I would like to generalize this
>setup using vsprintf and building the va_list dynamically at run-time (I do
>not know how many parameters will be in the list - but I could set an
>arbitrary max). Does anyone know of a portable way of implementing this?

No, there is no portable way to do this. While you can create a
definition of a variable argument function, all specific function *calls*
always have a fixed argument list in C. Similarly the only portable
way to create a valid va_list object is from the argument list
of a variable argument function.

--
-----------------------------------------


-----------------------------------------
--



Wed, 10 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?

Quote:

>I am interfacing with existing C code that uses sprintf to build output
>strings. There is existing logic to generate a format string (that I do not
>want to reinvent). However, the existing C code makes manual calls to
>sprintf with specific numbers of arguments. I would like to generalize this
>setup using vsprintf and building the va_list dynamically at run-time (I do
>not know how many parameters will be in the list - but I could set an
>arbitrary max). Does anyone know of a portable way of implementing this?

There isn't any portable way of doing this.

The Standard doesn't provide a way of doing it, and it doesn't specify how
variable argument lists are implemented.  If you figure out a way to do it,
it will be based on a particular implementation.

It may be impossible to do this in C, even non-portably.  You might have
to do it in assembly language.  Most implementations of C I've used
push these arguments on a stack, and provide no means of manipulating
the stack directly from C.

I would choose another approach, rather than wade through that swamp -
as the author of the exisiting code did also.

-- Gary Culp
-- Keil Software (www.keil.com)
--



Wed, 10 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?

Quote:


> >I am interfacing with existing C code that uses sprintf to build output
> >strings. There is existing logic to generate a format string (that I do not
> >want to reinvent). However, the existing C code makes manual calls to
> >sprintf with specific numbers of arguments. I would like to generalize this
> >setup using vsprintf and building the va_list dynamically at run-time (I do
> >not know how many parameters will be in the list - but I could set an
> >arbitrary max). Does anyone know of a portable way of implementing this?

> There isn't any portable way of doing this.

> The Standard doesn't provide a way of doing it, and it doesn't specify how
> variable argument lists are implemented.  If you figure out a way to do it,
> it will be based on a particular implementation.

> It may be impossible to do this in C, even non-portably.  You might have
> to do it in assembly language.  Most implementations of C I've used
> push these arguments on a stack, and provide no means of manipulating
> the stack directly from C.

Hmm.  There's no standard way to manipulate the stack in C, but there are some
tricks that you can use which are totally non portable.  If you declare a
local array, and the compiler happens to put that on the top of the stack, then
you might be able to exploit this to fake out a var_args function.

The following code is seems to work on FreeBSD.  It may or may not work on any
particular compiler.  It depends a lot on your system's calling convention.
It's very dangerous C code.

#include <stdio.h>

int main(void) {
  void* stack[3];
  stack[0] = "world!";
  stack[1] = (void*)69;
  stack[2] = (void*)'X';
  printf("Hello %s (%d %c)\n");

  return 0;

Quote:
}

A more sensible way to implement this (although also non-portable) would be to
figure out what va_list looks like on your platform and manually construct one
with your arguments.

/peter
--



Thu, 11 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?

Quote:

>Hmm.  There's no standard way to manipulate the stack in C, but
>there are some tricks that you can use which are totally non portable.
>If you declare a local array, and the compiler happens to put that on
>the top of the stack, then you might be able to exploit this
>to fake out a var_args function.

>The following code is seems to work on FreeBSD.  It may or may not
>work on any particular compiler.  It depends a lot on your system's
>calling convention. It's very dangerous C code.

>#include <stdio.h>

>int main(void) {
>  void* stack[3];
>  stack[0] = "world!";
>  stack[1] = (void*)69;
>  stack[2] = (void*)'X';
>  printf("Hello %s (%d %c)\n");

>  return 0;
>}

YIKES!

Reading that code was a good scary start to the Hallowe'en weekend.

/\  /\     Gary Culp
  /\       Senior Softscare Engineer
\/\/\/     Keil Software, Inc.  www.keil.com
--



Wed, 17 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?

Quote:

> >int main(void) {
> >  void* stack[3];
> >  stack[0] = "world!";
> >  stack[1] = (void*)69;
> >  stack[2] = (void*)'X';
> >  printf("Hello %s (%d %c)\n");

> >  return 0;
> >}

Shouldn't you pass stack as a last arg to printf() ?
I can't image sprintf() looking at the stack _below_
it's entry point, which is where the local array
will be located?

(Now I hope this wasn't a clueless question.)

--



Fri, 19 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?

Quote:

> > >int main(void) {
> > >  void* stack[3];
> > >  stack[0] = "world!";
> > >  stack[1] = (void*)69;
> > >  stack[2] = (void*)'X';
> > >  printf("Hello %s (%d %c)\n");

> > >  return 0;
> > >}

> Shouldn't you pass stack as a last arg to printf() ?
> I can't image sprintf() looking at the stack _below_
> it's entry point, which is where the local array
> will be located?

Nope.  On IA32 platforms, the arguments to a function are
usually all passed on the stack.  So functions always look
above (remember, stacks grow downward on most platforms)
their base pointer to find their arguments.  Arguments
usually look something like this on the stack (growing
downward):

argn
argn-1
....
arg3
arg2
arg1
return address

In this case, I've taken advantage of the fact that the array
gets allocated on the machine stack:

stack[2]
stack[1]
stack[0]
arg1 (the string)
return address

/peter
--



Sat, 20 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?

Quote:

> > >int main(void) {
> > >  void* stack[3];
> > >  stack[0] = "world!";
> > >  stack[1] = (void*)69;
> > >  stack[2] = (void*)'X';
> > >  printf("Hello %s (%d %c)\n");

> > >  return 0;
> > >}

> Shouldn't you pass stack as a last arg to printf() ?
> I can't image sprintf() looking at the stack _below_
> it's entry point, which is where the local array
> will be located?

It depends on the order in which function arguments are pushed onto
the stack.  This example assumes (among other things) that first
argument is passed last.  When only a stack pointer exists (no base
pointers or anything), this is the only viable way to pass stack
arguments to varargs functions like printf().

I once had a neat bug along these lines.  Of course, the routine
passing missing arguments to vfprintf() was an error-reporting
routine, which lead to much merriment.

Quote:
> (Now I hope this wasn't a clueless question.)

Ditto this answer.

--

Compugen Ltd.          |Tel: +972-2-6795059 (Jerusalem) \  100% recycled bits!
72 Pinhas Rosen St.    |Tel: +972-3-7658520 (Main office)`--------------------
Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555  http://3w.compugen.co.il/~ariels
--



Sat, 20 Apr 2002 03:00:00 GMT  
 Dynamic building of va_list ?

Quote:



writes:

> >I know what I am trying is a kludge (so forgive me :-).

> >I am interfacing with existing C code that uses sprintf to build
> >output strings. There is existing logic to generate a format string
> >(that I do not want to reinvent). However, the existing C code makes
> >manual calls to sprintf with specific numbers of arguments. I would
> >like to generalize this setup using vsprintf and building the
> >va_list dynamically at run-time (I do not know how many parameters
> >will be in the list - but I could set an arbitrary max). Does anyone
> >know of a portable way of implementing this?

> No, there is no portable way to do this. While you can create a
> definition of a variable argument function, all specific function
> *calls* always have a fixed argument list in C. Similarly the only
> portable way to create a valid va_list object is from the argument
> list of a variable argument function.

> -----------------------------------------


> -----------------------------------------

I am simply speculating here, but it seems to me that the format string
can always be built dynamically for anything in the printf family.  The
actual call can have its parameters padded with nuls for any parameters
not actually passed.  If you are willing to accept the restriction that
everything is passed by referance, or whatever integer is the same size
as a pointer, a bunch of casts to (void *) should handle the parameter
matching.

Thus, if you pass a format string that does not specify all the
parameters, the stack clean up would remove the unused nuls at the
caller after the printf return.

This satisfies the requirements for a fixed parameter count at the call
via something like:

     printf(formatstring, (void *) param1, (void *) param2, nul, nul);

I would never use anything like this except where no portability or
readability is ever needed.  Some earlier message in this thread
mentioned using a "stack(x)" ability, but this assumes knowledge of
stack order, use of a stack, etc. etc.  In fact, I even have heavy
doubts that the stack clean up by the caller can be relied upon.

The original poster would probably be much better off building things
in terms of linked lists.  Then each item could specify its own format,
and the output function would simply do a list walk.

--
    Chuck Falconer

Sent via Deja.com http://www.deja.com/
Before you buy.
--



Sat, 20 Apr 2002 03:00:00 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Dynamic building of va_list ?

2. a va_list in a va_list

3. Building Dynamic Objects

4. Building a dynamic byte arrary

5. Q: Building dynamic libraries with gcc

6. dynamic build cause errors?

7. Building dynamic-sized structures

8. Dynamic memory allocate/deallocate crashes on release build

9. Dynamic Build Number

10. Problem building dynamic assembly

11. Dynamic arrays not really dynamic in managec C++?

12. Determining dynamic from non-dynamic memory

 

 
Powered by phpBB® Forum Software