diff options
Diffstat (limited to 'iconv')
-rw-r--r-- | iconv/gconv_cache.c | 128 | ||||
-rw-r--r-- | iconv/iconvconfig.c | 23 |
2 files changed, 94 insertions, 57 deletions
diff --git a/iconv/gconv_cache.c b/iconv/gconv_cache.c index 42f41ef3d6..498993db82 100644 --- a/iconv/gconv_cache.c +++ b/iconv/gconv_cache.c @@ -178,7 +178,7 @@ find_module (const char *directory, const char *filename, size_t dirlen = strlen (directory); size_t fnamelen = strlen (filename) + 1; char *fullname; - int status = __GCONV_OK; + int status = __GCONV_NOCONV; fullname = (char *) malloc (dirlen + fnamelen); if (fullname == NULL) @@ -187,17 +187,22 @@ find_module (const char *directory, const char *filename, memcpy (__mempcpy (fullname, directory, dirlen), filename, fnamelen); result->__shlib_handle = __gconv_find_shlib (fullname); - if (result->__shlib_handle == NULL) - return __GCONV_NOCONV; + if (result->__shlib_handle != NULL) + { + status = __GCONV_OK; + + result->__modname = fullname; + result->__fct = result->__shlib_handle->fct; + result->__init_fct = result->__shlib_handle->init_fct; + result->__end_fct = result->__shlib_handle->end_fct; - result->__modname = fullname; - result->__fct = result->__shlib_handle->fct; - result->__init_fct = result->__shlib_handle->init_fct; - result->__end_fct = result->__shlib_handle->end_fct; + result->__data = NULL; + if (result->__init_fct != NULL) + status = DL_CALL_FCT (result->__init_fct, (result)); + } - result->__data = NULL; - if (result->__init_fct != NULL) - status = DL_CALL_FCT (result->__init_fct, (result)); + if (__builtin_expect (status, __GCONV_OK) != __GCONV_OK) + free (fullname); return status; } @@ -235,7 +240,8 @@ __gconv_lookup_cache (const char *toset, const char *fromset, if (find_module_idx (toset, &toidx) != 0 || (header->module_offset + (toidx + 1) * sizeof (struct module_entry) > cache_size)) - return __GCONV_NOCONV; + {puts("toset not found"); + return __GCONV_NOCONV;} to_module = &modtab[toidx]; /* Avoid copy-only transformations if the user requests. */ @@ -243,7 +249,8 @@ __gconv_lookup_cache (const char *toset, const char *fromset, return __GCONV_NOCONV; /* If there are special conversions available examine them first. */ - if (__builtin_expect (from_module->extra_offset, 0) != 0) + if (fromidx != 0 && toidx != 0 + && __builtin_expect (from_module->extra_offset, 0) != 0) { /* Search through the list to see whether there is a module matching the destination character set. */ @@ -317,8 +324,8 @@ __gconv_lookup_cache (const char *toset, const char *fromset, try_internal: /* See whether we can convert via the INTERNAL charset. */ - if (__builtin_expect (from_module->fromname_offset, 1) == 0 - || __builtin_expect (to_module->toname_offset, 1) == 0) + if ((fromidx != 0 && __builtin_expect (from_module->fromname_offset, 1) == 0) + || (toidx != 0 && __builtin_expect (to_module->toname_offset, 1) == 0)) /* Not possible. Nothing we can do. */ return __GCONV_NOCONV; @@ -328,62 +335,75 @@ __gconv_lookup_cache (const char *toset, const char *fromset, return __GCONV_NOMEM; *handle = result; - *nsteps = 2; + *nsteps = 0; /* Generate data structure for conversion to INTERNAL. */ - result[0].__from_name = (char *) strtab + from_module->canonname_offset; - result[0].__to_name = (char *) "INTERNAL"; + if (fromidx != 0) + { + result[0].__from_name = (char *) strtab + from_module->canonname_offset; + result[0].__to_name = (char *) "INTERNAL"; - result[0].__counter = 1; - result[0].__data = NULL; + result[0].__counter = 1; + result[0].__data = NULL; #ifndef STATIC_GCONV - if (strtab[from_module->todir_offset] != '\0') - { - /* Load the module, return handle for it. */ - int res = find_module (strtab + from_module->todir_offset, - strtab + from_module->toname_offset, - &result[0]); - if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) + if (strtab[from_module->todir_offset] != '\0') { - /* Something went wrong. */ - free (result); - return res; + /* Load the module, return handle for it. */ + int res = find_module (strtab + from_module->todir_offset, + strtab + from_module->toname_offset, + &result[0]); + if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) + { + /* Something went wrong. */ + free (result); + return res; + } } - } - else + else #endif - /* It's a builtin transformation. */ - __gconv_get_builtin_trans (strtab + from_module->toname_offset, - &result[0]); + /* It's a builtin transformation. */ + __gconv_get_builtin_trans (strtab + from_module->toname_offset, + &result[0]); + + ++*nsteps; + } /* Generate data structure for conversion from INTERNAL. */ - result[1].__from_name = (char *) "INTERNAL"; - result[1].__to_name = (char *) strtab + to_module->canonname_offset; + if (toidx != 0) + { + int idx = *nsteps; - result[1].__counter = 1; - result[1].__data = NULL; + result[idx].__from_name = (char *) "INTERNAL"; + result[idx].__to_name = (char *) strtab + to_module->canonname_offset; + + result[idx].__counter = 1; + result[idx].__data = NULL; #ifndef STATIC_GCONV - if (strtab[to_module->fromdir_offset] != '\0') - { - /* Load the module, return handle for it. */ - int res = find_module (strtab + to_module->fromdir_offset, - strtab + to_module->fromname_offset, - &result[1]); - if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) + if (strtab[to_module->fromdir_offset] != '\0') { - /* Something went wrong. */ - __gconv_release_step (&result[0]); - free (result); - return res; + /* Load the module, return handle for it. */ + int res = find_module (strtab + to_module->fromdir_offset, + strtab + to_module->fromname_offset, + &result[idx]); + if (__builtin_expect (res, __GCONV_OK) != __GCONV_OK) + { + /* Something went wrong. */ + if (idx != 0) + __gconv_release_step (&result[0]); + free (result); + return res; + } } - } - else + else #endif - /* It's a builtin transformation. */ - __gconv_get_builtin_trans (strtab + to_module->fromname_offset, - &result[1]); + /* It's a builtin transformation. */ + __gconv_get_builtin_trans (strtab + to_module->fromname_offset, + &result[idx]); + + ++*nsteps; + } return __GCONV_OK; } diff --git a/iconv/iconvconfig.c b/iconv/iconvconfig.c index a8523bf25c..1d76c8f1ca 100644 --- a/iconv/iconvconfig.c +++ b/iconv/iconvconfig.c @@ -714,6 +714,8 @@ add_builtins (void) /* add the builtin transformations. */ for (cnt = 0; cnt < nbuiltin_trans; ++cnt) + { + printf("%s: %s -> %s\n", builtin_trans[cnt].module,builtin_trans[cnt].from,builtin_trans[cnt].to); new_module (builtin_trans[cnt].from, strlen (builtin_trans[cnt].from) + 1, builtin_trans[cnt].to, @@ -721,6 +723,7 @@ add_builtins (void) "", builtin_trans[cnt].module, strlen (builtin_trans[cnt].module) + 1, builtin_trans[cnt].cost, 0); + } } @@ -755,6 +758,11 @@ generate_name_list (void) { size_t i; + /* A name we always need. */ + tsearch (new_name ("INTERNAL", strtabadd (strtab, "INTERNAL", + sizeof ("INTERNAL"))), + &names, name_compare); + for (i = 0; i < nmodule_list; ++i) { struct module *runp; @@ -796,10 +804,19 @@ static void generate_name_info (void) { size_t i; + int idx; - name_info = (struct name_info *) xcalloc (nmodule_list, + name_info = (struct name_info *) xcalloc (nmodule_list + 1, sizeof (struct name_info)); + /* First add a special entry for the INTERNAL name. This must have + index zero. */ + idx = name_to_module_idx ("INTERNAL", 1); + name_info[0].canonical_name = "INTERNAL"; + name_info[0].canonical_strent = strtabadd (strtab, "INTERNAL", + sizeof ("INTERNAL")); + assert (nname_info == 1); + for (i = 0; i < nmodule_list; ++i) { struct module *runp; @@ -807,7 +824,7 @@ generate_name_info (void) for (runp = module_list[i]; runp != NULL; runp = runp->next) if (strcmp (runp->fromname, "INTERNAL") == 0) { - int idx = name_to_module_idx (runp->toname, 1); + idx = name_to_module_idx (runp->toname, 1); name_info[idx].from_internal = runp; assert (name_info[idx].canonical_name == NULL || strcmp (name_info[idx].canonical_name, @@ -817,7 +834,7 @@ generate_name_info (void) } else if (strcmp (runp->toname, "INTERNAL") == 0) { - int idx = name_to_module_idx (runp->fromname, 1); + idx = name_to_module_idx (runp->fromname, 1); name_info[idx].to_internal = runp; assert (name_info[idx].canonical_name == NULL || strcmp (name_info[idx].canonical_name, |