Coverage Report

Created: 2025-08-26 06:55

/src/glib/glib/gnulib/printf-args.c
Line
Count
Source (jump to first uncovered line)
1
/* Decomposed printf argument list.
2
   Copyright (C) 1999, 2002-2003, 2005-2007, 2009-2019 Free Software
3
   Foundation, Inc.
4
5
   This program is free software; you can redistribute it and/or modify
6
   it under the terms of the GNU Lesser General Public License as published by
7
   the Free Software Foundation; either version 2.1, or (at your option)
8
   any later version.
9
10
   This program is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public License along
16
   with this program; if not, see <https://www.gnu.org/licenses/>.  */
17
18
/* This file can be parametrized with the following macros:
19
     ENABLE_UNISTDIO    Set to 1 to enable the unistdio extensions.
20
     PRINTF_FETCHARGS   Name of the function to be defined.
21
     STATIC             Set to 'static' to declare the function static.  */
22
23
#ifndef PRINTF_FETCHARGS
24
# include <config.h>
25
#endif
26
27
#include "g-gnulib.h"
28
29
/* Specification.  */
30
#ifndef PRINTF_FETCHARGS
31
# include "printf-args.h"
32
#endif
33
34
#ifdef STATIC
35
STATIC
36
#endif
37
int
38
PRINTF_FETCHARGS (va_list args, arguments *a)
39
72.2M
{
40
72.2M
  size_t i;
41
72.2M
  argument *ap;
42
43
155M
  for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
44
83.6M
    switch (ap->type)
45
83.6M
      {
46
0
      case TYPE_SCHAR:
47
0
        ap->a.a_schar = va_arg (args, /*signed char*/ int);
48
0
        break;
49
0
      case TYPE_UCHAR:
50
0
        ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
51
0
        break;
52
0
      case TYPE_SHORT:
53
0
        ap->a.a_short = va_arg (args, /*short*/ int);
54
0
        break;
55
0
      case TYPE_USHORT:
56
0
        ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
57
0
        break;
58
39.7k
      case TYPE_INT:
59
39.7k
        ap->a.a_int = va_arg (args, int);
60
39.7k
        break;
61
78.0M
      case TYPE_UINT:
62
78.0M
        ap->a.a_uint = va_arg (args, unsigned int);
63
78.0M
        break;
64
0
      case TYPE_LONGINT:
65
0
        ap->a.a_longint = va_arg (args, long int);
66
0
        break;
67
34.8k
      case TYPE_ULONGINT:
68
34.8k
        ap->a.a_ulongint = va_arg (args, unsigned long int);
69
34.8k
        break;
70
0
#if HAVE_LONG_LONG
71
0
      case TYPE_LONGLONGINT:
72
0
        ap->a.a_longlongint = va_arg (args, long long int);
73
0
        break;
74
0
      case TYPE_ULONGLONGINT:
75
0
        ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
76
0
        break;
77
0
#endif
78
1.84k
      case TYPE_DOUBLE:
79
1.84k
        ap->a.a_double = va_arg (args, double);
80
1.84k
        break;
81
0
      case TYPE_LONGDOUBLE:
82
0
        ap->a.a_longdouble = va_arg (args, long double);
83
0
        break;
84
753
      case TYPE_CHAR:
85
753
        ap->a.a_char = va_arg (args, int);
86
753
        break;
87
0
#if HAVE_WINT_T
88
0
      case TYPE_WIDE_CHAR:
89
        /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
90
           default argument promotions", this is not the case in mingw32,
91
           where wint_t is 'unsigned short'.  */
92
0
        ap->a.a_wide_char =
93
0
          (sizeof (wint_t) < sizeof (int)
94
0
           ? (wint_t) va_arg (args, int)
95
0
           : va_arg (args, wint_t));
96
0
        break;
97
0
#endif
98
5.54M
      case TYPE_STRING:
99
5.54M
        ap->a.a_string = va_arg (args, const char *);
100
        /* A null pointer is an invalid argument for "%s", but in practice
101
           it occurs quite frequently in printf statements that produce
102
           debug output.  Use a fallback in this case.  */
103
5.54M
        if (ap->a.a_string == NULL)
104
38.2k
          ap->a.a_string = "(NULL)";
105
5.54M
        break;
106
0
#if HAVE_WCHAR_T
107
0
      case TYPE_WIDE_STRING:
108
0
        ap->a.a_wide_string = va_arg (args, const wchar_t *);
109
        /* A null pointer is an invalid argument for "%ls", but in practice
110
           it occurs quite frequently in printf statements that produce
111
           debug output.  Use a fallback in this case.  */
112
0
        if (ap->a.a_wide_string == NULL)
113
0
          {
114
0
            static const wchar_t wide_null_string[] =
115
0
              {
116
0
                (wchar_t)'(',
117
0
                (wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
118
0
                (wchar_t)')',
119
0
                (wchar_t)0
120
0
              };
121
0
            ap->a.a_wide_string = wide_null_string;
122
0
          }
123
0
        break;
124
0
#endif
125
0
      case TYPE_POINTER:
126
0
        ap->a.a_pointer = va_arg (args, void *);
127
0
        break;
128
0
      case TYPE_COUNT_SCHAR_POINTER:
129
0
        ap->a.a_count_schar_pointer = va_arg (args, signed char *);
130
0
        break;
131
0
      case TYPE_COUNT_SHORT_POINTER:
132
0
        ap->a.a_count_short_pointer = va_arg (args, short *);
133
0
        break;
134
0
      case TYPE_COUNT_INT_POINTER:
135
0
        ap->a.a_count_int_pointer = va_arg (args, int *);
136
0
        break;
137
0
      case TYPE_COUNT_LONGINT_POINTER:
138
0
        ap->a.a_count_longint_pointer = va_arg (args, long int *);
139
0
        break;
140
0
#if HAVE_LONG_LONG
141
0
      case TYPE_COUNT_LONGLONGINT_POINTER:
142
0
        ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
143
0
        break;
144
0
#endif
145
#if ENABLE_UNISTDIO
146
      /* The unistdio extensions.  */
147
      case TYPE_U8_STRING:
148
        ap->a.a_u8_string = va_arg (args, const uint8_t *);
149
        /* A null pointer is an invalid argument for "%U", but in practice
150
           it occurs quite frequently in printf statements that produce
151
           debug output.  Use a fallback in this case.  */
152
        if (ap->a.a_u8_string == NULL)
153
          {
154
            static const uint8_t u8_null_string[] =
155
              { '(', 'N', 'U', 'L', 'L', ')', 0 };
156
            ap->a.a_u8_string = u8_null_string;
157
          }
158
        break;
159
      case TYPE_U16_STRING:
160
        ap->a.a_u16_string = va_arg (args, const uint16_t *);
161
        /* A null pointer is an invalid argument for "%lU", but in practice
162
           it occurs quite frequently in printf statements that produce
163
           debug output.  Use a fallback in this case.  */
164
        if (ap->a.a_u16_string == NULL)
165
          {
166
            static const uint16_t u16_null_string[] =
167
              { '(', 'N', 'U', 'L', 'L', ')', 0 };
168
            ap->a.a_u16_string = u16_null_string;
169
          }
170
        break;
171
      case TYPE_U32_STRING:
172
        ap->a.a_u32_string = va_arg (args, const uint32_t *);
173
        /* A null pointer is an invalid argument for "%llU", but in practice
174
           it occurs quite frequently in printf statements that produce
175
           debug output.  Use a fallback in this case.  */
176
        if (ap->a.a_u32_string == NULL)
177
          {
178
            static const uint32_t u32_null_string[] =
179
              { '(', 'N', 'U', 'L', 'L', ')', 0 };
180
            ap->a.a_u32_string = u32_null_string;
181
          }
182
        break;
183
#endif
184
0
      default:
185
        /* Unknown type.  */
186
0
        return -1;
187
83.6M
      }
188
72.2M
  return 0;
189
72.2M
}