~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to include/m_string.h

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 MySQL AB
 
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 as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
/* There may be prolems include all of theese. Try to test in
 
17
   configure with ones are needed? */
 
18
 
 
19
/*  This is needed for the definitions of strchr... on solaris */
 
20
 
 
21
#ifndef _m_string_h
 
22
#define _m_string_h
 
23
#ifndef __USE_GNU
 
24
#define __USE_GNU                               /* We want to use stpcpy */
 
25
#endif
 
26
#if defined(HAVE_STRINGS_H)
 
27
#include <strings.h>
 
28
#endif
 
29
#if defined(HAVE_STRING_H)
 
30
#include <string.h>
 
31
#endif
 
32
 
 
33
/* need by my_vsnprintf */
 
34
#include <stdarg.h> 
 
35
 
 
36
#ifdef _AIX
 
37
#undef HAVE_BCMP
 
38
#endif
 
39
 
 
40
/*  This is needed for the definitions of bzero... on solaris */
 
41
#if defined(HAVE_STRINGS_H)
 
42
#include <strings.h>
 
43
#endif
 
44
 
 
45
/*  This is needed for the definitions of memcpy... on solaris */
 
46
#if defined(HAVE_MEMORY_H) && !defined(__cplusplus)
 
47
#include <memory.h>
 
48
#endif
 
49
 
 
50
#if !defined(HAVE_MEMCPY) && !defined(HAVE_MEMMOVE)
 
51
# define memcpy(d, s, n)        bcopy ((s), (d), (n))
 
52
# define memset(A,C,B)          bfill((A),(B),(C))
 
53
# define memmove(d, s, n)       bmove ((d), (s), (n))
 
54
#elif defined(HAVE_MEMMOVE)
 
55
# define bmove(d, s, n)         memmove((d), (s), (n))
 
56
#else
 
57
# define memmove(d, s, n)       bmove((d), (s), (n)) /* our bmove */
 
58
#endif
 
59
 
 
60
/* Unixware 7 */
 
61
#if !defined(HAVE_BFILL)
 
62
# define bfill(A,B,C)           memset((A),(C),(B))
 
63
# define bmove_align(A,B,C)    memcpy((A),(B),(C))
 
64
#endif
 
65
 
 
66
#if !defined(HAVE_BCMP)
 
67
# define bcopy(s, d, n)         memcpy((d), (s), (n))
 
68
# define bcmp(A,B,C)            memcmp((A),(B),(C))
 
69
# define bzero(A,B)             memset((A),0,(B))
 
70
# define bmove_align(A,B,C)     memcpy((A),(B),(C))
 
71
#endif
 
72
 
 
73
#if defined(__cplusplus)
 
74
extern "C" {
 
75
#endif
 
76
 
 
77
/*
 
78
  my_str_malloc() and my_str_free() are assigned to implementations in
 
79
  strings/alloc.c, but can be overridden in the calling program.
 
80
 */
 
81
extern void *(*my_str_malloc)(size_t);
 
82
extern void (*my_str_free)(void *);
 
83
 
 
84
#if defined(HAVE_STPCPY)
 
85
#define strmov(A,B) stpcpy((A),(B))
 
86
#ifndef stpcpy
 
87
extern char *stpcpy(char *, const char *);      /* For AIX with gcc 2.95.3 */
 
88
#endif
 
89
#endif
 
90
 
 
91
/* Declared in int2str() */
 
92
extern char _dig_vec_upper[];
 
93
extern char _dig_vec_lower[];
 
94
 
 
95
#ifdef BAD_STRING_COMPILER
 
96
#define strmov(A,B)  (memccpy(A,B,0,INT_MAX)-1)
 
97
#else
 
98
#define strmov_overlapp(A,B) strmov(A,B)
 
99
#define strmake_overlapp(A,B,C) strmake(A,B,C)
 
100
#endif
 
101
 
 
102
#ifdef BAD_MEMCPY                       /* Problem with gcc on Alpha */
 
103
#define memcpy_fixed(A,B,C) bmove((A),(B),(C))
 
104
#else
 
105
#define memcpy_fixed(A,B,C) memcpy((A),(B),(C))
 
106
#endif
 
107
 
 
108
#if (!defined(USE_BMOVE512) || defined(HAVE_purify)) && !defined(bmove512)
 
109
#define bmove512(A,B,C) memcpy(A,B,C)
 
110
#endif
 
111
 
 
112
        /* Prototypes for string functions */
 
113
 
 
114
#if !defined(bfill) && !defined(HAVE_BFILL)
 
115
extern  void bfill(uchar *dst,size_t len,pchar fill);
 
116
#endif
 
117
 
 
118
#if !defined(bzero) && !defined(HAVE_BZERO)
 
119
extern  void bzero(uchar * dst,size_t len);
 
120
#endif
 
121
 
 
122
#if !defined(bcmp) && !defined(HAVE_BCMP)
 
123
extern  size_t bcmp(const uchar *s1,const uchar *s2,size_t len);
 
124
#endif
 
125
#ifdef HAVE_purify
 
126
extern  size_t my_bcmp(const uchar *s1,const uchar *s2,size_t len);
 
127
#undef bcmp
 
128
#define bcmp(A,B,C) my_bcmp((A),(B),(C))
 
129
#define bzero_if_purify(A,B) bzero(A,B)
 
130
#else
 
131
#define bzero_if_purify(A,B)
 
132
#endif /* HAVE_purify */
 
133
 
 
134
#ifndef bmove512
 
135
extern  void bmove512(uchar *dst,const uchar *src,size_t len);
 
136
#endif
 
137
 
 
138
#if !defined(HAVE_BMOVE) && !defined(bmove)
 
139
extern  void bmove(uuchar *dst, const uchar *src,size_t len);
 
140
#endif
 
141
 
 
142
extern  void bmove_upp(uchar *dst,const uchar *src,size_t len);
 
143
extern  void bchange(uchar *dst,size_t old_len,const uchar *src,
 
144
                     size_t new_len,size_t tot_len);
 
145
extern  void strappend(char *s,size_t len,pchar fill);
 
146
extern  char *strend(const char *s);
 
147
extern  char *strcend(const char *, pchar);
 
148
extern  char *strfield(char *src,int fields,int chars,int blanks,
 
149
                           int tabch);
 
150
extern  char *strfill(char * s,size_t len,pchar fill);
 
151
extern  size_t strinstr(const char *str,const char *search);
 
152
extern  size_t r_strinstr(const char *str, size_t from, const char *search);
 
153
extern  char *strkey(char *dst,char *head,char *tail,char *flags);
 
154
extern  char *strmake(char *dst,const char *src,size_t length);
 
155
#ifndef strmake_overlapp
 
156
extern  char *strmake_overlapp(char *dst,const char *src, size_t length);
 
157
#endif
 
158
 
 
159
#ifndef strmov
 
160
extern  char *strmov(char *dst,const char *src);
 
161
#endif
 
162
extern  char *strnmov(char *dst,const char *src,size_t n);
 
163
extern  char *strsuff(const char *src,const char *suffix);
 
164
extern  char *strcont(const char *src,const char *set);
 
165
extern  char *strxcat _VARARGS((char *dst,const char *src, ...));
 
166
extern  char *strxmov _VARARGS((char *dst,const char *src, ...));
 
167
extern  char *strxcpy _VARARGS((char *dst,const char *src, ...));
 
168
extern  char *strxncat _VARARGS((char *dst,size_t len, const char *src, ...));
 
169
extern  char *strxnmov _VARARGS((char *dst,size_t len, const char *src, ...));
 
170
extern  char *strxncpy _VARARGS((char *dst,size_t len, const char *src, ...));
 
171
 
 
172
/* Prototypes of normal stringfunctions (with may ours) */
 
173
 
 
174
#ifdef WANT_STRING_PROTOTYPES
 
175
extern char *strcat(char *, const char *);
 
176
extern char *strchr(const char *, pchar);
 
177
extern char *strrchr(const char *, pchar);
 
178
extern char *strcpy(char *, const char *);
 
179
extern int strcmp(const char *, const char *);
 
180
#ifndef __GNUC__
 
181
extern size_t strlen(const char *);
 
182
#endif
 
183
#endif
 
184
#ifndef HAVE_STRNLEN
 
185
extern size_t strnlen(const char *s, size_t n);
 
186
#endif
 
187
 
 
188
#if !defined(__cplusplus)
 
189
#ifndef HAVE_STRPBRK
 
190
extern char *strpbrk(const char *, const char *);
 
191
#endif
 
192
#ifndef HAVE_STRSTR
 
193
extern char *strstr(const char *, const char *);
 
194
#endif
 
195
#endif
 
196
extern int is_prefix(const char *, const char *);
 
197
 
 
198
/* Conversion routines */
 
199
typedef enum {
 
200
  MY_GCVT_ARG_FLOAT,
 
201
  MY_GCVT_ARG_DOUBLE
 
202
} my_gcvt_arg_type;
 
203
 
 
204
double my_strtod(const char *str, char **end, int *error);
 
205
double my_atof(const char *nptr);
 
206
size_t my_fcvt(double x, int precision, char *to, my_bool *error);
 
207
size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
 
208
               my_bool *error);
 
209
 
 
210
#define NOT_FIXED_DEC 31
 
211
 
 
212
/*
 
213
  The longest string my_fcvt can return is 311 + "precision" bytes.
 
214
  Here we assume that we never cal my_fcvt() with precision >= NOT_FIXED_DEC
 
215
  (+ 1 byte for the terminating '\0').
 
216
*/
 
217
#define FLOATING_POINT_BUFFER (311 + NOT_FIXED_DEC)
 
218
 
 
219
/*
 
220
  We want to use the 'e' format in some cases even if we have enough space
 
221
  for the 'f' one just to mimic sprintf("%.15g") behavior for large integers,
 
222
  and to improve it for numbers < 10^(-4).
 
223
  That is, for |x| < 1 we require |x| >= 10^(-15), and for |x| > 1 we require
 
224
  it to be integer and be <= 10^DBL_DIG for the 'f' format to be used.
 
225
  We don't lose precision, but make cases like "1e200" or "0.00001" look nicer.
 
226
*/
 
227
#define MAX_DECPT_FOR_F_FORMAT DBL_DIG
 
228
 
 
229
/*
 
230
  The maximum possible field width for my_gcvt() conversion.
 
231
  (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
 
232
  MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
 
233
*/
 
234
#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT))
 
235
  
 
236
 
 
237
extern char *llstr(longlong value,char *buff);
 
238
extern char *ullstr(longlong value,char *buff);
 
239
#ifndef HAVE_STRTOUL
 
240
extern long strtol(const char *str, char **ptr, int base);
 
241
extern ulong strtoul(const char *str, char **ptr, int base);
 
242
#endif
 
243
 
 
244
extern char *int2str(long val, char *dst, int radix, int upcase);
 
245
extern char *int10_to_str(long val,char *dst,int radix);
 
246
extern char *str2int(const char *src,int radix,long lower,long upper,
 
247
                         long *val);
 
248
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
 
249
#if SIZEOF_LONG == SIZEOF_LONG_LONG
 
250
#define longlong2str(A,B,C) int2str((A),(B),(C),1)
 
251
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
 
252
#undef strtoll
 
253
#define strtoll(A,B,C) strtol((A),(B),(C))
 
254
#define strtoull(A,B,C) strtoul((A),(B),(C))
 
255
#ifndef HAVE_STRTOULL
 
256
#define HAVE_STRTOULL
 
257
#endif
 
258
#ifndef HAVE_STRTOLL
 
259
#define HAVE_STRTOLL
 
260
#endif
 
261
#else
 
262
#ifdef HAVE_LONG_LONG
 
263
extern char *longlong2str(longlong val,char *dst,int radix);
 
264
extern char *longlong10_to_str(longlong val,char *dst,int radix);
 
265
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
 
266
extern longlong strtoll(const char *str, char **ptr, int base);
 
267
extern ulonglong strtoull(const char *str, char **ptr, int base);
 
268
#endif
 
269
#endif
 
270
#endif
 
271
 
 
272
/* my_vsnprintf.c */
 
273
 
 
274
extern size_t my_vsnprintf(char *str, size_t n,
 
275
                           const char *format, va_list ap);
 
276
extern size_t my_snprintf(char *to, size_t n, const char *fmt, ...)
 
277
  ATTRIBUTE_FORMAT(printf, 3, 4);
 
278
 
 
279
#if defined(__cplusplus)
 
280
}
 
281
#endif
 
282
 
 
283
/*
 
284
  LEX_STRING -- a pair of a C-string and its length.
 
285
*/
 
286
 
 
287
#ifndef _my_plugin_h
 
288
/* This definition must match the one given in mysql/plugin.h */
 
289
struct st_mysql_lex_string
 
290
{
 
291
  char *str;
 
292
  size_t length;
 
293
};
 
294
#endif
 
295
typedef struct st_mysql_lex_string LEX_STRING;
 
296
 
 
297
#define STRING_WITH_LEN(X) (X), ((size_t) (sizeof(X) - 1))
 
298
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
 
299
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
 
300
 
 
301
/* SPACE_INT is a word that contains only spaces */
 
302
#if SIZEOF_INT == 4
 
303
#define SPACE_INT 0x20202020
 
304
#elif SIZEOF_INT == 8
 
305
#define SPACE_INT 0x2020202020202020
 
306
#else
 
307
#error define the appropriate constant for a word full of spaces
 
308
#endif
 
309
 
 
310
/**
 
311
  Skip trailing space.
 
312
 
 
313
  On most systems reading memory in larger chunks (ideally equal to the size of
 
314
  the chinks that the machine physically reads from memory) causes fewer memory
 
315
  access loops and hence increased performance.
 
316
  This is why the 'int' type is used : it's closest to that (according to how
 
317
  it's defined in C).
 
318
  So when we determine the amount of whitespace at the end of a string we do
 
319
  the following :
 
320
    1. We divide the string into 3 zones :
 
321
      a) from the start of the string (__start) to the first multiple
 
322
        of sizeof(int)  (__start_words)
 
323
      b) from the end of the string (__end) to the last multiple of sizeof(int)
 
324
        (__end_words)
 
325
      c) a zone that is aligned to sizeof(int) and can be safely accessed
 
326
        through an int *
 
327
    2. We start comparing backwards from (c) char-by-char. If all we find is
 
328
       space then we continue
 
329
    3. If there are elements in zone (b) we compare them as unsigned ints to a
 
330
       int mask (SPACE_INT) consisting of all spaces
 
331
    4. Finally we compare the remaining part (a) of the string char by char.
 
332
       This covers for the last non-space unsigned int from 3. (if any)
 
333
 
 
334
   This algorithm works well for relatively larger strings, but it will slow
 
335
   the things down for smaller strings (because of the additional calculations
 
336
   and checks compared to the naive method). Thus the barrier of length 20
 
337
   is added.
 
338
 
 
339
   @param     ptr   pointer to the input string
 
340
   @param     len   the length of the string
 
341
   @return          the last non-space character
 
342
*/
 
343
 
 
344
static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
 
345
{
 
346
  const uchar *end= ptr + len;
 
347
 
 
348
  if (len > 20)
 
349
  {
 
350
    const uchar *end_words= (const uchar *)(intptr)
 
351
      (((ulonglong)(intptr)end) / SIZEOF_INT * SIZEOF_INT);
 
352
    const uchar *start_words= (const uchar *)(intptr)
 
353
       ((((ulonglong)(intptr)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
 
354
 
 
355
    DBUG_ASSERT(((ulonglong)(intptr)ptr) >= SIZEOF_INT);
 
356
    if (end_words > ptr)
 
357
    {
 
358
      while (end > end_words && end[-1] == 0x20)
 
359
        end--;
 
360
      if (end[-1] == 0x20 && start_words < end_words)
 
361
        while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
 
362
          end -= SIZEOF_INT;
 
363
    }
 
364
  }
 
365
  while (end > ptr && end[-1] == 0x20)
 
366
    end--;
 
367
  return (end);
 
368
}
 
369
 
 
370
#endif