Improve va_list portability

Support for va_list declared as an array (cannot be referenced
explicitly)
diff --git a/trio.c b/trio.c
index d885db9..adfd324 100644
--- a/trio.c
+++ b/trio.c
@@ -126,13 +126,23 @@
 # define TRIO_ERROR_RETURN(x,y) (-1)
 #endif
 
+#ifndef VA_LIST_IS_ARRAY
+#define TRIO_VA_LIST_PTR	va_list *
+#define TRIO_VA_LIST_ADDR(l)	(&(l))
+#define TRIO_VA_LIST_DEREF(l)	(*(l))
+#else
+#define TRIO_VA_LIST_PTR	va_list
+#define TRIO_VA_LIST_ADDR(l)	(l)
+#define TRIO_VA_LIST_DEREF(l)	(l)
+#endif
+
 typedef unsigned long trio_flags_t;
 
 
 /*************************************************************************
  * Platform specific definitions
  */
-#if defined(TRIO_PLATFORM_UNIX)
+#if defined(TRIO_PLATFORM_UNIX) || defined(TRIO_PLATFORM_OS400)
 # include <unistd.h>
 # include <signal.h>
 # include <locale.h>
@@ -1167,7 +1177,7 @@
 	   int type,
 	   TRIO_CONST char *format,
 	   trio_parameter_t *parameters,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   /* Count the number of times a parameter is referenced */
@@ -1945,14 +1955,14 @@
 	  if (flags & FLAGS_WIDECHAR)
 	    {
 	      parameters[i].data.wstring = (argarray == NULL)
-		? va_arg(*arglist, trio_wchar_t *)
+		? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_wchar_t *)
 		: (trio_wchar_t *)(argarray[num]);
 	    }
 	  else
 #endif
 	    {
 	      parameters[i].data.string = (argarray == NULL)
-		? va_arg(*arglist, char *)
+		? va_arg(TRIO_VA_LIST_DEREF(arglist), char *)
 		: (char *)(argarray[num]);
 	    }
 	  break;
@@ -1964,7 +1974,7 @@
 	case FORMAT_COUNT:
 	case FORMAT_UNKNOWN:
 	  parameters[i].data.pointer = (argarray == NULL)
-	    ? va_arg(*arglist, trio_pointer_t )
+	    ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
 	    : argarray[num];
 	  break;
 
@@ -1974,7 +1984,7 @@
 	    {
               if (argarray == NULL)
                 parameters[i].data.pointer =
-                  (trio_pointer_t)va_arg(*arglist, trio_pointer_t);
+                  (trio_pointer_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t);
               else
                 {
                   if (parameters[i].type == FORMAT_CHAR)
@@ -2032,36 +2042,36 @@
 #if defined(QUALIFIER_SIZE_T) || defined(QUALIFIER_SIZE_T_UPPER)
 	      if (parameters[i].flags & FLAGS_SIZE_T)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, size_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), size_t)
 		  : (trio_uintmax_t)(*((size_t *)argarray[num]));
 	      else
 #endif
 #if defined(QUALIFIER_PTRDIFF_T)
 	      if (parameters[i].flags & FLAGS_PTRDIFF_T)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, ptrdiff_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), ptrdiff_t)
 		  : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
 	      else
 #endif
 #if defined(QUALIFIER_INTMAX_T)
 	      if (parameters[i].flags & FLAGS_INTMAX_T)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, trio_intmax_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_intmax_t)
 		  : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
 	      else
 #endif
 	      if (parameters[i].flags & FLAGS_QUAD)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, trio_ulonglong_t)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), trio_ulonglong_t)
 		  : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
 	      else if (parameters[i].flags & FLAGS_LONG)
 		parameters[i].data.number.as_unsigned = (argarray == NULL)
-		  ? (trio_uintmax_t)va_arg(*arglist, long)
+		  ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), long)
 		  : (trio_uintmax_t)(*((long *)argarray[num]));
 	      else
 		{
 		  if (argarray == NULL)
-		    parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(*arglist, int);
+		    parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int);
 		  else
 		    {
 		      if (parameters[i].type == FORMAT_CHAR)
@@ -2082,11 +2092,11 @@
 	   */
 	  if (parameters[i].flags & FLAGS_USER_DEFINED)
 	    parameters[i].data.pointer = (argarray == NULL)
-	      ? va_arg(*arglist, trio_pointer_t )
+	      ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_pointer_t )
 	      : argarray[num];
 	  else
 	    parameters[i].data.number.as_unsigned = (argarray == NULL)
-	      ? (trio_uintmax_t)va_arg(*arglist, int)
+	      ? (trio_uintmax_t)va_arg(TRIO_VA_LIST_DEREF(arglist), int)
 	      : (trio_uintmax_t)(*((int *)argarray[num]));
 	  break;
 
@@ -2095,17 +2105,17 @@
 	    {
 	      if (parameters[i].flags & FLAGS_LONGDOUBLE)
 		parameters[i].data.longdoublePointer = (argarray == NULL)
-		  ? va_arg(*arglist, trio_long_double_t *)
+		  ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t *)
 		  : (trio_long_double_t *)argarray[num];
 	      else
                 {
 		  if (parameters[i].flags & FLAGS_LONG)
 		    parameters[i].data.doublePointer = (argarray == NULL)
-		      ? va_arg(*arglist, double *)
+		      ? va_arg(TRIO_VA_LIST_DEREF(arglist), double *)
 		      : (double *)argarray[num];
 		  else
 		    parameters[i].data.doublePointer = (argarray == NULL)
-		      ? (double *)va_arg(*arglist, float *)
+		      ? (double *)va_arg(TRIO_VA_LIST_DEREF(arglist), float *)
 		      : (double *)((float *)argarray[num]);
                 }
 	    }
@@ -2113,13 +2123,13 @@
 	    {
 	      if (parameters[i].flags & FLAGS_LONGDOUBLE)
 		parameters[i].data.longdoubleNumber = (argarray == NULL)
-		  ? va_arg(*arglist, trio_long_double_t)
+		  ? va_arg(TRIO_VA_LIST_DEREF(arglist), trio_long_double_t)
 		  : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
 	      else
 		{
 		  if (argarray == NULL)
 		    parameters[i].data.longdoubleNumber =
-		      (trio_long_double_t)va_arg(*arglist, double);
+		      (trio_long_double_t)va_arg(TRIO_VA_LIST_DEREF(arglist), double);
 		  else
 		    {
 		      if (parameters[i].flags & FLAGS_SHORT)
@@ -3384,7 +3394,7 @@
 TRIO_ARGS4((reference, format, arglist, argarray),
 	   trio_reference_t *reference,
 	   TRIO_CONST char *format,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   int status;
@@ -3412,7 +3422,7 @@
 	   size_t destinationSize,
 	   void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
 	   TRIO_CONST char *format,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   int status;
@@ -3638,7 +3648,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+  status = TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3658,7 +3668,7 @@
 {
   assert(VALID(format));
 
-  return TrioFormat(stdout, 0, TrioOutStreamFile, format, &args, NULL);
+  return TrioFormat(stdout, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 /**
@@ -3705,7 +3715,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+  status = TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3728,7 +3738,7 @@
   assert(VALID(file));
   assert(VALID(format));
 
-  return TrioFormat(file, 0, TrioOutStreamFile, format, &args, NULL);
+  return TrioFormat(file, 0, TrioOutStreamFile, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 /**
@@ -3777,7 +3787,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+  status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3799,7 +3809,7 @@
 {
   assert(VALID(format));
 
-  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, &args, NULL);
+  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 /**
@@ -3843,7 +3853,7 @@
   TRIO_VA_START(args, format);
   data.stream.out = stream;
   data.closure = closure;
-  status = TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+  status = TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -3863,7 +3873,7 @@
 
   data.stream.out = stream;
   data.closure = closure;
-  return TrioFormat(&data, 0, TrioOutStreamCustom, format, &args, NULL);
+  return TrioFormat(&data, 0, TrioOutStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -3910,7 +3920,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(args, format);
-  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
   *buffer = NIL; /* Terminate with NIL character */
   TRIO_VA_END(args);
   return status;
@@ -3936,7 +3946,7 @@
   assert(VALID(buffer));
   assert(VALID(format));
 
-  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, &args, NULL);
+  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, TRIO_VA_LIST_ADDR(args), NULL);
   *buffer = NIL;
   return status;
 }
@@ -3995,7 +4005,7 @@
 
   TRIO_VA_START(args, format);
   status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   if (max > 0)
     *buffer = NIL;
   TRIO_VA_END(args);
@@ -4025,7 +4035,7 @@
   assert(VALID(format));
 
   status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   if (max > 0)
     *buffer = NIL;
   return status;
@@ -4086,7 +4096,7 @@
   buffer = &buffer[buf_len];
 
   status = TrioFormat(&buffer, max - 1 - buf_len,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   *buffer = NIL;
   return status;
@@ -4109,7 +4119,7 @@
   buf_len = trio_length(buffer);
   buffer = &buffer[buf_len];
   status = TrioFormat(&buffer, max - 1 - buf_len,
-		      TrioOutStreamStringMax, format, &args, NULL);
+		      TrioOutStreamStringMax, format, TRIO_VA_LIST_ADDR(args), NULL);
   *buffer = NIL;
   return status;
 }
@@ -4136,7 +4146,7 @@
     {
       TRIO_VA_START(args, format);
       (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
-		       format, &args, NULL);
+		       format, TRIO_VA_LIST_ADDR(args), NULL);
       TRIO_VA_END(args);
 
       trio_string_terminate(info);
@@ -4162,7 +4172,7 @@
   if (info)
     {
       (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
-		       format, &args, NULL);
+		       format, TRIO_VA_LIST_ADDR(args), NULL);
       trio_string_terminate(info);
       result = trio_string_extract(info);
       trio_string_destroy(info);
@@ -4194,7 +4204,7 @@
     {
       TRIO_VA_START(args, format);
       status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
-			  format, &args, NULL);
+			  format, TRIO_VA_LIST_ADDR(args), NULL);
       TRIO_VA_END(args);
       if (status >= 0)
 	{
@@ -4228,7 +4238,7 @@
   else
     {
       status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
-			  format, &args, NULL);
+			  format, TRIO_VA_LIST_ADDR(args), NULL);
       if (status >= 0)
 	{
 	  trio_string_terminate(info);
@@ -4930,7 +4940,7 @@
   assert(VALID(format));
 
   TRIO_VA_START(arglist, format);
-  status = TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+  status = TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
   TRIO_VA_END(arglist);
   return status;
 }
@@ -4947,7 +4957,7 @@
 {
   assert(VALID(format));
 
-  return TrioFormatRef((trio_reference_t *)ref, format, &arglist, NULL);
+  return TrioFormatRef((trio_reference_t *)ref, format, TRIO_VA_LIST_ADDR(arglist), NULL);
 }
 
 /*************************************************************************
@@ -6374,7 +6384,7 @@
 	   size_t sourceSize,
 	   void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
 	   TRIO_CONST char *format,
-	   va_list *arglist,
+	   TRIO_VA_LIST_PTR arglist,
 	   trio_pointer_t *argarray)
 {
   int status;
@@ -6586,7 +6596,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)stdin, 0,
 		    TrioInStreamFile,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6601,7 +6611,7 @@
 
   return TrioScan((trio_pointer_t)stdin, 0,
 		  TrioInStreamFile,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6636,7 +6646,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)file, 0,
 		    TrioInStreamFile,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6653,7 +6663,7 @@
 
   return TrioScan((trio_pointer_t)file, 0,
 		  TrioInStreamFile,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6689,7 +6699,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)&fd, 0,
 		    TrioInStreamFileDescriptor,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6705,7 +6715,7 @@
 
   return TrioScan((trio_pointer_t)&fd, 0,
 		  TrioInStreamFileDescriptor,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6743,7 +6753,7 @@
   TRIO_VA_START(args, format);
   data.stream.in = stream;
   data.closure = closure;
-  status = TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+  status = TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6763,7 +6773,7 @@
 
   data.stream.in = stream;
   data.closure = closure;
-  return TrioScan(&data, 0, TrioInStreamCustom, format, &args, NULL);
+  return TrioScan(&data, 0, TrioInStreamCustom, format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int
@@ -6803,7 +6813,7 @@
   TRIO_VA_START(args, format);
   status = TrioScan((trio_pointer_t)&buffer, 0,
 		    TrioInStreamString,
-		    format, &args, NULL);
+		    format, TRIO_VA_LIST_ADDR(args), NULL);
   TRIO_VA_END(args);
   return status;
 }
@@ -6820,7 +6830,7 @@
 
   return TrioScan((trio_pointer_t)&buffer, 0,
 		  TrioInStreamString,
-		  format, &args, NULL);
+		  format, TRIO_VA_LIST_ADDR(args), NULL);
 }
 
 TRIO_PUBLIC int