Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
446a6b93
Commit
446a6b93
authored
Jan 07, 2003
by
monty@mashka.mysql.fi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Enchanced my_once..() functions.
Cleaned up charset.c Removed non fatal memory leak in charset.c
parent
6b937028
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
188 additions
and
165 deletions
+188
-165
include/my_sys.h
include/my_sys.h
+2
-0
mysys/charset.c
mysys/charset.c
+167
-165
mysys/my_once.c
mysys/my_once.c
+19
-0
No files found.
include/my_sys.h
View file @
446a6b93
...
@@ -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
,
...
...
mysys/charset.c
View file @
446a6b93
...
@@ -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
);
...
...
mysys/my_once.c
View file @
446a6b93
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment