~drizzle-trunk/drizzle/development

1 by brian
clean slate
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
/* Functions to handle typelib */
17
18
#include "mysys_priv.h"
212.5.18 by Monty Taylor
Moved m_ctype, m_string and my_bitmap. Removed t_ctype.
19
#include <mystrings/m_string.h>
20
#include <mystrings/m_ctype.h>
612.2.6 by Monty Taylor
OpenSolaris builds.
21
#include <stdio.h>
1 by brian
clean slate
22
23
24
static const char field_separator=',';
25
287.3.11 by Monty Taylor
Rolled back a couple of overly anxious consts.
26
int find_type_or_exit(char *x, TYPELIB *typelib, const char *option)
1 by brian
clean slate
27
{
28
  int res;
29
  const char **ptr;
30
287.3.11 by Monty Taylor
Rolled back a couple of overly anxious consts.
31
  if ((res= find_type(x, typelib, 2)) <= 0)
1 by brian
clean slate
32
  {
33
    ptr= typelib->type_names;
34
    if (!*x)
35
      fprintf(stderr, "No option given to %s\n", option);
36
    else
37
      fprintf(stderr, "Unknown option to %s: %s\n", option, x);
38
    fprintf(stderr, "Alternatives are: '%s'", *ptr);
39
    while (*++ptr)
40
      fprintf(stderr, ",'%s'", *ptr);
41
    fprintf(stderr, "\n");
42
    exit(1);
43
  }
44
  return res;
45
}
46
47
48
/*
49
  Search after a string in a list of strings. Endspace in x is not compared.
50
51
  SYNOPSIS
52
   find_type()
53
   x			String to find
54
   lib			TYPELIB (struct of pointer to values + count)
55
   full_name		bitmap of what to do
56
			If & 1 accept only whole names
57
			If & 2 don't expand if half field
58
			If & 4 allow #number# as type
59
			If & 8 use ',' as string terminator
60
61
  NOTES
62
    If part, uniq field is found and full_name == 0 then x is expanded
63
    to full field.
64
65
  RETURN
66
    -1	Too many matching values
67
    0	No matching value
68
    >0  Offset+1 in typelib for matched string
69
*/
70
71
482 by Brian Aker
Remove uint.
72
int find_type(char *x, const TYPELIB *typelib, uint32_t full_name)
1 by brian
clean slate
73
{
77.1.71 by Monty Taylor
Uninitialized use.
74
  int find,pos,findpos=0;
1 by brian
clean slate
75
  register char * i;
76
  register const char *j;
77
78
  if (!typelib->count)
79
  {
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
80
    return(0);
1 by brian
clean slate
81
  }
82
  find=0;
83
  for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
84
  {
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
85
    for (i=x ;
1 by brian
clean slate
86
    	*i && (!(full_name & 8) || *i != field_separator) &&
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
87
        my_toupper(&my_charset_utf8_general_ci,*i) ==
383.1.11 by Brian Aker
Cleanup default character set.
88
    		my_toupper(&my_charset_utf8_general_ci,*j) ; i++, j++) ;
1 by brian
clean slate
89
    if (! *j)
90
    {
91
      while (*i == ' ')
92
	i++;					/* skip_end_space */
93
      if (! *i || ((full_name & 8) && *i == field_separator))
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
94
	return(pos+1);
1 by brian
clean slate
95
    }
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
96
    if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
1 by brian
clean slate
97
        (!*j || !(full_name & 1)))
98
    {
99
      find++;
100
      findpos=pos;
101
    }
102
  }
376 by Brian Aker
strend remove
103
  if (find == 0 && (full_name & 4) && x[0] == '#' && strchr(x, '\0')[-1] == '#' &&
1 by brian
clean slate
104
      (findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
105
    find=1;
106
  else if (find == 0 || ! x[0])
107
  {
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
108
    return(0);
1 by brian
clean slate
109
  }
110
  else if (find != 1 || (full_name & 1))
111
  {
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
112
    return(-1);
1 by brian
clean slate
113
  }
114
  if (!(full_name & 2))
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
115
    (void) strcpy(x,typelib->type_names[findpos]);
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
116
  return(findpos+1);
1 by brian
clean slate
117
} /* find_type */
118
119
120
	/* Get name of type nr 'nr' */
121
	/* Warning first type is 1, 0 = empty field */
122
482 by Brian Aker
Remove uint.
123
void make_type(register char * to, register uint32_t nr,
1 by brian
clean slate
124
	       register TYPELIB *typelib)
125
{
126
  if (!nr)
127
    to[0]=0;
128
  else
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
129
    (void) strcpy(to,get_type(typelib,nr-1));
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
130
  return;
1 by brian
clean slate
131
} /* make_type */
132
133
134
	/* Get type */
135
	/* Warning first type is 0 */
136
482 by Brian Aker
Remove uint.
137
const char *get_type(TYPELIB *typelib, uint32_t nr)
1 by brian
clean slate
138
{
139
  if (nr < (uint) typelib->count && typelib->type_names)
140
    return(typelib->type_names[nr]);
141
  return "?";
142
}
143
144
145
/*
146
  Create an integer value to represent the supplied comma-seperated
147
  string where each string in the TYPELIB denotes a bit position.
148
149
  SYNOPSIS
150
    find_typeset()
151
    x		string to decompose
152
    lib		TYPELIB (struct of pointer to values + count)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
153
    err		index (not char position) of string element which was not
1 by brian
clean slate
154
                found or 0 if there was no error
155
156
  RETURN
157
    a integer representation of the supplied string
158
*/
159
155 by Brian Aker
Removing a few "additional" ways of saying uint64_t
160
uint64_t find_typeset(char *x, TYPELIB *lib, int *err)
1 by brian
clean slate
161
{
155 by Brian Aker
Removing a few "additional" ways of saying uint64_t
162
  uint64_t result;
1 by brian
clean slate
163
  int find;
164
  char *i;
165
166
  if (!lib->count)
167
  {
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
168
    return(0);
1 by brian
clean slate
169
  }
170
  result= 0;
171
  *err= 0;
172
  while (*x)
173
  {
174
    (*err)++;
175
    i= x;
176
    while (*x && *x != field_separator) x++;
177
    if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
178
      return(0);
80.1.1 by Brian Aker
LL() cleanup
179
    result|= (1ULL << find);
1 by brian
clean slate
180
  }
181
  *err= 0;
51.3.14 by Jay Pipes
Phase 2 removal of DBUG in mysys
182
  return(result);
1 by brian
clean slate
183
} /* find_set */
184
185
186
/*
187
  Create a copy of a specified TYPELIB structure.
188
189
  SYNOPSIS
190
    copy_typelib()
191
    root	pointer to a MEM_ROOT object for allocations
192
    from	pointer to a source TYPELIB structure
193
194
  RETURN
195
    pointer to the new TYPELIB structure on successful copy, or
196
    NULL otherwise
197
*/
198
199
TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
200
{
201
  TYPELIB *to;
482 by Brian Aker
Remove uint.
202
  uint32_t i;
1 by brian
clean slate
203
204
  if (!from)
205
    return NULL;
206
207
  if (!(to= (TYPELIB*) alloc_root(root, sizeof(TYPELIB))))
208
    return NULL;
209
210
  if (!(to->type_names= (const char **)
211
        alloc_root(root, (sizeof(char *) + sizeof(int)) * (from->count + 1))))
212
    return NULL;
213
  to->type_lengths= (unsigned int *)(to->type_names + from->count + 1);
214
  to->count= from->count;
215
  if (from->name)
216
  {
217
    if (!(to->name= strdup_root(root, from->name)))
218
      return NULL;
219
  }
220
  else
221
    to->name= NULL;
222
223
  for (i= 0; i < from->count; i++)
224
  {
225
    if (!(to->type_names[i]= strmake_root(root, from->type_names[i],
226
                                          from->type_lengths[i])))
227
      return NULL;
228
    to->type_lengths[i]= from->type_lengths[i];
229
  }
230
  to->type_names[to->count]= NULL;
231
  to->type_lengths[to->count]= 0;
232
233
  return to;
234
}