1
/* Copyright (C) 2000 MySQL AB
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.
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.
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 */
16
/* Functions to handle typelib */
18
#include "mysys_priv.h"
23
static const char field_separator=',';
25
int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
30
if ((res= find_type((char *) x, typelib, 2)) <= 0)
32
ptr= typelib->type_names;
34
fprintf(stderr, "No option given to %s\n", option);
36
fprintf(stderr, "Unknown option to %s: %s\n", option, x);
37
fprintf(stderr, "Alternatives are: '%s'", *ptr);
39
fprintf(stderr, ",'%s'", *ptr);
40
fprintf(stderr, "\n");
48
Search after a string in a list of strings. Endspace in x is not compared.
53
lib TYPELIB (struct of pointer to values + count)
54
full_name bitmap of what to do
55
If & 1 accept only whole names
56
If & 2 don't expand if half field
57
If & 4 allow #number# as type
58
If & 8 use ',' as string terminator
61
If part, uniq field is found and full_name == 0 then x is expanded
65
-1 Too many matching values
67
>0 Offset+1 in typelib for matched string
71
int find_type(char *x, const TYPELIB *typelib, uint full_name)
75
register const char *j;
76
DBUG_ENTER("find_type");
77
DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) typelib));
81
DBUG_PRINT("exit",("no count"));
85
for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
88
*i && (!(full_name & 8) || *i != field_separator) &&
89
my_toupper(&my_charset_latin1,*i) ==
90
my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
94
i++; /* skip_end_space */
95
if (! *i || ((full_name & 8) && *i == field_separator))
98
if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
99
(!*j || !(full_name & 1)))
105
if (find == 0 && (full_name & 4) && x[0] == '#' && strend(x)[-1] == '#' &&
106
(findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
108
else if (find == 0 || ! x[0])
110
DBUG_PRINT("exit",("Couldn't find type"));
113
else if (find != 1 || (full_name & 1))
115
DBUG_PRINT("exit",("Too many possybilities"));
118
if (!(full_name & 2))
119
(void) strmov(x,typelib->type_names[findpos]);
120
DBUG_RETURN(findpos+1);
124
/* Get name of type nr 'nr' */
125
/* Warning first type is 1, 0 = empty field */
127
void make_type(register char * to, register uint nr,
128
register TYPELIB *typelib)
130
DBUG_ENTER("make_type");
134
(void) strmov(to,get_type(typelib,nr-1));
140
/* Warning first type is 0 */
142
const char *get_type(TYPELIB *typelib, uint nr)
144
if (nr < (uint) typelib->count && typelib->type_names)
145
return(typelib->type_names[nr]);
151
Create an integer value to represent the supplied comma-seperated
152
string where each string in the TYPELIB denotes a bit position.
156
x string to decompose
157
lib TYPELIB (struct of pointer to values + count)
158
err index (not char position) of string element which was not
159
found or 0 if there was no error
162
a integer representation of the supplied string
165
my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
170
DBUG_ENTER("find_set");
171
DBUG_PRINT("enter",("x: '%s' lib: 0x%lx", x, (long) lib));
175
DBUG_PRINT("exit",("no count"));
184
while (*x && *x != field_separator) x++;
185
if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
187
result|= (ULL(1) << find);
195
Create a copy of a specified TYPELIB structure.
199
root pointer to a MEM_ROOT object for allocations
200
from pointer to a source TYPELIB structure
203
pointer to the new TYPELIB structure on successful copy, or
207
TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
215
if (!(to= (TYPELIB*) alloc_root(root, sizeof(TYPELIB))))
218
if (!(to->type_names= (const char **)
219
alloc_root(root, (sizeof(char *) + sizeof(int)) * (from->count + 1))))
221
to->type_lengths= (unsigned int *)(to->type_names + from->count + 1);
222
to->count= from->count;
225
if (!(to->name= strdup_root(root, from->name)))
231
for (i= 0; i < from->count; i++)
233
if (!(to->type_names[i]= strmake_root(root, from->type_names[i],
234
from->type_lengths[i])))
236
to->type_lengths[i]= from->type_lengths[i];
238
to->type_names[to->count]= NULL;
239
to->type_lengths[to->count]= 0;