X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fpropername.c;h=54a6adaffdb7ba58effe4b1bd3687bd8cb734db3;hb=1276a2c5f24c0c932426aca9c899fa524d2443f2;hp=b3c91aee166faeb345b37a7877d32424e28dd441;hpb=4eda4ba54f3cf29f6b7fe4458e719cd2325be4c4;p=gnulib.git diff --git a/lib/propername.c b/lib/propername.c index b3c91aee1..54a6adaff 100644 --- a/lib/propername.c +++ b/lib/propername.c @@ -1,5 +1,5 @@ /* Localization of proper names. - Copyright (C) 2006-2008 Free Software Foundation, Inc. + Copyright (C) 2006-2014 Free Software Foundation, Inc. Written by Bruno Haible , 2006. This program is free software: you can redistribute it and/or modify @@ -15,6 +15,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +/* Without this pragma, gcc 4.7.0 20111124 mistakenly suggests that + the proper_name function might be candidate for attribute 'const' */ +#if (__GNUC__ == 4 && 6 <= __GNUC_MINOR__) || 4 < __GNUC__ +# pragma GCC diagnostic ignored "-Wsuggest-attribute=const" +#endif + #include /* Specification. */ @@ -55,92 +61,92 @@ mbsstr_trimmed_wordbounded (const char *string, const char *sub) { const char *tsub_in_string = mbsstr (string, tsub); if (tsub_in_string == NULL) - break; + break; else - { - if (MB_CUR_MAX > 1) - { - mbui_iterator_t string_iter; - bool word_boundary_before; - bool word_boundary_after; - - mbui_init (string_iter, string); - word_boundary_before = true; - if (mbui_cur_ptr (string_iter) < tsub_in_string) - { - mbchar_t last_char_before_tsub; - do - { - if (!mbui_avail (string_iter)) - abort (); - last_char_before_tsub = mbui_cur (string_iter); - mbui_advance (string_iter); - } - while (mbui_cur_ptr (string_iter) < tsub_in_string); - if (mb_isalnum (last_char_before_tsub)) - word_boundary_before = false; - } - - mbui_init (string_iter, tsub_in_string); - { - mbui_iterator_t tsub_iter; - - for (mbui_init (tsub_iter, tsub); - mbui_avail (tsub_iter); - mbui_advance (tsub_iter)) - { - if (!mbui_avail (string_iter)) - abort (); - mbui_advance (string_iter); - } - } - word_boundary_after = true; - if (mbui_avail (string_iter)) - { - mbchar_t first_char_after_tsub = mbui_cur (string_iter); - if (mb_isalnum (first_char_after_tsub)) - word_boundary_after = false; - } - - if (word_boundary_before && word_boundary_after) - { - found = true; - break; - } - - mbui_init (string_iter, tsub_in_string); - if (!mbui_avail (string_iter)) - break; - string = tsub_in_string + mb_len (mbui_cur (string_iter)); - } - else - { - bool word_boundary_before; - const char *p; - bool word_boundary_after; - - word_boundary_before = true; - if (string < tsub_in_string) - if (isalnum ((unsigned char) tsub_in_string[-1])) - word_boundary_before = false; - - p = tsub_in_string + strlen (tsub); - word_boundary_after = true; - if (*p != '\0') - if (isalnum ((unsigned char) *p)) - word_boundary_after = false; - - if (word_boundary_before && word_boundary_after) - { - found = true; - break; - } - - if (*tsub_in_string == '\0') - break; - string = tsub_in_string + 1; - } - } + { + if (MB_CUR_MAX > 1) + { + mbui_iterator_t string_iter; + bool word_boundary_before; + bool word_boundary_after; + + mbui_init (string_iter, string); + word_boundary_before = true; + if (mbui_cur_ptr (string_iter) < tsub_in_string) + { + mbchar_t last_char_before_tsub; + do + { + if (!mbui_avail (string_iter)) + abort (); + last_char_before_tsub = mbui_cur (string_iter); + mbui_advance (string_iter); + } + while (mbui_cur_ptr (string_iter) < tsub_in_string); + if (mb_isalnum (last_char_before_tsub)) + word_boundary_before = false; + } + + mbui_init (string_iter, tsub_in_string); + { + mbui_iterator_t tsub_iter; + + for (mbui_init (tsub_iter, tsub); + mbui_avail (tsub_iter); + mbui_advance (tsub_iter)) + { + if (!mbui_avail (string_iter)) + abort (); + mbui_advance (string_iter); + } + } + word_boundary_after = true; + if (mbui_avail (string_iter)) + { + mbchar_t first_char_after_tsub = mbui_cur (string_iter); + if (mb_isalnum (first_char_after_tsub)) + word_boundary_after = false; + } + + if (word_boundary_before && word_boundary_after) + { + found = true; + break; + } + + mbui_init (string_iter, tsub_in_string); + if (!mbui_avail (string_iter)) + break; + string = tsub_in_string + mb_len (mbui_cur (string_iter)); + } + else + { + bool word_boundary_before; + const char *p; + bool word_boundary_after; + + word_boundary_before = true; + if (string < tsub_in_string) + if (isalnum ((unsigned char) tsub_in_string[-1])) + word_boundary_before = false; + + p = tsub_in_string + strlen (tsub); + word_boundary_after = true; + if (*p != '\0') + if (isalnum ((unsigned char) *p)) + word_boundary_after = false; + + if (word_boundary_before && word_boundary_after) + { + found = true; + break; + } + + if (*tsub_in_string == '\0') + break; + string = tsub_in_string + 1; + } + } } free (tsub); return found; @@ -158,16 +164,16 @@ proper_name (const char *name) { /* See whether the translation contains the original name. */ if (mbsstr_trimmed_wordbounded (translation, name)) - return translation; + return translation; else - { - /* Return "TRANSLATION (NAME)". */ - char *result = - XNMALLOC (strlen (translation) + 2 + strlen (name) + 1 + 1, char); - - sprintf (result, "%s (%s)", translation, name); - return result; - } + { + /* Return "TRANSLATION (NAME)". */ + char *result = + XNMALLOC (strlen (translation) + 2 + strlen (name) + 1 + 1, char); + + sprintf (result, "%s (%s)", translation, name); + return result; + } } else return name; @@ -196,37 +202,38 @@ proper_name_utf8 (const char *name_ascii, const char *name_utf8) { #if HAVE_ICONV name_converted = alloc_name_converted = - xstr_iconv (name_utf8, "UTF-8", locale_code); + xstr_iconv (name_utf8, "UTF-8", locale_code); -# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2 \ +# if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \ + && !defined __UCLIBC__) \ || _LIBICONV_VERSION >= 0x0105 { - char *converted_translit; + char *converted_translit; - size_t len = strlen (locale_code); - char *locale_code_translit = XNMALLOC (len + 10 + 1, char); - memcpy (locale_code_translit, locale_code, len); - memcpy (locale_code_translit + len, "//TRANSLIT", 10 + 1); + size_t len = strlen (locale_code); + char *locale_code_translit = XNMALLOC (len + 10 + 1, char); + memcpy (locale_code_translit, locale_code, len); + memcpy (locale_code_translit + len, "//TRANSLIT", 10 + 1); - converted_translit = - xstr_iconv (name_utf8, "UTF-8", locale_code_translit); + converted_translit = + xstr_iconv (name_utf8, "UTF-8", locale_code_translit); - free (locale_code_translit); + free (locale_code_translit); - if (converted_translit != NULL) - { + if (converted_translit != NULL) + { # if !_LIBICONV_VERSION - /* Don't use the transliteration if it added question marks. - glibc's transliteration falls back to question marks; libiconv's - transliteration does not. - mbschr is equivalent to strchr in this case. */ - if (strchr (converted_translit, '?') != NULL) - free (converted_translit); - else + /* Don't use the transliteration if it added question marks. + glibc's transliteration falls back to question marks; libiconv's + transliteration does not. + mbschr is equivalent to strchr in this case. */ + if (strchr (converted_translit, '?') != NULL) + free (converted_translit); + else # endif - name_converted_translit = alloc_name_converted_translit = - converted_translit; - } + name_converted_translit = alloc_name_converted_translit = + converted_translit; + } } # endif #endif @@ -239,46 +246,49 @@ proper_name_utf8 (const char *name_ascii, const char *name_utf8) /* The name in locale encoding. */ name = (name_converted != NULL ? name_converted : - name_converted_translit != NULL ? name_converted_translit : - name_ascii); + name_converted_translit != NULL ? name_converted_translit : + name_ascii); - if (translation != name_ascii) + /* See whether we have a translation. Some translators have not understood + that they should use the UTF-8 form of the name, if possible. So if the + translator provided a no-op translation, we ignore it. */ + if (strcmp (translation, name_ascii) != 0) { /* See whether the translation contains the original name. */ if (mbsstr_trimmed_wordbounded (translation, name_ascii) - || (name_converted != NULL - && mbsstr_trimmed_wordbounded (translation, name_converted)) - || (name_converted_translit != NULL - && mbsstr_trimmed_wordbounded (translation, name_converted_translit))) - { - if (alloc_name_converted != NULL) - free (alloc_name_converted); - if (alloc_name_converted_translit != NULL) - free (alloc_name_converted_translit); - return translation; - } + || (name_converted != NULL + && mbsstr_trimmed_wordbounded (translation, name_converted)) + || (name_converted_translit != NULL + && mbsstr_trimmed_wordbounded (translation, name_converted_translit))) + { + if (alloc_name_converted != NULL) + free (alloc_name_converted); + if (alloc_name_converted_translit != NULL) + free (alloc_name_converted_translit); + return translation; + } else - { - /* Return "TRANSLATION (NAME)". */ - char *result = - XNMALLOC (strlen (translation) + 2 + strlen (name) + 1 + 1, char); - - sprintf (result, "%s (%s)", translation, name); - - if (alloc_name_converted != NULL) - free (alloc_name_converted); - if (alloc_name_converted_translit != NULL) - free (alloc_name_converted_translit); - return result; - } + { + /* Return "TRANSLATION (NAME)". */ + char *result = + XNMALLOC (strlen (translation) + 2 + strlen (name) + 1 + 1, char); + + sprintf (result, "%s (%s)", translation, name); + + if (alloc_name_converted != NULL) + free (alloc_name_converted); + if (alloc_name_converted_translit != NULL) + free (alloc_name_converted_translit); + return result; + } } else { if (alloc_name_converted != NULL && alloc_name_converted != name) - free (alloc_name_converted); + free (alloc_name_converted); if (alloc_name_converted_translit != NULL - && alloc_name_converted_translit != name) - free (alloc_name_converted_translit); + && alloc_name_converted_translit != name) + free (alloc_name_converted_translit); return name; } }