/*
- * "$Id: language.c 4985 2006-01-25 21:57:18Z mike $"
+ * "$Id: language.c 6916 2007-09-05 21:14:08Z mike $"
*
* I18N/language support for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products 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 missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * 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.
*
* cupsLangEncoding() - Return the character encoding (us-ascii, etc.)
* for the given language.
* cupsLangFlush() - Flush all language data out of the cache.
- * _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.
- * _cupsRestoreLocale() - Restore the original locale...
- * _cupsSaveLocale() - Set the locale and save a copy of the old locale...
* appleLangDefault() - Get the default locale string.
* cups_cache_lookup() - Lookup a language in the cache...
* cups_message_compare() - Compare two messages.
#include "globals.h"
#include "debug.h"
#include <stdlib.h>
+#include <errno.h>
#ifdef HAVE_LANGINFO_H
# include <langinfo.h>
#endif /* HAVE_LANGINFO_H */
#endif /* HAVE_COREFOUNDATION_H */
+/*
+ * Local globals...
+ */
+
+#ifdef HAVE_PTHREAD_H
+static pthread_mutex_t lang_mutex = PTHREAD_MUTEX_INITIALIZER;
+ /* Mutex to control access to cache */
+#endif /* HAVE_PTHREAD_H */
+static cups_lang_t *lang_cache = NULL;
+ /* Language string cache */
+
+
/*
* Local functions...
*/
"windows-1256", "windows-1257",
"windows-1258", "koi8-r",
"koi8-u", "iso-8859-11",
- "iso-8859-16", "unknown",
+ "iso-8859-16", "mac-roman",
"unknown", "unknown",
"unknown", "unknown",
"unknown", "unknown",
void
cupsLangFlush(void)
-{
- _cupsLangFlush(_cupsGlobals());
-}
-
-
-/*
- * '_cupsLangFlush()' - Flush all language data out of the cache.
- */
-
-void
-_cupsLangFlush(_cups_globals_t *cg) /* I - Global data */
{
cups_lang_t *lang, /* Current language */
*next; /* Next language */
* Free all languages in the cache...
*/
- for (lang = cg->lang_cache; lang != NULL; lang = next)
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
+
+ for (lang = lang_cache; lang != NULL; lang = next)
{
/*
* Free all messages...
free(lang);
}
- cg->lang_cache = NULL;
+ lang_cache = NULL;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
}
void
cupsLangFree(cups_lang_t *lang) /* I - Language to free */
{
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
+
if (lang != NULL && lang->used > 0)
lang->used --;
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
}
cupsLangGet(const char *language) /* I - Language or locale */
{
int i; /* Looping var */
- char locale[255], /* Copy of locale name */
- langname[16], /* Requested language name */
+#ifndef __APPLE__
+ char locale[255]; /* Copy of locale name */
+#endif /* !__APPLE__ */
+ char langname[16], /* Requested language name */
country[16], /* Country code */
charset[16], /* Character set */
-#ifdef CODESET
*csptr, /* Pointer to CODESET string */
-#endif /* CODESET */
*ptr, /* Pointer into language/charset */
real[48], /* Real language name */
filename[1024]; /* Filename for language locale file */
cups_encoding_t encoding; /* Encoding to use */
cups_lang_t *lang; /* Current language... */
- char *oldlocale; /* Old locale name */
_cups_globals_t *cg = _cupsGlobals();
/* Pointer to library globals */
static const char * const locale_encodings[] =
"CP1250", "CP1251", "CP1252", "CP1253",
"CP1254", "CP1255", "CP1256", "CP1257",
"CP1258", "KOI8R", "KOI8U", "ISO885911",
- "ISO885916", "", "", "",
+ "ISO885916", "MACROMAN", "", "",
"", "", "", "",
"", "", "", "",
DEBUG_printf(("cupsLangGet(language=\"%s\")\n", language ? language : "(null)"));
#ifdef __APPLE__
+ /*
+ * Set the character set to UTF-8...
+ */
+
+ strcpy(charset, "UTF8");
+
/*
* Apple's setlocale doesn't give us the user's localization
* preference so we have to look it up this way...
*/
- if (language == NULL)
+ if (!language && (language = getenv("LANG")) == NULL)
language = appleLangDefault();
+
#else
- if (language == NULL)
+ /*
+ * Set the charset to "unknown"...
+ */
+
+ charset[0] = '\0';
+
+ /*
+ * Use setlocale() to determine the currently set locale, and then
+ * fallback to environment variables to avoid setting the locale,
+ * since setlocale() is not thread-safe!
+ */
+
+ if (!language)
{
/*
* First see if the locale has been set; if it is still "C" or
- * "POSIX", set the locale to the default...
+ * "POSIX", use the environment to get the default...
*/
# ifdef LC_MESSAGES
ptr ? ptr : "(null)"));
if (!ptr || !strcmp(ptr, "C") || !strcmp(ptr, "POSIX"))
-# ifdef LC_MESSAGES
{
- ptr = setlocale(LC_MESSAGES, "");
- setlocale(LC_CTYPE, "");
+ /*
+ * Get the character set from the LC_CTYPE locale setting...
+ */
+
+ if ((ptr = getenv("LC_CTYPE")) == NULL)
+ if ((ptr = getenv("LC_ALL")) == NULL)
+ if ((ptr = getenv("LANG")) == NULL)
+ ptr = "en_US";
+
+ if ((csptr = strchr(ptr, '.')) != NULL)
+ {
+ /*
+ * Extract the character set from the environment...
+ */
+
+ for (ptr = charset, csptr ++; *csptr; csptr ++)
+ if (ptr < (charset + sizeof(charset) - 1) && isalnum(*csptr & 255))
+ *ptr++ = *csptr;
+
+ *ptr = '\0';
+ }
+
+ /*
+ * Get the locale for messages from the LC_MESSAGES locale setting...
+ */
+
+ if ((ptr = getenv("LC_MESSAGES")) == NULL)
+ if ((ptr = getenv("LC_ALL")) == NULL)
+ if ((ptr = getenv("LANG")) == NULL)
+ ptr = "en_US";
}
-# else
- ptr = setlocale(LC_ALL, "");
-# endif /* LC_MESSAGES */
if (ptr)
{
strlcpy(locale, ptr, sizeof(locale));
language = locale;
- DEBUG_printf(("cupsLangGet: new language value is \"%s\"\n",
- language ? language : "(null)"));
+ /*
+ * CUPS STR #2575: Map "nb" to "no" for back-compatibility...
+ */
+
+ if (!strncmp(locale, "nb", 2))
+ locale[1] = 'o';
+
+ DEBUG_printf(("cupsLangGet: new language value is \"%s\"\n", language));
}
}
#endif /* __APPLE__ */
if (!language)
{
/*
- * Switch to the value of the "LANG" environment variable, and if
- * that is NULL as well, use "C".
+ * Switch to the POSIX ("C") locale...
*/
- if ((language = getenv("LANG")) == NULL)
- language = "C";
+ language = "C";
}
- /*
- * Set the charset to "unknown"...
- */
-
- charset[0] = '\0';
-
#ifdef CODESET
/*
* On systems that support the nl_langinfo(CODESET) call, use
* this value as the character set...
*/
- if ((csptr = nl_langinfo(CODESET)) != NULL)
+ if (!charset[0] && (csptr = nl_langinfo(CODESET)) != NULL)
{
/*
* Copy all of the letters and numbers in the CODESET string...
#endif /* CODESET */
/*
- * Set the locale back to POSIX while we do string ops, since
- * apparently some buggy C libraries break ctype() for non-I18N
- * chars...
+ * If we don't have a character set by now, default to UTF-8...
*/
-#if defined(__APPLE__)
- /* The ctype bug isn't in Apple's libc */
- (void)locale; /* anti-compiler-warning-code */
- (void)oldlocale; /* anti-compiler-warning-code */
-#elif !defined(LC_CTYPE)
- oldlocale = _cupsSaveLocale(LC_ALL, "C");
-#else
- oldlocale = _cupsSaveLocale(LC_CTYPE, "C");
-#endif /* __APPLE__ */
+ if (!charset[0])
+ strcpy(charset, "UTF8");
/*
* Parse the language string passed in to a locale string. "C" is the
}
}
- /*
- * Restore the locale...
- */
-
-#if defined(__APPLE__)
- /* The ctype bug isn't in Apple's libc */
-#elif !defined(LC_CTYPE)
- _cupsRestoreLocale(LC_ALL, oldlocale);
-#else
- _cupsRestoreLocale(LC_CTYPE, oldlocale);
-#endif /* __APPLE__ */
-
DEBUG_printf(("cupsLangGet: langname=\"%s\", country=\"%s\", charset=\"%s\"\n",
langname, country, charset));
if (charset[0])
{
- for (i = 0; i < (int)(sizeof(locale_encodings) / sizeof(locale_encodings[0])); i ++)
+ for (i = 0;
+ i < (int)(sizeof(locale_encodings) / sizeof(locale_encodings[0]));
+ i ++)
if (!strcasecmp(charset, locale_encodings[i]))
{
encoding = (cups_encoding_t)i;
break;
}
+
+ if (encoding == CUPS_AUTO_ENCODING)
+ {
+ /*
+ * Map alternate names for various character sets...
+ */
+
+ if (!strcasecmp(charset, "iso-2022-jp") ||
+ !strcasecmp(charset, "sjis"))
+ encoding = CUPS_WINDOWS_932;
+ else if (!strcasecmp(charset, "iso-2022-cn"))
+ encoding = CUPS_WINDOWS_936;
+ else if (!strcasecmp(charset, "iso-2022-kr"))
+ encoding = CUPS_WINDOWS_949;
+ else if (!strcasecmp(charset, "big5"))
+ encoding = CUPS_WINDOWS_950;
+ }
}
DEBUG_printf(("cupsLangGet: encoding=%d(%s)\n", encoding,
* See if we already have this language/country loaded...
*/
- snprintf(real, sizeof(real), "%s_%s", langname, country);
+ if (country[0])
+ {
+ snprintf(real, sizeof(real), "%s_%s", langname, country);
+
+ snprintf(filename, sizeof(filename), "%s/%s/cups_%s.po", cg->localedir,
+ real, real);
+ }
+ else
+ {
+ strcpy(real, langname);
+ filename[0] = '\0'; /* anti-compiler-warning-code */
+ }
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_lock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
if ((lang = cups_cache_lookup(real, encoding)) != NULL)
- return (lang);
+ {
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
- snprintf(filename, sizeof(filename), "%s/%s/cups_%s", cg->localedir,
- real, real);
+ return (lang);
+ }
if (!country[0] || access(filename, 0))
{
* Country localization not available, look for generic localization...
*/
- if ((lang = cups_cache_lookup(langname, encoding)) != NULL)
- return (lang);
-
- snprintf(filename, sizeof(filename), "%s/%s/cups_%s", cg->localedir,
+ snprintf(filename, sizeof(filename), "%s/%s/cups_%s.po", cg->localedir,
langname, langname);
if (access(filename, 0))
* No generic localization, so use POSIX...
*/
- strcpy(real, "C");
- snprintf(filename, sizeof(filename), "%s/C/cups_C", cg->localedir);
+ DEBUG_printf(("access(\"%s\", 0): %s\n", filename, strerror(errno)));
+
+ snprintf(filename, sizeof(filename), "%s/C/cups_C.po", cg->localedir);
}
- else
- strcpy(real, langname);
}
/*
* record...
*/
- for (lang = cg->lang_cache; lang != NULL; lang = lang->next)
+ for (lang = lang_cache; lang != NULL; lang = lang->next)
if (lang->used == 0)
break;
*/
if ((lang = calloc(sizeof(cups_lang_t), 1)) == NULL)
+ {
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
+
return (NULL);
+ }
- lang->next = cg->lang_cache;
- cg->lang_cache = lang;
+ lang->next = lang_cache;
+ lang_cache = lang;
}
+ else
+ {
+ /*
+ * Free all old strings as needed...
+ */
- /*
- * Free all old strings as needed...
- */
-
- _cupsMessageFree(lang->strings);
+ _cupsMessageFree(lang->strings);
+ }
/*
* Then assign the language and encoding fields...
* Return...
*/
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_unlock(&lang_mutex);
+#endif /* HAVE_PTHREAD_H */
+
return (lang);
}
if (!lang || !message)
return (message);
+#ifdef HAVE_PTHREAD_H
+ {
+ const char *s; /* Localized message */
+
+ pthread_mutex_lock(&lang_mutex);
+
+ s = _cupsMessageLookup(lang->strings, message);
+
+ pthread_mutex_unlock(&lang_mutex);
+
+ return (s);
+ }
+#else
return (_cupsMessageLookup(lang->strings, message));
+#endif /* HAVE_PTHREAD_H */
}
int length; /* Length of combined strings */
+ DEBUG_printf(("_cupsMessageLoad(filename=\"%s\")\n", filename));
+
/*
* Create an array to hold the messages...
*/
* msgid "some text"
* msgstr "localized text"
*
- * The localized text can span multiple lines using the form:
+ * The ID and localized text can span multiple lines using the form:
*
- * msgid "some long text"
- * msgstr "localized text spanning "
+ * msgid ""
+ * "some long text"
+ * msgstr ""
+ * "localized text spanning "
* "multiple lines"
*/
if (!strncmp(s, "msgid", 5))
{
+ /*
+ * Add previous message as needed...
+ */
+
+ if (m)
+ cupsArrayAdd(a, m);
+
+ /*
+ * Create a new message with the given msgid string...
+ */
+
if ((m = (_cups_message_t *)calloc(1, sizeof(_cups_message_t))) == NULL)
{
cupsFileClose(fp);
}
m->id = strdup(ptr);
- cupsArrayAdd(a, m);
}
- else if ((s[0] == '\"' || !strncmp(s, "msgstr", 6)) && m)
+ else if (s[0] == '\"' && m)
{
- if (m->str)
- {
- /*
- * Append the string...
- */
+ /*
+ * Append to current string...
+ */
- length = strlen(m->str);
+ length = (int)strlen(m->str ? m->str : m->id);
- if ((temp = realloc(m->str, length + strlen(ptr) + 1)) == NULL)
- {
- cupsFileClose(fp);
- return (a);
- }
- else
- m->str = temp;
+ if ((temp = realloc(m->str ? m->str : m->id,
+ length + strlen(ptr) + 1)) == NULL)
+ {
+ cupsFileClose(fp);
+ return (a);
+ }
+ if (m->str)
+ {
/*
- * Copy the new portion at the end - safe because the buffer is
- * allocated to the correct size...
+ * Copy the new portion to the end of the msgstr string - safe
+ * to use strcpy because the buffer is allocated to the correct
+ * size...
*/
+ m->str = temp;
+
strcpy(m->str + length, ptr);
}
else
{
/*
- * Set the string...
+ * Copy the new portion to the end of the msgid string - safe
+ * to use strcpy because the buffer is allocated to the correct
+ * size...
*/
- m->str = strdup(ptr);
+ m->id = temp;
+
+ strcpy(m->id + length, ptr);
}
}
+ else if (!strncmp(s, "msgstr", 6) && m)
+ {
+ /*
+ * Set the string...
+ */
+
+ m->str = strdup(ptr);
+ }
}
+ /*
+ * Add the last message string to the array as needed...
+ */
+
+ if (m)
+ cupsArrayAdd(a, m);
+
/*
* Close the message catalog file and return the new array...
*/
}
-/*
- * '_cupsRestoreLocale()' - Restore the original locale...
- */
-
-void
-_cupsRestoreLocale(int category, /* I - Category */
- char *oldlocale) /* I - Old locale or NULL */
-{
- DEBUG_printf(("_cupsRestoreLocale(category=%d, oldlocale=\"%s\")\n",
- category, oldlocale));
-
- if (oldlocale)
- {
- /*
- * Reset the locale and free the locale string...
- */
-
- setlocale(category, oldlocale);
- free(oldlocale);
- }
-}
-
-
-/*
- * '_cupsSaveLocale()' - Set the locale and save a copy of the old locale...
- */
-
-char * /* O - Old locale or NULL */
-_cupsSaveLocale(int category, /* I - Category */
- const char *locale) /* I - New locale or NULL */
-{
- char *oldlocale; /* Old locale */
-
-
- DEBUG_printf(("_cupsSaveLocale(category=%d, locale=\"%s\")\n",
- category, locale));
-
- /*
- * Get the old locale and copy it...
- */
-
- if ((oldlocale = setlocale(category, NULL)) != NULL)
- oldlocale = strdup(oldlocale);
-
- DEBUG_printf((" oldlocale=\"%s\"\n", oldlocale ? oldlocale : "(null)"));
-
- /*
- * Set the new locale...
- */
-
- setlocale(category, locale);
-
- /*
- * Return a copy of the old locale...
- */
-
- return (oldlocale);
-}
-
-
#ifdef __APPLE__
/*
* Code & data to translate OSX's language names to their ISO 639-1 locale.
*/
# ifdef HAVE_CF_LOCALE_ID
+
+typedef struct
+{
+ const char * const name; /* Language name */
+ const char * const locale; /* Locale name */
+} _apple_name_locale_t;
+
+static const _apple_name_locale_t apple_name_locale[] =
+{
+ { "en" , "en_US" },
+ { "nb" , "no" },
+ { "zh-Hans" , "zh_CN" },
+ { "zh-Hant" , "zh_TW" }
+};
+
+
/*
* 'appleLangDefault()' - Get the default locale string.
*/
static const char * /* O - Locale string */
appleLangDefault(void)
{
+ int i; /* Looping var */
+ CFBundleRef bundle; /* Main bundle (if any) */
+ CFArrayRef bundleList; /* List of localizations in bundle */
CFPropertyListRef localizationList;
/* List of localization data */
CFStringRef languageName; /* Current name */
CFStringRef localeName; /* Canonical from of name */
+ char *lang; /* LANG environment variable */
_cups_globals_t *cg = _cupsGlobals();
/* Pointer to library globals */
if (!cg->language[0])
{
- localizationList =
- CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
- kCFPreferencesCurrentApplication);
+ if ((lang = getenv("LANG")))
+ {
+ strlcpy(cg->language, lang, sizeof(cg->language));
+ return (cg->language);
+ }
+ else if ((bundle = CFBundleGetMainBundle()) != NULL &&
+ (bundleList = CFBundleCopyBundleLocalizations(bundle)) != NULL)
+ {
+ localizationList =
+ CFBundleCopyPreferredLocalizationsFromArray(bundleList);
+
+ CFRelease(bundleList);
+ }
+ else
+ localizationList =
+ CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
+ kCFPreferencesCurrentApplication);
- if (localizationList != NULL)
+ if (localizationList)
{
if (CFGetTypeID(localizationList) == CFArrayGetTypeID() &&
CFArrayGetCount(localizationList) > 0)
{
- languageName = CFArrayGetValueAtIndex(localizationList, 0);
+ languageName = CFArrayGetValueAtIndex(localizationList, 0);
- if (languageName != NULL &&
- CFGetTypeID(languageName) == CFStringGetTypeID())
- {
+ if (languageName &&
+ CFGetTypeID(languageName) == CFStringGetTypeID())
+ {
localeName = CFLocaleCreateCanonicalLocaleIdentifierFromString(
- kCFAllocatorDefault, languageName);
+ kCFAllocatorDefault, languageName);
- if (localeName != NULL)
+ if (localeName)
{
CFStringGetCString(localeName, cg->language, sizeof(cg->language),
kCFStringEncodingASCII);
CFRelease(localeName);
- if (!strcmp(cg->language, "en"))
- strlcpy(cg->language, "en_US.UTF-8", sizeof(cg->language));
- else if (strchr(cg->language, '.') == NULL)
+ DEBUG_printf(("appleLangDefault: cg->language=\"%s\"\n",
+ cg->language));
+
+ /*
+ * Map new language identifiers to locales...
+ */
+
+ for (i = 0;
+ i < sizeof(apple_name_locale) / sizeof(apple_name_locale[0]);
+ i++)
+ {
+ if (!strcmp(cg->language, apple_name_locale[i].name))
+ {
+ DEBUG_printf(("appleLangDefault: mapping \"%s\" to \"%s\"...\n",
+ cg->language, apple_name_locale[i].locale));
+ strlcpy(cg->language, apple_name_locale[i].locale,
+ sizeof(cg->language));
+ break;
+ }
+ }
+
+ /*
+ * Convert language subtag into region subtag...
+ */
+
+ if (cg->language[2] == '-')
+ cg->language[2] = '_';
+
+ if (!strchr(cg->language, '.'))
strlcat(cg->language, ".UTF-8", sizeof(cg->language));
}
- }
+ }
}
CFRelease(localizationList);
char buff[256]; /* Temporary buffer */
_cups_globals_t *cg = _cupsGlobals();
/* Pointer to library globals */
+ char *lang; /* LANG environment variable */
/*
* Only do the lookup and translation the first time.
*/
- if (cg->language == NULL)
+ if (!cg->language[0])
{
- localizationList =
- CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
- kCFPreferencesCurrentApplication);
-
- if (localizationList != NULL)
+ if ((lang = getenv("LANG")))
+ strlcpy(cg->language, lang, sizeof(cg->language));
+ else
{
- if (CFGetTypeID(localizationList) == CFArrayGetTypeID() &&
- CFArrayGetCount(localizationList) > 0)
- {
- localizationName = CFArrayGetValueAtIndex(localizationList, 0);
+ localizationList =
+ CFPreferencesCopyAppValue(CFSTR("AppleLanguages"),
+ kCFPreferencesCurrentApplication);
- if (localizationName != NULL &&
- CFGetTypeID(localizationName) == CFStringGetTypeID())
+ if (localizationList != NULL)
+ {
+ if (CFGetTypeID(localizationList) == CFArrayGetTypeID() &&
+ CFArrayGetCount(localizationList) > 0)
{
- CFIndex length = CFStringGetLength(localizationName);
+ localizationName = CFArrayGetValueAtIndex(localizationList, 0);
- if (length <= sizeof(buff) &&
- CFStringGetCString(localizationName, buff, sizeof(buff),
- kCFStringEncodingASCII))
+ if (localizationName != NULL &&
+ CFGetTypeID(localizationName) == CFStringGetTypeID())
{
- buff[sizeof(buff) - 1] = '\0';
+ CFIndex length = CFStringGetLength(localizationName);
- for (i = 0;
- i < sizeof(apple_name_locale) / sizeof(apple_name_locale[0]);
- i++)
+ if (length <= sizeof(buff) &&
+ CFStringGetCString(localizationName, buff, sizeof(buff),
+ kCFStringEncodingASCII))
{
- if (!strcasecmp(buff, apple_name_locale[i].name))
+ buff[sizeof(buff) - 1] = '\0';
+
+ for (i = 0;
+ i < sizeof(apple_name_locale) / sizeof(apple_name_locale[0]);
+ i++)
{
- cg->language = apple_name_locale[i].locale;
- break;
+ if (!strcasecmp(buff, apple_name_locale[i].name))
+ {
+ strlcpy(cg->language, apple_name_locale[i].locale,
+ sizeof(cg->language));
+ break;
+ }
}
}
}
}
- }
- CFRelease(localizationList);
+ CFRelease(localizationList);
+ }
}
/*
* If we didn't find the language, default to en_US...
*/
- if (cg->language == NULL)
- cg->language = apple_name_locale[0].locale;
+ if (!cg->language[0])
+ strlcpy(cg->language, apple_name_locale[0].locale, sizeof(cg->language));
}
/*
* Loop through the cache and return a match if found...
*/
- for (lang = _cupsGlobals()->lang_cache; lang != NULL; lang = lang->next)
+ for (lang = lang_cache; lang != NULL; lang = lang->next)
{
DEBUG_printf(("cups_cache_lookup: lang=%p, language=\"%s\", encoding=%d(%s)\n",
lang, lang->language, lang->encoding,
*d = *d * 8 + *s - '0';
s ++;
}
+
+ d ++;
}
else
{
/*
- * End of "$Id: language.c 4985 2006-01-25 21:57:18Z mike $".
+ * End of "$Id: language.c 6916 2007-09-05 21:14:08Z mike $".
*/