xref: /netbsd-src/external/gpl2/gettext/dist/gettext-runtime/intl/printf-args.c (revision 946379e7b37692fc43f68eb0d1c10daa0a7f3b6c)
1*946379e7Schristos /* Decomposed printf argument list.
2*946379e7Schristos    Copyright (C) 1999, 2002-2003, 2005-2006 Free Software Foundation, Inc.
3*946379e7Schristos 
4*946379e7Schristos    This program is free software; you can redistribute it and/or modify it
5*946379e7Schristos    under the terms of the GNU Library General Public License as published
6*946379e7Schristos    by the Free Software Foundation; either version 2, or (at your option)
7*946379e7Schristos    any later version.
8*946379e7Schristos 
9*946379e7Schristos    This program is distributed in the hope that it will be useful,
10*946379e7Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
11*946379e7Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12*946379e7Schristos    Library General Public License for more details.
13*946379e7Schristos 
14*946379e7Schristos    You should have received a copy of the GNU Library General Public
15*946379e7Schristos    License along with this program; if not, write to the Free Software
16*946379e7Schristos    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17*946379e7Schristos    USA.  */
18*946379e7Schristos 
19*946379e7Schristos #include <config.h>
20*946379e7Schristos 
21*946379e7Schristos /* Specification.  */
22*946379e7Schristos #include "printf-args.h"
23*946379e7Schristos 
24*946379e7Schristos #ifdef STATIC
25*946379e7Schristos STATIC
26*946379e7Schristos #endif
27*946379e7Schristos int
printf_fetchargs(va_list args,arguments * a)28*946379e7Schristos printf_fetchargs (va_list args, arguments *a)
29*946379e7Schristos {
30*946379e7Schristos   size_t i;
31*946379e7Schristos   argument *ap;
32*946379e7Schristos 
33*946379e7Schristos   for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
34*946379e7Schristos     switch (ap->type)
35*946379e7Schristos       {
36*946379e7Schristos       case TYPE_SCHAR:
37*946379e7Schristos 	ap->a.a_schar = va_arg (args, /*signed char*/ int);
38*946379e7Schristos 	break;
39*946379e7Schristos       case TYPE_UCHAR:
40*946379e7Schristos 	ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
41*946379e7Schristos 	break;
42*946379e7Schristos       case TYPE_SHORT:
43*946379e7Schristos 	ap->a.a_short = va_arg (args, /*short*/ int);
44*946379e7Schristos 	break;
45*946379e7Schristos       case TYPE_USHORT:
46*946379e7Schristos 	ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
47*946379e7Schristos 	break;
48*946379e7Schristos       case TYPE_INT:
49*946379e7Schristos 	ap->a.a_int = va_arg (args, int);
50*946379e7Schristos 	break;
51*946379e7Schristos       case TYPE_UINT:
52*946379e7Schristos 	ap->a.a_uint = va_arg (args, unsigned int);
53*946379e7Schristos 	break;
54*946379e7Schristos       case TYPE_LONGINT:
55*946379e7Schristos 	ap->a.a_longint = va_arg (args, long int);
56*946379e7Schristos 	break;
57*946379e7Schristos       case TYPE_ULONGINT:
58*946379e7Schristos 	ap->a.a_ulongint = va_arg (args, unsigned long int);
59*946379e7Schristos 	break;
60*946379e7Schristos #ifdef HAVE_LONG_LONG_INT
61*946379e7Schristos       case TYPE_LONGLONGINT:
62*946379e7Schristos 	ap->a.a_longlongint = va_arg (args, long long int);
63*946379e7Schristos 	break;
64*946379e7Schristos       case TYPE_ULONGLONGINT:
65*946379e7Schristos 	ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
66*946379e7Schristos 	break;
67*946379e7Schristos #endif
68*946379e7Schristos       case TYPE_DOUBLE:
69*946379e7Schristos 	ap->a.a_double = va_arg (args, double);
70*946379e7Schristos 	break;
71*946379e7Schristos #ifdef HAVE_LONG_DOUBLE
72*946379e7Schristos       case TYPE_LONGDOUBLE:
73*946379e7Schristos 	ap->a.a_longdouble = va_arg (args, long double);
74*946379e7Schristos 	break;
75*946379e7Schristos #endif
76*946379e7Schristos       case TYPE_CHAR:
77*946379e7Schristos 	ap->a.a_char = va_arg (args, int);
78*946379e7Schristos 	break;
79*946379e7Schristos #ifdef HAVE_WINT_T
80*946379e7Schristos       case TYPE_WIDE_CHAR:
81*946379e7Schristos 	/* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
82*946379e7Schristos 	   default argument promotions", this is not the case in mingw32,
83*946379e7Schristos 	   where wint_t is 'unsigned short'.  */
84*946379e7Schristos 	ap->a.a_wide_char =
85*946379e7Schristos 	  (sizeof (wint_t) < sizeof (int)
86*946379e7Schristos 	   ? va_arg (args, int)
87*946379e7Schristos 	   : va_arg (args, wint_t));
88*946379e7Schristos 	break;
89*946379e7Schristos #endif
90*946379e7Schristos       case TYPE_STRING:
91*946379e7Schristos 	ap->a.a_string = va_arg (args, const char *);
92*946379e7Schristos 	/* A null pointer is an invalid argument for "%s", but in practice
93*946379e7Schristos 	   it occurs quite frequently in printf statements that produce
94*946379e7Schristos 	   debug output.  Use a fallback in this case.  */
95*946379e7Schristos 	if (ap->a.a_string == NULL)
96*946379e7Schristos 	  ap->a.a_string = "(NULL)";
97*946379e7Schristos 	break;
98*946379e7Schristos #ifdef HAVE_WCHAR_T
99*946379e7Schristos       case TYPE_WIDE_STRING:
100*946379e7Schristos 	ap->a.a_wide_string = va_arg (args, const wchar_t *);
101*946379e7Schristos 	/* A null pointer is an invalid argument for "%ls", but in practice
102*946379e7Schristos 	   it occurs quite frequently in printf statements that produce
103*946379e7Schristos 	   debug output.  Use a fallback in this case.  */
104*946379e7Schristos 	if (ap->a.a_wide_string == NULL)
105*946379e7Schristos 	  {
106*946379e7Schristos 	    static const wchar_t wide_null_string[] =
107*946379e7Schristos 	      {
108*946379e7Schristos 		(wchar_t)'(',
109*946379e7Schristos 		(wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
110*946379e7Schristos 		(wchar_t)')',
111*946379e7Schristos 		(wchar_t)0
112*946379e7Schristos 	      };
113*946379e7Schristos 	    ap->a.a_wide_string = wide_null_string;
114*946379e7Schristos 	  }
115*946379e7Schristos 	break;
116*946379e7Schristos #endif
117*946379e7Schristos       case TYPE_POINTER:
118*946379e7Schristos 	ap->a.a_pointer = va_arg (args, void *);
119*946379e7Schristos 	break;
120*946379e7Schristos       case TYPE_COUNT_SCHAR_POINTER:
121*946379e7Schristos 	ap->a.a_count_schar_pointer = va_arg (args, signed char *);
122*946379e7Schristos 	break;
123*946379e7Schristos       case TYPE_COUNT_SHORT_POINTER:
124*946379e7Schristos 	ap->a.a_count_short_pointer = va_arg (args, short *);
125*946379e7Schristos 	break;
126*946379e7Schristos       case TYPE_COUNT_INT_POINTER:
127*946379e7Schristos 	ap->a.a_count_int_pointer = va_arg (args, int *);
128*946379e7Schristos 	break;
129*946379e7Schristos       case TYPE_COUNT_LONGINT_POINTER:
130*946379e7Schristos 	ap->a.a_count_longint_pointer = va_arg (args, long int *);
131*946379e7Schristos 	break;
132*946379e7Schristos #ifdef HAVE_LONG_LONG_INT
133*946379e7Schristos       case TYPE_COUNT_LONGLONGINT_POINTER:
134*946379e7Schristos 	ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
135*946379e7Schristos 	break;
136*946379e7Schristos #endif
137*946379e7Schristos       default:
138*946379e7Schristos 	/* Unknown type.  */
139*946379e7Schristos 	return -1;
140*946379e7Schristos       }
141*946379e7Schristos   return 0;
142*946379e7Schristos }
143