📄 language.c
字号:
/* * "$Id: language.c,v 1.53 2005/01/03 19:29:45 mike Exp $" * * I18N/language support for the Common UNIX Printing System (CUPS). * * Copyright 1997-2005 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 * * This file is subject to the Apple OS-Developed Software exception. * * Contents: * * 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. * _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... *//* * Include necessary headers... */#include <stdio.h>#include <stdlib.h>#include <ctype.h>#ifdef HAVE_LANGINFO_H# include <langinfo.h>#endif /* HAVE_LANGINFO_H */#ifdef WIN32# include <io.h>#else# include <unistd.h>#endif /* WIN32 */#include "string.h"#include "language.h"#include "debug.h"/* * Local functions... */#ifdef __APPLE__# include <CoreFoundation/CoreFoundation.h>static const char *appleLangDefault(void);#endif /* __APPLE__ */static cups_lang_t *cups_cache_lookup(const char *name, cups_encoding_t encoding);/* * Local globals... */static cups_lang_t *lang_cache = NULL; /* Language string cache */static const char lang_blank[] = ""; /* Blank constant string */static const char * const lang_encodings[] = { /* Encoding strings */ "us-ascii", "iso-8859-1", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-9", "iso-8859-10", "utf-8", "iso-8859-13", "iso-8859-14", "iso-8859-15", "windows-874", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "koi8-r", "koi8-u" };static const char * const lang_default[] = { /* Default POSIX locale */#include "cups_C.h" NULL };/* * 'cupsLangEncoding()' - Return the character encoding (us-ascii, etc.) * for the given language. */char * /* O - Character encoding */cupsLangEncoding(cups_lang_t *lang) /* I - Language data */{ if (lang == NULL) return ((char*)lang_encodings[0]); else return ((char*)lang_encodings[lang->encoding]);}/* * 'cupsLangFlush()' - Flush all language data out of the cache. */voidcupsLangFlush(void){ int i; /* Looping var */ cups_lang_t *lang, /* Current language */ *next; /* Next language */ /* * Free all languages in the cache... */ for (lang = lang_cache; lang != NULL; lang = next) { /* * Free all messages... */ for (i = 0; i < CUPS_MSG_MAX; i ++) if (lang->messages[i] != NULL && lang->messages[i] != lang_blank) free(lang->messages[i]); /* * Then free the language structure itself... */ next = lang->next; free(lang); } lang_cache = NULL;}/* * 'cupsLangFree()' - Free language data. * * This does not actually free anything; use cupsLangFlush() for that. */voidcupsLangFree(cups_lang_t *lang) /* I - Language to free */{ if (lang != NULL && lang->used > 0) lang->used --;}/* * 'cupsLangGet()' - Get a language. */cups_lang_t * /* O - Language data */cupsLangGet(const char *language) /* I - Language or locale */{ int i, count; /* Looping vars */ char locale[255], /* Copy of locale name */ 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 */ *localedir; /* Directory for locale files */ cups_encoding_t encoding; /* Encoding to use */ FILE *fp; /* Language locale file pointer */ char line[1024]; /* Line from file */ cups_msg_t msg; /* Message number */ char *text; /* Message text */ cups_lang_t *lang; /* Current language... */ char *oldlocale; /* Old locale name */ static const char * const locale_encodings[] = { /* Locale charset names */ "ASCII", "ISO88591", "ISO88592", "ISO88593", "ISO88594", "ISO88595", "ISO88596", "ISO88597", "ISO88598", "ISO88599", "ISO885910", "UTF8", "ISO885913", "ISO885914", "ISO885915", "CP874", "CP1250", "CP1251", "CP1252", "CP1253", "CP1254", "CP1255", "CP1256", "CP1257", "CP1258", "KOI8R", "KOI8U" }; DEBUG_printf(("cupsLangGet(language=\"%s\")\n", language ? language : "(null)"));#ifdef __APPLE__ /* * Apple's setlocale doesn't give us the user's localization * preference so we have to look it up this way... */ if (language == NULL) language = appleLangDefault();#else if (language == NULL) { /* * First see if the locale has been set; if it is still "C" or * "POSIX", set the locale to the default... */# ifdef LC_MESSAGES ptr = setlocale(LC_MESSAGES, NULL);# else ptr = setlocale(LC_ALL, NULL);# endif /* LC_MESSAGES */ DEBUG_printf(("cupsLangGet: current locale is \"%s\"\n", ptr ? ptr : "(null)")); if (!ptr || !strcmp(ptr, "C") || !strcmp(ptr, "POSIX"))# ifdef LC_MESSAGES { ptr = setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); }# 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)")); } }#endif /* __APPLE__ */ /* * If "language" is NULL at this point, then chances are we are using * a language that is not installed for the base OS. */ if (!language) { /* * Switch to the value of the "LANG" environment variable, and if * that is NULL as well, use "C". */ if ((language = getenv("LANG")) == NULL) 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) { /* * Copy all of the letters and numbers in the CODESET string... */ for (ptr = charset; *csptr; csptr ++) if (isalnum(*csptr & 255) && ptr < (charset + sizeof(charset) - 1)) *ptr++ = *csptr; *ptr = '\0'; DEBUG_printf(("cupsLangGet: charset set to \"%s\" via nl_langinfo(CODESET)...\n", charset)); }#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 defined(__APPLE__) /* The ctype bug isn't in Apple's libc */#elif !defined(LC_CTYPE) oldlocale = _cupsSaveLocale(LC_ALL, "C");#else oldlocale = _cupsSaveLocale(LC_CTYPE, "C");#endif /* __APPLE__ */ /* * Parse the language string passed in to a locale string. "C" is the * standard POSIX locale and is copied unchanged. Otherwise the * language string is converted from ll-cc[.charset] (language-country) * to ll_CC[.CHARSET] to match the file naming convention used by all * POSIX-compliant operating systems. Invalid language names are mapped * to the POSIX locale. */ country[0] = '\0'; if (language == NULL || !language[0] || strcmp(language, "POSIX") == 0) strcpy(langname, "C"); else { /* * Copy the parts of the locale string over safely... */ for (ptr = langname; *language; language ++) if (*language == '_' || *language == '-' || *language == '.') break; else if (ptr < (langname + sizeof(langname) - 1)) *ptr++ = tolower(*language & 255); *ptr = '\0'; if (*language == '_' || *language == '-') { /* * Copy the country code... */ for (language ++, ptr = country; *language; language ++) if (*language == '.') break; else if (ptr < (country + sizeof(country) - 1)) *ptr++ = toupper(*language & 255); *ptr = '\0'; } if (*language == '.' && !charset[0]) { /* * Copy the encoding... */ for (language ++, ptr = charset; *language; language ++) if (isalnum(*language & 255) && ptr < (charset + sizeof(charset) - 1)) *ptr++ = toupper(*language & 255); *ptr = '\0'; } /* * Force a POSIX locale for an invalid language name... */ if (strlen(langname) != 2) { strcpy(langname, "C"); country[0] = '\0'; charset[0] = '\0'; } } /* * 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)); /* * Figure out the desired encoding... */ encoding = CUPS_AUTO_ENCODING; if (charset[0]) { 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; } } DEBUG_printf(("cupsLangGet: encoding=%d(%s)\n", encoding, encoding == CUPS_AUTO_ENCODING ? "auto" : lang_encodings[encoding])); /* * Now find the message catalog for this locale... */ if ((localedir = getenv("LOCALEDIR")) == NULL) localedir = CUPS_LOCALEDIR; /* * See if we already have this language/country loaded... */ snprintf(real, sizeof(real), "%s_%s", langname, country); if ((lang = cups_cache_lookup(real, encoding)) != NULL) return (lang); snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir, real, real); 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", localedir, langname, langname); if (access(filename, 0)) { /* * No generic localization, so use POSIX... */ strcpy(real, "C"); snprintf(filename, sizeof(filename), "%s/C/cups_C", localedir); } else strcpy(real, langname); } /* * Open the messages file; the first line contains the default * language encoding (us-ascii, iso-8859-1, etc.), and the rest are
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -