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