MySQL 8.0.31
Source Code Documentation
ut0core.h
Go to the documentation of this file.
1/* Copyright (c) 2021, 2022, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22*/
23
24/** @file include/ut0log.h Base of InnoDB utilities. */
25
26#ifndef ut0core_h
27#define ut0core_h
28
29#include "ut0dbg.h"
30
31namespace ut {
32struct Location {
33 const char *filename;
34 size_t line;
35 std::ostream &print(std::ostream &out) const {
36 out << "[Location: file=" << filename << ", line=" << line << "]";
37 return out;
38 }
39};
40} // namespace ut
41
42inline std::ostream &operator<<(std::ostream &out, const ut::Location &obj) {
43 return obj.print(out);
44}
45
46#define UT_LOCATION_HERE (ut::Location{__FILE__, __LINE__})
47
48namespace ib {
49
50#ifdef UNIV_DEBUG
51/** Finds the first format specifier in `fmt` format string
52@param[in] fmt The format string
53@return Either the longest suffix of `fmt` which starts with format specifier,
54or `nullptr` if could not find any format specifier inside `fmt`.
55*/
56static inline const char *get_first_format(const char *fmt) {
57 const char *pos = strchr(fmt, '%');
58 if (pos != nullptr && pos[1] == '%') {
59 return (get_first_format(pos + 2));
60 }
61 return (pos);
62}
63
64/** Verifies that the `fmt` format string does not require any arguments
65@param[in] fmt The format string
66@return true if and only if there is no format specifier inside `fmt` which
67requires passing an argument */
68static inline bool verify_fmt_match(const char *fmt) {
69 return (get_first_format(fmt) == nullptr);
70}
71
72/** Verifies that the `fmt` format string contains format specifiers which match
73the type and order of the arguments
74@param[in] fmt The format string
75@param[in] head The first argument
76@param[in] tail Others (perhaps none) arguments
77@return true if and only if the format specifiers found in `fmt` correspond to
78types of head, tail...
79*/
80template <typename Head, typename... Tail>
81static bool verify_fmt_match(const char *fmt, Head &&head [[maybe_unused]],
82 Tail &&... tail) {
83 using H =
85 const char *pos = get_first_format(fmt);
86 if (pos == nullptr) {
87 return (false);
88 }
89 /* We currently only handle :
90 %[-0-9.*]*(d|ld|lld|u|lu|llu|zu|zx|zd|s|x|i|f|c|X|p|lx|llx|lf)
91 Feel free to extend the parser, if you need something more, as the parser is
92 not intended to be any stricter than real printf-format parser, and if it does
93 not handle something, it is only to keep the code simpler. */
94 const std::string skipable("-+ #0123456789.*");
95
96 pos++;
97 while (*pos != '\0' && skipable.find_first_of(*pos) != std::string::npos) {
98 pos++;
99 }
100 if (*pos == '\0') {
101 return (false);
102 }
103 bool is_ok = true;
104 if (pos[0] == 'l') {
105 if (pos[1] == 'l') {
106 if (pos[2] == 'd') {
107 is_ok = std::is_same<H, long long int>::value;
108 } else if (pos[2] == 'u' || pos[2] == 'x') {
109 is_ok = std::is_same<H, unsigned long long int>::value;
110 } else {
111 is_ok = false;
112 }
113 } else if (pos[1] == 'd') {
114 is_ok = std::is_same<H, long int>::value;
115 } else if (pos[1] == 'u') {
116 is_ok = std::is_same<H, unsigned long int>::value;
117 } else if (pos[1] == 'x') {
118 is_ok = std::is_same<H, unsigned long int>::value;
119 } else if (pos[1] == 'f') {
120 is_ok = std::is_same<H, double>::value;
121 } else {
122 is_ok = false;
123 }
124 } else if (pos[0] == 'd') {
125 is_ok = std::is_same<H, int>::value;
126 } else if (pos[0] == 'u') {
127 is_ok = std::is_same<H, unsigned int>::value;
128 } else if (pos[0] == 'x') {
129 is_ok = std::is_same<H, unsigned int>::value;
130 } else if (pos[0] == 'X') {
131 is_ok = std::is_same<H, unsigned int>::value;
132 } else if (pos[0] == 'i') {
133 is_ok = std::is_same<H, int>::value;
134 } else if (pos[0] == 'f') {
135 is_ok = std::is_same<H, float>::value;
136 } else if (pos[0] == 'c') {
137 is_ok = std::is_same<H, char>::value;
138 } else if (pos[0] == 'p') {
139 is_ok = std::is_pointer<H>::value;
140 } else if (pos[0] == 's') {
141 is_ok = (std::is_same<H, char *>::value ||
142 std::is_same<H, char const *>::value ||
143 (std::is_array<H>::value &&
144 std::is_same<typename std::remove_cv<
146 char>::value));
147 } else if (pos[0] == 'z') {
148 if (pos[1] == 'u') {
149 is_ok = std::is_same<H, size_t>::value;
150 } else if (pos[1] == 'x') {
151 is_ok = std::is_same<H, size_t>::value;
152 } else if (pos[1] == 'd') {
153 is_ok = std::is_same<H, ssize_t>::value;
154 } else {
155 is_ok = false;
156 }
157 } else {
158 is_ok = false;
159 }
160 return (is_ok && verify_fmt_match(pos + 1, std::forward<Tail>(tail)...));
161}
162#endif /* UNIV_DEBUG */
163
164/** This is a wrapper class, used to print any unsigned integer type
165in hexadecimal format. The main purpose of this data type is to
166overload the global operator<<, so that we can print the given
167wrapper value in hex. */
168struct hex {
169 explicit hex(uintmax_t t) : m_val(t) {}
170 const uintmax_t m_val;
171};
172
173/** This is an overload of the global operator<< for the user defined type
174ib::hex. The unsigned value held in the ib::hex wrapper class will be printed
175into the given output stream in hexadecimal format.
176@param[in,out] lhs the output stream into which rhs is written.
177@param[in] rhs the object to be written into lhs.
178@retval reference to the output stream. */
179inline std::ostream &operator<<(std::ostream &lhs, const hex &rhs) {
180 std::ios_base::fmtflags ff = lhs.flags();
181 lhs << std::showbase << std::hex << rhs.m_val;
182 lhs.setf(ff);
183 return (lhs);
184}
185
186} // namespace ib
187
188#endif
char * pos
Definition: do_ctype.cc:76
constexpr pos_type Head
Definition: http_request.h:257
Definition: ut0core.h:48
static bool verify_fmt_match(const char *fmt)
Verifies that the fmt format string does not require any arguments.
Definition: ut0core.h:68
static const char * get_first_format(const char *fmt)
Finds the first format specifier in fmt format string.
Definition: ut0core.h:56
std::ostream & operator<<(std::ostream &lhs, const hex &rhs)
This is an overload of the global operator<< for the user defined type ib::hex.
Definition: ut0core.h:179
This file contains a set of libraries providing overloads for regular dynamic allocation routines whi...
Definition: aligned_alloc.h:47
required string type
Definition: replication_group_member_actions.proto:33
This is a wrapper class, used to print any unsigned integer type in hexadecimal format.
Definition: ut0core.h:168
const uintmax_t m_val
Definition: ut0core.h:170
hex(uintmax_t t)
Definition: ut0core.h:169
Definition: ut0core.h:32
const char * filename
Definition: ut0core.h:33
size_t line
Definition: ut0core.h:34
std::ostream & print(std::ostream &out) const
Definition: ut0core.h:35
std::ostream & operator<<(std::ostream &out, const ut::Location &obj)
Definition: ut0core.h:42
Debug utilities for Innobase.