~skinny.moey/drizzle/branch-rev

« back to all changes in this revision

Viewing changes to mysys/typelib.c

  • 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
/* Functions to handle typelib */
 
17
 
 
18
#include "mysys_priv.h"
 
19
#include <m_string.h>
 
20
#include <m_ctype.h>
 
21
 
 
22
 
 
23
static const char field_separator=',';
 
24
 
 
25
int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option)
 
26
{
 
27
  int res;
 
28
  const char **ptr;
 
29
 
 
30
  if ((res= find_type((char *) x, typelib, 2)) <= 0)
 
31
  {
 
32
    ptr= typelib->type_names;
 
33
    if (!*x)
 
34
      fprintf(stderr, "No option given to %s\n", option);
 
35
    else
 
36
      fprintf(stderr, "Unknown option to %s: %s\n", option, x);
 
37
    fprintf(stderr, "Alternatives are: '%s'", *ptr);
 
38
    while (*++ptr)
 
39
      fprintf(stderr, ",'%s'", *ptr);
 
40
    fprintf(stderr, "\n");
 
41
    exit(1);
 
42
  }
 
43
  return res;
 
44
}
 
45
 
 
46
 
 
47
/*
 
48
  Search after a string in a list of strings. Endspace in x is not compared.
 
49
 
 
50
  SYNOPSIS
 
51
   find_type()
 
52
   x                    String to find
 
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
 
59
 
 
60
  NOTES
 
61
    If part, uniq field is found and full_name == 0 then x is expanded
 
62
    to full field.
 
63
 
 
64
  RETURN
 
65
    -1  Too many matching values
 
66
    0   No matching value
 
67
    >0  Offset+1 in typelib for matched string
 
68
*/
 
69
 
 
70
 
 
71
int find_type(char *x, const TYPELIB *typelib, uint full_name)
 
72
{
 
73
  int find,pos,findpos;
 
74
  register char * i;
 
75
  register const char *j;
 
76
  DBUG_ENTER("find_type");
 
77
  DBUG_PRINT("enter",("x: '%s'  lib: 0x%lx", x, (long) typelib));
 
78
 
 
79
  if (!typelib->count)
 
80
  {
 
81
    DBUG_PRINT("exit",("no count"));
 
82
    DBUG_RETURN(0);
 
83
  }
 
84
  find=0;
 
85
  for (pos=0 ; (j=typelib->type_names[pos]) ; pos++)
 
86
  {
 
87
    for (i=x ; 
 
88
        *i && (!(full_name & 8) || *i != field_separator) &&
 
89
        my_toupper(&my_charset_latin1,*i) == 
 
90
                my_toupper(&my_charset_latin1,*j) ; i++, j++) ;
 
91
    if (! *j)
 
92
    {
 
93
      while (*i == ' ')
 
94
        i++;                                    /* skip_end_space */
 
95
      if (! *i || ((full_name & 8) && *i == field_separator))
 
96
        DBUG_RETURN(pos+1);
 
97
    }
 
98
    if ((!*i && (!(full_name & 8) || *i != field_separator)) && 
 
99
        (!*j || !(full_name & 1)))
 
100
    {
 
101
      find++;
 
102
      findpos=pos;
 
103
    }
 
104
  }
 
105
  if (find == 0 && (full_name & 4) && x[0] == '#' && strend(x)[-1] == '#' &&
 
106
      (findpos=atoi(x+1)-1) >= 0 && (uint) findpos < typelib->count)
 
107
    find=1;
 
108
  else if (find == 0 || ! x[0])
 
109
  {
 
110
    DBUG_PRINT("exit",("Couldn't find type"));
 
111
    DBUG_RETURN(0);
 
112
  }
 
113
  else if (find != 1 || (full_name & 1))
 
114
  {
 
115
    DBUG_PRINT("exit",("Too many possybilities"));
 
116
    DBUG_RETURN(-1);
 
117
  }
 
118
  if (!(full_name & 2))
 
119
    (void) strmov(x,typelib->type_names[findpos]);
 
120
  DBUG_RETURN(findpos+1);
 
121
} /* find_type */
 
122
 
 
123
 
 
124
        /* Get name of type nr 'nr' */
 
125
        /* Warning first type is 1, 0 = empty field */
 
126
 
 
127
void make_type(register char * to, register uint nr,
 
128
               register TYPELIB *typelib)
 
129
{
 
130
  DBUG_ENTER("make_type");
 
131
  if (!nr)
 
132
    to[0]=0;
 
133
  else
 
134
    (void) strmov(to,get_type(typelib,nr-1));
 
135
  DBUG_VOID_RETURN;
 
136
} /* make_type */
 
137
 
 
138
 
 
139
        /* Get type */
 
140
        /* Warning first type is 0 */
 
141
 
 
142
const char *get_type(TYPELIB *typelib, uint nr)
 
143
{
 
144
  if (nr < (uint) typelib->count && typelib->type_names)
 
145
    return(typelib->type_names[nr]);
 
146
  return "?";
 
147
}
 
148
 
 
149
 
 
150
/*
 
151
  Create an integer value to represent the supplied comma-seperated
 
152
  string where each string in the TYPELIB denotes a bit position.
 
153
 
 
154
  SYNOPSIS
 
155
    find_typeset()
 
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
 
160
 
 
161
  RETURN
 
162
    a integer representation of the supplied string
 
163
*/
 
164
 
 
165
my_ulonglong find_typeset(char *x, TYPELIB *lib, int *err)
 
166
{
 
167
  my_ulonglong result;
 
168
  int find;
 
169
  char *i;
 
170
  DBUG_ENTER("find_set");
 
171
  DBUG_PRINT("enter",("x: '%s'  lib: 0x%lx", x, (long) lib));
 
172
 
 
173
  if (!lib->count)
 
174
  {
 
175
    DBUG_PRINT("exit",("no count"));
 
176
    DBUG_RETURN(0);
 
177
  }
 
178
  result= 0;
 
179
  *err= 0;
 
180
  while (*x)
 
181
  {
 
182
    (*err)++;
 
183
    i= x;
 
184
    while (*x && *x != field_separator) x++;
 
185
    if ((find= find_type(i, lib, 2 | 8) - 1) < 0)
 
186
      DBUG_RETURN(0);
 
187
    result|= (ULL(1) << find);
 
188
  }
 
189
  *err= 0;
 
190
  DBUG_RETURN(result);
 
191
} /* find_set */
 
192
 
 
193
 
 
194
/*
 
195
  Create a copy of a specified TYPELIB structure.
 
196
 
 
197
  SYNOPSIS
 
198
    copy_typelib()
 
199
    root        pointer to a MEM_ROOT object for allocations
 
200
    from        pointer to a source TYPELIB structure
 
201
 
 
202
  RETURN
 
203
    pointer to the new TYPELIB structure on successful copy, or
 
204
    NULL otherwise
 
205
*/
 
206
 
 
207
TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from)
 
208
{
 
209
  TYPELIB *to;
 
210
  uint i;
 
211
 
 
212
  if (!from)
 
213
    return NULL;
 
214
 
 
215
  if (!(to= (TYPELIB*) alloc_root(root, sizeof(TYPELIB))))
 
216
    return NULL;
 
217
 
 
218
  if (!(to->type_names= (const char **)
 
219
        alloc_root(root, (sizeof(char *) + sizeof(int)) * (from->count + 1))))
 
220
    return NULL;
 
221
  to->type_lengths= (unsigned int *)(to->type_names + from->count + 1);
 
222
  to->count= from->count;
 
223
  if (from->name)
 
224
  {
 
225
    if (!(to->name= strdup_root(root, from->name)))
 
226
      return NULL;
 
227
  }
 
228
  else
 
229
    to->name= NULL;
 
230
 
 
231
  for (i= 0; i < from->count; i++)
 
232
  {
 
233
    if (!(to->type_names[i]= strmake_root(root, from->type_names[i],
 
234
                                          from->type_lengths[i])))
 
235
      return NULL;
 
236
    to->type_lengths[i]= from->type_lengths[i];
 
237
  }
 
238
  to->type_names[to->count]= NULL;
 
239
  to->type_lengths[to->count]= 0;
 
240
 
 
241
  return to;
 
242
}