Blame intl/langprefs.c

Packit Service a721b1
/* Determine the user's language preferences.
Packit Service a721b1
   Copyright (C) 2004-2006 Free Software Foundation, Inc.
Packit Service a721b1
Packit Service a721b1
   This program is free software; you can redistribute it and/or modify it
Packit Service a721b1
   under the terms of the GNU Library General Public License as published
Packit Service a721b1
   by the Free Software Foundation; either version 2, or (at your option)
Packit Service a721b1
   any later version.
Packit Service a721b1
Packit Service a721b1
   This program is distributed in the hope that it will be useful,
Packit Service a721b1
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a721b1
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service a721b1
   Library General Public License for more details.
Packit Service a721b1
Packit Service a721b1
   You should have received a copy of the GNU Library General Public
Packit Service a721b1
   License along with this program; if not, write to the Free Software
Packit Service a721b1
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
Packit Service a721b1
   USA.  */
Packit Service a721b1
Packit Service a721b1
/* Written by Bruno Haible <bruno@clisp.org>.  */
Packit Service a721b1
Packit Service a721b1
#ifdef HAVE_CONFIG_H
Packit Service a721b1
# include <config.h>
Packit Service a721b1
#endif
Packit Service a721b1
Packit Service a721b1
#include <stdlib.h>
Packit Service a721b1
Packit Service a721b1
#if HAVE_CFPREFERENCESCOPYAPPVALUE
Packit Service a721b1
# include <string.h>
Packit Service a721b1
# include <CoreFoundation/CFPreferences.h>
Packit Service a721b1
# include <CoreFoundation/CFPropertyList.h>
Packit Service a721b1
# include <CoreFoundation/CFArray.h>
Packit Service a721b1
# include <CoreFoundation/CFString.h>
Packit Service a721b1
extern void _nl_locale_name_canonicalize (char *name);
Packit Service a721b1
#endif
Packit Service a721b1
Packit Service a721b1
/* Determine the user's language preferences, as a colon separated list of
Packit Service a721b1
   locale names in XPG syntax
Packit Service a721b1
     language[_territory][.codeset][@modifier]
Packit Service a721b1
   The result must not be freed; it is statically allocated.
Packit Service a721b1
   The LANGUAGE environment variable does not need to be considered; it is
Packit Service a721b1
   already taken into account by the caller.  */
Packit Service a721b1
Packit Service a721b1
const char *
Packit Service a721b1
_nl_language_preferences_default (void)
Packit Service a721b1
{
Packit Service a721b1
#if HAVE_CFPREFERENCESCOPYAPPVALUE /* MacOS X 10.2 or newer */
Packit Service a721b1
  {
Packit Service a721b1
    /* Cache the preferences list, since CoreFoundation calls are expensive.  */
Packit Service a721b1
    static const char *cached_languages;
Packit Service a721b1
    static int cache_initialized;
Packit Service a721b1
Packit Service a721b1
    if (!cache_initialized)
Packit Service a721b1
      {
Packit Service a721b1
	CFTypeRef preferences =
Packit Service a721b1
	  CFPreferencesCopyAppValue (CFSTR ("AppleLanguages"),
Packit Service a721b1
				     kCFPreferencesCurrentApplication);
Packit Service a721b1
	if (preferences != NULL
Packit Service a721b1
	    && CFGetTypeID (preferences) == CFArrayGetTypeID ())
Packit Service a721b1
	  {
Packit Service a721b1
	    CFArrayRef prefArray = (CFArrayRef)preferences;
Packit Service a721b1
	    int n = CFArrayGetCount (prefArray);
Packit Service a721b1
	    char buf[256];
Packit Service a721b1
	    size_t size = 0;
Packit Service a721b1
	    int i;
Packit Service a721b1
Packit Service a721b1
	    for (i = 0; i < n; i++)
Packit Service a721b1
	      {
Packit Service a721b1
		CFTypeRef element = CFArrayGetValueAtIndex (prefArray, i);
Packit Service a721b1
		if (element != NULL
Packit Service a721b1
		    && CFGetTypeID (element) == CFStringGetTypeID ()
Packit Service a721b1
		    && CFStringGetCString ((CFStringRef)element,
Packit Service a721b1
					   buf, sizeof (buf),
Packit Service a721b1
					   kCFStringEncodingASCII))
Packit Service a721b1
		  {
Packit Service a721b1
		    _nl_locale_name_canonicalize (buf);
Packit Service a721b1
		    size += strlen (buf) + 1;
Packit Service a721b1
		    /* Most GNU programs use msgids in English and don't ship
Packit Service a721b1
		       an en.mo message catalog.  Therefore when we see "en"
Packit Service a721b1
		       in the preferences list, arrange for gettext() to
Packit Service a721b1
		       return the msgid, and ignore all further elements of
Packit Service a721b1
		       the preferences list.  */
Packit Service a721b1
		    if (strcmp (buf, "en") == 0)
Packit Service a721b1
		      break;
Packit Service a721b1
		  }
Packit Service a721b1
		else
Packit Service a721b1
		  break;
Packit Service a721b1
	      }
Packit Service a721b1
	    if (size > 0)
Packit Service a721b1
	      {
Packit Service a721b1
		char *languages = (char *) malloc (size);
Packit Service a721b1
Packit Service a721b1
		if (languages != NULL)
Packit Service a721b1
		  {
Packit Service a721b1
		    char *p = languages;
Packit Service a721b1
Packit Service a721b1
		    for (i = 0; i < n; i++)
Packit Service a721b1
		      {
Packit Service a721b1
			CFTypeRef element =
Packit Service a721b1
			  CFArrayGetValueAtIndex (prefArray, i);
Packit Service a721b1
			if (element != NULL
Packit Service a721b1
		            && CFGetTypeID (element) == CFStringGetTypeID ()
Packit Service a721b1
			    && CFStringGetCString ((CFStringRef)element,
Packit Service a721b1
						   buf, sizeof (buf),
Packit Service a721b1
						   kCFStringEncodingASCII))
Packit Service a721b1
			  {
Packit Service a721b1
			    _nl_locale_name_canonicalize (buf);
Packit Service a721b1
			    strcpy (p, buf);
Packit Service a721b1
			    p += strlen (buf);
Packit Service a721b1
			    *p++ = ':';
Packit Service a721b1
			    if (strcmp (buf, "en") == 0)
Packit Service a721b1
			      break;
Packit Service a721b1
			  }
Packit Service a721b1
			else
Packit Service a721b1
			  break;
Packit Service a721b1
		      }
Packit Service a721b1
		    *--p = '\0';
Packit Service a721b1
Packit Service a721b1
		    cached_languages = languages;
Packit Service a721b1
		  }
Packit Service a721b1
	      }
Packit Service a721b1
	  }
Packit Service a721b1
	cache_initialized = 1;
Packit Service a721b1
      }
Packit Service a721b1
    if (cached_languages != NULL)
Packit Service a721b1
      return cached_languages;
Packit Service a721b1
  }
Packit Service a721b1
#endif
Packit Service a721b1
Packit Service a721b1
  return NULL;
Packit Service a721b1
}