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