12
12
You should have received a copy of the GNU General Public License
13
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18
#include "drizzled/charset.h"
19
#include "drizzled/error.h"
20
#include "drizzled/charset_info.h"
21
#include "drizzled/internal/m_string.h"
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
#include "mysys_priv.h"
17
#include "mysys_err.h"
18
#include <mystrings/m_ctype.h>
19
#include <mystrings/m_string.h>
22
20
#include <drizzled/configmake.h>
31
We collect memory in this vector that we free on delete.
33
static vector<void *>memory_vector;
36
24
The code below implements this functionality:
86
74
state_map[i]=(unsigned char) MY_LEX_IDENT;
87
75
else if (my_isdigit(cs,i))
88
76
state_map[i]=(unsigned char) MY_LEX_NUMBER_IDENT;
77
#if defined(USE_MB) && defined(USE_MB_IDENT)
89
78
else if (my_mbcharlen(cs, i)>1)
90
79
state_map[i]=(unsigned char) MY_LEX_IDENT;
91
81
else if (my_isspace(cs,i))
92
82
state_map[i]=(unsigned char) MY_LEX_SKIP;
129
static bool charset_initialized= false;
119
#define MY_CHARSET_INDEX "Index.xml"
121
const char *charsets_dir= NULL;
122
static int charset_initialized=0;
125
char *get_charsets_dir(char *buf)
129
if (charsets_dir != NULL)
130
strncpy(buf, charsets_dir, FN_REFLEN-1);
133
if (test_if_hard_path(PKGDATADIR) ||
134
is_prefix(PKGDATADIR, PREFIX))
135
sprintf(buf,"%s/%s",PKGDATADIR,CHARSET_DIR);
137
sprintf(buf,"%s/%s/%s",PREFIX,PKGDATADIR,CHARSET_DIR);
139
res= convert_dirname(buf,buf,NULL);
131
143
CHARSET_INFO *all_charsets[256];
132
144
const CHARSET_INFO *default_charset_info = &my_charset_utf8_general_ci;
140
152
void *cs_alloc(size_t size)
142
void *ptr= malloc(size);
144
memory_vector.push_back(ptr);
151
158
static bool init_available_charsets(myf myflags)
160
char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
155
163
We have to use charset_initialized to not lock on THR_LOCK_charset
156
164
inside get_internal_charset...
158
if (charset_initialized == false)
166
if (!charset_initialized)
160
168
CHARSET_INFO **cs;
161
memset(&all_charsets, 0, sizeof(all_charsets));
162
init_compiled_charsets(myflags);
164
/* Copy compiled charsets */
165
for (cs=all_charsets;
166
cs < all_charsets+array_elements(all_charsets)-1 ;
170
To make things thread safe we are not allowing other threads to interfere
171
while we may changing the cs_info_table
173
pthread_mutex_lock(&THR_LOCK_charset);
174
if (!charset_initialized)
176
memset(&all_charsets, 0, sizeof(all_charsets));
177
init_compiled_charsets(myflags);
179
/* Copy compiled charsets */
180
for (cs=all_charsets;
181
cs < all_charsets+array_elements(all_charsets)-1 ;
172
if (init_state_maps(*cs))
187
if (init_state_maps(*cs))
192
strcpy(get_charsets_dir(fname), MY_CHARSET_INDEX);
193
charset_initialized=1;
177
charset_initialized= true;
195
pthread_mutex_unlock(&THR_LOCK_charset);
179
assert(charset_initialized);
185
201
void free_charsets(void)
187
charset_initialized= true;
189
while (memory_vector.empty() == false)
191
void *ptr= memory_vector.back();
192
memory_vector.pop_back();
195
memory_vector.clear();
203
charset_initialized=0;
276
284
cs= get_internal_charset(cs_number);
286
if (!cs && (flags & MY_WME))
288
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)], cs_string[23];
289
strcpy(get_charsets_dir(index_file),MY_CHARSET_INDEX);
291
int10_to_str(cs_number, cs_string+1, 10);
292
my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_string, index_file);
281
const CHARSET_INFO *get_charset_by_name(const char *cs_name)
297
const CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
283
299
uint32_t cs_number;
284
300
const CHARSET_INFO *cs;
285
301
(void) init_available_charsets(MYF(0)); /* If it isn't initialized */
287
cs_number= get_collation_number(cs_name);
303
cs_number=get_collation_number(cs_name);
288
304
cs= cs_number ? get_internal_charset(cs_number) : NULL;
306
if (!cs && (flags & MY_WME))
308
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
309
strcpy(get_charsets_dir(index_file),MY_CHARSET_INDEX);
310
my_error(EE_UNKNOWN_COLLATION, MYF(ME_BELL), cs_name, index_file);
294
const CHARSET_INFO *get_charset_by_csname(const char *cs_name, uint32_t cs_flags)
317
const CHARSET_INFO *get_charset_by_csname(const char *cs_name,
296
321
uint32_t cs_number;
297
322
const CHARSET_INFO *cs;
301
326
cs_number= get_charset_number(cs_name, cs_flags);
302
327
cs= cs_number ? get_internal_charset(cs_number) : NULL;
329
if (!cs && (flags & MY_WME))
331
char index_file[FN_REFLEN + sizeof(MY_CHARSET_INDEX)];
332
strcpy(get_charsets_dir(index_file),MY_CHARSET_INDEX);
333
my_error(EE_UNKNOWN_CHARSET, MYF(ME_BELL), cs_name, index_file);
341
Resolve character set by the character set name (utf8, latin1, ...).
343
The function tries to resolve character set by the specified name. If
344
there is character set with the given name, it is assigned to the "cs"
345
parameter and false is returned. If there is no such character set,
346
"default_cs" is assigned to the "cs" and true is returned.
348
@param[in] cs_name Character set name.
349
@param[in] default_cs Default character set.
350
@param[out] cs Variable to store character set.
352
@return false if character set was resolved successfully; true if there
353
is no character set with given name.
356
bool resolve_charset(const char *cs_name,
357
const CHARSET_INFO *default_cs,
358
const CHARSET_INFO **cs)
360
*cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0));
373
Resolve collation by the collation name (utf8_general_ci, ...).
375
The function tries to resolve collation by the specified name. If there
376
is collation with the given name, it is assigned to the "cl" parameter
377
and false is returned. If there is no such collation, "default_cl" is
378
assigned to the "cl" and true is returned.
380
@param[out] cl Variable to store collation.
381
@param[in] cl_name Collation name.
382
@param[in] default_cl Default collation.
384
@return false if collation was resolved successfully; true if there is no
385
collation with given name.
388
bool resolve_collation(const char *cl_name,
389
const CHARSET_INFO *default_cl,
390
const CHARSET_INFO **cl)
392
*cl= get_charset_by_name(cl_name, MYF(0));
404
#ifdef BACKSLASH_MBTAIL
405
static CHARSET_INFO *fs_cset_cache= NULL;
407
CHARSET_INFO *fs_character_set()
412
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_IDEFAULTANSICODEPAGE,
413
buf+2, sizeof(buf)-3);
415
We cannot call get_charset_by_name here
416
because fs_character_set() is executed before
417
LOCK_THD_charset mutex initialization, which
418
is used inside get_charset_by_name.
419
As we're now interested in cp932 only,
420
let's just detect it using strcmp().
422
fs_cset_cache= !strcmp(buf, "cp932") ?
423
&my_charset_cp932_japanese_ci : &my_charset_bin;
425
return fs_cset_cache;
309
430
Escape apostrophes by doubling them up