mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-18 08:51:06 +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>
|
||||
|
||||
* iconv/gconv_simple.c: Fix lots of bugs.
|
||||
|
@ -46,6 +46,8 @@ struct r_search_path *_dl_search_paths;
|
||||
const char *_dl_profile;
|
||||
struct link_map *_dl_profile_map;
|
||||
|
||||
extern void __libc_init_secure (void);
|
||||
|
||||
|
||||
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_pagesize = __getpagesize ();
|
||||
|
||||
__libc_init_secure ();
|
||||
|
||||
/* Initialize the data structures for the search paths for shared
|
||||
objects. */
|
||||
_dl_init_paths ();
|
||||
@ -65,7 +71,5 @@ non_dynamic_init (void)
|
||||
/* Now determine the length of the platform string. */
|
||||
if (_dl_platform != NULL)
|
||||
_dl_platformlen = strlen (_dl_platform);
|
||||
|
||||
_dl_pagesize = __getpagesize ();
|
||||
}
|
||||
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;
|
||||
int result;
|
||||
|
||||
if (cd == (gconv_t) -1L)
|
||||
return GCONV_ILLEGAL_DESCRIPTOR;
|
||||
|
||||
cd->data[last_step].outbuf = *outbuf;
|
||||
cd->data[last_step].outbufavail = 0;
|
||||
cd->data[last_step].outbufsize = *outbytesleft;
|
||||
|
@ -37,6 +37,7 @@ enum
|
||||
GCONV_EMPTY_INPUT,
|
||||
GCONV_FULL_OUTPUT,
|
||||
GCONV_ILLEGAL_INPUT,
|
||||
GCONV_INCOMPLETE_INPUT,
|
||||
|
||||
GCONV_ILLEGAL_DESCRIPTOR,
|
||||
GCONV_INTERNAL_ERROR
|
||||
|
@ -18,17 +18,17 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
BUILTIN_TRANSFORMATION ("\\([^/]+\\)/UCS4/\\([^/]*\\)", NULL, 0,
|
||||
BUILTIN_TRANSFORMATION ("([^/]+)/UCS4/([^/]*)", NULL, 0,
|
||||
"\\1/UTF8/\\2", 1, "=ucs4->utf8",
|
||||
__gconv_transform_ucs4_utf8,
|
||||
__gconv_transform_init_rstate,
|
||||
__gconv_transform_end_rstate)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("\\([^/]+\\)/UTF8/\\([^/]*\\)", NULL, 0,
|
||||
BUILTIN_TRANSFORMATION ("([^/]+)/UTF8/([^/]*)", NULL, 0,
|
||||
"\\1/UCS4/\\2", 1, "=utf8->ucs4",
|
||||
__gconv_transform_utf8_ucs4,
|
||||
__gconv_transform_init_rstate,
|
||||
__gconv_transform_end_rstate)
|
||||
|
||||
BUILTIN_TRANSFORMATION ("\\(.*\\)", NULL, 0, "\\1", 1, "=dummy",
|
||||
BUILTIN_TRANSFORMATION ("(.*)", NULL, 0, "\\1", 1, "=dummy",
|
||||
__gconv_transform_dummy, NULL, NULL)
|
||||
|
@ -48,9 +48,8 @@ __gconv_close (gconv_t cd)
|
||||
|
||||
/* Next step. */
|
||||
++srunp;
|
||||
++drunp;
|
||||
}
|
||||
while (!drunp->is_last);
|
||||
while (!(drunp++)->is_last);
|
||||
|
||||
/* Save the pointer, we need it below. */
|
||||
srunp = cd->steps;
|
||||
|
@ -19,6 +19,7 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <gconv.h>
|
||||
#include <search.h>
|
||||
#include <stdio.h>
|
||||
@ -35,6 +36,12 @@ static const char default_gconv_path[] = GCONV_PATH;
|
||||
along the path. */
|
||||
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. */
|
||||
static struct gconv_module builtin_modules[] =
|
||||
{
|
||||
@ -111,15 +118,18 @@ add_alias (char *rp)
|
||||
|
||||
new_alias = (struct gconv_alias *)
|
||||
malloc (sizeof (struct gconv_alias) + (wp - from));
|
||||
new_alias->fromname = memcpy ((char *) new_alias
|
||||
+ sizeof (struct gconv_alias),
|
||||
from, to - from);
|
||||
new_alias->toname = memcpy ((char *) new_alias + sizeof (struct gconv_alias)
|
||||
+ (to - from), to, wp - to);
|
||||
if (new_alias != NULL)
|
||||
{
|
||||
new_alias->fromname = memcpy ((char *) new_alias
|
||||
+ sizeof (struct gconv_alias),
|
||||
from, wp - from);
|
||||
new_alias->toname = new_alias->fromname + (to - from);
|
||||
|
||||
if (__tsearch (new_alias, &__gconv_alias_db, __gconv_alias_compare) == NULL)
|
||||
/* Something went wrong, free this entry. */
|
||||
free (new_alias);
|
||||
if (__tsearch (new_alias, &__gconv_alias_db, __gconv_alias_compare)
|
||||
== NULL)
|
||||
/* 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;
|
||||
size_t const_len;
|
||||
int from_is_regex;
|
||||
int need_ext;
|
||||
int cost;
|
||||
|
||||
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. */
|
||||
++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. */
|
||||
|
||||
const_len = 0;
|
||||
if (from_is_regex)
|
||||
do
|
||||
++const_len;
|
||||
while (isalnum (from[const_len]) || from[const_len] == '-'
|
||||
|| from[const_len] == '/' || from[const_len] == '.'
|
||||
|| from[const_len] == '_');
|
||||
{
|
||||
const_len = 0;
|
||||
while (isalnum (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)
|
||||
+ (wp - from) + const_len
|
||||
+ dir_len);
|
||||
+ (wp - from)
|
||||
+ dir_len + need_ext);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
new_module->from_pattern = new_module->from_constpfx;
|
||||
else
|
||||
{
|
||||
new_module->from_pattern = NULL;
|
||||
new_module->from_constpfx = memcpy ((char *) new_module
|
||||
+ sizeof (struct gconv_module),
|
||||
from, to - from);
|
||||
new_module->from_constpfx_len = to - from - 1;
|
||||
const_len = to - from;
|
||||
}
|
||||
new_module->from_pattern = NULL;
|
||||
|
||||
new_module->from_constpfx_len = const_len;
|
||||
|
||||
new_module->from_regex = NULL;
|
||||
|
||||
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->module_name = (char *) new_module->to_string + (module - to);
|
||||
|
||||
if (dir_len == 0)
|
||||
new_module->module_name = memcpy ((char *) new_module->to_string
|
||||
+ (module - to),
|
||||
module, wp - module);
|
||||
tmp = (char *) new_module->module_name;
|
||||
else
|
||||
{
|
||||
char *tmp;
|
||||
new_module->module_name = ((char *) new_module->to_string
|
||||
+ (module - to));
|
||||
tmp = __mempcpy ((char *) new_module->module_name,
|
||||
directory, dir_len - 1);
|
||||
*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)
|
||||
/* Something went wrong while inserting the new module. */
|
||||
free (new_module);
|
||||
@ -267,7 +281,7 @@ static void
|
||||
insert_module (const void *nodep, VISIT value, int level)
|
||||
{
|
||||
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
|
||||
@ -302,8 +316,6 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
|
||||
break;
|
||||
|
||||
rp = line;
|
||||
while (isspace (*rp))
|
||||
++rp;
|
||||
/* Terminate the line (excluding comments or newline) by an NUL byte
|
||||
to simplify the following code. */
|
||||
endp = strchr (rp, '#');
|
||||
@ -316,6 +328,9 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
|
||||
*endp = '\0';
|
||||
}
|
||||
|
||||
while (isspace (*rp))
|
||||
++rp;
|
||||
|
||||
/* If this is an empty line go on with the next one. */
|
||||
if (rp == endp)
|
||||
continue;
|
||||
@ -325,10 +340,10 @@ read_conf_file (const char *filename, const char *directory, size_t dir_len,
|
||||
++rp;
|
||||
|
||||
if (rp - word == sizeof ("alias") - 1
|
||||
&& memcpy (word, "alias", sizeof ("alias") - 1) == 0)
|
||||
&& memcmp (word, "alias", sizeof ("alias") - 1) == 0)
|
||||
add_alias (rp);
|
||||
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);
|
||||
/* else */
|
||||
/* Otherwise ignore the line. */
|
||||
@ -349,6 +364,7 @@ __gconv_read_conf (void)
|
||||
char *gconv_path, *elem;
|
||||
void *modules = NULL;
|
||||
size_t nmodules = 0;
|
||||
int save_errno = errno;
|
||||
|
||||
if (user_path == NULL)
|
||||
/* 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
|
||||
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)
|
||||
__gconv_modules_db = NULL;
|
||||
else
|
||||
{
|
||||
__gconv_modules_db = NULL;
|
||||
return;
|
||||
__gconv_modules_db =
|
||||
(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 =
|
||||
(struct gconv_module **) malloc (nmodules * sizeof (struct gconv_module));
|
||||
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);
|
||||
/* Restore the error number. */
|
||||
__set_errno (save_errno);
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ derivation_lookup (const char *fromset, const char *toset,
|
||||
struct known_derivation key = { fromset, toset, NULL, 0 };
|
||||
struct known_derivation *result;
|
||||
|
||||
result = __tfind (&key, known_derivations, derivation_compare);
|
||||
result = __tfind (&key, &known_derivations, derivation_compare);
|
||||
|
||||
if (result == NULL)
|
||||
return GCONV_NOCONV;
|
||||
@ -169,11 +169,18 @@ gen_steps (struct derivation_step *best, const char *toset,
|
||||
* step_cnt);
|
||||
if (result != NULL)
|
||||
{
|
||||
int failed = 0;
|
||||
|
||||
*nsteps = step_cnt;
|
||||
current = best;
|
||||
while (step_cnt-- > 0)
|
||||
{
|
||||
result[step_cnt].from_name = current->last->result_set;
|
||||
result[step_cnt].to_name = current->result_set;
|
||||
result[step_cnt].from_name = (step_cnt == 0
|
||||
? __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] == '/')
|
||||
{
|
||||
@ -182,7 +189,10 @@ gen_steps (struct derivation_step *best, const char *toset,
|
||||
__gconv_find_shlib (current->code->module_name);
|
||||
|
||||
if (shlib_handle == NULL)
|
||||
break;
|
||||
{
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
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
|
||||
wrong here. */
|
||||
__gconv_release_shlib (result[step_cnt].shlib_handle);
|
||||
failed = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -208,18 +219,18 @@ gen_steps (struct derivation_step *best, const char *toset,
|
||||
current = current->last;
|
||||
}
|
||||
|
||||
if (step_cnt != 0)
|
||||
if (failed != 0)
|
||||
{
|
||||
/* Something went wrong while initializing the modules. */
|
||||
while (step_cnt-- > 0)
|
||||
while (++step_cnt < *nsteps)
|
||||
__gconv_release_shlib (result[step_cnt].shlib_handle);
|
||||
free (result);
|
||||
*nsteps = 0;
|
||||
status = GCONV_NOCONV;
|
||||
}
|
||||
else
|
||||
{
|
||||
*handle = result;
|
||||
*nsteps = step_cnt;
|
||||
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 given name or the alias) to the `toset' (again with alias). */
|
||||
static int
|
||||
internal_function
|
||||
find_derivation (const char *toset, const char *toset_expand,
|
||||
const char *fromset, const char *fromset_expand,
|
||||
struct gconv_step **handle, size_t *nsteps)
|
||||
{
|
||||
__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 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. */
|
||||
if (fromset_expand != NULL)
|
||||
{
|
||||
current = NEW_STEP (fromset_expand, NULL, NULL);
|
||||
current->next = NEW_STEP (fromset, NULL, NULL);
|
||||
lastp = ¤t->next->next;
|
||||
first = NEW_STEP (fromset_expand, NULL, NULL);
|
||||
first->next = NEW_STEP (fromset, NULL, NULL);
|
||||
lastp = &first->next->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
current = NEW_STEP (fromset, NULL, NULL);
|
||||
lastp = ¤t->next;
|
||||
first = NEW_STEP (fromset, NULL, NULL);
|
||||
lastp = &first->next;
|
||||
}
|
||||
|
||||
current = first;
|
||||
while (current != NULL)
|
||||
{
|
||||
/* Now match all the available module specifications against the
|
||||
@ -419,13 +432,28 @@ find_derivation (const char *toset, const char *toset_expand,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Append at the end. */
|
||||
*lastp = NEW_STEP (result_set, __gconv_modules_db[cnt],
|
||||
current);
|
||||
lastp = &(*lastp)->next;
|
||||
/* Append at the end if there is no entry with this name. */
|
||||
struct derivation_step *runp = first;
|
||||
|
||||
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)
|
||||
@ -470,15 +498,15 @@ __gconv_find_transform (const char *toset, const char *fromset,
|
||||
if (__gconv_alias_db != NULL)
|
||||
{
|
||||
struct gconv_alias key;
|
||||
struct gconv_alias *found;
|
||||
struct gconv_alias **found;
|
||||
|
||||
key.fromname = fromset;
|
||||
found = __tfind (&key, __gconv_alias_db, __gconv_alias_compare);
|
||||
fromset_expand = found != NULL ? found->toname : NULL;
|
||||
found = __tfind (&key, &__gconv_alias_db, __gconv_alias_compare);
|
||||
fromset_expand = found != NULL ? (*found)->toname : NULL;
|
||||
|
||||
key.fromname = toset;
|
||||
found = __tfind (&key, __gconv_alias_db, __gconv_alias_compare);
|
||||
toset_expand = found != NULL ? found->toname : NULL;
|
||||
found = __tfind (&key, &__gconv_alias_db, __gconv_alias_compare);
|
||||
toset_expand = found != NULL ? (*found)->toname : NULL;
|
||||
}
|
||||
|
||||
result = find_derivation (toset, toset_expand, fromset, fromset_expand,
|
||||
|
@ -84,6 +84,7 @@ do_open (void *a)
|
||||
|
||||
|
||||
static int
|
||||
internal_function
|
||||
dlerror_run (void (*operate) (void *), void *args)
|
||||
{
|
||||
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
|
||||
will be passed to `known_compare' (above). */
|
||||
|
||||
found = __tfind (&name, loaded, known_compare);
|
||||
found = __tfind (&name, &loaded, known_compare);
|
||||
if (found == NULL)
|
||||
{
|
||||
/* This name was not known before. */
|
||||
@ -208,7 +209,7 @@ static void *release_handle;
|
||||
static void
|
||||
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)
|
||||
return;
|
||||
|
@ -69,19 +69,19 @@ __gconv_open (const char *toset, const char *fromset, gconv_t *handle)
|
||||
if (res != GCONV_OK)
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (!data[cnt].is_last)
|
||||
{
|
||||
data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
|
||||
data[cnt].outbuf =
|
||||
(char *) malloc (data[cnt].outbufsize);
|
||||
if (data[cnt].outbuf == NULL)
|
||||
{
|
||||
res = GCONV_NOMEM;
|
||||
break;
|
||||
}
|
||||
data[cnt].outbufavail = 0;
|
||||
}
|
||||
|
||||
if (!data[cnt].is_last && data[cnt].outbuf == NULL)
|
||||
{
|
||||
data[cnt].outbufsize = GCONV_DEFAULT_BUFSIZE;
|
||||
data[cnt].outbuf =
|
||||
(char *) malloc (data[cnt].outbufsize);
|
||||
if (data[cnt].outbuf == NULL)
|
||||
{
|
||||
res = GCONV_NOMEM;
|
||||
break;
|
||||
}
|
||||
data[cnt].outbufavail = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ __gconv_transform_ucs4_utf8 (struct gconv_step *step,
|
||||
do
|
||||
{
|
||||
const char *newinbuf = inbuf;
|
||||
size_t actually = __wcsnrtombs (&data->outbuf[data->outbufavail],
|
||||
size_t actually = __wmemrtombs (&data->outbuf[data->outbufavail],
|
||||
(const wchar_t **) &newinbuf,
|
||||
*inlen / sizeof (wchar_t),
|
||||
data->outbufsize - data->outbufavail,
|
||||
@ -206,7 +206,7 @@ __gconv_transform_utf8_ucs4 (struct gconv_step *step,
|
||||
do
|
||||
{
|
||||
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,
|
||||
((data->outbufsize
|
||||
- data->outbufavail)
|
||||
|
@ -19,9 +19,12 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <iconv.h>
|
||||
#include <gconv.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
size_t
|
||||
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;
|
||||
size_t converted;
|
||||
int result;
|
||||
|
||||
if (__gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted)
|
||||
!= GCONV_OK)
|
||||
return (size_t) -1;
|
||||
result = __gconv (gcd, inbuf, inbytesleft, outbuf, outbytesleft, &converted);
|
||||
switch (result)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <iconv.h>
|
||||
|
||||
#include <gconv.h>
|
||||
@ -26,5 +27,11 @@
|
||||
int
|
||||
iconv_close (iconv_t cd)
|
||||
{
|
||||
if (cd == (iconv_t *) -1L)
|
||||
{
|
||||
__set_errno (EBADF);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return __gconv_close ((gconv_t) cd) ? -1 : 0;
|
||||
}
|
||||
|
@ -27,11 +27,9 @@
|
||||
|
||||
|
||||
static inline void
|
||||
strip (char *s)
|
||||
strip (char *wp, const char *s)
|
||||
{
|
||||
int slash_count = 0;
|
||||
char *wp;
|
||||
wp = s;
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
@ -39,7 +37,7 @@ strip (char *s)
|
||||
*wp++ = *s;
|
||||
else if (*s == '/')
|
||||
{
|
||||
if (++slash_count == 2)
|
||||
if (++slash_count == 3)
|
||||
break;
|
||||
*wp++ = '/';
|
||||
}
|
||||
@ -67,14 +65,15 @@ iconv_open (const char *tocode, const char *fromcode)
|
||||
'_', '-', '/', and '.'. */
|
||||
tocode_len = strlen (tocode);
|
||||
tocode_conv = alloca (tocode_len + 3);
|
||||
strip (memcpy (tocode_conv, tocode, tocode_len + 1));
|
||||
strip (tocode_conv, tocode);
|
||||
|
||||
fromcode_len = strlen (fromcode);
|
||||
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,
|
||||
fromcode_conv[2] == '\0' ? fromcode, fromcode_conv, &cd);
|
||||
fromcode_conv[2] == '\0' ? fromcode : fromcode_conv,
|
||||
&cd);
|
||||
|
||||
if (res != GCONV_OK)
|
||||
{
|
||||
|
@ -26,9 +26,8 @@
|
||||
/* Safest assumption, if somehow the initializer isn't run. */
|
||||
int __libc_enable_secure = 1;
|
||||
|
||||
static void
|
||||
__attribute__ ((unused, constructor))
|
||||
init_secure (void)
|
||||
void
|
||||
__libc_init_secure (void)
|
||||
{
|
||||
__libc_enable_secure = (__geteuid () != __getuid () ||
|
||||
__getegid () != __getgid ());
|
||||
|
@ -29,7 +29,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
|
||||
wmemcmp wmemcpy wmemmove wmemset wcpcpy wcpncpy \
|
||||
btowc wctob mbsinit \
|
||||
mbrlen mbrtowc wcrtomb mbsrtowcs wcsrtombs \
|
||||
mbsnrtowcs wcsnrtombs \
|
||||
mbsnrtowcs wcsnrtombs wmemrtowcs wmemrtombs \
|
||||
wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
|
||||
wcstol_l wcstoul_l wcstoll_l wcstoull_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,
|
||||
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
|
||||
from the wide character string SRC to 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,
|
||||
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. */
|
||||
|
||||
|
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