aboutsummaryrefslogtreecommitdiff
path: root/iconv/iconv_prog.c
diff options
context:
space:
mode:
Diffstat (limited to 'iconv/iconv_prog.c')
-rw-r--r--iconv/iconv_prog.c48
1 files changed, 43 insertions, 5 deletions
diff --git a/iconv/iconv_prog.c b/iconv/iconv_prog.c
index 00b4b95672..e71f8d7369 100644
--- a/iconv/iconv_prog.c
+++ b/iconv/iconv_prog.c
@@ -39,6 +39,7 @@
#include <charmap.h>
#include <gconv_int.h>
#include "iconv_prog.h"
+#include "iconvconfig.h"
/* Get libc version number. */
#include "../version.h"
@@ -46,6 +47,9 @@
#define PACKAGE _libc_intl_domainname
+/* Defined in gconv_cache.c. */
+extern void *__gconv_cache;
+
/* Name and version of program. */
static void print_version (FILE *stream, struct argp_state *state);
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
@@ -653,7 +657,7 @@ add_known_names (struct gconv_module *node)
if (strcmp (node->from_string, "INTERNAL"))
tsearch (node->from_string, &printlist,
(__compar_fn_t) strverscmp);
- if (strcmp (node->to_string, "INTERNAL"))
+ if (strcmp (node->to_string, "INTERNAL") != 0)
tsearch (node->to_string, &printlist, (__compar_fn_t) strverscmp);
node = node->same;
@@ -661,6 +665,31 @@ add_known_names (struct gconv_module *node)
while (node != NULL);
}
+
+static void
+insert_cache (void)
+{
+ const struct gconvcache_header *header;
+ const char *strtab;
+ const struct hash_entry *hashtab;
+ size_t cnt;
+
+ header = (const struct gconvcache_header *) __gconv_cache;
+ strtab = (char *) __gconv_cache + header->string_offset;
+ hashtab = (struct hash_entry *) ((char *) __gconv_cache
+ + header->hash_offset);
+
+ for (cnt = 0; cnt < header->hash_size; ++cnt)
+ if (hashtab[cnt].string_offset != 0)
+ {
+ const char *str = strtab + hashtab[cnt].string_offset;
+
+ if (strcmp (str, "INTERNAL") != 0)
+ tsearch (str, &printlist, (__compar_fn_t) strverscmp);
+ }
+}
+
+
static void
internal_function
print_known_names (void)
@@ -671,11 +700,20 @@ print_known_names (void)
h = iconv_open ("L1", "L1");
iconv_close (h);
- /* First add the aliases. */
- twalk (__gconv_alias_db, insert_print_list);
+ /* See whether we have a cache. */
+ if (__gconv_cache != NULL)
+ /* Yep, use only this information. */
+ insert_cache ();
+ else
+ {
+ /* No, then use the information read from the gconv-modules file.
+ First add the aliases. */
+ twalk (__gconv_alias_db, insert_print_list);
- /* Add the from- and to-names from the known modules. */
- add_known_names (__gconv_modules_db);
+ /* Add the from- and to-names from the known modules. */
+ if (__gconv_modules_db != NULL)
+ add_known_names (__gconv_modules_db);
+ }
fputs (_("\
The following list contain all the coded character sets known. This does\n\