1 /*
2    Copyright (c) 2000, 2012, Oracle and/or its affiliates.
3    Copyright (c) 2019, MariaDB Corporation.
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; version 2 of the License.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
17 
18 /* There may be problems included in all of these. Try to test in
19    configure which ones are needed? */
20 
21 /*  This is needed for the definitions of strchr... on solaris */
22 
23 #ifndef _m_string_h
24 #define _m_string_h
25 
26 #include "my_decimal_limits.h"
27 
28 #ifndef __USE_GNU
29 #define __USE_GNU				/* We want to use stpcpy */
30 #endif
31 #if defined(HAVE_STRINGS_H)
32 #include <strings.h>
33 #endif
34 #if defined(HAVE_STRING_H)
35 #include <string.h>
36 #endif
37 
38 /*  This is needed for the definitions of memcpy... on solaris */
39 #if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
40 #include <memory.h>
41 #endif
42 
43 #if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE)
44 # define memcpy(d, s, n)	bcopy ((s), (d), (n))
45 # define memset(A,C,B)		bfill((A),(B),(C))
46 # define memmove(d, s, n)	bmove ((d), (s), (n))
47 #elif defined(HAVE_MEMMOVE)
48 # define bmove(d, s, n)		memmove((d), (s), (n))
49 #endif
50 
51 /* Unixware 7 */
52 #if !defined(HAVE_BFILL)
53 # define bfill(A,B,C)           memset((A),(C),(B))
54 #endif
55 
56 # define bmove_align(A,B,C)     memcpy((A),(B),(C))
57 
58 # define bcmp(A,B,C)		memcmp((A),(B),(C))
59 
60 #if !defined(bzero)
61 # define bzero(A,B)             memset((A),0,(B))
62 #endif
63 
64 #if defined(__cplusplus)
65 extern "C" {
66 #endif
67 
68 #ifdef DBUG_OFF
69 #if defined(HAVE_STPCPY) && MY_GNUC_PREREQ(3, 4) && !defined(__INTEL_COMPILER)
70 #define strmov(A,B) __builtin_stpcpy((A),(B))
71 #elif defined(HAVE_STPCPY)
72 #define strmov(A,B) stpcpy((A),(B))
73 #endif
74 #endif
75 
76 /* Declared in int2str() */
77 extern const char _dig_vec_upper[];
78 extern const char _dig_vec_lower[];
79 
80 extern char *strmov_overlapp(char *dest, const char *src);
81 
82 #if defined(_lint) || defined(FORCE_INIT_OF_VARS)
83 #define LINT_INIT_STRUCT(var) bzero(&var, sizeof(var)) /* No uninitialize-warning */
84 #else
85 #define LINT_INIT_STRUCT(var)
86 #endif
87 
88 /* Prototypes for string functions */
89 
90 extern	void bmove_upp(uchar *dst,const uchar *src,size_t len);
91 extern	void bchange(uchar *dst,size_t old_len,const uchar *src,
92 		     size_t new_len,size_t tot_len);
93 extern	void strappend(char *s,size_t len,pchar fill);
94 extern	char *strend(const char *s);
95 extern  char *strcend(const char *, pchar);
96 extern	char *strfill(char * s,size_t len,pchar fill);
97 extern	char *strmake(char *dst,const char *src,size_t length);
98 
99 #if !defined(__GNUC__) || (__GNUC__ < 4)
100 #define strmake_buf(D,S)        strmake(D, S, sizeof(D) - 1)
101 #else
102 #define strmake_buf(D,S) ({                             \
103   __typeof__ (D) __x __attribute__((unused)) = { 2 };   \
104   strmake(D, S, sizeof(D) - 1);                         \
105   })
106 #endif
107 
108 #ifndef strmov
109 extern	char *strmov(char *dst,const char *src);
110 #endif
111 extern	char *strnmov(char *dst, const char *src, size_t n);
112 extern	char *strcont(const char *src, const char *set);
113 extern	char *strxmov(char *dst, const char *src, ...);
114 extern	char *strxnmov(char *dst, size_t len, const char *src, ...);
115 
116 /* Prototypes of normal stringfunctions (with may ours) */
117 #ifndef HAVE_STRNLEN
118 extern size_t strnlen(const char *s, size_t n);
119 #endif
120 
121 extern int is_prefix(const char *, const char *);
122 
123 /* Conversion routines */
124 typedef enum {
125   MY_GCVT_ARG_FLOAT,
126   MY_GCVT_ARG_DOUBLE
127 } my_gcvt_arg_type;
128 
129 double my_strtod(const char *str, char **end, int *error);
130 double my_atof(const char *nptr);
131 size_t my_fcvt(double x, int precision, char *to, my_bool *error);
132 size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
133                my_bool *error);
134 
135 /*
136   The longest string my_fcvt can return is 311 + "precision" bytes.
137   Here we assume that we never cal my_fcvt() with
138   precision >= DECIMAL_NOT_SPECIFIED
139   (+ 1 byte for the terminating '\0').
140 */
141 #define FLOATING_POINT_BUFFER (311 + DECIMAL_NOT_SPECIFIED)
142 
143 /*
144   We want to use the 'e' format in some cases even if we have enough space
145   for the 'f' one just to mimic sprintf("%.15g") behavior for large integers,
146   and to improve it for numbers < 10^(-4).
147   That is, for |x| < 1 we require |x| >= 10^(-15), and for |x| > 1 we require
148   it to be integer and be <= 10^DBL_DIG for the 'f' format to be used.
149   We don't lose precision, but make cases like "1e200" or "0.00001" look nicer.
150 */
151 #define MAX_DECPT_FOR_F_FORMAT DBL_DIG
152 
153 /*
154   The maximum possible field width for my_gcvt() conversion.
155   (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
156   MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
157 */
158 #define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + MY_MAX(5, MAX_DECPT_FOR_F_FORMAT)) \
159 
160 extern char *llstr(longlong value,char *buff);
161 extern char *ullstr(longlong value,char *buff);
162 #ifndef HAVE_STRTOUL
163 extern long strtol(const char *str, char **ptr, int base);
164 extern ulong strtoul(const char *str, char **ptr, int base);
165 #endif
166 
167 extern char *int2str(long val, char *dst, int radix, int upcase);
168 extern char *int10_to_str(long val,char *dst,int radix);
169 extern char *str2int(const char *src,int radix,long lower,long upper,
170 			 long *val);
171 longlong my_strtoll10(const char *nptr, char **endptr, int *error);
172 #if SIZEOF_LONG == SIZEOF_LONG_LONG
173 #define ll2str(A,B,C,D) int2str((A),(B),(C),(D))
174 #define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
175 #undef strtoll
176 #define strtoll(A,B,C) strtol((A),(B),(C))
177 #define strtoull(A,B,C) strtoul((A),(B),(C))
178 #ifndef HAVE_STRTOULL
179 #define HAVE_STRTOULL
180 #endif
181 #ifndef HAVE_STRTOLL
182 #define HAVE_STRTOLL
183 #endif
184 #else
185 #ifdef HAVE_LONG_LONG
186 extern char *ll2str(longlong val,char *dst,int radix, int upcase);
187 extern char *longlong10_to_str(longlong val,char *dst,int radix);
188 #if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
189 extern longlong strtoll(const char *str, char **ptr, int base);
190 extern ulonglong strtoull(const char *str, char **ptr, int base);
191 #endif
192 #endif
193 #endif
194 #define longlong2str(A,B,C) ll2str((A),(B),(C),1)
195 
196 #if defined(__cplusplus)
197 }
198 #endif
199 
200 #include <mysql/plugin.h>
201 
202 #define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
203 #define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
204 #define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
205 #define LEX_STRING_WITH_LEN(X) (X).str, (X).length
206 
207 typedef struct st_mysql_const_lex_string LEX_CSTRING;
208 
209 /* A variant with const and unsigned */
210 struct st_mysql_const_unsigned_lex_string
211 {
212   const uchar *str;
213   size_t length;
214 };
215 typedef struct st_mysql_const_unsigned_lex_string LEX_CUSTRING;
216 
lex_string_set(LEX_CSTRING * lex_str,const char * c_str)217 static inline void lex_string_set(LEX_CSTRING *lex_str, const char *c_str)
218 {
219   lex_str->str= c_str;
220   lex_str->length= strlen(c_str);
221 }
lex_string_set3(LEX_CSTRING * lex_str,const char * c_str,size_t len)222 static inline void lex_string_set3(LEX_CSTRING *lex_str, const char *c_str,
223                                    size_t len)
224 {
225   lex_str->str= c_str;
226   lex_str->length= len;
227 }
228 
229 #ifdef __cplusplus
safe_str(char * str)230 static inline char *safe_str(char *str)
231 { return str ? str : const_cast<char*>(""); }
232 #endif
233 
safe_str(const char * str)234 static inline const char *safe_str(const char *str)
235 { return str ? str : ""; }
236 
safe_strlen(const char * str)237 static inline size_t safe_strlen(const char *str)
238 { return str ? strlen(str) : 0; }
239 
240 #endif
241