1 // Debugging support -*- C++ -*-
3 // Copyright (C) 2013-2015 Free Software Foundation, Inc.
5 // This file is part of GCC.
7 // GCC is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 3, or (at your option)
12 // GCC is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
27 #include <bits/functexcept.h>
28 #include <bits/locale_facets.h>
31 _GLIBCXX_BEGIN_NAMESPACE_VERSION
32 template<typename _CharT, typename _ValueT>
34 __int_to_char(_CharT* __bufend, _ValueT __v, const _CharT* __lit,
35 ios_base::fmtflags __flags, bool __dec);
36 _GLIBCXX_END_NAMESPACE_VERSION
41 // Private helper to throw logic error if snprintf_lite runs out
42 // of space (which is not expected to ever happen).
43 // NUL-terminates __buf.
45 __throw_insufficient_space(const char *__buf, const char *__bufend)
46 __attribute__((__noreturn__));
49 __throw_insufficient_space(const char *__buf, const char *__bufend)
51 // Include space for trailing NUL.
52 const size_t __len = __bufend - __buf + 1;
54 const char __err[] = "not enough space for format expansion "
55 "(Please submit full bug report at http://gcc.gnu.org/bugs.html):\n ";
56 const size_t __errlen = sizeof(__err) - 1;
59 = static_cast<char*>(__builtin_alloca(__errlen + __len));
61 __builtin_memcpy(__e, __err, __errlen);
62 __builtin_memcpy(__e + __errlen, __buf, __len - 1);
63 __e[__errlen + __len - 1] = '\0';
64 std::__throw_logic_error(__e);
68 // Private routine to append decimal representation of VAL to the given
69 // BUFFER, but not more than BUFSIZE characters.
70 // Does not NUL-terminate the output buffer.
71 // Returns number of characters appended, or -1 if BUFSIZE is too small.
72 int __concat_size_t(char *__buf, size_t __bufsize, size_t __val)
74 // __int_to_char is explicitly instantiated and available only for
75 // some, but not all, types. See locale-inst.cc.
76 #ifdef _GLIBCXX_USE_LONG_LONG
77 unsigned long long __val2 = __val;
79 unsigned long __val2 = __val;
81 // Long enough for decimal representation.
82 int __ilen = 3 * sizeof(__val2);
83 char *__cs = static_cast<char*>(__builtin_alloca(__ilen));
84 size_t __len = std::__int_to_char(__cs + __ilen, __val2,
85 std::__num_base::_S_atoms_out,
86 std::ios_base::dec, true);
87 if (__bufsize < __len)
90 __builtin_memcpy(__buf, __cs + __ilen - __len, __len);
95 // Private routine to print into __buf arguments according to format,
96 // not to exceed __bufsize.
97 // Only '%%', '%s' and '%zu' format specifiers are understood.
98 // Returns number of characters printed (excluding terminating NUL).
99 // Always NUL-terminates __buf.
100 // Throws logic_error on insufficient space.
101 int __snprintf_lite(char *__buf, size_t __bufsize, const char *__fmt,
105 const char *__s = __fmt;
106 const char *const __limit = __d + __bufsize - 1; // Leave space for NUL.
108 while (__s[0] != '\0' && __d < __limit)
113 default: // Stray '%'. Just print it.
120 const char *__v = va_arg(__ap, const char *);
122 while (__v[0] != '\0' && __d < __limit)
126 // Not enough space for __fmt expansion.
127 __throw_insufficient_space(__buf, __d);
129 __s += 2; // Step over %s.
134 if (__s[2] == 'u') // '%zu' -- expand next size_t arg.
136 const int __len = __concat_size_t(__d, __limit - __d,
137 va_arg(__ap, size_t));
141 // Not enough space for __fmt expansion.
142 __throw_insufficient_space(__buf, __d);
144 __s += 3; // Step over %zu
147 // Stray '%zX'. Just print it.
154 // Not enough space for __fmt expansion.
155 __throw_insufficient_space(__buf, __d);