mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-19 09:20:07 +00:00
Update.
1997-11-24 03:01 Ulrich Drepper <drepper@cygnus.com> * elf/dl-support.c: Call __libc_init_secure to make sure __libc_enable_secure is defined early. * sysdeps/generic/enbl-secure.c: Change function name to __libc_init_secure and make it global instead of a constructor. * iconv/gconv.c: Fix lots of bugs. * iconv/gconv.h: Likewise. * iconv/gconv_builtin.h: Likewise. * iconv/gconv_close.c: Likewise. * iconv/gconv_conf.c: Likewise. * iconv/gconv_db.c: Likewise. * iconv/gconv_dl.c: Likewise. * iconv/gconv_open.c: Likewise. * iconv/gconv_simple.c: Likewise. * iconv/iconv.c: Likewise. * iconv/iconv_close.c: Likewise. * iconv/iconv_open.c: Likewise. * wcsmbs/Makefile (routines): Add wmemrtowcs and wmemrtombs. * wcsmbs/wchar.h: Add prototypes for wmemrtowcs and wmemrtombs. * wcsmbs/wmemrtombs.c: New file. * wcsmbs/wmemrtowcs.c: New file.
This commit is contained in:
parent
f43ce637b5
commit
e34b0f2902
25
ChangeLog
25
ChangeLog
@ -1,3 +1,28 @@
|
|||||||
|
1997-11-24 03:01 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
|
* elf/dl-support.c: Call __libc_init_secure to make sure
|
||||||
|
__libc_enable_secure is defined early.
|
||||||
|
* sysdeps/generic/enbl-secure.c: Change function name to
|
||||||
|
__libc_init_secure and make it global instead of a constructor.
|
||||||
|
|
||||||
|
* iconv/gconv.c: Fix lots of bugs.
|
||||||
|
* iconv/gconv.h: Likewise.
|
||||||
|
* iconv/gconv_builtin.h: Likewise.
|
||||||
|
* iconv/gconv_close.c: Likewise.
|
||||||
|
* iconv/gconv_conf.c: Likewise.
|
||||||
|
* iconv/gconv_db.c: Likewise.
|
||||||
|
* iconv/gconv_dl.c: Likewise.
|
||||||
|
* iconv/gconv_open.c: Likewise.
|
||||||
|
* iconv/gconv_simple.c: Likewise.
|
||||||
|
* iconv/iconv.c: Likewise.
|
||||||
|
* iconv/iconv_close.c: Likewise.
|
||||||
|
* iconv/iconv_open.c: Likewise.
|
||||||
|
|
||||||
|
* wcsmbs/Makefile (routines): Add wmemrtowcs and wmemrtombs.
|
||||||
|
* wcsmbs/wchar.h: Add prototypes for wmemrtowcs and wmemrtombs.
|
||||||
|
* wcsmbs/wmemrtombs.c: New file.
|
||||||
|
* wcsmbs/wmemrtowcs.c: New file.
|
||||||
|
|
||||||
1997-11-22 19:28 Ulrich Drepper <drepper@cygnus.com>
|
1997-11-22 19:28 Ulrich Drepper <drepper@cygnus.com>
|
||||||
|
|
||||||
* iconv/gconv_simple.c: Fix lots of bugs.
|
* iconv/gconv_simple.c: Fix lots of bugs.
|
||||||
|
@ -46,6 +46,8 @@ struct r_search_path *_dl_search_paths;
|
|||||||
const char *_dl_profile;
|
const char *_dl_profile;
|
||||||
struct link_map *_dl_profile_map;
|
struct link_map *_dl_profile_map;
|
||||||
|
|
||||||
|
extern void __libc_init_secure (void);
|
||||||
|
|
||||||
|
|
||||||
static void non_dynamic_init (void) __attribute__ ((unused));
|
static void non_dynamic_init (void) __attribute__ ((unused));
|
||||||
|
|
||||||
@ -54,6 +56,10 @@ non_dynamic_init (void)
|
|||||||
{
|
{
|
||||||
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
|
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
|
||||||
|
|
||||||
|
_dl_pagesize = __getpagesize ();
|
||||||
|
|
||||||
|
__libc_init_secure ();
|
||||||
|
|
||||||
/* Initialize the data structures for the search paths for shared
|
/* Initialize the data structures for the search paths for shared
|
||||||
objects. */
|
objects. */
|
||||||
_dl_init_paths ();
|
_dl_init_paths ();
|
||||||
@ -65,7 +71,5 @@ non_dynamic_init (void)
|
|||||||
/* Now determine the length of the platform string. */
|
/* Now determine the length of the platform string. */
|
||||||
if (_dl_platform != NULL)
|
if (_dl_platform != NULL)
|
||||||
_dl_platformlen = strlen (_dl_platform);
|
_dl_platformlen = strlen (_dl_platform);
|
||||||
|
|
||||||
_dl_pagesize = __getpagesize ();
|
|
||||||
}
|
}
|
||||||
text_set_element (__libc_subinit, non_dynamic_init);
|
text_set_element (__libc_subinit, non_dynamic_init);
|
||||||
|
@ -30,6 +30,9 @@ __gconv (gconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
|
|||||||
size_t oldinbytes = *inbytesleft;
|
size_t oldinbytes = *inbytesleft;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
if (cd == (gconv_t) -1L)
|
||||||
|
return GCONV_ILLEGAL_DESCRIPTOR;
|
||||||
|
|
||||||
cd->data[last_step].outbuf = *outbuf;
|
cd->data[last_step].outbuf = *outbuf;
|
||||||
cd->data[last_step].outbufavail = 0;
|
cd->data[last_step].outbufavail = 0;
|
||||||
cd->data[last_step].outbufsize = *outbytesleft;
|
cd->data[last_step].outbufsize = *outbytesleft;
|
||||||
|
@ -37,6 +37,7 @@ enum
|
|||||||
GCONV_EMPTY_INPUT,
|
GCONV_EMPTY_INPUT,
|
||||||
GCONV_FULL_OUTPUT,
|
GCONV_FULL_OUTPUT,
|
||||||
GCONV_ILLEGAL_INPUT,
|
GCONV_ILLEGAL_INPUT,
|
||||||
|
GCONV_INCOMPLETE_INPUT,
|
||||||
|
|
||||||
GCONV_ILLEGAL_DESCRIPTOR,
|
GCONV_ILLEGAL_DESCRIPTOR,
|
||||||
GCONV_INTERNAL_ERROR
|
GCONV_INTERNAL_ERROR
|
||||||
|
@ -18,17 +18,17 @@
|
|||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
BUILTIN_TRANSFORMATION ("\\([^/]+\\)/UCS4/\\([^/]*\\)", NULL, 0,
|
BUILTIN_TRANSFORMATION ("([^/]+)/UCS4/([^/]*)", NULL, 0,
|
||||||
"\\1/UTF8/\\2", 1, "=ucs4->utf8",
|
"\\1/UTF8/\\2", 1, "=ucs4->utf8",
|
||||||
__gconv_transform_ucs4_utf8,
|
__gconv_transform_ucs4_utf8,
|
||||||
__gconv_transform_init_rstate,
|
__gconv_transform_init_rstate,
|
||||||
__gconv_transform_end_rstate)
|
__gconv_transform_end_rstate)
|
||||||
|
|
||||||
BUILTIN_TRANSFORMATION ("\\([^/]+\\)/UTF8/\\([^/]*\\)", NULL, 0,
|
BUILTIN_TRANSFORMATION ("([^/]+)/UTF8/([^/]*)", NULL, 0,
|
||||||
"\\1/UCS4/\\2", 1, "=utf8->ucs4",
|
"\\1/UCS4/\\2", 1, "=utf8->ucs4",
|
||||||
__gconv_transform_utf8_ucs4,
|
__gconv_transform_utf8_ucs4,
|
||||||
__gconv_transform_init_rstate,
|
__gconv_transform_init_rstate,
|
||||||
__gconv_transform_end_rstate)
|
__gconv_transform_end_rstate)
|
||||||
|
|
||||||
BUILTIN_TRANSFORMATION ("\\(.*\\)", NULL, 0, "\\1", 1, "=dummy",
|
BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
|
||||||
__gconv_transform_dummy, NULL, NULL)
|
__gconv_transform_dummy, NULL, NULL)
|
||||||
|
@ -48,9 +48,8 @@ __gconv_close (gconv_t cd)
|
|||||||
|
|
||||||
/* Next step. */
|
/* Next step. */
|
||||||
++srunp;
|
++srunp;
|
||||||
++drunp;
|
|
||||||
}
|
}
|
||||||
while (!drunp->is_last);
|
while (!(drunp++)->is_last);
|
||||||
|
|
||||||
/* Save the pointer, we need it below. */
|
/* Save the pointer, we need it below. */
|
||||||
srunp = cd->steps;
|
srunp = cd->steps;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <gconv.h>
|
#include <gconv.h>
|
||||||
#include <search.h>
|
#include <search.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -35,6 +36,12 @@ static const char default_gconv_path[] = GCONV_PATH;
|
|||||||
along the path. */
|
along the path. */
|
||||||
static const char gconv_conf_filename[] = "gconv-modules";
|
static const char gconv_conf_filename[] = "gconv-modules";
|
||||||
|
|
||||||
|
/* Filename extension for the modules. */
|
||||||
|
#ifndef MODULE_EXT
|
||||||
|
# define MODULE_EXT ".so"
|
||||||
|
#endif
|
||||||
|
static const char gconv_module_ext[] = MODULE_EXT;
|
||||||
|
|
||||||
/* We have a few builtin transformations. */
|
/* We have a few builtin transformations. */
|
||||||
static struct gconv_module builtin_modules[] =
|
static struct gconv_module builtin_modules[] =
|
||||||
{
|
{
|
||||||
@ -111,15 +118,18 @@ add_alias (char *rp)
|
|||||||
|
|
||||||
new_alias = (struct gconv_alias *)
|
new_alias = (struct gconv_alias *)
|
||||||
malloc (sizeof (struct gconv_alias) + (wp - from));
|
malloc (sizeof (struct gconv_alias) + (wp - from));
|
||||||
new_alias->fromname = memcpy ((char *) new_alias
|
if (new_alias != NULL)
|
||||||
+ sizeof (struct gconv_alias),
|
{
|
||||||
from, to - from);
|
new_alias->fromname = memcpy ((char *) new_alias
|
||||||
new_alias->toname = memcpy ((char *) new_alias + sizeof (struct gconv_alias)
|
+ sizeof (struct gconv_alias),
|
||||||
+ (to - from), to, wp - to);
|
from, wp - from);
|
||||||
|
new_alias->toname = new_alias->fromname + (to - from);
|
||||||
|
|
||||||
if (__tsearch (new_alias, &__gconv_alias_db, __gconv_alias_compare) == NULL)
|
if (__tsearch (new_alias, &__gconv_alias_db, __gconv_alias_compare)
|
||||||
/* Something went wrong, free this entry. */
|
== NULL)
|
||||||
free (new_alias);
|
/* Something went wrong, free this entry. */
|
||||||
|
free (new_alias);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -138,6 +148,7 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
|
|||||||
char *from, *to, *module, *wp;
|
char *from, *to, *module, *wp;
|
||||||
size_t const_len;
|
size_t const_len;
|
||||||
int from_is_regex;
|
int from_is_regex;
|
||||||
|
int need_ext;
|
||||||
int cost;
|
int cost;
|
||||||
|
|
||||||
while (isspace (*rp))
|
while (isspace (*rp))
|
||||||
@ -195,65 +206,68 @@ add_module (char *rp, const char *directory, size_t dir_len, void **modules,
|
|||||||
/* Increment by one for the slash. */
|
/* Increment by one for the slash. */
|
||||||
++dir_len;
|
++dir_len;
|
||||||
|
|
||||||
|
/* See whether we must add the ending. */
|
||||||
|
need_ext = 0;
|
||||||
|
if (wp - module < sizeof (gconv_module_ext)
|
||||||
|
|| memcmp (wp - sizeof (gconv_module_ext), gconv_module_ext,
|
||||||
|
sizeof (gconv_module_ext)) != 0)
|
||||||
|
/* We must add the module extension. */
|
||||||
|
need_ext = sizeof (gconv_module_ext) - 1;
|
||||||
|
|
||||||
/* We've collected all the information, now create an entry. */
|
/* We've collected all the information, now create an entry. */
|
||||||
|
|
||||||
const_len = 0;
|
|
||||||
if (from_is_regex)
|
if (from_is_regex)
|
||||||
do
|
{
|
||||||
++const_len;
|
const_len = 0;
|
||||||
while (isalnum (from[const_len]) || from[const_len] == '-'
|
while (isalnum (from[const_len]) || from[const_len] == '-'
|
||||||
|| from[const_len] == '/' || from[const_len] == '.'
|
|| from[const_len] == '/' || from[const_len] == '.'
|
||||||
|| from[const_len] == '_');
|
|| from[const_len] == '_')
|
||||||
|
++const_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
const_len = to - from - 1;
|
||||||
|
|
||||||
new_module = (struct gconv_module *) malloc (sizeof (struct gconv_module)
|
new_module = (struct gconv_module *) malloc (sizeof (struct gconv_module)
|
||||||
+ (wp - from) + const_len
|
+ (wp - from)
|
||||||
+ dir_len);
|
+ dir_len + need_ext);
|
||||||
if (new_module != NULL)
|
if (new_module != NULL)
|
||||||
{
|
{
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
|
new_module->from_constpfx = memcpy ((char *) new_module
|
||||||
|
+ sizeof (struct gconv_module),
|
||||||
|
from, to - from);
|
||||||
if (from_is_regex)
|
if (from_is_regex)
|
||||||
{
|
new_module->from_pattern = new_module->from_constpfx;
|
||||||
new_module->from_pattern = memcpy ((char *) new_module
|
|
||||||
+ sizeof (struct gconv_module),
|
|
||||||
from, to - from);
|
|
||||||
new_module->from_constpfx = memcpy ((char *) new_module->from_pattern
|
|
||||||
+ (to - from),
|
|
||||||
from, const_len);
|
|
||||||
((char *) new_module->from_constpfx)[const_len] = '\0';
|
|
||||||
new_module->from_constpfx_len = const_len;
|
|
||||||
++const_len;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
new_module->from_pattern = NULL;
|
||||||
new_module->from_pattern = NULL;
|
|
||||||
new_module->from_constpfx = memcpy ((char *) new_module
|
new_module->from_constpfx_len = const_len;
|
||||||
+ sizeof (struct gconv_module),
|
|
||||||
from, to - from);
|
|
||||||
new_module->from_constpfx_len = to - from - 1;
|
|
||||||
const_len = to - from;
|
|
||||||
}
|
|
||||||
new_module->from_regex = NULL;
|
new_module->from_regex = NULL;
|
||||||
|
|
||||||
new_module->to_string = memcpy ((char *) new_module->from_constpfx
|
new_module->to_string = memcpy ((char *) new_module->from_constpfx
|
||||||
+ const_len + 1, to, module - to);
|
+ (to - from), to, module - to);
|
||||||
|
|
||||||
new_module->cost = cost;
|
new_module->cost = cost;
|
||||||
|
|
||||||
|
new_module->module_name = (char *) new_module->to_string + (module - to);
|
||||||
|
|
||||||
if (dir_len == 0)
|
if (dir_len == 0)
|
||||||
new_module->module_name = memcpy ((char *) new_module->to_string
|
tmp = (char *) new_module->module_name;
|
||||||
+ (module - to),
|
|
||||||
module, wp - module);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *tmp;
|
|
||||||
new_module->module_name = ((char *) new_module->to_string
|
|
||||||
+ (module - to));
|
|
||||||
tmp = __mempcpy ((char *) new_module->module_name,
|
tmp = __mempcpy ((char *) new_module->module_name,
|
||||||
directory, dir_len - 1);
|
directory, dir_len - 1);
|
||||||
*tmp++ = '/';
|
*tmp++ = '/';
|
||||||
memcpy (tmp, module, wp - module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__tfind (new_module, *modules, module_compare) != NULL)
|
tmp = __mempcpy (tmp, module, wp - module);
|
||||||
|
|
||||||
|
if (need_ext)
|
||||||
|
memcpy (tmp - 1, gconv_module_ext, sizeof (gconv_module_ext));
|
||||||
|
|
||||||
|
if (__tfind (new_module, modules, module_compare) == NULL)
|
||||||
if (__tsearch (new_module, modules, module_compare) == NULL)
|
if (__tsearch (new_module, modules, module_compare) == NULL)
|
||||||
/* Something went wrong while inserting the new module. */
|
/* Something went wrong while inserting the new module. */
|
||||||
free (new_module);
|
free (new_module);
|
||||||
@ -267,7 +281,7 @@ static void
|
|||||||
insert_module (const void *nodep, VISIT value, int level)
|
insert_module (const void *nodep, VISIT value, int level)
|
||||||
{
|
{
|
||||||
if (value == preorder || value == leaf)
|
if (value == preorder || value == leaf)
|
||||||
__gconv_modules_db[__gconv_nmodules++] = (struct gconv_module *) nodep;
|
__gconv_modules_db[__gconv_nmodules++] = *(struct gconv_module **) nodep;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -302,8 +316,6 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
rp = line;
|
rp = line;
|
||||||
while (isspace (*rp))
|
|
||||||
++rp;
|
|
||||||
/* Terminate the line (excluding comments or newline) by an NUL byte
|
/* Terminate the line (excluding comments or newline) by an NUL byte
|
||||||
to simplify the following code. */
|
to simplify the following code. */
|
||||||
endp = strchr (rp, '#');
|
endp = strchr (rp, '#');
|
||||||
@ -316,6 +328,9 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
|
|||||||
*endp = '\0';
|
*endp = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (isspace (*rp))
|
||||||
|
++rp;
|
||||||
|
|
||||||
/* If this is an empty line go on with the next one. */
|
/* If this is an empty line go on with the next one. */
|
||||||
if (rp == endp)
|
if (rp == endp)
|
||||||
continue;
|
continue;
|
||||||
@ -325,10 +340,10 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
|
|||||||
++rp;
|
++rp;
|
||||||
|
|
||||||
if (rp - word == sizeof ("alias") - 1
|
if (rp - word == sizeof ("alias") - 1
|
||||||
&& memcpy (word, "alias", sizeof ("alias") - 1) == 0)
|
&& memcmp (word, "alias", sizeof ("alias") - 1) == 0)
|
||||||
add_alias (rp);
|
add_alias (rp);
|
||||||
else if (rp - word == sizeof ("module") - 1
|
else if (rp - word == sizeof ("module") - 1
|
||||||
&& memcpy (word, "module", sizeof ("module") - 1) == 0)
|
&& memcmp (word, "module", sizeof ("module") - 1) == 0)
|
||||||
add_module (rp, directory, dir_len, modules, nmodules);
|
add_module (rp, directory, dir_len, modules, nmodules);
|
||||||
/* else */
|
/* else */
|
||||||
/* Otherwise ignore the line. */
|
/* Otherwise ignore the line. */
|
||||||
@ -349,6 +364,7 @@ __gconv_read_conf (void)
|
|||||||
char *gconv_path, *elem;
|
char *gconv_path, *elem;
|
||||||
void *modules = NULL;
|
void *modules = NULL;
|
||||||
size_t nmodules = 0;
|
size_t nmodules = 0;
|
||||||
|
int save_errno = errno;
|
||||||
|
|
||||||
if (user_path == NULL)
|
if (user_path == NULL)
|
||||||
/* No user-defined path. Make a modifiable copy of the default path. */
|
/* No user-defined path. Make a modifiable copy of the default path. */
|
||||||
@ -390,31 +406,31 @@ __gconv_read_conf (void)
|
|||||||
|
|
||||||
/* If the configuration files do not contain any valid module specification
|
/* If the configuration files do not contain any valid module specification
|
||||||
remember this by setting the pointer to the module array to NULL. */
|
remember this by setting the pointer to the module array to NULL. */
|
||||||
nmodules = sizeof (builtin_modules) / sizeof (struct gconv_module);
|
nmodules += sizeof (builtin_modules) / sizeof (builtin_modules[0]);
|
||||||
if (nmodules == 0)
|
if (nmodules == 0)
|
||||||
|
__gconv_modules_db = NULL;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
__gconv_modules_db = NULL;
|
__gconv_modules_db =
|
||||||
return;
|
(struct gconv_module **) malloc (nmodules
|
||||||
|
* sizeof (struct gconv_module));
|
||||||
|
if (__gconv_modules_db != NULL)
|
||||||
|
{
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
|
/* Insert all module entries into the array. */
|
||||||
|
__twalk (modules, insert_module);
|
||||||
|
|
||||||
|
/* No remove the tree data structure. */
|
||||||
|
__tdestroy (modules, nothing);
|
||||||
|
|
||||||
|
/* Finally insert the builtin transformations. */
|
||||||
|
for (cnt = 0; cnt < (sizeof (builtin_modules)
|
||||||
|
/ sizeof (struct gconv_module)); ++cnt)
|
||||||
|
__gconv_modules_db[__gconv_nmodules++] = &builtin_modules[cnt];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__gconv_modules_db =
|
/* Restore the error number. */
|
||||||
(struct gconv_module **) malloc (nmodules * sizeof (struct gconv_module));
|
__set_errno (save_errno);
|
||||||
if (__gconv_modules_db == NULL)
|
|
||||||
/* We cannot do anything. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* First insert the builtin transformations. */
|
|
||||||
while (__gconv_nmodules < (sizeof (builtin_modules)
|
|
||||||
/ sizeof (struct gconv_module)))
|
|
||||||
{
|
|
||||||
__gconv_modules_db[__gconv_nmodules] =
|
|
||||||
&builtin_modules[__gconv_nmodules];
|
|
||||||
++__gconv_nmodules;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Insert all module entries into the array. */
|
|
||||||
__twalk (modules, insert_module);
|
|
||||||
|
|
||||||
/* No remove the tree data structure. */
|
|
||||||
__tdestroy (modules, nothing);
|
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ derivation_lookup (const char *fromset, const char *toset,
|
|||||||
struct known_derivation key = { fromset, toset, NULL, 0 };
|
struct known_derivation key = { fromset, toset, NULL, 0 };
|
||||||
struct known_derivation *result;
|
struct known_derivation *result;
|
||||||
|
|
||||||
result = __tfind (&key, known_derivations, derivation_compare);
|
result = __tfind (&key, &known_derivations, derivation_compare);
|
||||||
|
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return GCONV_NOCONV;
|
return GCONV_NOCONV;
|
||||||
@ -169,11 +169,18 @@ gen_steps (struct derivation_step *best, const char *toset,
|
|||||||
* step_cnt);
|
* step_cnt);
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
{
|
{
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
*nsteps = step_cnt;
|
||||||
current = best;
|
current = best;
|
||||||
while (step_cnt-- > 0)
|
while (step_cnt-- > 0)
|
||||||
{
|
{
|
||||||
result[step_cnt].from_name = current->last->result_set;
|
result[step_cnt].from_name = (step_cnt == 0
|
||||||
result[step_cnt].to_name = current->result_set;
|
? __strdup (fromset)
|
||||||
|
: current->last->result_set);
|
||||||
|
result[step_cnt].to_name = (step_cnt + 1 == *nsteps
|
||||||
|
? __strdup (current->result_set)
|
||||||
|
: result[step_cnt + 1].from_name);
|
||||||
|
|
||||||
if (current->code->module_name[0] == '/')
|
if (current->code->module_name[0] == '/')
|
||||||
{
|
{
|
||||||
@ -182,7 +189,10 @@ gen_steps (struct derivation_step *best, const char *toset,
|
|||||||
__gconv_find_shlib (current->code->module_name);
|
__gconv_find_shlib (current->code->module_name);
|
||||||
|
|
||||||
if (shlib_handle == NULL)
|
if (shlib_handle == NULL)
|
||||||
break;
|
{
|
||||||
|
failed = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
result[step_cnt].shlib_handle = shlib_handle;
|
result[step_cnt].shlib_handle = shlib_handle;
|
||||||
|
|
||||||
@ -192,6 +202,7 @@ gen_steps (struct derivation_step *best, const char *toset,
|
|||||||
/* Argh, no conversion function. There is something
|
/* Argh, no conversion function. There is something
|
||||||
wrong here. */
|
wrong here. */
|
||||||
__gconv_release_shlib (result[step_cnt].shlib_handle);
|
__gconv_release_shlib (result[step_cnt].shlib_handle);
|
||||||
|
failed = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,18 +219,18 @@ gen_steps (struct derivation_step *best, const char *toset,
|
|||||||
current = current->last;
|
current = current->last;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step_cnt != 0)
|
if (failed != 0)
|
||||||
{
|
{
|
||||||
/* Something went wrong while initializing the modules. */
|
/* Something went wrong while initializing the modules. */
|
||||||
while (step_cnt-- > 0)
|
while (++step_cnt < *nsteps)
|
||||||
__gconv_release_shlib (result[step_cnt].shlib_handle);
|
__gconv_release_shlib (result[step_cnt].shlib_handle);
|
||||||
free (result);
|
free (result);
|
||||||
|
*nsteps = 0;
|
||||||
status = GCONV_NOCONV;
|
status = GCONV_NOCONV;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*handle = result;
|
*handle = result;
|
||||||
*nsteps = step_cnt;
|
|
||||||
status = GCONV_OK;
|
status = GCONV_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -231,12 +242,13 @@ gen_steps (struct derivation_step *best, const char *toset,
|
|||||||
/* The main function: find a possible derivation from the `fromset' (either
|
/* The main function: find a possible derivation from the `fromset' (either
|
||||||
the given name or the alias) to the `toset' (again with alias). */
|
the given name or the alias) to the `toset' (again with alias). */
|
||||||
static int
|
static int
|
||||||
|
internal_function
|
||||||
find_derivation (const char *toset, const char *toset_expand,
|
find_derivation (const char *toset, const char *toset_expand,
|
||||||
const char *fromset, const char *fromset_expand,
|
const char *fromset, const char *fromset_expand,
|
||||||
struct gconv_step **handle, size_t *nsteps)
|
struct gconv_step **handle, size_t *nsteps)
|
||||||
{
|
{
|
||||||
__libc_lock_define_initialized (static, lock)
|
__libc_lock_define_initialized (static, lock)
|
||||||
struct derivation_step *current, **lastp, *best = NULL;
|
struct derivation_step *first, *current, **lastp, *best = NULL;
|
||||||
int best_cost = 0;
|
int best_cost = 0;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
@ -260,16 +272,17 @@ find_derivation (const char *toset, const char *toset_expand,
|
|||||||
The task is to match the `toset' with any of the available. */
|
The task is to match the `toset' with any of the available. */
|
||||||
if (fromset_expand != NULL)
|
if (fromset_expand != NULL)
|
||||||
{
|
{
|
||||||
current = NEW_STEP (fromset_expand, NULL, NULL);
|
first = NEW_STEP (fromset_expand, NULL, NULL);
|
||||||
current->next = NEW_STEP (fromset, NULL, NULL);
|
first->next = NEW_STEP (fromset, NULL, NULL);
|
||||||
lastp = ¤t->next->next;
|
lastp = &first->next->next;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current = NEW_STEP (fromset, NULL, NULL);
|
first = NEW_STEP (fromset, NULL, NULL);
|
||||||
lastp = ¤t->next;
|
lastp = &first->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current = first;
|
||||||
while (current != NULL)
|
while (current != NULL)
|
||||||
{
|
{
|
||||||
/* Now match all the available module specifications against the
|
/* Now match all the available module specifications against the
|
||||||
@ -419,13 +432,28 @@ find_derivation (const char *toset, const char *toset_expand,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Append at the end. */
|
/* Append at the end if there is no entry with this name. */
|
||||||
*lastp = NEW_STEP (result_set, __gconv_modules_db[cnt],
|
struct derivation_step *runp = first;
|
||||||
current);
|
|
||||||
lastp = &(*lastp)->next;
|
while (runp != NULL)
|
||||||
|
{
|
||||||
|
if (__strcasecmp (result_set, runp->result_set) == 0)
|
||||||
|
break;
|
||||||
|
runp = runp->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (runp == NULL)
|
||||||
|
{
|
||||||
|
*lastp = NEW_STEP (result_set, __gconv_modules_db[cnt],
|
||||||
|
current);
|
||||||
|
lastp = &(*lastp)->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Go on with the next entry. */
|
||||||
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best != NULL)
|
if (best != NULL)
|
||||||
@ -470,15 +498,15 @@ __gconv_find_transform (const char *toset, const char *fromset,
|
|||||||
if (__gconv_alias_db != NULL)
|
if (__gconv_alias_db != NULL)
|
||||||
{
|
{
|
||||||
struct gconv_alias key;
|
struct gconv_alias key;
|
||||||
struct gconv_alias *found;
|
struct gconv_alias **found;
|
||||||
|
|
||||||
key.fromname = fromset;
|
key.fromname = fromset;
|
||||||
found = __tfind (&key, __gconv_alias_db, __gconv_alias_compare);
|
found = __tfind (&key, &__gconv_alias_db, __gconv_alias_compare);
|
||||||
fromset_expand = found != NULL ? found->toname : NULL;
|
fromset_expand = found != NULL ? (*found)->toname : NULL;
|
||||||
|
|
||||||
key.fromname = toset;
|
key.fromname = toset;
|
||||||
found = __tfind (&key, __gconv_alias_db, __gconv_alias_compare);
|
found = __tfind (&key, &__gconv_alias_db, __gconv_alias_compare);
|
||||||
toset_expand = found != NULL ? found->toname : NULL;
|
toset_expand = found != NULL ? (*found)->toname : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = find_derivation (toset, toset_expand, fromset, fromset_expand,
|
result = find_derivation (toset, toset_expand, fromset, fromset_expand,
|
||||||
|
@ -84,6 +84,7 @@ do_open (void *a)
|
|||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
internal_function
|
||||||
dlerror_run (void (*operate) (void *), void *args)
|
dlerror_run (void (*operate) (void *), void *args)
|
||||||
{
|
{
|
||||||
char *last_errstring = NULL;
|
char *last_errstring = NULL;
|
||||||
@ -156,7 +157,7 @@ __gconv_find_shlib (const char *name)
|
|||||||
enough to a pointer to our structure to use as a lookup key that
|
enough to a pointer to our structure to use as a lookup key that
|
||||||
will be passed to `known_compare' (above). */
|
will be passed to `known_compare' (above). */
|
||||||
|
|
||||||
found = __tfind (&name, loaded, known_compare);
|
found = __tfind (&name, &loaded, known_compare);
|
||||||
if (found == NULL)
|
if (found == NULL)
|
||||||
{
|
{
|
||||||
/* This name was not known before. */
|
/* This name was not known before. */
|
||||||
@ -208,7 +209,7 @@ static void *release_handle;
|
|||||||
static void
|
static void
|
||||||
do_release_shlib (const void *nodep, VISIT value, int level)
|
do_release_shlib (const void *nodep, VISIT value, int level)
|
||||||
{
|
{
|
||||||
struct loaded_object *obj = (struct loaded_object *) nodep;
|
struct loaded_object *obj = *(struct loaded_object **) nodep;
|
||||||
|
|
||||||
if (value != preorder && value != leaf)
|
if (value != preorder && value != leaf)
|
||||||
return;
|
return;
|
||||||
|
@ -69,19 +69,19 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
|
|||||||
if (res != GCONV_OK)
|
if (res != GCONV_OK)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (!data[cnt].is_last)
|
if (!data[cnt].is_last && data[cnt].outbuf == NULL)
|
||||||
{
|
{
|
||||||
data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
|
data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
|
||||||
data[cnt].outbuf =
|
data[cnt].outbuf =
|
||||||
(char *) malloc (data[cnt].outbufsize);
|
(char *) malloc (data[cnt].outbufsize);
|
||||||
if (data[cnt].outbuf == NULL)
|
if (data[cnt].outbuf == NULL)
|
||||||
{
|
{
|
||||||
res = GCONV_NOMEM;
|
res = GCONV_NOMEM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
data[cnt].outbufavail = 0;
|
data[cnt].outbufavail = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
const char *newinbuf = inbuf;
|
const char *newinbuf = inbuf;
|
||||||
size_t actually = __wcsnrtombs (&data->outbuf[data->outbufavail],
|
size_t actually = __wmemrtombs (&data->outbuf[data->outbufavail],
|
||||||
(const wchar_t **) &newinbuf,
|
(const wchar_t **) &newinbuf,
|
||||||
*inlen / sizeof (wchar_t),
|
*inlen / sizeof (wchar_t),
|
||||||
data->outbufsize - data->outbufavail,
|
data->outbufsize - data->outbufavail,
|
||||||
@ -206,7 +206,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
const char *newinbuf = inbuf;
|
const char *newinbuf = inbuf;
|
||||||
size_t actually = __mbsnrtowcs ((wchar_t *) &data->outbuf[data->outbufavail],
|
size_t actually = __wmemrtowcs ((wchar_t *) &data->outbuf[data->outbufavail],
|
||||||
&newinbuf, *inlen,
|
&newinbuf, *inlen,
|
||||||
((data->outbufsize
|
((data->outbufsize
|
||||||
- data->outbufavail)
|
- data->outbufavail)
|
||||||
|
@ -19,9 +19,12 @@
|
|||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
#include <gconv.h>
|
#include <gconv.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
|
iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
|
||||||
@ -29,10 +32,39 @@ iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf,
|
|||||||
{
|
{
|
||||||
gconv_t gcd = (gconv_t) cd;
|
gconv_t gcd = (gconv_t) cd;
|
||||||
size_t converted;
|
size_t converted;
|
||||||
|
int result;
|
||||||
|
|
||||||
if (__gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted)
|
result = __gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted);
|
||||||
!= GCONV_OK)
|
switch (result)
|
||||||
return (size_t) -1;
|
{
|
||||||
|
case GCONV_ILLEGAL_DESCRIPTOR:
|
||||||
|
__set_errno (EBADF);
|
||||||
|
converted = (size_t) -1L;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GCONV_ILLEGAL_INPUT:
|
||||||
|
__set_errno (EILSEQ);
|
||||||
|
converted = (size_t) -1L;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GCONV_FULL_OUTPUT:
|
||||||
|
__set_errno (E2BIG);
|
||||||
|
converted = (size_t) -1L;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GCONV_INCOMPLETE_INPUT:
|
||||||
|
__set_errno (EINVAL);
|
||||||
|
converted = (size_t) -1L;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GCONV_EMPTY_INPUT:
|
||||||
|
case GCONV_OK:
|
||||||
|
/* Nothing. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert (!"Nothing like this should happen");
|
||||||
|
}
|
||||||
|
|
||||||
return converted;
|
return converted;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
Boston, MA 02111-1307, USA. */
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <iconv.h>
|
#include <iconv.h>
|
||||||
|
|
||||||
#include <gconv.h>
|
#include <gconv.h>
|
||||||
@ -26,5 +27,11 @@
|
|||||||
int
|
int
|
||||||
iconv_close (iconv_t cd)
|
iconv_close (iconv_t cd)
|
||||||
{
|
{
|
||||||
|
if (cd == (iconv_t *) -1L)
|
||||||
|
{
|
||||||
|
__set_errno (EBADF);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return __gconv_close ((gconv_t) cd) ? -1 : 0;
|
return __gconv_close ((gconv_t) cd) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,9 @@
|
|||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
strip (char *s)
|
strip (char *wp, const char *s)
|
||||||
{
|
{
|
||||||
int slash_count = 0;
|
int slash_count = 0;
|
||||||
char *wp;
|
|
||||||
wp = s;
|
|
||||||
|
|
||||||
while (*s != '\0')
|
while (*s != '\0')
|
||||||
{
|
{
|
||||||
@ -39,7 +37,7 @@ strip (char *s)
|
|||||||
*wp++ = *s;
|
*wp++ = *s;
|
||||||
else if (*s == '/')
|
else if (*s == '/')
|
||||||
{
|
{
|
||||||
if (++slash_count == 2)
|
if (++slash_count == 3)
|
||||||
break;
|
break;
|
||||||
*wp++ = '/';
|
*wp++ = '/';
|
||||||
}
|
}
|
||||||
@ -67,14 +65,15 @@ iconv_open (const char *tocode, const char *fromcode)
|
|||||||
'_', '-', '/', and '.'. */
|
'_', '-', '/', and '.'. */
|
||||||
tocode_len = strlen (tocode);
|
tocode_len = strlen (tocode);
|
||||||
tocode_conv = alloca (tocode_len + 3);
|
tocode_conv = alloca (tocode_len + 3);
|
||||||
strip (memcpy (tocode_conv, tocode, tocode_len + 1));
|
strip (tocode_conv, tocode);
|
||||||
|
|
||||||
fromcode_len = strlen (fromcode);
|
fromcode_len = strlen (fromcode);
|
||||||
fromcode_conv = alloca (fromcode_len + 3);
|
fromcode_conv = alloca (fromcode_len + 3);
|
||||||
strip (memcpy (fromcode_conv, fromcode, fromcode_len + 1));
|
strip (fromcode_conv, fromcode);
|
||||||
|
|
||||||
res = __gconv_open (tocode_conv[2] == '\0' ? tocode : tocode_conv,
|
res = __gconv_open (tocode_conv[2] == '\0' ? tocode : tocode_conv,
|
||||||
fromcode_conv[2] == '\0' ? fromcode, fromcode_conv, &cd);
|
fromcode_conv[2] == '\0' ? fromcode : fromcode_conv,
|
||||||
|
&cd);
|
||||||
|
|
||||||
if (res != GCONV_OK)
|
if (res != GCONV_OK)
|
||||||
{
|
{
|
||||||
|
@ -26,9 +26,8 @@
|
|||||||
/* Safest assumption, if somehow the initializer isn't run. */
|
/* Safest assumption, if somehow the initializer isn't run. */
|
||||||
int __libc_enable_secure = 1;
|
int __libc_enable_secure = 1;
|
||||||
|
|
||||||
static void
|
void
|
||||||
__attribute__ ((unused, constructor))
|
__libc_init_secure (void)
|
||||||
init_secure (void)
|
|
||||||
{
|
{
|
||||||
__libc_enable_secure = (__geteuid () != __getuid () ||
|
__libc_enable_secure = (__geteuid () != __getuid () ||
|
||||||
__getegid () != __getgid ());
|
__getegid () != __getgid ());
|
||||||
|
@ -29,7 +29,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
|
|||||||
wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy \
|
wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy \
|
||||||
btowc wctob mbsinit \
|
btowc wctob mbsinit \
|
||||||
mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
|
mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
|
||||||
mbsnrtowcs wcsnrtombs \
|
mbsnrtowcs wcsnrtombs wmemrtowcs wmemrtombs \
|
||||||
wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
|
wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
|
||||||
wcstol_l wcstoul_l wcstoll_l wcstoull_l \
|
wcstol_l wcstoul_l wcstoll_l wcstoull_l \
|
||||||
wcstod_l wcstold_l wcstof_l \
|
wcstod_l wcstold_l wcstof_l \
|
||||||
|
@ -253,6 +253,16 @@ extern size_t mbsnrtowcs __P ((wchar_t *__restrict __dst,
|
|||||||
__const char **__restrict __src, size_t __nmc,
|
__const char **__restrict __src, size_t __nmc,
|
||||||
size_t __len, mbstate_t *__restrict __ps));
|
size_t __len, mbstate_t *__restrict __ps));
|
||||||
|
|
||||||
|
/* Similar function to the above but this does not stop at NUL bytes. */
|
||||||
|
extern size_t __wmemrtowcs __P ((wchar_t *__restrict __dst,
|
||||||
|
__const char **__restrict __src,
|
||||||
|
size_t __nmc, size_t __len,
|
||||||
|
mbstate_t *__restrict __ps));
|
||||||
|
extern size_t wmemrtowcs __P ((wchar_t *__restrict __dst,
|
||||||
|
__const char **__restrict __src,
|
||||||
|
size_t __nmc, size_t __len,
|
||||||
|
mbstate_t *__restrict __ps));
|
||||||
|
|
||||||
/* Write multibyte character representation of at most NWC characters
|
/* Write multibyte character representation of at most NWC characters
|
||||||
from the wide character string SRC to DST. */
|
from the wide character string SRC to DST. */
|
||||||
extern size_t __wcsnrtombs __P ((char *__restrict __dst,
|
extern size_t __wcsnrtombs __P ((char *__restrict __dst,
|
||||||
@ -264,6 +274,16 @@ extern size_t wcsnrtombs __P ((char *__restrict __dst,
|
|||||||
size_t __nwc, size_t __len,
|
size_t __nwc, size_t __len,
|
||||||
mbstate_t *__restrict __ps));
|
mbstate_t *__restrict __ps));
|
||||||
|
|
||||||
|
/* Similar function to the above but this does not stop at NUL bytes. */
|
||||||
|
extern size_t __wmemrtombs __P ((char *__restrict __dst,
|
||||||
|
__const wchar_t **__restrict __src,
|
||||||
|
size_t __nwc, size_t len,
|
||||||
|
mbstate_t *__restrict __ps));
|
||||||
|
extern size_t wmemrtombs __P ((char *__restrict __dst,
|
||||||
|
__const wchar_t **__restrict __src,
|
||||||
|
size_t __nwc, size_t len,
|
||||||
|
mbstate_t *__restrict __ps));
|
||||||
|
|
||||||
|
|
||||||
/* The following functions are extensions found in X/Open CAE. */
|
/* The following functions are extensions found in X/Open CAE. */
|
||||||
|
|
||||||
|
121
wcsmbs/wmemrtombs.c
Normal file
121
wcsmbs/wmemrtombs.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* Copyright (C) 1997 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@gnu.org>, 1997.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||||
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#ifndef EILSEQ
|
||||||
|
#define EILSEQ EINVAL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static const wchar_t encoding_mask[] =
|
||||||
|
{
|
||||||
|
~0x7ff, ~0xffff, ~0x1fffff, ~0x3ffffff
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char encoding_byte[] =
|
||||||
|
{
|
||||||
|
0xc0, 0xe0, 0xf0, 0xf8, 0xfc
|
||||||
|
};
|
||||||
|
|
||||||
|
/* We don't need the state really because we don't have shift states
|
||||||
|
to maintain between calls to this function. */
|
||||||
|
static mbstate_t internal;
|
||||||
|
|
||||||
|
/* This is a non-standard function but it is very useful in the
|
||||||
|
implementation of stdio because we have to deal with unterminated
|
||||||
|
buffers. At most NWC wide character will be converted. */
|
||||||
|
size_t
|
||||||
|
__wmemrtombs (dst, src, nwc, len, ps)
|
||||||
|
char *dst;
|
||||||
|
const wchar_t **src;
|
||||||
|
size_t nwc;
|
||||||
|
size_t len;
|
||||||
|
mbstate_t *ps;
|
||||||
|
{
|
||||||
|
size_t written = 0;
|
||||||
|
const wchar_t *run = *src;
|
||||||
|
|
||||||
|
if (ps == NULL)
|
||||||
|
ps = &internal;
|
||||||
|
|
||||||
|
if (dst == NULL)
|
||||||
|
/* The LEN parameter has to be ignored if we don't actually write
|
||||||
|
anything. */
|
||||||
|
len = ~0;
|
||||||
|
|
||||||
|
while (written < len && nwc-- > 0)
|
||||||
|
{
|
||||||
|
wchar_t wc = *run++;
|
||||||
|
|
||||||
|
if (wc < 0 || wc > 0x7fffffff)
|
||||||
|
{
|
||||||
|
/* This is no correct ISO 10646 character. */
|
||||||
|
__set_errno (EILSEQ);
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wc < 0x80)
|
||||||
|
{
|
||||||
|
/* It's an one byte sequence. */
|
||||||
|
if (dst != NULL)
|
||||||
|
*dst++ = (char) wc;
|
||||||
|
++written;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t step;
|
||||||
|
|
||||||
|
for (step = 2; step < 6; ++step)
|
||||||
|
if ((wc & encoding_mask[step - 2]) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (written + step >= len)
|
||||||
|
/* Too long. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (dst != NULL)
|
||||||
|
{
|
||||||
|
size_t cnt = step;
|
||||||
|
|
||||||
|
dst[0] = encoding_byte[cnt - 2];
|
||||||
|
|
||||||
|
--cnt;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
dst[cnt] = 0x80 | (wc & 0x3f);
|
||||||
|
wc >>= 6;
|
||||||
|
}
|
||||||
|
while (--cnt > 0);
|
||||||
|
dst[0] |= wc;
|
||||||
|
|
||||||
|
dst += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
written += step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store position of first unprocessed word. */
|
||||||
|
*src = run;
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
weak_alias (__wmemrtombs, wmemrtombs)
|
134
wcsmbs/wmemrtowcs.c
Normal file
134
wcsmbs/wmemrtowcs.c
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
/* Copyright (C) 1997 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@gnu.org>, 1997.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public License as
|
||||||
|
published by the Free Software Foundation; either version 2 of the
|
||||||
|
License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||||
|
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#ifndef EILSEQ
|
||||||
|
#define EILSEQ EINVAL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* We don't need the state really because we don't have shift states
|
||||||
|
to maintain between calls to this function. */
|
||||||
|
static mbstate_t internal;
|
||||||
|
|
||||||
|
/* This is a non-standard function but it is very useful in the
|
||||||
|
implementation of stdio because we have to deal with unterminated
|
||||||
|
buffers. At most NMC bytes will be converted. */
|
||||||
|
size_t
|
||||||
|
__wmemrtowcs (dst, src, nmc, len, ps)
|
||||||
|
wchar_t *dst;
|
||||||
|
const char **src;
|
||||||
|
size_t nmc;
|
||||||
|
size_t len;
|
||||||
|
mbstate_t *ps;
|
||||||
|
{
|
||||||
|
size_t written = 0;
|
||||||
|
const char *run = *src;
|
||||||
|
const char *last = run + nmc;
|
||||||
|
|
||||||
|
if (ps == NULL)
|
||||||
|
ps = &internal;
|
||||||
|
|
||||||
|
if (dst == NULL)
|
||||||
|
/* The LEN parameter has to be ignored if we don't actually write
|
||||||
|
anything. */
|
||||||
|
len = ~0;
|
||||||
|
|
||||||
|
/* Copy all words. */
|
||||||
|
while (written < len && run < last)
|
||||||
|
{
|
||||||
|
wchar_t value;
|
||||||
|
size_t count;
|
||||||
|
unsigned char byte = *run++;
|
||||||
|
|
||||||
|
/* We expect a start of a new multibyte character. */
|
||||||
|
if (byte < 0x80)
|
||||||
|
{
|
||||||
|
/* One byte sequence. */
|
||||||
|
count = 0;
|
||||||
|
value = byte;
|
||||||
|
}
|
||||||
|
else if ((byte & 0xe0) == 0xc0)
|
||||||
|
{
|
||||||
|
count = 1;
|
||||||
|
value = byte & 0x1f;
|
||||||
|
}
|
||||||
|
else if ((byte & 0xf0) == 0xe0)
|
||||||
|
{
|
||||||
|
/* We expect three bytes. */
|
||||||
|
count = 2;
|
||||||
|
value = byte & 0x0f;
|
||||||
|
}
|
||||||
|
else if ((byte & 0xf8) == 0xf0)
|
||||||
|
{
|
||||||
|
/* We expect four bytes. */
|
||||||
|
count = 3;
|
||||||
|
value = byte & 0x07;
|
||||||
|
}
|
||||||
|
else if ((byte & 0xfc) == 0xf8)
|
||||||
|
{
|
||||||
|
/* We expect five bytes. */
|
||||||
|
count = 4;
|
||||||
|
value = byte & 0x03;
|
||||||
|
}
|
||||||
|
else if ((byte & 0xfe) == 0xfc)
|
||||||
|
{
|
||||||
|
/* We expect six bytes. */
|
||||||
|
count = 5;
|
||||||
|
value = byte & 0x01;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is an illegal encoding. */
|
||||||
|
__set_errno (EILSEQ);
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the possible remaining bytes. */
|
||||||
|
while (count-- > 0)
|
||||||
|
{
|
||||||
|
byte = *run++;
|
||||||
|
|
||||||
|
if ((byte & 0xc0) != 0x80)
|
||||||
|
{
|
||||||
|
/* This is an illegal encoding. */
|
||||||
|
__set_errno (EILSEQ);
|
||||||
|
return (size_t) -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
value <<= 6;
|
||||||
|
value |= byte & 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store value is required. */
|
||||||
|
if (dst != NULL)
|
||||||
|
*dst++ = value;
|
||||||
|
|
||||||
|
/* Increment counter of produced words. */
|
||||||
|
++written;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store address of next byte to process. */
|
||||||
|
*src = run;
|
||||||
|
|
||||||
|
return written;
|
||||||
|
}
|
||||||
|
weak_alias (__wmemrtowcs, wmemrtowcs)
|
Loading…
Reference in New Issue
Block a user