~ubuntu-branches/ubuntu/oneiric/cups/oneiric-proposed

« back to all changes in this revision

Viewing changes to cups/language.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt, Till Kamppeter, Martin Pitt
  • Date: 2011-08-07 12:53:12 UTC
  • mfrom: (1.2.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20110807125312-s323cyb3oqaxaemo
Tags: 1.5.0-1
[ Till Kamppeter ]
* New upstream release
* debian/patches/usb-backend-no-segfault-on-bad-device-id.patch,
  debian/patches/usb-backend-accept-old-usblp-uris.patch,
  debian/patches/use-ps2write-ghostscript-device-for-pdftops-filter.patch:
  Removed, included upstream.
* debian/patches/poppler-based-pdftops-fixes.patch,
  debian/patches/do-not-emit-ps-level-3-with-poppler.patch: Replaced patch
  by a new one only containing the parts which remain after removing the
  parts included upstream.
* debian/patches/pidfile.patch,
  debian/patches/ppd-poll-with-client-conf.patch,
  debian/patches/cups-avahi.patch,
  debian/patches/drop_unnecessary_dependencies.patch,
  debian/patches/do-not-broadcast-with-hostnames.patch,
  debian/patches/ppdc-dynamic-linking.patch,
  debian/patches/pstops-based-workflow-only-for-printing-ps-on-a-ps-printer.patch:
  Manually regenerated to adapt to upstream changes.
* debian/patches/manpage-translations.patch,
  debian/patches/rootbackends-worldreadable.patch,
  debian/patches/no-conffile-timestamp.patch,
  debian/patches/read-embedded-options-from-incoming-postscript-and-add-to-ipp-attrs.patch,
  debian/patches/cups-snmp-oids-device-id-hp-ricoh.patch,
  debian/patches/configure-default-browse-protocols.patch,
  debian/patches/logfiles_adm_readable.patch,
  debian/patches/confdirperms.patch,
  debian/patches/printer-filtering.patch,
  debian/patches/show-compile-command-lines.patch,
  debian/patches/log-debug-history-nearly-unlimited.patch:
  Refreshed using quilt.
* debian/patches/default-ripcache-size-auto.patch: Dropped, as once,
  Ghostscript 9.04 is ignoring the cache size value as it crashes easily
  otherwise (Ghostscript upstream bug #691586) and second, CUPS defaults to
  more reasonable 128 MB (now only used for imagetops).
* debian/patches/support-gzipped-charmaps.patch: Dropped, as the SBCS and
  VBCS character maps are not used any more by CUPS.
* debian/rules: Enable threads in the ./configure command line, as otherwise
  CUPS 1.5.0 does not build at all.
* debian/local/filters/pdf-filters/filter/pdftoijs.cxx,
  debian/local/filters/pdf-filters/filter/pdftoraster.cxx,
  debian/local/filters/pdf-filters/pdftoopvp/pdftoopvp.cxx,
  debian/local/filters/pdf-filters/pdftopdf/pdftopdf.cxx: Under CUPS 1.5.x.
  all programs using the PPD API of CUPS need to explicitly include
  "<cups/ppd.h>". Updated the PDF filter add-on package.
* debian/local/filters/pdf-filters/addtocups: Make the addition of the
  pdftopdf and pdftoopvp directories also work with CUPS 1.5.x.
* debian/local/filters/pdf-filters/addtocups,
  debian/local/filters/pdf-filters/removefromcups: Added a symbolic link
  cups/i18n.h, so that texttopdf builds.
* debian/cups-client.install: Install the new ipptool and its sample
  files and manpages.
* debian/cups-client.install: Commented out lines for dropped man page
  translations: ipptool, lppasswd, client.conf, ipptoolfile, cupsenable,
  lpadmin, lpinfo, cupsreject, cupsdisable, cupsaccept
* debian/cups-common.install, debian/rules: The /usr/share/cups/charmaps
  directory got removed from CUPS.
* debian/libcups2-dev.install: cups/i18n.h got renamed to
  cups/language-private.h. Install this as /usr/include/cups/i18n.h.
* debian/libcups2.symbols, debian/libcupsmime1.symbols: Updated.
* debian/cups.lintian-overrides, debian/cups.postinst, debian/cups.prerm,
  debian/cups.templates, debian/local/apparmor-profile: The "scsi"
  CUPS backend got dropped upstream, removed its treatment from these files.

[ Martin Pitt ]
* Add Serbian (Cyrillic) debconf translations, thanks Zlatan Todoric.
  (Closes: #635105)
* Add Serbian (Latin) debconf translations, thanks Zlatan Todoric.
  (Closes: #635108)
* debian/local/apparmor-profile: Allow access to serial printers on USB
  adapters. (LP: #677432)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * "$Id: language.c 9233 2010-08-10 06:15:55Z mike $"
3
 
 *
4
 
 *   I18N/language support for the Common UNIX Printing System (CUPS).
5
 
 *
6
 
 *   Copyright 2007-2009 by Apple Inc.
 
2
 * "$Id: language.c 9793 2011-05-20 03:49:49Z mike $"
 
3
 *
 
4
 *   I18N/language support for CUPS.
 
5
 *
 
6
 *   Copyright 2007-2011 by Apple Inc.
7
7
 *   Copyright 1997-2007 by Easy Software Products.
8
8
 *
9
9
 *   These coded instructions, statements, and computer programs are the
16
16
 *
17
17
 * Contents:
18
18
 *
19
 
 *   _cupsAppleLanguage()   - Get the Apple language identifier associated
20
 
 *                            with a locale ID.
21
 
 *   _cupsEncodingName()    - Return the character encoding name string
22
 
 *                            for the given encoding enumeration.
 
19
 *   _cupsAppleLanguage()   - Get the Apple language identifier associated with
 
20
 *                            a locale ID.
 
21
 *   _cupsEncodingName()    - Return the character encoding name string for the
 
22
 *                            given encoding enumeration.
23
23
 *   cupsLangDefault()      - Return the default language.
24
 
 *   cupsLangEncoding()     - Return the character encoding (us-ascii, etc.)
25
 
 *                            for the given language.
 
24
 *   cupsLangEncoding()     - Return the character encoding (us-ascii, etc.) for
 
25
 *                            the given language.
26
26
 *   cupsLangFlush()        - Flush all language data out of the cache.
27
27
 *   cupsLangFree()         - Free language data.
28
28
 *   cupsLangGet()          - Get a language.
31
31
 *   _cupsMessageLoad()     - Load a .po file into a messages array.
32
32
 *   _cupsMessageLookup()   - Lookup a message string.
33
33
 *   appleLangDefault()     - Get the default locale string.
 
34
 *   appleMessageLoad()     - Load a message catalog from a localizable bundle.
34
35
 *   cups_cache_lookup()    - Lookup a language in the cache...
35
36
 *   cups_message_compare() - Compare two messages.
 
37
 *   cups_message_free()    - Free a message.
36
38
 *   cups_unquote()         - Unquote characters in strings...
37
39
 */
38
40
 
40
42
 * Include necessary headers...
41
43
 */
42
44
 
43
 
#include "globals.h"
44
 
#include "debug.h"
45
 
#include <stdlib.h>
46
 
#include <errno.h>
 
45
#include "cups-private.h"
47
46
#ifdef HAVE_LANGINFO_H
48
47
#  include <langinfo.h>
49
48
#endif /* HAVE_LANGINFO_H */
61
60
 * Local globals...
62
61
 */
63
62
 
64
 
#ifdef HAVE_PTHREAD_H
65
 
static pthread_mutex_t  lang_mutex = PTHREAD_MUTEX_INITIALIZER;
 
63
static _cups_mutex_t    lang_mutex = _CUPS_MUTEX_INITIALIZER;
66
64
                                        /* Mutex to control access to cache */
67
 
#endif /* HAVE_PTHREAD_H */
68
65
static cups_lang_t      *lang_cache = NULL;
69
66
                                        /* Language string cache */
70
67
static const char * const lang_encodings[] =
76
73
                          "iso-8859-8",         "iso-8859-9",
77
74
                          "iso-8859-10",        "utf-8",
78
75
                          "iso-8859-13",        "iso-8859-14",
79
 
                          "iso-8859-15",        "windows-874",
80
 
                          "windows-1250",       "windows-1251",
81
 
                          "windows-1252",       "windows-1253",
82
 
                          "windows-1254",       "windows-1255",
83
 
                          "windows-1256",       "windows-1257",
84
 
                          "windows-1258",       "koi8-r",
 
76
                          "iso-8859-15",        "cp874",
 
77
                          "cp1250",             "cp1251",
 
78
                          "cp1252",             "cp1253",
 
79
                          "cp1254",             "cp1255",
 
80
                          "cp1256",             "cp1257",
 
81
                          "cp1258",             "koi8-r",
85
82
                          "koi8-u",             "iso-8859-11",
86
83
                          "iso-8859-16",        "mac-roman",
87
84
                          "unknown",            "unknown",
101
98
                          "unknown",            "unknown",
102
99
                          "unknown",            "unknown",
103
100
                          "unknown",            "unknown",
104
 
                          "windows-932",        "windows-936",
105
 
                          "windows-949",        "windows-950",
106
 
                          "windows-1361",       "unknown",
 
101
                          "cp932",              "cp936",
 
102
                          "cp949",              "cp950",
 
103
                          "cp1361",             "unknown",
107
104
                          "unknown",            "unknown",
108
105
                          "unknown",            "unknown",
109
106
                          "unknown",            "unknown",
147
144
 
148
145
static const _apple_language_locale_t apple_language_locale[] =
149
146
{                                       /* Locale to language ID LUT */
150
 
  { "en"        , "en_US" },
151
 
  { "nb"        , "no"    },
152
 
  { "zh-Hans"   , "zh_CN" },
153
 
  { "zh-Hant"   , "zh_TW" }
 
147
  { "en",      "en_US" },
 
148
  { "nb",      "no" },
 
149
  { "zh-Hans", "zh_CN" },
 
150
  { "zh-Hant", "zh_TW" }
154
151
};
155
152
#endif /* __APPLE__ */
156
153
 
159
156
 * Local functions...
160
157
 */
161
158
 
 
159
 
162
160
#ifdef __APPLE__
163
161
static const char       *appleLangDefault(void);
 
162
#  ifdef CUPS_BUNDLEDIR
 
163
#    ifndef CF_RETURNS_RETAINED
 
164
#      if __has_feature(attribute_cf_returns_retained)
 
165
#        define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
 
166
#      else
 
167
#        define CF_RETURNS_RETAINED
 
168
#      endif /* __has_feature(attribute_cf_returns_retained) */
 
169
#    endif /* !CF_RETURNED_RETAINED */
 
170
static cups_array_t     *appleMessageLoad(const char *locale)
 
171
                        CF_RETURNS_RETAINED;
 
172
#  endif /* CUPS_BUNDLEDIR */
164
173
#endif /* __APPLE__ */
165
174
static cups_lang_t      *cups_cache_lookup(const char *name,
166
175
                                           cups_encoding_t encoding);
167
176
static int              cups_message_compare(_cups_message_t *m1,
168
177
                                             _cups_message_t *m2);
 
178
static void             cups_message_free(_cups_message_t *m);
169
179
static void             cups_unquote(char *d, const char *s);
170
180
 
171
181
 
172
182
#ifdef __APPLE__
173
183
/*
174
 
 *   _cupsAppleLanguage()   - Get the Apple language identifier associated
175
 
 *                            with a locale ID.
 
184
 * '_cupsAppleLanguage()' - Get the Apple language identifier associated with a
 
185
 *                          locale ID.
176
186
 */
177
187
 
178
188
const char *                            /* O - Language ID */
322
332
  * Free all languages in the cache...
323
333
  */
324
334
 
325
 
#ifdef HAVE_PTHREAD_H
326
 
  pthread_mutex_lock(&lang_mutex);
327
 
#endif /* HAVE_PTHREAD_H */
 
335
  _cupsMutexLock(&lang_mutex);
328
336
 
329
337
  for (lang = lang_cache; lang != NULL; lang = next)
330
338
  {
344
352
 
345
353
  lang_cache = NULL;
346
354
 
347
 
#ifdef HAVE_PTHREAD_H
348
 
  pthread_mutex_unlock(&lang_mutex);
349
 
#endif /* HAVE_PTHREAD_H */
 
355
  _cupsMutexUnlock(&lang_mutex);
350
356
}
351
357
 
352
358
 
359
365
void
360
366
cupsLangFree(cups_lang_t *lang)         /* I - Language to free */
361
367
{
362
 
#ifdef HAVE_PTHREAD_H
363
 
  pthread_mutex_lock(&lang_mutex);
364
 
#endif /* HAVE_PTHREAD_H */
 
368
  _cupsMutexLock(&lang_mutex);
365
369
 
366
370
  if (lang != NULL && lang->used > 0)
367
371
    lang->used --;
368
372
 
369
 
#ifdef HAVE_PTHREAD_H
370
 
  pthread_mutex_unlock(&lang_mutex);
371
 
#endif /* HAVE_PTHREAD_H */
 
373
  _cupsMutexUnlock(&lang_mutex);
372
374
}
373
375
 
374
376
 
388
390
                        charset[16],    /* Character set */
389
391
                        *csptr,         /* Pointer to CODESET string */
390
392
                        *ptr,           /* Pointer into language/charset */
391
 
                        real[48],       /* Real language name */
392
 
                        filename[1024]; /* Filename for language locale file */
 
393
                        real[48];       /* Real language name */
393
394
  cups_encoding_t       encoding;       /* Encoding to use */
394
395
  cups_lang_t           *lang;          /* Current language... */
 
396
#if !defined(__APPLE__) || !defined(CUPS_BUNDLEDIR)
 
397
  char                  filename[1024]; /* Filename for language locale file */
395
398
  _cups_globals_t       *cg = _cupsGlobals();
396
399
                                        /* Pointer to library globals */
 
400
#endif /* !__APPLE__ || !CUPS_BUNDLEDIR */
397
401
  static const char * const locale_encodings[] =
398
402
                {                       /* Locale charset names */
399
403
                  "ASCII",      "ISO88591",     "ISO88592",     "ISO88593",
447
451
  strcpy(charset, "UTF8");
448
452
 
449
453
 /*
450
 
  * Apple's setlocale doesn't give us the user's localization 
 
454
  * Apple's setlocale doesn't give us the user's localization
451
455
  * preference so we have to look it up this way...
452
456
  */
453
457
 
664
668
    for (i = 0;
665
669
         i < (int)(sizeof(locale_encodings) / sizeof(locale_encodings[0]));
666
670
         i ++)
667
 
      if (!strcasecmp(charset, locale_encodings[i]))
 
671
      if (!_cups_strcasecmp(charset, locale_encodings[i]))
668
672
      {
669
673
        encoding = (cups_encoding_t)i;
670
674
        break;
676
680
      * Map alternate names for various character sets...
677
681
      */
678
682
 
679
 
      if (!strcasecmp(charset, "iso-2022-jp") ||
680
 
          !strcasecmp(charset, "sjis"))
 
683
      if (!_cups_strcasecmp(charset, "iso-2022-jp") ||
 
684
          !_cups_strcasecmp(charset, "sjis"))
681
685
        encoding = CUPS_WINDOWS_932;
682
 
      else if (!strcasecmp(charset, "iso-2022-cn"))
 
686
      else if (!_cups_strcasecmp(charset, "iso-2022-cn"))
683
687
        encoding = CUPS_WINDOWS_936;
684
 
      else if (!strcasecmp(charset, "iso-2022-kr"))
 
688
      else if (!_cups_strcasecmp(charset, "iso-2022-kr"))
685
689
        encoding = CUPS_WINDOWS_949;
686
 
      else if (!strcasecmp(charset, "big5"))
 
690
      else if (!_cups_strcasecmp(charset, "big5"))
687
691
        encoding = CUPS_WINDOWS_950;
688
692
    }
689
693
  }
700
704
  {
701
705
    snprintf(real, sizeof(real), "%s_%s", langname, country);
702
706
 
 
707
#if !defined(__APPLE__) || !defined(CUPS_BUNDLEDIR)
703
708
    snprintf(filename, sizeof(filename), "%s/%s/cups_%s.po", cg->localedir,
704
709
             real, real);
 
710
#endif /* !__APPLE__ || !CUPS_BUNDLEDIR */
705
711
  }
706
712
  else
707
713
  {
708
714
    strcpy(real, langname);
 
715
#if !defined(__APPLE__) || !defined(CUPS_BUNDLEDIR)
709
716
    filename[0] = '\0';                 /* anti-compiler-warning-code */
 
717
#endif /* !__APPLE__ || !CUPS_BUNDLEDIR */
710
718
  }
711
719
 
712
 
#ifdef HAVE_PTHREAD_H
713
 
  pthread_mutex_lock(&lang_mutex);
714
 
#endif /* HAVE_PTHREAD_H */
 
720
  _cupsMutexLock(&lang_mutex);
715
721
 
716
722
  if ((lang = cups_cache_lookup(real, encoding)) != NULL)
717
723
  {
718
 
#ifdef HAVE_PTHREAD_H
719
 
    pthread_mutex_unlock(&lang_mutex);
720
 
#endif /* HAVE_PTHREAD_H */
 
724
    _cupsMutexUnlock(&lang_mutex);
721
725
 
722
726
    DEBUG_printf(("3cupsLangGet: Using cached copy of \"%s\"...", real));
723
727
 
724
728
    return (lang);
725
729
  }
726
730
 
 
731
#if !defined(__APPLE__) || !defined(CUPS_BUNDLEDIR)
727
732
  if (!country[0] || access(filename, 0))
728
733
  {
729
734
   /*
745
750
      snprintf(filename, sizeof(filename), "%s/C/cups_C.po", cg->localedir);
746
751
    }
747
752
  }
 
753
#endif /* !__APPLE__ || !CUPS_BUNDLEDIR */
748
754
 
749
755
 /*
750
756
  * See if there is a free language available; if so, use that
763
769
 
764
770
    if ((lang = calloc(sizeof(cups_lang_t), 1)) == NULL)
765
771
    {
766
 
#ifdef HAVE_PTHREAD_H
767
 
      pthread_mutex_unlock(&lang_mutex);
768
 
#endif /* HAVE_PTHREAD_H */
 
772
      _cupsMutexUnlock(&lang_mutex);
769
773
 
770
774
      return (NULL);
771
775
    }
798
802
  * Read the strings from the file...
799
803
  */
800
804
 
 
805
#if defined(__APPLE__) && defined(CUPS_BUNDLEDIR)
 
806
  lang->strings = appleMessageLoad(lang->language);
 
807
#else
801
808
  lang->strings = _cupsMessageLoad(filename, 1);
 
809
#endif /* __APPLE__ && CUPS_BUNDLEDIR */
802
810
 
803
811
 /*
804
812
  * Return...
805
813
  */
806
814
 
807
 
#ifdef HAVE_PTHREAD_H
808
 
  pthread_mutex_unlock(&lang_mutex);
809
 
#endif /* HAVE_PTHREAD_H */
 
815
  _cupsMutexUnlock(&lang_mutex);
810
816
 
811
817
  return (lang);
812
818
}
823
829
_cupsLangString(cups_lang_t *lang,      /* I - Language */
824
830
                const char  *message)   /* I - Message */
825
831
{
 
832
  const char *s;                        /* Localized message */
 
833
 
826
834
 /*
827
835
  * Range check input...
828
836
  */
830
838
  if (!lang || !message)
831
839
    return (message);
832
840
 
833
 
#ifdef HAVE_PTHREAD_H
834
 
  {
835
 
    const char *s;                      /* Localized message */
836
 
 
837
 
    pthread_mutex_lock(&lang_mutex);
838
 
 
839
 
    s = _cupsMessageLookup(lang->strings, message);
840
 
 
841
 
    pthread_mutex_unlock(&lang_mutex);
842
 
 
843
 
    return (s);
844
 
  }
845
 
#else
846
 
  return (_cupsMessageLookup(lang->strings, message));
847
 
#endif /* HAVE_PTHREAD_H */
 
841
  _cupsMutexLock(&lang_mutex);
 
842
 
 
843
  s = _cupsMessageLookup(lang->strings, message);
 
844
 
 
845
  _cupsMutexUnlock(&lang_mutex);
 
846
 
 
847
  return (s);
848
848
}
849
849
 
850
850
 
855
855
void
856
856
_cupsMessageFree(cups_array_t *a)       /* I - Message array */
857
857
{
858
 
  _cups_message_t       *m;             /* Current message */
859
 
 
860
 
 
861
 
  for (m = (_cups_message_t *)cupsArrayFirst(a);
862
 
       m;
863
 
       m = (_cups_message_t *)cupsArrayNext(a))
864
 
  {
865
 
   /*
866
 
    * Remove the message from the array, then free the message and strings.
867
 
    */
868
 
 
869
 
    cupsArrayRemove(a, m);
870
 
 
871
 
    if (m->id)
872
 
      free(m->id);
873
 
 
874
 
    if (m->str)
875
 
      free(m->str);
876
 
 
877
 
    free(m);
878
 
  }
 
858
#if defined(__APPLE__) && defined(CUPS_BUNDLEDIR)
 
859
 /*
 
860
  * Release the cups.strings dictionary as needed...
 
861
  */
 
862
 
 
863
  if (cupsArrayUserData(a))
 
864
    CFRelease((CFDictionaryRef)cupsArrayUserData(a));
 
865
#endif /* __APPLE__ && CUPS_BUNDLEDIR */
879
866
 
880
867
 /*
881
868
  * Free the array...
891
878
 
892
879
cups_array_t *                          /* O - New message array */
893
880
_cupsMessageLoad(const char *filename,  /* I - Message catalog to load */
894
 
                 int        unquote)    /* I - Unescape \foo in strings */
 
881
                 int        unquote)    /* I - Unescape \foo in strings? */
895
882
{
896
883
  cups_file_t           *fp;            /* Message file */
897
884
  cups_array_t          *a;             /* Message array */
908
895
  * Create an array to hold the messages...
909
896
  */
910
897
 
911
 
  if ((a = cupsArrayNew((cups_array_func_t)cups_message_compare, NULL)) == NULL)
 
898
  if ((a = cupsArrayNew3((cups_array_func_t)cups_message_compare, NULL,
 
899
                         (cups_ahash_func_t)NULL, 0,
 
900
                         (cups_acopy_func_t)NULL,
 
901
                         (cups_afree_func_t)cups_message_free)) == NULL)
912
902
  {
913
903
    DEBUG_puts("5_cupsMessageLoad: Unable to allocate array!");
914
904
    return (NULL);
965
955
   /*
966
956
    * Find start of value...
967
957
    */
968
 
    
 
958
 
969
959
    if ((ptr = strchr(s, '\"')) == NULL)
970
960
      continue;
971
961
 
1102
1092
  key.id = (char *)m;
1103
1093
  match  = (_cups_message_t *)cupsArrayFind(a, &key);
1104
1094
 
 
1095
#if defined(__APPLE__) && defined(CUPS_BUNDLEDIR)
 
1096
  if (!match && cupsArrayUserData(a))
 
1097
  {
 
1098
   /*
 
1099
    * Try looking the string up in the cups.strings dictionary...
 
1100
    */
 
1101
 
 
1102
    CFDictionaryRef     dict;           /* cups.strings dictionary */
 
1103
    CFStringRef         cfm,            /* Message as a CF string */
 
1104
                        cfstr;          /* Localized text as a CF string */
 
1105
 
 
1106
    dict      = (CFDictionaryRef)cupsArrayUserData(a);
 
1107
    cfm       = CFStringCreateWithCString(kCFAllocatorDefault, m,
 
1108
                                          kCFStringEncodingUTF8);
 
1109
    match     = calloc(1, sizeof(_cups_message_t));
 
1110
    match->id = strdup(m);
 
1111
    cfstr     = cfm ? CFDictionaryGetValue(dict, cfm) : NULL;
 
1112
 
 
1113
    if (cfstr)
 
1114
    {
 
1115
      char      buffer[1024];           /* Message buffer */
 
1116
 
 
1117
      CFStringGetCString(cfstr, buffer, sizeof(buffer), kCFStringEncodingUTF8);
 
1118
      match->str = strdup(buffer);
 
1119
 
 
1120
      DEBUG_printf(("1_cupsMessageLookup: Found \"%s\" as \"%s\"...",
 
1121
                    m, buffer));
 
1122
    }
 
1123
    else
 
1124
    {
 
1125
      match->str = strdup(m);
 
1126
 
 
1127
      DEBUG_printf(("1_cupsMessageLookup: Did not find \"%s\"...", m));
 
1128
    }
 
1129
 
 
1130
    cupsArrayAdd(a, match);
 
1131
 
 
1132
    if (cfm)
 
1133
      CFRelease(cfm);
 
1134
  }
 
1135
#endif /* __APPLE__ && CUPS_BUNDLEDIR */
 
1136
 
1105
1137
  if (match && match->str)
1106
1138
    return (match->str);
1107
1139
  else
1190
1222
              {
1191
1223
                DEBUG_printf(("9appleLangDefault: mapping \"%s\" to \"%s\"...",
1192
1224
                              cg->language, apple_language_locale[i].locale));
1193
 
                strlcpy(cg->language, apple_language_locale[i].locale, 
 
1225
                strlcpy(cg->language, apple_language_locale[i].locale,
1194
1226
                        sizeof(cg->language));
1195
1227
                break;
1196
1228
              }
1211
1243
 
1212
1244
      CFRelease(localizationList);
1213
1245
    }
1214
 
  
 
1246
 
1215
1247
   /*
1216
1248
    * If we didn't find the language, default to en_US...
1217
1249
    */
1226
1258
 
1227
1259
  return (cg->language);
1228
1260
}
 
1261
 
 
1262
 
 
1263
#  ifdef CUPS_BUNDLEDIR
 
1264
/*
 
1265
 * 'appleMessageLoad()' - Load a message catalog from a localizable bundle.
 
1266
 */
 
1267
 
 
1268
static cups_array_t *                   /* O - Message catalog */
 
1269
appleMessageLoad(const char *locale)    /* I - Locale ID */
 
1270
{
 
1271
  char                  filename[1024], /* Path to cups.strings file */
 
1272
                        applelang[256]; /* Apple language ID */
 
1273
  CFURLRef              url;            /* URL to cups.strings file */
 
1274
  CFReadStreamRef       stream = NULL;  /* File stream */
 
1275
  CFPropertyListRef     plist = NULL;   /* Localization file */
 
1276
#ifdef DEBUG
 
1277
  CFErrorRef            error = NULL;   /* Error when opening file */
 
1278
#endif /* DEBUG */
 
1279
 
 
1280
 
 
1281
  DEBUG_printf(("appleMessageLoad(locale=\"%s\")", locale));
 
1282
 
 
1283
 /*
 
1284
  * Load the cups.strings file...
 
1285
  */
 
1286
 
 
1287
  snprintf(filename, sizeof(filename),
 
1288
           CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings",
 
1289
           _cupsAppleLanguage(locale, applelang, sizeof(applelang)));
 
1290
  DEBUG_printf(("1appleMessageLoad: filename=\"%s\"", filename));
 
1291
 
 
1292
  if (access(filename, 0))
 
1293
  {
 
1294
   /*
 
1295
    * Try alternate lproj directory names...
 
1296
    */
 
1297
 
 
1298
    if (!strncmp(locale, "en", 2))
 
1299
      locale = "English";
 
1300
    else if (!strncmp(locale, "nb", 2) || !strncmp(locale, "nl", 2))
 
1301
      locale = "Dutch";
 
1302
    else if (!strncmp(locale, "fr", 2))
 
1303
      locale = "French";
 
1304
    else if (!strncmp(locale, "de", 2))
 
1305
      locale = "German";
 
1306
    else if (!strncmp(locale, "it", 2))
 
1307
      locale = "Italian";
 
1308
    else if (!strncmp(locale, "ja", 2))
 
1309
      locale = "Japanese";
 
1310
    else if (!strncmp(locale, "es", 2))
 
1311
      locale = "Spanish";
 
1312
 
 
1313
    snprintf(filename, sizeof(filename),
 
1314
             CUPS_BUNDLEDIR "/Resources/%s.lproj/cups.strings", locale);
 
1315
    DEBUG_printf(("1appleMessageLoad: alternate filename=\"%s\"", filename));
 
1316
  }
 
1317
 
 
1318
  url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
 
1319
                                                (UInt8 *)filename,
 
1320
                                                strlen(filename), false);
 
1321
  if (url)
 
1322
  {
 
1323
    stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
 
1324
    if (stream)
 
1325
    {
 
1326
     /*
 
1327
      * Read the property list containing the localization data.
 
1328
      *
 
1329
      * NOTE: This code currently generates a clang "potential leak"
 
1330
      * warning, but the object is released in _cupsMessageFree().
 
1331
      */
 
1332
 
 
1333
      CFReadStreamOpen(stream);
 
1334
 
 
1335
#ifdef DEBUG
 
1336
      plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0,
 
1337
                                             kCFPropertyListImmutable, NULL,
 
1338
                                             &error);
 
1339
      if (error)
 
1340
      {
 
1341
        CFStringRef     msg = CFErrorCopyDescription(error);
 
1342
                                        /* Error message */
 
1343
 
 
1344
        CFStringGetCString(msg, filename, sizeof(filename),
 
1345
                           kCFStringEncodingUTF8);
 
1346
        DEBUG_printf(("1appleMessageLoad: %s", filename));
 
1347
 
 
1348
        CFRelease(msg);
 
1349
        CFRelease(error);
 
1350
      }
 
1351
 
 
1352
#else
 
1353
      plist = CFPropertyListCreateWithStream(kCFAllocatorDefault, stream, 0,
 
1354
                                             kCFPropertyListImmutable, NULL,
 
1355
                                             NULL);
 
1356
#endif /* DEBUG */
 
1357
 
 
1358
      if (plist && CFGetTypeID(plist) != CFDictionaryGetTypeID())
 
1359
      {
 
1360
         CFRelease(plist);
 
1361
         plist = NULL;
 
1362
      }
 
1363
 
 
1364
      CFRelease(stream);
 
1365
    }
 
1366
 
 
1367
    CFRelease(url);
 
1368
  }
 
1369
 
 
1370
  DEBUG_printf(("1appleMessageLoad: url=%p, stream=%p, plist=%p", url, stream,
 
1371
                plist));
 
1372
 
 
1373
 /*
 
1374
  * Create and return an empty array to act as a cache for messages, passing the
 
1375
  * plist as the user data.
 
1376
  */
 
1377
 
 
1378
  return (cupsArrayNew3((cups_array_func_t)cups_message_compare, (void *)plist,
 
1379
                        (cups_ahash_func_t)NULL, 0,
 
1380
                        (cups_acopy_func_t)NULL,
 
1381
                        (cups_afree_func_t)cups_message_free));
 
1382
}
 
1383
#  endif /* CUPS_BUNDLEDIR */
1229
1384
#endif /* __APPLE__ */
1230
1385
 
1231
1386
 
1234
1389
 */
1235
1390
 
1236
1391
static cups_lang_t *                    /* O - Language data or NULL */
1237
 
cups_cache_lookup(const char      *name,/* I - Name of locale */
1238
 
                  cups_encoding_t encoding)
1239
 
                                        /* I - Encoding of locale */
 
1392
cups_cache_lookup(
 
1393
    const char      *name,              /* I - Name of locale */
 
1394
    cups_encoding_t encoding)           /* I - Encoding of locale */
1240
1395
{
1241
1396
  cups_lang_t   *lang;                  /* Current language */
1242
1397
 
1286
1441
 
1287
1442
 
1288
1443
/*
 
1444
 * 'cups_message_free()' - Free a message.
 
1445
 */
 
1446
 
 
1447
static void
 
1448
cups_message_free(_cups_message_t *m)   /* I - Message */
 
1449
{
 
1450
  if (m->id)
 
1451
    free(m->id);
 
1452
 
 
1453
  if (m->str)
 
1454
    free(m->str);
 
1455
 
 
1456
  free(m);
 
1457
}
 
1458
 
 
1459
 
 
1460
/*
1289
1461
 * 'cups_unquote()' - Unquote characters in strings...
1290
1462
 */
1291
1463
 
1333
1505
 
1334
1506
 
1335
1507
/*
1336
 
 * End of "$Id: language.c 9233 2010-08-10 06:15:55Z mike $".
 
1508
 * End of "$Id: language.c 9793 2011-05-20 03:49:49Z mike $".
1337
1509
 */