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