Coverage Report

Created: 2023-08-28 06:31

/src/binutils-gdb/libiberty/vprintf-support.c
Line
Count
Source (jump to first uncovered line)
1
/* Estimate the length of the string generated by a vprintf-like
2
   function.  Used by vasprintf and xvasprintf.
3
   Copyright (C) 1994-2023 Free Software Foundation, Inc.
4
5
This file is part of the libiberty library.
6
Libiberty is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Library General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
10
11
Libiberty is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
Library General Public License for more details.
15
16
You should have received a copy of the GNU Library General Public
17
License along with libiberty; see the file COPYING.LIB.  If not, write
18
to the Free Software Foundation, Inc., 51 Franklin Street - Fifth
19
Floor, Boston, MA 02110-1301, USA.  */
20
21
#ifdef HAVE_CONFIG_H
22
#include "config.h"
23
#endif
24
#include <ansidecl.h>
25
#include <stdarg.h>
26
#if !defined (va_copy) && defined (__va_copy)
27
# define va_copy(d,s)  __va_copy((d),(s))
28
#endif
29
#include <stdio.h>
30
#ifdef HAVE_STRING_H
31
#include <string.h>
32
#endif
33
#ifdef HAVE_STDLIB_H
34
#include <stdlib.h>
35
#else
36
extern unsigned long strtoul ();
37
#endif
38
#include "libiberty.h"
39
40
int
41
libiberty_vprintf_buffer_size (const char *format, va_list args)
42
118k
{
43
118k
  const char *p = format;
44
  /* Add one to make sure that it is never zero, which might cause malloc
45
     to return NULL.  */
46
118k
  int total_width = strlen (format) + 1;
47
118k
  va_list ap;
48
49
118k
#ifdef va_copy
50
118k
  va_copy (ap, args);
51
#else
52
  memcpy ((void *) &ap, (void *) &args, sizeof (va_list));
53
#endif
54
55
1.77M
  while (*p != '\0')
56
1.65M
    {
57
1.65M
      if (*p++ == '%')
58
118k
  {
59
118k
    while (strchr ("-+ #0", *p))
60
0
      ++p;
61
118k
    if (*p == '*')
62
0
      {
63
0
        ++p;
64
0
        total_width += abs (va_arg (ap, int));
65
0
      }
66
118k
    else
67
118k
      total_width += strtoul (p, (char **) &p, 10);
68
118k
    if (*p == '.')
69
0
      {
70
0
        ++p;
71
0
        if (*p == '*')
72
0
    {
73
0
      ++p;
74
0
      total_width += abs (va_arg (ap, int));
75
0
    }
76
0
        else
77
0
        total_width += strtoul (p, (char **) &p, 10);
78
0
      }
79
118k
    while (strchr ("hlL", *p))
80
0
      ++p;
81
    /* Should be big enough for any format specifier except %s and floats.  */
82
118k
    total_width += 30;
83
118k
    switch (*p)
84
118k
      {
85
0
      case 'd':
86
0
      case 'i':
87
0
      case 'o':
88
118k
      case 'u':
89
118k
      case 'x':
90
118k
      case 'X':
91
118k
      case 'c':
92
118k
        (void) va_arg (ap, int);
93
118k
        break;
94
0
      case 'f':
95
0
      case 'e':
96
0
      case 'E':
97
0
      case 'g':
98
0
      case 'G':
99
0
        (void) va_arg (ap, double);
100
        /* Since an ieee double can have an exponent of 307, we'll
101
     make the buffer wide enough to cover the gross case. */
102
0
        total_width += 307;
103
0
        break;
104
0
      case 's':
105
0
        total_width += strlen (va_arg (ap, char *));
106
0
        break;
107
0
      case 'p':
108
0
      case 'n':
109
0
        (void) va_arg (ap, char *);
110
0
        break;
111
118k
      }
112
118k
    p++;
113
118k
  }
114
1.65M
    }
115
118k
#ifdef va_copy
116
118k
  va_end (ap);
117
118k
#endif
118
118k
  return total_width;
119
118k
}