stdargx.h 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #ifndef STDARGX_H_INCLUDED
  2. #define STDARGX_H_INCLUDED
  3. #include "xmlrpc_config.h"
  4. #include <stdarg.h>
  5. #include <string.h>
  6. /*----------------------------------------------------------------------------
  7. We need a special version of va_list in order to pass around the
  8. variable argument heap by reference, thus allowing a subroutine to
  9. advance the heap's pointer.
  10. On some systems (e.g. Gcc for PPC or AMD64), va_list is an array.
  11. That invites the scourge of array-to-pointer degeneration if you try
  12. to take its address. Burying it inside a struct as we do with out
  13. va_listx type makes it immune.
  14. Example of what would happen if we used va_list instead of va_listx,
  15. on a system where va_list is an array:
  16. void sub2(va_list * argsP) [
  17. ...
  18. }
  19. void sub1(va_list args) {
  20. sub2(&args);
  21. }
  22. This doesn't work. '&args' is the same thing as 'args', so is
  23. va_list, not va_list *. The compiler will even warn you about the
  24. pointer type mismatch.
  25. To use va_listx:
  26. void sub1_va(char * format, va_list args) {
  27. va_listx argsx;
  28. init_va_listx(&argsx, args);
  29. sub2(format, &argsx);
  30. }
  31. -----------------------------------------------------------------------------*/
  32. typedef struct {
  33. /*----------------------------------------------------------------------------
  34. Same thing as va_list, but in a form that works everywhere. See above.
  35. -----------------------------------------------------------------------------*/
  36. va_list v;
  37. } va_listx;
  38. static __inline__ void
  39. init_va_listx(va_listx * const argsxP,
  40. va_list const args) {
  41. #if VA_LIST_IS_ARRAY
  42. /* 'args' is NOT a va_list. It is a pointer to the first element of a
  43. 'va_list', which is the same address as a pointer to the va_list
  44. itself. (That's what happens when you pass an array in C).
  45. */
  46. memcpy(&argsxP->v, args, sizeof(argsxP->v));
  47. #else
  48. argsxP->v = args;
  49. #endif
  50. }
  51. #endif