00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <config.h>
00019
00020 #include <stdio.h>
00021
00022 #include <drizzled/internal/m_string.h>
00023 #include <drizzled/charset_info.h>
00024 #include <drizzled/typelib.h>
00025
00026 namespace drizzled
00027 {
00028
00029 static const char field_separator=',';
00030
00031 int st_typelib::find_type_or_exit(const char *x, const char *option) const
00032 {
00033 int res= find_type(const_cast<char*>(x), 2);
00034 if (res > 0)
00035 return res;
00036 if (!*x)
00037 fprintf(stderr, "No option given to %s\n", option);
00038 else
00039 fprintf(stderr, "Unknown option to %s: %s\n", option, x);
00040 const char **ptr= type_names;
00041 fprintf(stderr, "Alternatives are: '%s'", *ptr);
00042 while (*++ptr)
00043 fprintf(stderr, ",'%s'", *ptr);
00044 fprintf(stderr, "\n");
00045 exit(1);
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 int st_typelib::find_type(const char *x, uint32_t full_name) const
00074 {
00075 assert(full_name & 2);
00076 return find_type(const_cast<char*>(x), full_name);
00077 }
00078
00079 int st_typelib::find_type(char *x, uint32_t full_name) const
00080 {
00081 if (!count)
00082 return 0;
00083 int find= 0;
00084 int findpos= 0;
00085 const char *j;
00086 for (int pos= 0; (j= type_names[pos]); pos++)
00087 {
00088 const char *i;
00089 for (i= x;
00090 *i && (!(full_name & 8) || *i != field_separator) &&
00091 my_toupper(&my_charset_utf8_general_ci,*i) ==
00092 my_toupper(&my_charset_utf8_general_ci,*j) ; i++, j++) ;
00093 if (! *j)
00094 {
00095 while (*i == ' ')
00096 i++;
00097 if (! *i || ((full_name & 8) && *i == field_separator))
00098 return(pos+1);
00099 }
00100 if ((!*i && (!(full_name & 8) || *i != field_separator)) &&
00101 (!*j || !(full_name & 1)))
00102 {
00103 find++;
00104 findpos=pos;
00105 }
00106 }
00107 if (find == 0 && (full_name & 4) && x[0] == '#' && strchr(x, '\0')[-1] == '#' &&
00108 (findpos=atoi(x+1)-1) >= 0 && (uint32_t) findpos < count)
00109 find=1;
00110 else if (find == 0 || ! x[0])
00111 {
00112 return(0);
00113 }
00114 else if (find != 1 || (full_name & 1))
00115 {
00116 return(-1);
00117 }
00118 if (!(full_name & 2))
00119 strcpy(x, type_names[findpos]);
00120 return findpos + 1;
00121 }
00122
00123
00124
00125
00126
00127 void st_typelib::make_type(char *to, uint32_t nr) const
00128 {
00129 if (!nr)
00130 to[0]= 0;
00131 else
00132 strcpy(to, get_type(nr - 1));
00133 }
00134
00135
00136
00137
00138
00139 const char *st_typelib::get_type(uint32_t nr) const
00140 {
00141 if (nr < count && type_names)
00142 return type_names[nr];
00143 return "?";
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 uint64_t st_typelib::find_typeset(const char *x, int *err) const
00163 {
00164 if (!count)
00165 return 0;
00166 uint64_t result= 0;
00167 *err= 0;
00168 while (*x)
00169 {
00170 (*err)++;
00171 const char *i= x;
00172 while (*x && *x != field_separator) x++;
00173 int find= find_type(i, 2 | 8) - 1;
00174 if (find < 0)
00175 return 0;
00176 result|= (1ULL << find);
00177 }
00178 *err= 0;
00179 return result;
00180 }
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196 TYPELIB *st_typelib::copy_typelib(memory::Root *root) const
00197 {
00198 TYPELIB *to;
00199 uint32_t i;
00200
00201 if (!this)
00202 return NULL;
00203
00204 if (!(to= (TYPELIB*) root->alloc_root(sizeof(TYPELIB))))
00205 return NULL;
00206
00207 if (!(to->type_names= (const char **)
00208 root->alloc_root((sizeof(char *) + sizeof(int)) * (count + 1))))
00209 return NULL;
00210 to->type_lengths= (unsigned int *)(to->type_names + count + 1);
00211 to->count= count;
00212 if (name)
00213 {
00214 if (!(to->name= root->strdup_root(name)))
00215 return NULL;
00216 }
00217 else
00218 to->name= NULL;
00219
00220 for (i= 0; i < count; i++)
00221 {
00222 if (!(to->type_names[i]= root->strmake_root(type_names[i], type_lengths[i])))
00223 return NULL;
00224 to->type_lengths[i]= type_lengths[i];
00225 }
00226 to->type_names[to->count]= NULL;
00227 to->type_lengths[to->count]= 0;
00228
00229 return to;
00230 }
00231
00232 }