Commit 446a6b93 authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Enchanced my_once..() functions.

Cleaned up charset.c
Removed non fatal memory leak in charset.c
parent 6b937028
...@@ -505,6 +505,8 @@ extern int my_setwd(const char *dir,myf MyFlags); ...@@ -505,6 +505,8 @@ extern int my_setwd(const char *dir,myf MyFlags);
extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags); extern int my_lock(File fd,int op,my_off_t start, my_off_t length,myf MyFlags);
extern gptr my_once_alloc(uint Size,myf MyFlags); extern gptr my_once_alloc(uint Size,myf MyFlags);
extern void my_once_free(void); extern void my_once_free(void);
extern char *my_once_strdup(const char *src,myf myflags);
extern char *my_once_memdup(const char *src, uint len, myf myflags);
extern my_string my_tempnam(const char *dir,const char *pfx,myf MyFlags); extern my_string my_tempnam(const char *dir,const char *pfx,myf MyFlags);
extern File my_open(const char *FileName,int Flags,myf MyFlags); extern File my_open(const char *FileName,int Flags,myf MyFlags);
extern File my_register_filename(File fd, const char *FileName, extern File my_register_filename(File fd, const char *FileName,
......
...@@ -28,7 +28,7 @@ static my_bool create_fromuni(CHARSET_INFO *cs); ...@@ -28,7 +28,7 @@ static my_bool create_fromuni(CHARSET_INFO *cs);
#define MY_CHARSET_INDEX "Index.xml" #define MY_CHARSET_INDEX "Index.xml"
const char *charsets_dir = NULL; const char *charsets_dir= NULL;
static int charset_initialized=0; static int charset_initialized=0;
#define MAX_LINE 1024 #define MAX_LINE 1024
...@@ -39,9 +39,10 @@ static int charset_initialized=0; ...@@ -39,9 +39,10 @@ static int charset_initialized=0;
#define SORT_ORDER_TABLE_SIZE 256 #define SORT_ORDER_TABLE_SIZE 256
#define TO_UNI_TABLE_SIZE 256 #define TO_UNI_TABLE_SIZE 256
char *get_charsets_dir(char *buf) char *get_charsets_dir(char *buf)
{ {
const char *sharedir = SHAREDIR; const char *sharedir= SHAREDIR;
DBUG_ENTER("get_charsets_dir"); DBUG_ENTER("get_charsets_dir");
if (charsets_dir != NULL) if (charsets_dir != NULL)
...@@ -56,7 +57,7 @@ char *get_charsets_dir(char *buf) ...@@ -56,7 +57,7 @@ char *get_charsets_dir(char *buf)
NullS); NullS);
} }
convert_dirname(buf,buf,NullS); convert_dirname(buf,buf,NullS);
DBUG_PRINT("info",("charsets dir='%s'", buf)); DBUG_PRINT("info",("charsets dir: '%s'", buf));
DBUG_RETURN(strend(buf)); DBUG_RETURN(strend(buf));
} }
...@@ -66,7 +67,7 @@ char *get_charsets_dir(char *buf) ...@@ -66,7 +67,7 @@ char *get_charsets_dir(char *buf)
#ifndef DBUG_OFF #ifndef DBUG_OFF
static void mstr(char *str,const char *src,uint l1,uint l2) static void mstr(char *str,const char *src,uint l1,uint l2)
{ {
l1 = l1<l2 ? l1 : l2; l1= l1<l2 ? l1 : l2;
memcpy(str,src,l1); memcpy(str,src,l1);
str[l1]='\0'; str[l1]='\0';
} }
...@@ -127,8 +128,10 @@ static struct my_cs_file_section_st * cs_file_sec(const char *attr, uint len) ...@@ -127,8 +128,10 @@ static struct my_cs_file_section_st * cs_file_sec(const char *attr, uint len)
{ {
struct my_cs_file_section_st *s; struct my_cs_file_section_st *s;
for (s=sec; s->str; s++) for (s=sec; s->str; s++)
{
if (!strncmp(attr,s->str,len)) if (!strncmp(attr,s->str,len))
return s; return s;
}
return NULL; return NULL;
} }
...@@ -172,106 +175,90 @@ static void simple_cs_init_functions(CHARSET_INFO *cs) ...@@ -172,106 +175,90 @@ static void simple_cs_init_functions(CHARSET_INFO *cs)
cs->mbmaxlen = 1; cs->mbmaxlen = 1;
} }
/* FIXME: BAR: move to more proper place, my_alloc.c I suppose */
static char *my_once_strdup(const char *src,myf myflags)
{
uint len=strlen(src);
char *dst=my_once_alloc(len+1,myflags);
if (dst)
memcpy(dst,src,len+1);
return dst;
}
static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from) static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
{ {
to->number = from->number ? from->number : to->number; to->number= from->number ? from->number : to->number;
to->state |= from->state; to->state|= from->state;
if (from->csname) if (from->csname)
to->csname=my_once_strdup(from->csname,MYF(MY_WME)); to->csname= my_once_strdup(from->csname,MYF(MY_WME));
if (from->name) if (from->name)
to->name=my_once_strdup(from->name,MYF(MY_WME)); to->name= my_once_strdup(from->name,MYF(MY_WME));
if (from->ctype) if (from->ctype)
{ to->ctype= (uchar*) my_once_memdup((char*) from->ctype,
to->ctype = (uchar*) my_once_alloc(CTYPE_TABLE_SIZE,MYF(MY_WME)); CTYPE_TABLE_SIZE, MYF(MY_WME));
memcpy((char*)to->ctype,(char*)from->ctype,CTYPE_TABLE_SIZE);
}
if (from->to_lower) if (from->to_lower)
{ to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower,
to->to_lower = (uchar*) my_once_alloc(TO_LOWER_TABLE_SIZE,MYF(MY_WME)); TO_LOWER_TABLE_SIZE, MYF(MY_WME));
memcpy((char*)to->to_lower,(char*)from->to_lower,TO_LOWER_TABLE_SIZE);
}
if (from->to_upper) if (from->to_upper)
{ to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper,
to->to_upper = (uchar*) my_once_alloc(TO_UPPER_TABLE_SIZE,MYF(MY_WME)); TO_UPPER_TABLE_SIZE, MYF(MY_WME));
memcpy((char*)to->to_upper,(char*)from->to_upper,TO_UPPER_TABLE_SIZE);
}
if (from->sort_order) if (from->sort_order)
{ {
to->sort_order=(uchar*) my_once_alloc(SORT_ORDER_TABLE_SIZE,MYF(MY_WME)); to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order,
memcpy((char*)to->sort_order,(char*)from->sort_order, SORT_ORDER_TABLE_SIZE); SORT_ORDER_TABLE_SIZE,
MYF(MY_WME));
set_max_sort_char(to); set_max_sort_char(to);
} }
if (from->tab_to_uni) if (from->tab_to_uni)
{ {
uint sz=TO_UNI_TABLE_SIZE*sizeof(uint16); uint sz=TO_UNI_TABLE_SIZE*sizeof(uint16);
to->tab_to_uni=(uint16*)my_once_alloc(sz,MYF(MY_WME)); to->tab_to_uni= (uint16*) my_once_memdup((char*)from->tab_to_uni, sz,
memcpy((char*)to->tab_to_uni,(char*)from->tab_to_uni,sz); MYF(MY_WME));
create_fromuni(to); create_fromuni(to);
} }
} }
static my_bool simple_cs_is_full(CHARSET_INFO *cs) static my_bool simple_cs_is_full(CHARSET_INFO *cs)
{ {
return return ((cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper &&
(cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper && cs->to_lower) cs->to_lower) &&
&& (cs->number && cs->name && cs->sort_order));
(cs->number && cs->name && cs->sort_order);
} }
static int fill_uchar(uchar *a,uint size,const char *str, uint len) static int fill_uchar(uchar *a,uint size,const char *str, uint len)
{ {
uint i=0; uint i= 0;
const char *s, *b, *e=str+len; const char *s, *b, *e=str+len;
for (s=str ; s<e ; i++) for (s=str ; s < e ; i++)
{ {
for ( ; (s<e) && strchr(" \t\r\n",s[0]); s++); for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
b=s; b=s;
for ( ; (s<e) && !strchr(" \t\r\n",s[0]); s++); for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
if (s==b) if (s == b || i > size)
break;
if (i>size)
break; break;
a[i]=my_strntoul(my_charset_latin1,b,s-b,NULL,16); a[i]= my_strntoul(my_charset_latin1,b,s-b,NULL,16);
} }
return 0; return 0;
} }
static int fill_uint16(uint16 *a,uint size,const char *str, uint len) static int fill_uint16(uint16 *a,uint size,const char *str, uint len)
{ {
uint i=0; uint i= 0;
const char *s, *b, *e=str+len; const char *s, *b, *e=str+len;
for (s=str ; s<e ; i++) for (s=str ; s < e ; i++)
{ {
for ( ; (s<e) && strchr(" \t\r\n",s[0]); s++); for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
b=s; b=s;
for ( ; (s<e) && !strchr(" \t\r\n",s[0]); s++); for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
if (s==b) if (s == b || i > size)
break;
if (i>size)
break; break;
a[i]=my_strntol(my_charset_latin1,b,s-b,NULL,16); a[i]= my_strntol(my_charset_latin1,b,s-b,NULL,16);
} }
return 0; return 0;
} }
static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len) static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len)
{ {
struct my_cs_file_info *i = (struct my_cs_file_info *)st->user_data; struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
struct my_cs_file_section_st *s = cs_file_sec(attr,len); struct my_cs_file_section_st *s= cs_file_sec(attr,len);
if ( s && (s->state == _CS_CHARSET)) if ( s && (s->state == _CS_CHARSET))
{ {
...@@ -280,23 +267,23 @@ static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len) ...@@ -280,23 +267,23 @@ static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len)
return MY_XML_OK; return MY_XML_OK;
} }
static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len) static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len)
{ {
struct my_cs_file_info *i = (struct my_cs_file_info *)st->user_data; struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
struct my_cs_file_section_st *s = cs_file_sec(attr,len); struct my_cs_file_section_st *s= cs_file_sec(attr,len);
int state = s ? s->state : 0; int state= s ? s->state : 0;
if (state == _CS_COLLATION) if (state == _CS_COLLATION)
{ {
if (i->cs.name && (i->cs.number || (i->cs.number=get_charset_number(i->cs.name)))) if (i->cs.name && (i->cs.number ||
(i->cs.number=get_charset_number(i->cs.name))))
{ {
if (!all_charsets[i->cs.number]) if (!all_charsets[i->cs.number])
{ {
if (!(all_charsets[i->cs.number]= if (!(all_charsets[i->cs.number]=
(CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),i->myflags))) (CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),i->myflags)))
{
return MY_XML_ERROR; return MY_XML_ERROR;
}
bzero((void*)all_charsets[i->cs.number],sizeof(CHARSET_INFO)); bzero((void*)all_charsets[i->cs.number],sizeof(CHARSET_INFO));
} }
...@@ -309,22 +296,22 @@ static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len) ...@@ -309,22 +296,22 @@ static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len)
all_charsets[i->cs.number]->state |= MY_CS_LOADED; all_charsets[i->cs.number]->state |= MY_CS_LOADED;
} }
} }
i->cs.number=0; i->cs.number= 0;
i->cs.name=NULL; i->cs.name= NULL;
i->cs.state=0; i->cs.state= 0;
i->cs.sort_order=NULL; i->cs.sort_order= NULL;
i->cs.state=0; i->cs.state= 0;
} }
} }
return MY_XML_OK; return MY_XML_OK;
} }
static int cs_value(MY_XML_PARSER *st,const char *attr, uint len) static int cs_value(MY_XML_PARSER *st,const char *attr, uint len)
{ {
struct my_cs_file_info *i = (struct my_cs_file_info *)st->user_data; struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
struct my_cs_file_section_st *s; struct my_cs_file_section_st *s;
int state = (s=cs_file_sec(st->attr,strlen(st->attr))) ? s->state : 0; int state= (s=cs_file_sec(st->attr,strlen(st->attr))) ? s->state : 0;
#ifndef DBUG_OFF #ifndef DBUG_OFF
if(0){ if(0){
...@@ -334,49 +321,49 @@ static int cs_value(MY_XML_PARSER *st,const char *attr, uint len) ...@@ -334,49 +321,49 @@ static int cs_value(MY_XML_PARSER *st,const char *attr, uint len)
} }
#endif #endif
switch (state) switch (state) {
{ case _CS_ID:
case _CS_ID: i->cs.number= my_strntoul(my_charset_latin1,attr,len,(char**)NULL,0);
i->cs.number = my_strntoul(my_charset_latin1,attr,len,(char**)NULL,0); break;
break; case _CS_COLNAME:
case _CS_COLNAME: memcpy(i->name,attr,len=min(len,CS_MAX_NM_LEN-1));
memcpy(i->name,attr,len=min(len,CS_MAX_NM_LEN-1)); i->name[len]='\0';
i->name[len]='\0'; i->cs.name=i->name;
i->cs.name=i->name; break;
break; case _CS_NAME:
case _CS_NAME: memcpy(i->csname,attr,len=min(len,CS_MAX_NM_LEN-1));
memcpy(i->csname,attr,len=min(len,CS_MAX_NM_LEN-1)); i->csname[len]='\0';
i->csname[len]='\0'; i->cs.csname=i->csname;
i->cs.csname=i->csname; break;
break; case _CS_FLAG:
case _CS_FLAG: if (!strncmp("primary",attr,len))
if (!strncmp("primary",attr,len)) i->cs.state|= MY_CS_PRIMARY;
i->cs.state |= MY_CS_PRIMARY; break;
break; case _CS_UPPERMAP:
case _CS_UPPERMAP: fill_uchar(i->to_upper,TO_UPPER_TABLE_SIZE,attr,len);
fill_uchar(i->to_upper,TO_UPPER_TABLE_SIZE,attr,len); i->cs.to_upper=i->to_upper;
i->cs.to_upper=i->to_upper; break;
break; case _CS_LOWERMAP:
case _CS_LOWERMAP: fill_uchar(i->to_lower,TO_LOWER_TABLE_SIZE,attr,len);
fill_uchar(i->to_lower,TO_LOWER_TABLE_SIZE,attr,len); i->cs.to_lower=i->to_lower;
i->cs.to_lower=i->to_lower; break;
break; case _CS_UNIMAP:
case _CS_UNIMAP: fill_uint16(i->tab_to_uni,TO_UNI_TABLE_SIZE,attr,len);
fill_uint16(i->tab_to_uni,TO_UNI_TABLE_SIZE,attr,len); i->cs.tab_to_uni=i->tab_to_uni;
i->cs.tab_to_uni=i->tab_to_uni; break;
break; case _CS_COLLMAP:
case _CS_COLLMAP: fill_uchar(i->sort_order,SORT_ORDER_TABLE_SIZE,attr,len);
fill_uchar(i->sort_order,SORT_ORDER_TABLE_SIZE,attr,len); i->cs.sort_order=i->sort_order;
i->cs.sort_order=i->sort_order; break;
break; case _CS_CTYPEMAP:
case _CS_CTYPEMAP: fill_uchar(i->ctype,CTYPE_TABLE_SIZE,attr,len);
fill_uchar(i->ctype,CTYPE_TABLE_SIZE,attr,len); i->cs.ctype=i->ctype;
i->cs.ctype=i->ctype; break;
break;
} }
return MY_XML_OK; return MY_XML_OK;
} }
static my_bool read_charset_index(const char *filename, myf myflags) static my_bool read_charset_index(const char *filename, myf myflags)
{ {
char *buf; char *buf;
...@@ -385,10 +372,10 @@ static my_bool read_charset_index(const char *filename, myf myflags) ...@@ -385,10 +372,10 @@ static my_bool read_charset_index(const char *filename, myf myflags)
MY_XML_PARSER p; MY_XML_PARSER p;
struct my_cs_file_info i; struct my_cs_file_info i;
if (! (buf = (char *)my_malloc(MAX_BUF,myflags))) if (!(buf= (char *)my_malloc(MAX_BUF,myflags)))
return FALSE; return FALSE;
strmov(get_charsets_dir(buf),filename); strmov(get_charsets_dir(buf), filename);
if ((fd=my_open(buf,O_RDONLY,myflags)) < 0) if ((fd=my_open(buf,O_RDONLY,myflags)) < 0)
{ {
...@@ -405,18 +392,18 @@ static my_bool read_charset_index(const char *filename, myf myflags) ...@@ -405,18 +392,18 @@ static my_bool read_charset_index(const char *filename, myf myflags)
my_xml_set_leave_handler(&p,cs_leave); my_xml_set_leave_handler(&p,cs_leave);
my_xml_set_user_data(&p,(void*)&i); my_xml_set_user_data(&p,(void*)&i);
if (MY_XML_OK!=my_xml_parse(&p,buf,len)) if (my_xml_parse(&p,buf,len) != MY_XML_OK)
{ {
/* #ifdef NOT_YET
printf("ERROR at line %d pos %d '%s'\n", printf("ERROR at line %d pos %d '%s'\n",
my_xml_error_lineno(&p)+1, my_xml_error_lineno(&p)+1,
my_xml_error_pos(&p), my_xml_error_pos(&p),
my_xml_error_string(&p)); my_xml_error_string(&p));
*/ #endif
} }
my_xml_parser_free(&p); my_xml_parser_free(&p);
my_free(buf, myflags);
return FALSE; return FALSE;
} }
...@@ -429,7 +416,7 @@ static void set_max_sort_char(CHARSET_INFO *cs) ...@@ -429,7 +416,7 @@ static void set_max_sort_char(CHARSET_INFO *cs)
return; return;
max_char=cs->sort_order[(uchar) cs->max_sort_char]; max_char=cs->sort_order[(uchar) cs->max_sort_char];
for (i = 0; i < 256; i++) for (i= 0; i < 256; i++)
{ {
if ((uchar) cs->sort_order[i] > max_char) if ((uchar) cs->sort_order[i] > max_char)
{ {
...@@ -445,14 +432,14 @@ static my_bool init_available_charsets(myf myflags) ...@@ -445,14 +432,14 @@ static my_bool init_available_charsets(myf myflags)
/* /*
We have to use charset_initialized to not lock on THR_LOCK_charset We have to use charset_initialized to not lock on THR_LOCK_charset
inside get_internal_charset... inside get_internal_charset...
*/ */
if (!charset_initialized) if (!charset_initialized)
{ {
CHARSET_INFO **cs; CHARSET_INFO **cs;
/* /*
To make things thread safe we are not allowing other threads to interfere To make things thread safe we are not allowing other threads to interfere
while we may changing the cs_info_table while we may changing the cs_info_table
*/ */
pthread_mutex_lock(&THR_LOCK_charset); pthread_mutex_lock(&THR_LOCK_charset);
bzero(&all_charsets,sizeof(all_charsets)); bzero(&all_charsets,sizeof(all_charsets));
...@@ -464,7 +451,7 @@ static my_bool init_available_charsets(myf myflags) ...@@ -464,7 +451,7 @@ static my_bool init_available_charsets(myf myflags)
if (*cs) if (*cs)
set_max_sort_char(*cs); set_max_sort_char(*cs);
} }
error = read_charset_index(MY_CHARSET_INDEX,myflags); error= read_charset_index(MY_CHARSET_INDEX,myflags);
charset_initialized=1; charset_initialized=1;
pthread_mutex_unlock(&THR_LOCK_charset); pthread_mutex_unlock(&THR_LOCK_charset);
} }
...@@ -477,14 +464,17 @@ void free_charsets(void) ...@@ -477,14 +464,17 @@ void free_charsets(void)
charset_initialized=0; charset_initialized=0;
} }
static void get_charset_conf_name(const char *cs_name, char *buf) static void get_charset_conf_name(const char *cs_name, char *buf)
{ {
strxmov(get_charsets_dir(buf), cs_name, ".conf", NullS); strxmov(get_charsets_dir(buf), cs_name, ".conf", NullS);
} }
typedef struct {
int nchars; typedef struct
MY_UNI_IDX uidx; {
int nchars;
MY_UNI_IDX uidx;
} uni_idx; } uni_idx;
#define PLANE_SIZE 0x100 #define PLANE_SIZE 0x100
...@@ -493,16 +483,18 @@ typedef struct { ...@@ -493,16 +483,18 @@ typedef struct {
static int pcmp(const void * f, const void * s) static int pcmp(const void * f, const void * s)
{ {
const uni_idx *F=(const uni_idx*)f; const uni_idx *F= (const uni_idx*) f;
const uni_idx *S=(const uni_idx*)s; const uni_idx *S= (const uni_idx*) s;
int res; int res;
if(!(res=((S->nchars)-(F->nchars)))) if (!(res=((S->nchars)-(F->nchars))))
res=((F->uidx.from)-(S->uidx.to)); res=((F->uidx.from)-(S->uidx.to));
return res; return res;
} }
static my_bool create_fromuni(CHARSET_INFO *cs){
static my_bool create_fromuni(CHARSET_INFO *cs)
{
uni_idx idx[PLANE_NUM]; uni_idx idx[PLANE_NUM];
int i,n; int i,n;
...@@ -510,14 +502,14 @@ static my_bool create_fromuni(CHARSET_INFO *cs){ ...@@ -510,14 +502,14 @@ static my_bool create_fromuni(CHARSET_INFO *cs){
bzero(idx,sizeof(idx)); bzero(idx,sizeof(idx));
/* Count number of characters in each plane */ /* Count number of characters in each plane */
for(i=0;i<0x100;i++) for (i=0; i< 0x100; i++)
{ {
uint16 wc=cs->tab_to_uni[i]; uint16 wc=cs->tab_to_uni[i];
int pl= PLANE_NUMBER(wc); int pl= PLANE_NUMBER(wc);
if(wc || !i) if (wc || !i)
{ {
if(!idx[pl].nchars) if (!idx[pl].nchars)
{ {
idx[pl].uidx.from=wc; idx[pl].uidx.from=wc;
idx[pl].uidx.to=wc; idx[pl].uidx.to=wc;
...@@ -533,34 +525,37 @@ static my_bool create_fromuni(CHARSET_INFO *cs){ ...@@ -533,34 +525,37 @@ static my_bool create_fromuni(CHARSET_INFO *cs){
/* Sort planes in descending order */ /* Sort planes in descending order */
qsort(&idx,PLANE_NUM,sizeof(uni_idx),&pcmp); qsort(&idx,PLANE_NUM,sizeof(uni_idx),&pcmp);
for(i=0;i<PLANE_NUM;i++) for (i=0; i < PLANE_NUM; i++)
{ {
int ch,numchars; int ch,numchars;
/* Skip empty plane */ /* Skip empty plane */
if(!idx[i].nchars) if (!idx[i].nchars)
break; break;
numchars=idx[i].uidx.to-idx[i].uidx.from+1; numchars=idx[i].uidx.to-idx[i].uidx.from+1;
idx[i].uidx.tab=(unsigned char*)my_once_alloc(numchars*sizeof(*idx[i].uidx.tab),MYF(MY_WME)); idx[i].uidx.tab=(unsigned char*)my_once_alloc(numchars *
sizeof(*idx[i].uidx.tab),
MYF(MY_WME));
bzero(idx[i].uidx.tab,numchars*sizeof(*idx[i].uidx.tab)); bzero(idx[i].uidx.tab,numchars*sizeof(*idx[i].uidx.tab));
for(ch=1;ch<PLANE_SIZE;ch++) for (ch=1; ch < PLANE_SIZE; ch++)
{ {
uint16 wc=cs->tab_to_uni[ch]; uint16 wc=cs->tab_to_uni[ch];
if(wc>=idx[i].uidx.from && wc<=idx[i].uidx.to && wc) if (wc >= idx[i].uidx.from && wc <= idx[i].uidx.to && wc)
{ {
int ofs=wc-idx[i].uidx.from; int ofs= wc - idx[i].uidx.from;
idx[i].uidx.tab[ofs]=ch; idx[i].uidx.tab[ofs]= ch;
} }
} }
} }
/* Allocate and fill reverse table for each plane */ /* Allocate and fill reverse table for each plane */
n=i; n=i;
cs->tab_from_uni=(MY_UNI_IDX*)my_once_alloc(sizeof(MY_UNI_IDX)*(n+1),MYF(MY_WME)); cs->tab_from_uni= (MY_UNI_IDX*) my_once_alloc(sizeof(MY_UNI_IDX)*(n+1),
for(i=0;i<n;i++) MYF(MY_WME));
cs->tab_from_uni[i]=idx[i].uidx; for (i=0; i< n; i++)
cs->tab_from_uni[i]= idx[i].uidx;
/* Set end-of-list marker */ /* Set end-of-list marker */
bzero(&cs->tab_from_uni[i],sizeof(MY_UNI_IDX)); bzero(&cs->tab_from_uni[i],sizeof(MY_UNI_IDX));
...@@ -574,10 +569,11 @@ uint get_charset_number(const char *charset_name) ...@@ -574,10 +569,11 @@ uint get_charset_number(const char *charset_name)
if (init_available_charsets(MYF(0))) /* If it isn't initialized */ if (init_available_charsets(MYF(0))) /* If it isn't initialized */
return 0; return 0;
for (cs = all_charsets; cs < all_charsets+255; ++cs) for (cs= all_charsets; cs < all_charsets+255; ++cs)
{
if ( cs[0] && cs[0]->name && !strcmp(cs[0]->name, charset_name)) if ( cs[0] && cs[0]->name && !strcmp(cs[0]->name, charset_name))
return cs[0]->number; return cs[0]->number;
}
return 0; /* this mimics find_type() */ return 0; /* this mimics find_type() */
} }
...@@ -589,7 +585,7 @@ const char *get_charset_name(uint charset_number) ...@@ -589,7 +585,7 @@ const char *get_charset_name(uint charset_number)
return "?"; return "?";
cs=all_charsets[charset_number]; cs=all_charsets[charset_number];
if ( cs && (cs->number==charset_number) && cs->name ) if (cs && (cs->number == charset_number) && cs->name )
return (char*) cs->name; return (char*) cs->name;
return (char*) "?"; /* this mimics find_type() */ return (char*) "?"; /* this mimics find_type() */
...@@ -598,7 +594,7 @@ const char *get_charset_name(uint charset_number) ...@@ -598,7 +594,7 @@ const char *get_charset_name(uint charset_number)
static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
{ {
char buf[FN_REFLEN]; char buf[FN_REFLEN];
CHARSET_INFO *cs; CHARSET_INFO *cs;
/* /*
To make things thread safe we are not allowing other threads to interfere To make things thread safe we are not allowing other threads to interfere
...@@ -606,13 +602,13 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) ...@@ -606,13 +602,13 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
*/ */
pthread_mutex_lock(&THR_LOCK_charset); pthread_mutex_lock(&THR_LOCK_charset);
cs = all_charsets[cs_number]; cs= all_charsets[cs_number];
if (cs && !(cs->state & (MY_CS_COMPILED | MY_CS_LOADED))) if (cs && !(cs->state & (MY_CS_COMPILED | MY_CS_LOADED)))
{ {
strxmov(buf, cs->csname, ".xml", NullS); strxmov(buf, cs->csname, ".xml", NullS);
read_charset_index(buf,flags); read_charset_index(buf,flags);
cs = (cs->state & MY_CS_LOADED) ? cs : NULL; cs= (cs->state & MY_CS_LOADED) ? cs : NULL;
} }
pthread_mutex_unlock(&THR_LOCK_charset); pthread_mutex_unlock(&THR_LOCK_charset);
return cs; return cs;
...@@ -653,14 +649,16 @@ my_bool set_default_charset(uint cs, myf flags) ...@@ -653,14 +649,16 @@ my_bool set_default_charset(uint cs, myf flags)
CHARSET_INFO *new_charset; CHARSET_INFO *new_charset;
DBUG_ENTER("set_default_charset"); DBUG_ENTER("set_default_charset");
DBUG_PRINT("enter",("character set: %d",(int) cs)); DBUG_PRINT("enter",("character set: %d",(int) cs));
new_charset = get_charset(cs, flags);
new_charset= get_charset(cs, flags);
if (!new_charset) if (!new_charset)
{ {
DBUG_PRINT("error",("Couldn't set default character set")); DBUG_PRINT("error",("Couldn't set default character set"));
DBUG_RETURN(TRUE); /* error */ DBUG_RETURN(TRUE); /* error */
} }
default_charset_info = new_charset; default_charset_info= new_charset;
system_charset_info = new_charset; system_charset_info= new_charset;
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
...@@ -680,23 +678,26 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags) ...@@ -680,23 +678,26 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags)
return cs; return cs;
} }
my_bool set_default_charset_by_name(const char *cs_name, myf flags) my_bool set_default_charset_by_name(const char *cs_name, myf flags)
{ {
CHARSET_INFO *new_charset; CHARSET_INFO *new_charset;
DBUG_ENTER("set_default_charset_by_name"); DBUG_ENTER("set_default_charset_by_name");
DBUG_PRINT("enter",("character set: %s", cs_name)); DBUG_PRINT("enter",("character set: %s", cs_name));
new_charset = get_charset_by_name(cs_name, flags);
new_charset= get_charset_by_name(cs_name, flags);
if (!new_charset) if (!new_charset)
{ {
DBUG_PRINT("error",("Couldn't set default character set")); DBUG_PRINT("error",("Couldn't set default character set"));
DBUG_RETURN(TRUE); /* error */ DBUG_RETURN(TRUE); /* error */
} }
default_charset_info = new_charset; default_charset_info= new_charset;
system_charset_info = new_charset; system_charset_info= new_charset;
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
/* Only append name if it doesn't exist from before */ /* Only append name if it doesn't exist from before */
static my_bool charset_in_string(const char *name, DYNAMIC_STRING *s) static my_bool charset_in_string(const char *name, DYNAMIC_STRING *s)
...@@ -708,13 +709,14 @@ static my_bool charset_in_string(const char *name, DYNAMIC_STRING *s) ...@@ -708,13 +709,14 @@ static my_bool charset_in_string(const char *name, DYNAMIC_STRING *s)
if (! pos[length] || pos[length] == ' ') if (! pos[length] || pos[length] == ' ')
return TRUE; /* Already existed */ return TRUE; /* Already existed */
} }
return FALSE; return FALSE;
} }
static void charset_append(DYNAMIC_STRING *s, const char *name) static void charset_append(DYNAMIC_STRING *s, const char *name)
{ {
if (!charset_in_string(name, s)) { if (!charset_in_string(name, s))
{
dynstr_append(s, name); dynstr_append(s, name);
dynstr_append(s, " "); dynstr_append(s, " ");
} }
...@@ -724,7 +726,7 @@ static void charset_append(DYNAMIC_STRING *s, const char *name) ...@@ -724,7 +726,7 @@ static void charset_append(DYNAMIC_STRING *s, const char *name)
/* Returns a dynamically-allocated string listing the character sets /* Returns a dynamically-allocated string listing the character sets
requested. The caller is responsible for freeing the memory. */ requested. The caller is responsible for freeing the memory. */
char * list_charsets(myf want_flags) char *list_charsets(myf want_flags)
{ {
DYNAMIC_STRING s; DYNAMIC_STRING s;
char *p; char *p;
...@@ -735,7 +737,7 @@ char * list_charsets(myf want_flags) ...@@ -735,7 +737,7 @@ char * list_charsets(myf want_flags)
if (want_flags & MY_CS_COMPILED) if (want_flags & MY_CS_COMPILED)
{ {
CHARSET_INFO **cs; CHARSET_INFO **cs;
for (cs = all_charsets; cs < all_charsets+255; cs++) for (cs= all_charsets; cs < all_charsets+255; cs++)
{ {
if (cs[0]) if (cs[0])
{ {
...@@ -766,19 +768,19 @@ char * list_charsets(myf want_flags) ...@@ -766,19 +768,19 @@ char * list_charsets(myf want_flags)
if (want_flags & (MY_CS_INDEX|MY_CS_LOADED)) if (want_flags & (MY_CS_INDEX|MY_CS_LOADED))
{ {
CHARSET_INFO **cs; CHARSET_INFO **cs;
for (cs = all_charsets; cs < all_charsets + 255; cs++) for (cs= all_charsets; cs < all_charsets + 255; cs++)
if (cs[0] && cs[0]->name && (cs[0]->state & want_flags) ) if (cs[0] && cs[0]->name && (cs[0]->state & want_flags) )
charset_append(&s, cs[0]->name); charset_append(&s, cs[0]->name);
} }
if (s.length) if (s.length)
{ {
s.str[s.length - 1] = '\0'; /* chop trailing space */ s.str[s.length - 1]= '\0'; /* chop trailing space */
p = my_strdup(s.str, MYF(MY_WME)); p= my_strdup(s.str, MYF(MY_WME));
} }
else else
{ {
p = my_strdup("", MYF(MY_WME)); p= my_strdup("", MYF(MY_WME));
} }
dynstr_free(&s); dynstr_free(&s);
......
...@@ -78,6 +78,25 @@ gptr my_once_alloc(unsigned int Size, myf MyFlags) ...@@ -78,6 +78,25 @@ gptr my_once_alloc(unsigned int Size, myf MyFlags)
} /* my_once_alloc */ } /* my_once_alloc */
char *my_once_strdup(const char *src,myf myflags)
{
uint len=strlen(src)+1;
char *dst=my_once_alloc(len, myflags);
if (dst)
memcpy(dst, src, len);
return dst;
}
char *my_once_memdup(const char *src, uint len, myf myflags)
{
char *dst=my_once_alloc(len, myflags);
if (dst)
memcpy(dst, src, len);
return dst;
}
/* /*
Deallocate everything used by my_once_alloc Deallocate everything used by my_once_alloc
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment