MySQL  8.0.18
Source Code Documentation
m_string.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License, version 2.0,
6  as published by the Free Software Foundation.
7 
8  This program is also distributed with certain software (including
9  but not limited to OpenSSL) that is licensed under separate terms,
10  as designated in a particular file or component or in included license
11  documentation. The authors of MySQL hereby grant you an additional
12  permission to link the program and your derivative works with the
13  separately licensed software that they have included with MySQL.
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 #ifndef _m_string_h
25 #define _m_string_h
26 
27 /**
28  @file include/m_string.h
29 */
30 
31 #include <float.h>
32 #include <limits.h>
33 #include <stdbool.h> // IWYU pragma: keep
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 
39 #include "decimal.h"
40 #include "lex_string.h"
41 #include "my_config.h"
42 #include "my_inttypes.h"
43 #include "my_macros.h"
44 
45 /**
46  Definition of the null string (a null pointer of type char *),
47  used in some of our string handling code. New code should use
48  nullptr instead.
49 */
50 #define NullS (char *)0
51 
52 /*
53  my_str_malloc(), my_str_realloc() and my_str_free() are assigned to
54  implementations in strings/alloc.cc, but can be overridden in
55  the calling program.
56  */
57 extern void *(*my_str_malloc)(size_t);
58 extern void *(*my_str_realloc)(void *, size_t);
59 extern void (*my_str_free)(void *);
60 
61 /* Declared in int2str() */
62 extern char _dig_vec_upper[];
63 extern char _dig_vec_lower[];
64 
65 /* Prototypes for string functions */
66 
67 extern char *strmake(char *dst, const char *src, size_t length);
68 extern char *strcont(char *src, const char *set);
69 extern char *strxmov(char *dst, const char *src, ...);
70 extern char *strxnmov(char *dst, size_t len, const char *src, ...);
71 
72 /*
73  bchange(dst, old_length, src, new_length, tot_length)
74  replaces old_length characters at dst to new_length characters from
75  src in a buffer with tot_length bytes.
76 */
77 static inline void bchange(uchar *dst, size_t old_length, const uchar *src,
78  size_t new_length, size_t tot_length) {
79  memmove(dst + new_length, dst + old_length, tot_length - old_length);
80  memcpy(dst, src, new_length);
81 }
82 
83 /*
84  strend(s) returns a character pointer to the NUL which ends s. That
85  is, strend(s)-s == strlen(s). This is useful for adding things at
86  the end of strings. It is redundant, because strchr(s,'\0') could
87  be used instead, but this is clearer and faster.
88 */
89 static inline const char *strend(const char *s) {
90  while (*s++)
91  ;
92  return s - 1;
93 }
94 
95 static inline char *strend(char *s) {
96  while (*s++)
97  ;
98  return s - 1;
99 }
100 
101 /*
102  strcend(s, c) returns a pointer to the first place in s where c
103  occurs, or a pointer to the end-null of s if c does not occur in s.
104 */
105 static inline const char *strcend(const char *s, char c) {
106  for (;;) {
107  if (*s == c) return s;
108  if (!*s++) return s - 1;
109  }
110 }
111 
112 /*
113  strfill(dest, len, fill) makes a string of fill-characters. The result
114  string is of length == len. The des+len character is allways set to NULL.
115  strfill() returns pointer to dest+len;
116 */
117 static inline char *strfill(char *s, size_t len, char fill) {
118  while (len--) *s++ = fill;
119  *(s) = '\0';
120  return (s);
121 }
122 
123 /*
124  my_stpmov(dst, src) moves all the characters of src (including the
125  closing NUL) to dst, and returns a pointer to the new closing NUL in
126  dst. The similar UNIX routine strcpy returns the old value of dst,
127  which I have never found useful. my_stpmov(my_stpmov(dst,a),b) moves a//b
128  into dst, which seems useful.
129 */
130 static inline char *my_stpmov(char *dst, const char *src) {
131  while ((*dst++ = *src++))
132  ;
133  return dst - 1;
134 }
135 
136 /*
137  my_stpnmov(dst,src,length) moves length characters, or until end, of src to
138  dst and appends a closing NUL to dst if src is shorter than length.
139  The result is a pointer to the first NUL in dst, or is dst+n if dst was
140  truncated.
141 */
142 static inline char *my_stpnmov(char *dst, const char *src, size_t n) {
143  while (n-- != 0) {
144  if (!(*dst++ = *src++)) return (char *)dst - 1;
145  }
146  return dst;
147 }
148 
149 /**
150  Copy a string from src to dst until (and including) terminating null byte.
151 
152  @param dst Destination
153  @param src Source
154 
155  @note src and dst cannot overlap.
156  Use my_stpmov() if src and dst overlaps.
157 
158  @note Unsafe, consider using my_stpnpy() instead.
159 
160  @return pointer to terminating null byte.
161 */
162 static inline char *my_stpcpy(char *dst, const char *src) {
163 #if defined(HAVE_BUILTIN_STPCPY)
164  return __builtin_stpcpy(dst, src);
165 #elif defined(HAVE_STPCPY)
166  return stpcpy(dst, src);
167 #else
168  /* Fallback to implementation supporting overlap. */
169  return my_stpmov(dst, src);
170 #endif
171 }
172 
173 /**
174  Copy fixed-size string from src to dst.
175 
176  @param dst Destination
177  @param src Source
178  @param n Maximum number of characters to copy.
179 
180  @note src and dst cannot overlap
181  Use my_stpnmov() if src and dst overlaps.
182 
183  @return pointer to terminating null byte.
184 */
185 static inline char *my_stpncpy(char *dst, const char *src, size_t n) {
186 #if defined(HAVE_STPNCPY)
187  return stpncpy(dst, src, n);
188 #else
189  /* Fallback to implementation supporting overlap. */
190  return my_stpnmov(dst, src, n);
191 #endif
192 }
193 
194 static inline longlong my_strtoll(const char *nptr, char **endptr, int base) {
195 #if defined _WIN32
196  return _strtoi64(nptr, endptr, base);
197 #else
198  return strtoll(nptr, endptr, base);
199 #endif
200 }
201 
202 static inline ulonglong my_strtoull(const char *nptr, char **endptr, int base) {
203 #if defined _WIN32
204  return _strtoui64(nptr, endptr, base);
205 #else
206  return strtoull(nptr, endptr, base);
207 #endif
208 }
209 
210 static inline char *my_strtok_r(char *str, const char *delim, char **saveptr) {
211 #if defined _WIN32
212  return strtok_s(str, delim, saveptr);
213 #else
214  return strtok_r(str, delim, saveptr);
215 #endif
216 }
217 
218 /* native_ rather than my_ since my_strcasecmp already exists */
219 static inline int native_strcasecmp(const char *s1, const char *s2) {
220 #if defined _WIN32
221  return _stricmp(s1, s2);
222 #else
223  return strcasecmp(s1, s2);
224 #endif
225 }
226 
227 /* native_ rather than my_ for consistency with native_strcasecmp */
228 static inline int native_strncasecmp(const char *s1, const char *s2, size_t n) {
229 #if defined _WIN32
230  return _strnicmp(s1, s2, n);
231 #else
232  return strncasecmp(s1, s2, n);
233 #endif
234 }
235 
236 /*
237  is_prefix(s, t) returns 1 if s starts with t.
238  A empty t is always a prefix.
239 */
240 static inline int is_prefix(const char *s, const char *t) {
241  while (*t)
242  if (*s++ != *t++) return 0;
243  return 1; /* WRONG */
244 }
245 
246 /* Conversion routines */
248 
249 double my_strtod(const char *str, const char **end, int *error);
250 double my_atof(const char *nptr);
251 size_t my_fcvt(double x, int precision, char *to, bool *error);
252 size_t my_fcvt_compact(double x, char *to, bool *error);
253 size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
254  bool *error);
255 
256 /*
257  The longest string my_fcvt can return is 311 + "precision" bytes.
258  Here we assume that we never call my_fcvt() with precision >=
259  DECIMAL_NOT_SPECIFIED
260  (+ 1 byte for the terminating '\0').
261 */
262 static constexpr int FLOATING_POINT_BUFFER{311 + DECIMAL_NOT_SPECIFIED};
263 
264 /*
265  We want to use the 'e' format in some cases even if we have enough space
266  for the 'f' one just to mimic sprintf("%.15g") behavior for large integers,
267  and to improve it for numbers < 10^(-4).
268  That is, for |x| < 1 we require |x| >= 10^(-15), and for |x| > 1 we require
269  it to be integer and be <= 10^DBL_DIG for the 'f' format to be used.
270  We don't lose precision, but make cases like "1e200" or "0.00001" look nicer.
271 */
272 #define MAX_DECPT_FOR_F_FORMAT DBL_DIG
273 
274 /*
275  The maximum possible field width for my_gcvt() conversion.
276  (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
277  MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
278 */
279 #define MY_GCVT_MAX_FIELD_WIDTH \
280  (DBL_DIG + 4 + MY_MAX(5, MAX_DECPT_FOR_F_FORMAT))
281 
282 extern char *int2str(long val, char *dst, int radix, int upcase);
284 extern char *int10_to_str(long val, char *dst, int radix);
286 extern const char *str2int(const char *src, int radix, long lower, long upper,
287  long *val);
288 longlong my_strtoll10(const char *nptr, const char **endptr, int *error);
289 #if SIZEOF_LONG == SIZEOF_LONG_LONG
290 #define ll2str(A, B, C, D) int2str((A), (B), (C), (D))
291 #define longlong10_to_str(A, B, C) int10_to_str((A), (B), (C))
292 #undef strtoll
293 #define strtoll(A, B, C) strtol((A), (B), (C))
294 #define strtoull(A, B, C) strtoul((A), (B), (C))
295 #else
296 extern char *ll2str(longlong val, char *dst, int radix, int upcase);
297 extern char *longlong10_to_str(longlong val, char *dst, int radix);
298 #endif
299 #define longlong2str(A, B, C) ll2str((A), (B), (C), 1)
300 
301 /*
302  This function saves a longlong value in a buffer and returns the pointer to
303  the buffer.
304 */
305 static inline char *llstr(longlong value, char *buff) {
306  longlong10_to_str(value, buff, -10);
307  return buff;
308 }
309 
310 static inline char *ullstr(longlong value, char *buff) {
311  longlong10_to_str(value, buff, 10);
312  return buff;
313 }
314 
315 #define STRING_WITH_LEN(X) (X), ((sizeof(X) - 1))
316 
317 /**
318  Skip trailing space (ASCII spaces only).
319 
320  @return New end of the string.
321 */
322 static inline const uchar *skip_trailing_space(const uchar *ptr, size_t len) {
323  const uchar *end = ptr + len;
324  while (end - ptr >= 8) {
325  uint64_t chunk;
326  memcpy(&chunk, end - 8, sizeof(chunk));
327  if (chunk != 0x2020202020202020ULL) break;
328  end -= 8;
329  }
330  while (end > ptr && end[-1] == 0x20) end--;
331  return (end);
332 }
333 
334 /*
335  Format a double (representing number of bytes) into a human-readable string.
336 
337  @param buf Buffer used for printing
338  @param buf_len Length of buffer
339  @param dbl_val Value to be formatted
340 
341  @note
342  Sample output format: 42 1K 234M 2G
343  If we exceed ULLONG_MAX YiB we give up, and convert to "+INF".
344 
345  @todo Consider writing KiB GiB etc, since we use 1024 rather than 1000
346  */
347 static inline void human_readable_num_bytes(char *buf, int buf_len,
348  double dbl_val) {
349  const char size[] = {'\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'};
350  unsigned int i;
351  for (i = 0; dbl_val > 1024 && i < sizeof(size) - 1; i++) dbl_val /= 1024;
352  const char mult = size[i];
353  // 18446744073709551615 Yottabytes should be enough for most ...
354  if (dbl_val > ULLONG_MAX)
355  snprintf(buf, buf_len, "+INF");
356  else
357  snprintf(buf, buf_len, "%llu%c", (unsigned long long)dbl_val, mult);
358 }
359 
360 static inline void lex_string_set(LEX_STRING *lex_str, char *c_str) {
361  lex_str->str = c_str;
362  lex_str->length = strlen(c_str);
363 }
364 
365 static inline void lex_cstring_set(LEX_CSTRING *lex_str, const char *c_str) {
366  lex_str->str = c_str;
367  lex_str->length = strlen(c_str);
368 }
369 
370 #endif
Some common macros.
unsigned long long int ulonglong
Definition: my_inttypes.h:55
unsigned char uchar
Definition: my_inttypes.h:51
static void lex_string_set(LEX_STRING *lex_str, char *c_str)
Definition: m_string.h:360
char * str
Definition: mysql_lex_string.h:35
my_gcvt_arg_type
Definition: m_string.h:247
Definition: mysql_lex_string.h:34
Some integer typedefs for easier portability.
#define strtoull(A, B, C)
Definition: m_string.h:294
static void lex_cstring_set(LEX_CSTRING *lex_str, const char *c_str)
Definition: m_string.h:365
const char * str
Definition: mysql_lex_string.h:40
static ulonglong my_strtoull(const char *nptr, char **endptr, int base)
Definition: m_string.h:202
#define C_MODE_START
Definition: my_macros.h:39
char * int2str(long val, char *dst, int radix, int upcase)
Definition: mysql_lex_string.h:39
static int native_strcasecmp(const char *s1, const char *s2)
Definition: m_string.h:219
#define strtok_r(_s, _sep, _lasts)
Definition: win32.h:106
static char * ullstr(longlong value, char *buff)
Definition: m_string.h:310
char _dig_vec_lower[]
Definition: int2str.cc:38
static constexpr int FLOATING_POINT_BUFFER
Definition: m_string.h:262
static char * my_stpnmov(char *dst, const char *src, size_t n)
Definition: m_string.h:142
size_t my_fcvt_compact(double x, char *to, bool *error)
Converts a given floating point number to a zero-terminated string representation using the &#39;f&#39; forma...
Definition: dtoa.cc:238
#define longlong10_to_str(A, B, C)
Definition: m_string.h:291
char * strxnmov(char *dst, size_t len, const char *src,...)
Definition: strxnmov.cc:54
static const uchar * skip_trailing_space(const uchar *ptr, size_t len)
Skip trailing space (ASCII spaces only).
Definition: m_string.h:322
static char * my_stpcpy(char *dst, const char *src)
Copy a string from src to dst until (and including) terminating null byte.
Definition: m_string.h:162
char * strmake(char *dst, const char *src, size_t length)
Definition: strmake.cc:42
static constexpr int DECIMAL_NOT_SPECIFIED
Definition: decimal.h:150
char _dig_vec_upper[]
Definition: int2str.cc:37
char * strcont(char *src, const char *set)
Definition: strcont.cc:36
char * strxmov(char *dst, const char *src,...)
Definition: strxmov.cc:48
const char * str2int(const char *src, int radix, long lower, long upper, long *val)
double my_strtod(const char *str, const char **end, int *error)
Converts string to double (string does not have to be zero-terminated)
Definition: dtoa.cc:518
static char * llstr(longlong value, char *buff)
Definition: m_string.h:305
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:188
char * int10_to_str(long val, char *dst, int radix)
size_t length
Definition: mysql_lex_string.h:41
static Bigint * mult(Bigint *a, Bigint *b, Stack_alloc *alloc)
Definition: dtoa.cc:934
void(* my_str_free)(void *)
Definition: str_alloc.cc:43
static char * my_strtok_r(char *str, const char *delim, char **saveptr)
Definition: m_string.h:210
long long int longlong
Definition: my_inttypes.h:54
static char * my_stpmov(char *dst, const char *src)
Definition: m_string.h:130
static char * my_stpncpy(char *dst, const char *src, size_t n)
Copy fixed-size string from src to dst.
Definition: m_string.h:185
size_t length
Definition: mysql_lex_string.h:36
#define ll2str(A, B, C, D)
Definition: m_string.h:290
static const char * strcend(const char *s, char c)
Definition: m_string.h:105
int n
Definition: xcom_base.c:425
static int is_prefix(const char *s, const char *t)
Definition: m_string.h:240
longlong my_strtoll10(const char *nptr, const char **endptr, int *error)
Definition: my_strtoll10.cc:86
static const char * strend(const char *s)
Definition: m_string.h:89
int type
Definition: http_common.h:411
static void human_readable_num_bytes(char *buf, int buf_len, double dbl_val)
Definition: m_string.h:347
static char * strfill(char *s, size_t len, char fill)
Definition: m_string.h:117
#define C_MODE_END
Definition: my_macros.h:40
Definition: m_string.h:247
Definition: m_string.h:247
const string value("\alue\)
static void bchange(uchar *dst, size_t old_length, const uchar *src, size_t new_length, size_t tot_length)
Definition: m_string.h:77
#define strtoll(A, B, C)
Definition: m_string.h:293
static longlong my_strtoll(const char *nptr, char **endptr, int base)
Definition: m_string.h:194
size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to, bool *error)
Converts a given floating point number to a zero-terminated string representation with a given field ...
Definition: dtoa.cc:306
static std::string lower(std::string str)
Definition: config_parser.cc:66
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
static int native_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: m_string.h:228
double my_atof(const char *nptr)
Definition: dtoa.cc:530
size_t my_fcvt(double x, int precision, char *to, bool *error)
Converts a given floating point number to a zero-terminated string representation using the &#39;f&#39; forma...
Definition: dtoa.cc:207
Log error(cerr, "ERROR")