/*
- * "$Id: language.c 7558 2008-05-12 23:46:44Z mike $"
+ * "$Id$"
*
- * I18N/language support for CUPS.
+ * I18N/language support for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
- * Copyright 1997-2007 by Easy Software Products.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
- * This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- * _cupsAppleLanguage() - Get the Apple language identifier associated with
- * a locale ID.
- * _cupsEncodingName() - Return the character encoding name string for the
- * given encoding enumeration.
- * cupsLangDefault() - Return the default language.
- * cupsLangEncoding() - Return the character encoding (us-ascii, etc.) for
- * the given language.
- * cupsLangFlush() - Flush all language data out of the cache.
- * cupsLangFree() - Free language data.
- * cupsLangGet() - Get a language.
- * _cupsLangString() - Get a message string.
- * _cupsMessageFree() - Free a messages array.
- * _cupsMessageLoad() - Load a .po file into a messages array.
- * _cupsMessageLookup() - Lookup a message string.
- * appleLangDefault() - Get the default locale string.
- * appleMessageLoad() - Load a message catalog from a localizable bundle.
- * cups_cache_lookup() - Lookup a language in the cache...
- * cups_message_compare() - Compare two messages.
- * cups_message_free() - Free a message.
- * cups_message_load() - Load the message catalog for a language.
- * cups_unquote() - Unquote characters in strings...
+ * This file is subject to the Apple OS-Developed Software exception.
*/
/*
"unknown", "unknown",
"euc-cn", "euc-jp",
"euc-kr", "euc-tw",
- "jis-x0213"
+ "shift_jisx0213"
};
#ifdef __APPLE__
*/
language[2] = '_';
- language[3] = toupper(language[3] & 255);
- language[4] = toupper(language[4] & 255);
+ language[3] = (char)toupper(language[3] & 255);
+ language[4] = (char)toupper(language[4] & 255);
}
break;
}
if ((langid = CFLocaleCreateCanonicalLanguageIdentifierFromString(
kCFAllocatorDefault, localeid)) != NULL)
{
- CFStringGetCString(langid, language, langsize, kCFStringEncodingASCII);
+ CFStringGetCString(langid, language, (CFIndex)langsize, kCFStringEncodingASCII);
CFRelease(langid);
}
_cupsEncodingName(
cups_encoding_t encoding) /* I - Encoding value */
{
- if (encoding < 0 ||
- encoding >= (sizeof(lang_encodings) / sizeof(const char *)))
+ if (encoding < CUPS_US_ASCII ||
+ encoding >= (cups_encoding_t)(sizeof(lang_encodings) / sizeof(lang_encodings[0])))
{
DEBUG_printf(("1_cupsEncodingName(encoding=%d) = out of range (\"%s\")",
encoding, lang_encodings[0]));
* Set the character set to UTF-8...
*/
- strcpy(charset, "UTF8");
+ strlcpy(charset, "UTF8", sizeof(charset));
/*
* Apple's setlocale doesn't give us the user's localization
*/
if (!charset[0])
- strcpy(charset, "UTF8");
+ strlcpy(charset, "UTF8", sizeof(charset));
/*
* Parse the language string passed in to a locale string. "C" is the
if (language == NULL || !language[0] ||
!strcmp(language, "POSIX"))
- strcpy(langname, "C");
+ strlcpy(langname, "C", sizeof(langname));
else
{
/*
if (*language == '_' || *language == '-' || *language == '.')
break;
else if (ptr < (langname + sizeof(langname) - 1))
- *ptr++ = tolower(*language & 255);
+ *ptr++ = (char)tolower(*language & 255);
*ptr = '\0';
if (*language == '.')
break;
else if (ptr < (country + sizeof(country) - 1))
- *ptr++ = toupper(*language & 255);
+ *ptr++ = (char)toupper(*language & 255);
*ptr = '\0';
}
for (language ++, ptr = charset; *language; language ++)
if (_cups_isalnum(*language) && ptr < (charset + sizeof(charset) - 1))
- *ptr++ = toupper(*language & 255);
+ *ptr++ = (char)toupper(*language & 255);
*ptr = '\0';
}
if (strlen(langname) != 2)
{
- strcpy(langname, "C");
+ strlcpy(langname, "C", sizeof(langname));
country[0] = '\0';
charset[0] = '\0';
}
if (country[0])
snprintf(real, sizeof(real), "%s_%s", langname, country);
else
- strcpy(real, langname);
+ strlcpy(real, langname, sizeof(real));
_cupsMutexLock(&lang_mutex);
* Range check input...
*/
- if (!lang || !message)
+ if (!lang || !message || !*message)
return (message);
_cupsMutexLock(&lang_mutex);
char s[4096], /* String buffer */
*ptr, /* Pointer into buffer */
*temp; /* New string */
- int length; /* Length of combined strings */
+ size_t length, /* Length of combined strings */
+ ptrlen; /* Length of string */
DEBUG_printf(("4_cupsMessageLoad(filename=\"%s\")", filename));
* Create an array to hold the messages...
*/
- if ((a = cupsArrayNew3((cups_array_func_t)cups_message_compare, NULL,
- (cups_ahash_func_t)NULL, 0,
- (cups_acopy_func_t)NULL,
- (cups_afree_func_t)cups_message_free)) == NULL)
+ if ((a = _cupsMessageNew(NULL)) == NULL)
{
DEBUG_puts("5_cupsMessageLoad: Unable to allocate array!");
return (NULL);
*/
if (m)
- cupsArrayAdd(a, m);
+ {
+ if (m->str && m->str[0])
+ {
+ cupsArrayAdd(a, m);
+ }
+ else
+ {
+ /*
+ * Translation is empty, don't add it... (STR #4033)
+ */
+
+ free(m->id);
+ if (m->str)
+ free(m->str);
+ free(m);
+ }
+ }
/*
* Create a new message with the given msgid string...
* Append to current string...
*/
- length = (int)strlen(m->str ? m->str : m->id);
+ length = strlen(m->str ? m->str : m->id);
+ ptrlen = strlen(ptr);
- if ((temp = realloc(m->str ? m->str : m->id,
- length + strlen(ptr) + 1)) == NULL)
+ if ((temp = realloc(m->str ? m->str : m->id, length + ptrlen + 1)) == NULL)
{
+ if (m->str)
+ free(m->str);
+ free(m->id);
+ free(m);
+
cupsFileClose(fp);
return (a);
}
{
/*
* Copy the new portion to the end of the msgstr string - safe
- * to use strcpy because the buffer is allocated to the correct
+ * to use memcpy because the buffer is allocated to the correct
* size...
*/
m->str = temp;
- strcpy(m->str + length, ptr);
+ memcpy(m->str + length, ptr, ptrlen + 1);
}
else
{
/*
* Copy the new portion to the end of the msgid string - safe
- * to use strcpy because the buffer is allocated to the correct
+ * to use memcpy because the buffer is allocated to the correct
* size...
*/
m->id = temp;
- strcpy(m->id + length, ptr);
+ memcpy(m->id + length, ptr, ptrlen + 1);
}
}
else if (!strncmp(s, "msgstr", 6) && m)
if ((m->str = strdup(ptr)) == NULL)
{
+ free(m->id);
+ free(m);
+
cupsFileClose(fp);
return (a);
}
*/
if (m)
- cupsArrayAdd(a, m);
+ {
+ if (m->str && m->str[0])
+ {
+ cupsArrayAdd(a, m);
+ }
+ else
+ {
+ /*
+ * Translation is empty, don't add it... (STR #4033)
+ */
+
+ free(m->id);
+ if (m->str)
+ free(m->str);
+ free(m);
+ }
+ }
/*
* Close the message catalog file and return the new array...
}
+/*
+ * '_cupsMessageNew()' - Make a new message catalog array.
+ */
+
+cups_array_t * /* O - Array */
+_cupsMessageNew(void *context) /* I - User data */
+{
+ return (cupsArrayNew3((cups_array_func_t)cups_message_compare, context,
+ (cups_ahash_func_t)NULL, 0,
+ (cups_acopy_func_t)NULL,
+ (cups_afree_func_t)cups_message_free));
+}
+
+
#ifdef __APPLE__
/*
* 'appleLangDefault()' - Get the default locale string.
{
if (getenv("SOFTWARE") != NULL && (lang = getenv("LANG")) != NULL)
{
+ DEBUG_printf(("3appleLangDefault: Using LANG=%s", lang));
strlcpy(cg->language, lang, sizeof(cg->language));
return (cg->language);
}
else if ((bundle = CFBundleGetMainBundle()) != NULL &&
(bundleList = CFBundleCopyBundleLocalizations(bundle)) != NULL)
{
+ DEBUG_puts("3appleLangDefault: Getting localizationList from bundle.");
+
localizationList =
CFBundleCopyPreferredLocalizationsFromArray(bundleList);
CFRelease(bundleList);
}
else
+ {
+ DEBUG_puts("3appleLangDefault: Getting localizationList from preferences.");
+
localizationList =
CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
kCFPreferencesCurrentApplication);
+ }
if (localizationList)
{
+
+#ifdef DEBUG
+ if (CFGetTypeID(localizationList) == CFArrayGetTypeID())
+ DEBUG_printf(("3appleLangDefault: Got localizationList, %d entries.",
+ (int)CFArrayGetCount(localizationList)));
+ else
+ DEBUG_puts("3appleLangDefault: Got localizationList but not an array.");
+#endif /* DEBUG */
+
if (CFGetTypeID(localizationList) == CFArrayGetTypeID() &&
CFArrayGetCount(localizationList) > 0)
{
kCFStringEncodingASCII);
CFRelease(localeName);
- DEBUG_printf(("9appleLangDefault: cg->language=\"%s\"",
+ DEBUG_printf(("3appleLangDefault: cg->language=\"%s\"",
cg->language));
/*
{
if (!strcmp(cg->language, apple_language_locale[i].language))
{
- DEBUG_printf(("9appleLangDefault: mapping \"%s\" to \"%s\"...",
+ DEBUG_printf(("3appleLangDefault: mapping \"%s\" to \"%s\"...",
cg->language, apple_language_locale[i].locale));
strlcpy(cg->language, apple_language_locale[i].locale,
sizeof(cg->language));
if (!strchr(cg->language, '.'))
strlcat(cg->language, ".UTF-8", sizeof(cg->language));
}
+ else
+ DEBUG_puts("3appleLangDefault: Unable to get localeName.");
}
}
*/
if (!cg->language[0])
+ {
+ DEBUG_puts("3appleLangDefault: Defaulting to en_US.");
strlcpy(cg->language, "en_US.UTF-8", sizeof(cg->language));
+ }
}
/*
url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
(UInt8 *)filename,
- strlen(filename), false);
+ (CFIndex)strlen(filename), false);
if (url)
{
stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
* plist as the user data.
*/
- return (cupsArrayNew3((cups_array_func_t)cups_message_compare, (void *)plist,
- (cups_ahash_func_t)NULL, 0,
- (cups_acopy_func_t)NULL,
- (cups_afree_func_t)cups_message_free));
+ return (_cupsMessageNew((void *)plist));
}
# endif /* CUPS_BUNDLEDIR */
#endif /* __APPLE__ */
/*
- * End of "$Id: language.c 7558 2008-05-12 23:46:44Z mike $".
+ * End of "$Id$".
*/