diff options
Diffstat (limited to 'iconv')
-rw-r--r-- | iconv/gconv_int.h | 11 | ||||
-rw-r--r-- | iconv/gconv_open.c | 25 |
2 files changed, 27 insertions, 9 deletions
diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 34dff7d522..5bdf7143e6 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -102,18 +102,19 @@ extern struct gconv_module *__gconv_modules_db; /* The gconv functions expects the name to be in upper case and complete, including the trailing slashes if necessary. */ -#define norm_add_slashes(str) \ +#define norm_add_slashes(str,suffix) \ ({ \ const char *cp = (str); \ char *result; \ char *tmp; \ size_t cnt = 0; \ + size_t suffix_len = suffix == NULL ? 0 : strlen (suffix); \ \ while (*cp != '\0') \ if (*cp++ == '/') \ ++cnt; \ \ - tmp = result = alloca (cp - (str) + 3); \ + tmp = result = alloca (cp - (str) + 3 + suffix_len); \ cp = (str); \ while (*cp != '\0') \ *tmp++ = _toupper (*cp++); \ @@ -121,7 +122,11 @@ extern struct gconv_module *__gconv_modules_db; { \ *tmp++ = '/'; \ if (cnt < 1) \ - *tmp++ = '/'; \ + { \ + *tmp++ = '/'; \ + if (suffix != NULL) \ + tmp = __mempcpy (tmp, suffix, suffix_len); \ + } \ } \ *tmp = '\0'; \ result; \ diff --git a/iconv/gconv_open.c b/iconv/gconv_open.c index 14f1d5e0f9..d2963fa8ee 100644 --- a/iconv/gconv_open.c +++ b/iconv/gconv_open.c @@ -37,6 +37,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, int res; int conv_flags = 0; const char *errhand; + const char *ignore; /* Find out whether any error handling method is specified. */ errhand = strchr (toset, '/'); @@ -44,7 +45,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, errhand = strchr (errhand + 1, '/'); if (__builtin_expect (errhand != NULL, 1)) { - if (errhand[1] == '\0') + if (*++errhand == '\0') errhand = NULL; else { @@ -56,7 +57,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, flags = __GCONV_IGNORE_ERRORS; - if (strcasecmp (errhand, "IGNORE") == 0) + if (__strcasecmp (errhand, "IGNORE") == 0) { /* Found it. This means we should ignore conversion errors. */ flags = __GCONV_IGNORE_ERRORS; @@ -65,6 +66,18 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, } } + /* For the source character set we ignore the error handler specification. + XXX Is this really always the best? */ + ignore = strchr (fromset, '/'); + if (ignore != NULL && (ignore = strchr (ignore + 1, '/')) != NULL + && *++ignore != '\0') + { + char *newfromset = (char *) alloca (ignore - fromset + 1); + + newfromset[ignore - fromset] = '\0'; + fromset = memcpy (newfromset, fromset, ignore - fromset); + } + res = __gconv_find_transform (toset, fromset, &steps, &nsteps, flags); if (res == __GCONV_OK) { @@ -78,7 +91,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, if (errhand != NULL) { /* Find the appropriate transliteration handling. */ - if (strcasecmp (errhand, "TRANSLIT") == 0) + if (__strcasecmp (errhand, "TRANSLIT") == 0) { /* It's the builtin transliteration handling. We only suport for it working on the internal encoding. */ @@ -89,7 +102,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, trans_fct = __gconv_transliterate; /* No context, init, or end function. */ } - else if (strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0) + else if (__strcasecmp (errhand, "WORK AROUND A GCC BUG") == 0) { trans_init_fct = (__gconv_trans_init_fct) 1; } @@ -151,7 +164,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, /* Now see whether we can use the transliteration module for this step. */ for (n = 0; n < ncsnames; ++n) - if (strcasecmp (steps[cnt].__from_name, csnames[n]) == 0) + if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0) { /* Match! Now try the initializer. */ if (trans_init_fct == NULL @@ -182,7 +195,7 @@ __gconv_open (const char *toset, const char *fromset, __gconv_t *handle, /* Now see whether we can use the transliteration module for this step. */ for (n = 0; n < ncsnames; ++n) - if (strcasecmp (steps[cnt].__from_name, csnames[n]) == 0) + if (__strcasecmp (steps[cnt].__from_name, csnames[n]) == 0) { /* Match! Now try the initializer. */ if (trans_init_fct == NULL |