locale.c revision 21967fb1fb285c755c58b183e45b7b70c4d1978a
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                  L       OOO    CCCC   AAA   L      EEEEE                   %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                  L      O   O  C      A   A  L      E                       %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                  L      O   O  C      AAAAA  L      EEE                     %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                  L      O   O  C      A   A  L      E                       %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                  LLLLL   OOO    CCCC  A   A  LLLLL  EEEEE                   %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                      MagickCore Image Locale Methods                        %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 2003                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20b56bb24a985ca4366713bcd8ffdfacbb48a98a2fcristy%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
434c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/client.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/configure.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/hashmap.h"
49007e925e29fea767305ade6e1d635e5e517a13b3dirk#include "MagickCore/image-private.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/locale_.h"
515ff4eaf57b3cd47d0371f204f865cbba614674a0cristy#include "MagickCore/locale-private.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
54d2d11ec3ae6f94d5b49cbaf90e7f9ca18c252d29cristy#include "MagickCore/nt-base-private.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/semaphore.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/splay-tree.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
587832dc2d904c471770087cce18a9a2d76c2216a3cristy#include "MagickCore/string-private.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/token.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h"
61d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy#include "MagickCore/utility-private.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/xml-tree.h"
633291f51a77fdd817efb58d652c78c407cbfdf7d1cristy#include "MagickCore/xml-tree-private.h"
643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Define declarations.
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define LocaleFilename  "locale.xml"
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define MaxRecursionDepth  200
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Static declarations.
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic const char
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *LocaleMap =
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "<?xml version=\"1.0\"?>"
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "<localemap>"
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  <locale name=\"C\">"
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "    <Exception>"
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "     <Message name=\"\">"
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "     </Message>"
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "    </Exception>"
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "  </locale>"
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "</localemap>";
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SemaphoreInfo
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *locale_semaphore = (SemaphoreInfo *) NULL;
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic SplayTreeInfo
9086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  *locale_cache = (SplayTreeInfo *) NULL;
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
925cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H)
93a20c904a6f3e3a11939d5260485be72d5c849c63cristystatic volatile locale_t
94b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  c_locale = (locale_t) NULL;
95a723b6a0656cce17bf5495a3e6bc2780f0b7aed5cristy#endif
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
101904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy  IsLocaleTreeInstantiated(ExceptionInfo *),
102cd2cd1803dda951bcfff101c44032ae17e52655fcristy  LoadLocaleCache(SplayTreeInfo *,const char *,const char *,const char *,
103cd2cd1803dda951bcfff101c44032ae17e52655fcristy    const size_t,ExceptionInfo *);
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1055cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H)
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
111b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy+   A c q u i r e C L o c a l e                                               %
112a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
113a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
114a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
115a20c904a6f3e3a11939d5260485be72d5c849c63cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
117b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  AcquireCLocale() allocates the C locale object, or (locale_t) 0 with
118a20c904a6f3e3a11939d5260485be72d5c849c63cristy%  errno set if it cannot be acquired.
119a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
120b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  The format of the AcquireCLocale method is:
121a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
122b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%      locale_t AcquireCLocale(void)
123a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
124a20c904a6f3e3a11939d5260485be72d5c849c63cristy*/
125b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristystatic locale_t AcquireCLocale(void)
126a20c904a6f3e3a11939d5260485be72d5c849c63cristy{
127a20c904a6f3e3a11939d5260485be72d5c849c63cristy#if defined(MAGICKCORE_HAVE_NEWLOCALE)
128b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  if (c_locale == (locale_t) NULL)
129b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    c_locale=newlocale(LC_ALL_MASK,"C",(locale_t) 0);
130a20c904a6f3e3a11939d5260485be72d5c849c63cristy#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
131b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  if (c_locale == (locale_t) NULL)
132b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    c_locale=_create_locale(LC_ALL,"C");
133a20c904a6f3e3a11939d5260485be72d5c849c63cristy#endif
134b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  return(c_locale);
135b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy}
136a723b6a0656cce17bf5495a3e6bc2780f0b7aed5cristy#endif
137b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
13886e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy/*
13986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%                                                                             %
14186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%                                                                             %
14286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%                                                                             %
14386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%  A c q u i r e L o c a l e S p l a y T r e e                                %
14486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%                                                                             %
14586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%                                                                             %
14686e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%                                                                             %
14786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
14886e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
14986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%  AcquireLocaleSplayTree() caches one or more locale configurations which
15086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%  provides a mapping between locale attributes and a locale tag.
15186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
15286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%  The format of the AcquireLocaleSplayTree method is:
15386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
15486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%      SplayTreeInfo *AcquireLocaleSplayTree(const char *filename,
15586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%        ExceptionInfo *exception)
15686e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
15786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%  A description of each parameter follows:
15886e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
15986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%    o filename: the font file tag.
16086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
16186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%    o locale: the actual locale.
16286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
16386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%    o exception: return any errors or warnings in this structure.
16486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%
16586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy*/
16686e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy
16786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristystatic void *DestroyLocaleNode(void *locale_info)
16886e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy{
16986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  register LocaleInfo
17086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    *p;
17186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy
17286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  p=(LocaleInfo *) locale_info;
17386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  if (p->path != (char *) NULL)
17486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    p->path=DestroyString(p->path);
17586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  if (p->tag != (char *) NULL)
17686e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    p->tag=DestroyString(p->tag);
17786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  if (p->message != (char *) NULL)
17886e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    p->message=DestroyString(p->message);
17986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  return(RelinquishMagickMemory(p));
18086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy}
18186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy
18286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristystatic SplayTreeInfo *AcquireLocaleSplayTree(const char *filename,
18386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  const char *locale,ExceptionInfo *exception)
18486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy{
18586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  MagickStatusType
18686e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    status;
18786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy
18886e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  SplayTreeInfo
18986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    *locale_cache;
19086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy
19186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  locale_cache=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
19286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    DestroyLocaleNode);
19386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  if (locale_cache == (SplayTreeInfo *) NULL)
19486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
19586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  status=MagickTrue;
196191ba5c4efb33f9f70da0216a31343d658156ba7cristy#if !defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
19786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  {
19866f8c5f040cd0dc76d76e8e041764e2f799fae76cristy    const StringInfo
19966f8c5f040cd0dc76d76e8e041764e2f799fae76cristy      *option;
20066f8c5f040cd0dc76d76e8e041764e2f799fae76cristy
20166f8c5f040cd0dc76d76e8e041764e2f799fae76cristy    LinkedListInfo
20266f8c5f040cd0dc76d76e8e041764e2f799fae76cristy      *options;
20366f8c5f040cd0dc76d76e8e041764e2f799fae76cristy
20466f8c5f040cd0dc76d76e8e041764e2f799fae76cristy    options=GetLocaleOptions(filename,exception);
20586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    option=(const StringInfo *) GetNextValueInLinkedList(options);
20666f8c5f040cd0dc76d76e8e041764e2f799fae76cristy    while (option != (const StringInfo *) NULL)
20786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    {
208cd2cd1803dda951bcfff101c44032ae17e52655fcristy      status&=LoadLocaleCache(locale_cache,(const char *)
209cd2cd1803dda951bcfff101c44032ae17e52655fcristy        GetStringInfoDatum(option),GetStringInfoPath(option),locale,0,
210cd2cd1803dda951bcfff101c44032ae17e52655fcristy        exception);
21186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy      option=(const StringInfo *) GetNextValueInLinkedList(options);
21266f8c5f040cd0dc76d76e8e041764e2f799fae76cristy    }
21366f8c5f040cd0dc76d76e8e041764e2f799fae76cristy    options=DestroyLocaleOptions(options);
21466f8c5f040cd0dc76d76e8e041764e2f799fae76cristy    if (GetNumberOfNodesInSplayTree(locale_cache) == 0)
21586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy      {
21666f8c5f040cd0dc76d76e8e041764e2f799fae76cristy        options=GetLocaleOptions("english.xml",exception);
21786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy        option=(const StringInfo *) GetNextValueInLinkedList(options);
21866f8c5f040cd0dc76d76e8e041764e2f799fae76cristy        while (option != (const StringInfo *) NULL)
21966f8c5f040cd0dc76d76e8e041764e2f799fae76cristy        {
220cd2cd1803dda951bcfff101c44032ae17e52655fcristy          status&=LoadLocaleCache(locale_cache,(const char *)
221cd2cd1803dda951bcfff101c44032ae17e52655fcristy            GetStringInfoDatum(option),GetStringInfoPath(option),locale,0,
222cd2cd1803dda951bcfff101c44032ae17e52655fcristy            exception);
22366f8c5f040cd0dc76d76e8e041764e2f799fae76cristy          option=(const StringInfo *) GetNextValueInLinkedList(options);
22466f8c5f040cd0dc76d76e8e041764e2f799fae76cristy        }
22566f8c5f040cd0dc76d76e8e041764e2f799fae76cristy        options=DestroyLocaleOptions(options);
22686e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy      }
22766f8c5f040cd0dc76d76e8e041764e2f799fae76cristy  }
228191ba5c4efb33f9f70da0216a31343d658156ba7cristy#endif
229191ba5c4efb33f9f70da0216a31343d658156ba7cristy  if (GetNumberOfNodesInSplayTree(locale_cache) == 0)
230cd2cd1803dda951bcfff101c44032ae17e52655fcristy    status&=LoadLocaleCache(locale_cache,LocaleMap,"built-in",locale,0,
231cd2cd1803dda951bcfff101c44032ae17e52655fcristy      exception);
23286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  return(locale_cache);
23386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy}
23486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy
2355cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H)
236b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy/*
237b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
239b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
240b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
241b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy+   D e s t r o y C L o c a l e                                               %
242b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
243b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
244b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
245b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
247b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  DestroyCLocale() releases the resources allocated for a locale object
248b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  returned by a call to the AcquireCLocale() method.
249b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
250b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  The format of the DestroyCLocale method is:
251b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
252b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%      void DestroyCLocale(void)
253b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
254b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy*/
255b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristystatic void DestroyCLocale(void)
256b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{
257b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#if defined(MAGICKCORE_HAVE_NEWLOCALE)
258b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  if (c_locale != (locale_t) NULL)
259b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    freelocale(c_locale);
260b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
261b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  if (c_locale != (locale_t) NULL)
262b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    _free_locale(c_locale);
263b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#endif
264b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  c_locale=(locale_t) NULL;
265a20c904a6f3e3a11939d5260485be72d5c849c63cristy}
266a723b6a0656cce17bf5495a3e6bc2780f0b7aed5cristy#endif
267a20c904a6f3e3a11939d5260485be72d5c849c63cristy
268a20c904a6f3e3a11939d5260485be72d5c849c63cristy/*
269a20c904a6f3e3a11939d5260485be72d5c849c63cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
271a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
272a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   D e s t r o y L o c a l e O p t i o n s                                   %
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  DestroyLocaleOptions() releases memory associated with an locale
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  messages.
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the DestroyProfiles method is:
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      LinkedListInfo *DestroyLocaleOptions(Image *image)
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the image.
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void *DestroyOptions(void *message)
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(DestroyStringInfo((StringInfo *) message));
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport LinkedListInfo *DestroyLocaleOptions(LinkedListInfo *messages)
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(messages != (LinkedListInfo *) NULL);
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(DestroyLinkedList(messages,DestroyOptions));
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
309b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy+  F o r m a t L o c a l e F i l e                                            %
310a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
311a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
312a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
313a20c904a6f3e3a11939d5260485be72d5c849c63cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
315b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  FormatLocaleFile() prints formatted output of a variable argument list to a
316b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  file in the "C" locale.
317b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
318b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  The format of the FormatLocaleFile method is:
319a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
320b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%      ssize_t FormatLocaleFile(FILE *file,const char *format,...)
321a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
322b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  A description of each parameter follows.
323b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
324b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%   o file:  the file.
325b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
326b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%   o format:  A file describing the format to use to write the remaining
327b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%     arguments.
328a20c904a6f3e3a11939d5260485be72d5c849c63cristy%
329a20c904a6f3e3a11939d5260485be72d5c849c63cristy*/
330b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
3317832dc2d904c471770087cce18a9a2d76c2216a3cristyMagickPrivate ssize_t FormatLocaleFileList(FILE *file,
332ba56db507fc807dbf2edd6b5222d9a6184ba26cacristy  const char *restrict format,va_list operands)
333a20c904a6f3e3a11939d5260485be72d5c849c63cristy{
33420ec75933833a479a457aeb76c7f9338e1e1c093cristy  ssize_t
335b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    n;
336b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
3375cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H) && defined(MAGICKCORE_HAVE_VFPRINTF_L)
338b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  {
339b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    locale_t
340b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      locale;
341b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
342b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    locale=AcquireCLocale();
343b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    if (locale == (locale_t) NULL)
34420ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vfprintf(file,format,operands);
345b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    else
34626d782050ee830ab4503bf14708ec69f4396233acristy#if defined(MAGICKCORE_WINDOWS_SUPPORT)
34720ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vfprintf_l(file,format,locale,operands);
34826d782050ee830ab4503bf14708ec69f4396233acristy#else
34920ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vfprintf_l(file,locale,format,operands);
350405905f9a85da5d3b531e495986818fdd9f765cccristy#endif
351b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  }
352b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#else
3535cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H) && defined(MAGICKCORE_HAVE_USELOCALE)
354b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  {
355b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    locale_t
356b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      locale,
357b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      previous_locale;
358b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
359b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    locale=AcquireCLocale();
360b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    if (locale == (locale_t) NULL)
36120ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vfprintf(file,format,operands);
362b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    else
363b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      {
364b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy        previous_locale=uselocale(locale);
36520ec75933833a479a457aeb76c7f9338e1e1c093cristy        n=(ssize_t) vfprintf(file,format,operands);
366b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy        uselocale(previous_locale);
367b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      }
368b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  }
369b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#else
37020ec75933833a479a457aeb76c7f9338e1e1c093cristy  n=(ssize_t) vfprintf(file,format,operands);
371b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#endif
372a20c904a6f3e3a11939d5260485be72d5c849c63cristy#endif
3733da0b407cca2ae0112df448b5eb15047a552b3aacristy  return(n);
374b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy}
375b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
376ba56db507fc807dbf2edd6b5222d9a6184ba26cacristyMagickExport ssize_t FormatLocaleFile(FILE *file,const char *restrict format,
377ba56db507fc807dbf2edd6b5222d9a6184ba26cacristy  ...)
378b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{
379b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  ssize_t
380b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    n;
381b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
382b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  va_list
383b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    operands;
384b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
385b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  va_start(operands,format);
38620ec75933833a479a457aeb76c7f9338e1e1c093cristy  n=FormatLocaleFileList(file,format,operands);
387b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  va_end(operands);
388b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  return(n);
389b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy}
390b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
391b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy/*
392b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
393b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
394b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
395b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
396b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy+  F o r m a t L o c a l e S t r i n g                                        %
397b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
398b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
399b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%                                                                             %
400b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
402b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  FormatLocaleString() prints formatted output of a variable argument list to
403b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  a string buffer in the "C" locale.
404b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
405b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  The format of the FormatLocaleString method is:
406b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
407b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%      ssize_t FormatLocaleString(char *string,const size_t length,
408b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%        const char *format,...)
409b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
410b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%  A description of each parameter follows.
411b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
412b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%   o string:  FormatLocaleString() returns the formatted string in this
413b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%     character buffer.
414b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
415b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%   o length: the maximum length of the string.
416b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
417b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%   o format:  A string describing the format to use to write the remaining
418b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%     arguments.
419b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy%
420b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy*/
421b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
4227832dc2d904c471770087cce18a9a2d76c2216a3cristyMagickPrivate ssize_t FormatLocaleStringList(char *restrict string,
423ba56db507fc807dbf2edd6b5222d9a6184ba26cacristy  const size_t length,const char *restrict format,va_list operands)
424b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{
42520ec75933833a479a457aeb76c7f9338e1e1c093cristy  ssize_t
426b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    n;
427b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
4285cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H) && defined(MAGICKCORE_HAVE_VSNPRINTF_L)
429405905f9a85da5d3b531e495986818fdd9f765cccristy  {
430405905f9a85da5d3b531e495986818fdd9f765cccristy    locale_t
431405905f9a85da5d3b531e495986818fdd9f765cccristy      locale;
432405905f9a85da5d3b531e495986818fdd9f765cccristy
433405905f9a85da5d3b531e495986818fdd9f765cccristy    locale=AcquireCLocale();
434405905f9a85da5d3b531e495986818fdd9f765cccristy    if (locale == (locale_t) NULL)
43520ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vsnprintf(string,length,format,operands);
436405905f9a85da5d3b531e495986818fdd9f765cccristy    else
43726d782050ee830ab4503bf14708ec69f4396233acristy#if defined(MAGICKCORE_WINDOWS_SUPPORT)
43820ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vsnprintf_l(string,length,format,locale,operands);
43926d782050ee830ab4503bf14708ec69f4396233acristy#else
44020ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vsnprintf_l(string,length,locale,format,operands);
441405905f9a85da5d3b531e495986818fdd9f765cccristy#endif
442405905f9a85da5d3b531e495986818fdd9f765cccristy  }
443b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#elif defined(MAGICKCORE_HAVE_VSNPRINTF)
4445cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H) && defined(MAGICKCORE_HAVE_USELOCALE)
445b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  {
446b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    locale_t
447b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      locale,
448b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      previous_locale;
449b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
450b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    locale=AcquireCLocale();
451b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    if (locale == (locale_t) NULL)
45220ec75933833a479a457aeb76c7f9338e1e1c093cristy      n=(ssize_t) vsnprintf(string,length,format,operands);
453b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    else
454b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      {
455b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy        previous_locale=uselocale(locale);
45620ec75933833a479a457aeb76c7f9338e1e1c093cristy        n=(ssize_t) vsnprintf(string,length,format,operands);
457b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy        uselocale(previous_locale);
458b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      }
459b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  }
460b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#else
46120ec75933833a479a457aeb76c7f9338e1e1c093cristy  n=(ssize_t) vsnprintf(string,length,format,operands);
462b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#endif
463b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#else
46420ec75933833a479a457aeb76c7f9338e1e1c093cristy  n=(ssize_t) vsprintf(string,format,operands);
465b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy#endif
466b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  if (n < 0)
467b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    string[length-1]='\0';
46820ec75933833a479a457aeb76c7f9338e1e1c093cristy  return(n);
469b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy}
470b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
471ba56db507fc807dbf2edd6b5222d9a6184ba26cacristyMagickExport ssize_t FormatLocaleString(char *restrict string,
472ba56db507fc807dbf2edd6b5222d9a6184ba26cacristy  const size_t length,const char *restrict format,...)
473b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy{
474b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  ssize_t
475b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    n;
476b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
477b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  va_list
478b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    operands;
479b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy
480b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  va_start(operands,format);
48120ec75933833a479a457aeb76c7f9338e1e1c093cristy  n=FormatLocaleStringList(string,length,format,operands);
482b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  va_end(operands);
483b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  return(n);
484a20c904a6f3e3a11939d5260485be72d5c849c63cristy}
485a20c904a6f3e3a11939d5260485be72d5c849c63cristy
486a20c904a6f3e3a11939d5260485be72d5c849c63cristy/*
487a20c904a6f3e3a11939d5260485be72d5c849c63cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
489a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
490a20c904a6f3e3a11939d5260485be72d5c849c63cristy%                                                                             %
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+   G e t L o c a l e I n f o _                                               %
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetLocaleInfo_() searches the locale list for the specified tag and if
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  found returns attributes for that element.
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetLocaleInfo method is:
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      const LocaleInfo *GetLocaleInfo_(const char *tag,
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o tag: the locale tag.
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport const LocaleInfo *GetLocaleInfo_(const char *tag,
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
51549d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy  const LocaleInfo
51649d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy    *locale_info;
51749d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
519904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy  if (IsLocaleTreeInstantiated(exception) == MagickFalse)
520904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy    return((const LocaleInfo *) NULL);
52149d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy  LockSemaphoreInfo(locale_semaphore);
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0))
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
52486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy      ResetSplayTreeIterator(locale_cache);
52586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy      locale_info=(const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
52649d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy      UnlockSemaphoreInfo(locale_semaphore);
52749d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy      return(locale_info);
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
52986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  locale_info=(const LocaleInfo *) GetValueFromSplayTree(locale_cache,tag);
53049d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy  UnlockSemaphoreInfo(locale_semaphore);
53149d4d2247a71eab1c5c56bae91a5f9d0fcc4475ccristy  return(locale_info);
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t L o c a l e I n f o L i s t                                         %
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetLocaleInfoList() returns any locale messages that match the
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  specified pattern.
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetLocaleInfoList function is:
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      const LocaleInfo **GetLocaleInfoList(const char *pattern,
551bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%        size_t *number_messages,ExceptionInfo *exception)
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pattern: Specifies a pointer to a text string containing a pattern.
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o number_messages:  This integer returns the number of locale messages in
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    the list.
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int LocaleInfoCompare(const void *x,const void *y)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const LocaleInfo
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **p,
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **q;
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=(const LocaleInfo **) x,
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=(const LocaleInfo **) y;
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (LocaleCompare((*p)->path,(*q)->path) == 0)
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(LocaleCompare((*p)->tag,(*q)->tag));
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(LocaleCompare((*p)->path,(*q)->path));
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport const LocaleInfo **GetLocaleInfoList(const char *pattern,
586bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t *number_messages,ExceptionInfo *exception)
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const LocaleInfo
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **messages;
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const LocaleInfo
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
594bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate locale list.
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pattern != (char *) NULL);
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  assert(number_messages != (size_t *) NULL);
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *number_messages=0;
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=GetLocaleInfo_("*",exception);
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (p == (const LocaleInfo *) NULL)
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((const LocaleInfo **) NULL);
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  messages=(const LocaleInfo **) AcquireQuantumMemory((size_t)
60886e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    GetNumberOfNodesInSplayTree(locale_cache)+1UL,sizeof(*messages));
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (messages == (const LocaleInfo **) NULL)
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((const LocaleInfo **) NULL);
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Generate locale list.
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
614f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(locale_semaphore);
61586e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  ResetSplayTreeIterator(locale_cache);
61686e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  p=(const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; p != (const LocaleInfo *) NULL; )
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((p->stealth == MagickFalse) &&
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      messages[i++]=p;
62286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    p=(const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
624f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(locale_semaphore);
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  qsort((void *) messages,(size_t) i,sizeof(*messages),LocaleInfoCompare);
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  messages[i]=(LocaleInfo *) NULL;
627bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  *number_messages=(size_t) i;
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(messages);
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t L o c a l e L i s t                                                 %
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetLocaleList() returns any locale messages that match the specified
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pattern.
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetLocaleList function is:
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
647bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      char **GetLocaleList(const char *pattern,size_t *number_messages,
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        Exceptioninfo *exception)
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pattern: Specifies a pointer to a text string containing a pattern.
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o number_messages:  This integer returns the number of messages in the
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      list.
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristyextern "C" {
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int LocaleTagCompare(const void *x,const void *y)
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register char
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **p,
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **q;
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=(char **) x;
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=(char **) y;
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(LocaleCompare(*p,*q));
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(__cplusplus) || defined(c_plusplus)
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6805cd9a679bfdcfab16665175604c2e3ed9542da88cristyMagickExport char **GetLocaleList(const char *pattern,size_t *number_messages,
6815cd9a679bfdcfab16665175604c2e3ed9542da88cristy  ExceptionInfo *exception)
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **messages;
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register const LocaleInfo
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
689bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Allocate locale list.
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(pattern != (char *) NULL);
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
697bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  assert(number_messages != (size_t *) NULL);
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *number_messages=0;
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=GetLocaleInfo_("*",exception);
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (p == (const LocaleInfo *) NULL)
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((char **) NULL);
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  messages=(char **) AcquireQuantumMemory((size_t)
70386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    GetNumberOfNodesInSplayTree(locale_cache)+1UL,sizeof(*messages));
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (messages == (char **) NULL)
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return((char **) NULL);
706f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(locale_semaphore);
70786e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  p=(const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (i=0; p != (const LocaleInfo *) NULL; )
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((p->stealth == MagickFalse) &&
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      messages[i++]=ConstantString(p->tag);
71386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    p=(const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
715f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(locale_semaphore);
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  qsort((void *) messages,(size_t) i,sizeof(*messages),LocaleTagCompare);
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  messages[i]=(char *) NULL;
718bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  *number_messages=(size_t) i;
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(messages);
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t L o c a l e M e s s a g e                                           %
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetLocaleMessage() returns a message in the current locale that matches the
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supplied tag.
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetLocaleMessage method is:
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      const char *GetLocaleMessage(const char *tag)
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o tag: Return a message that matches this tag in the current locale.
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport const char *GetLocaleMessage(const char *tag)
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
74821967fb1fb285c755c58b183e45b7b70c4d1978acristy    name[MagickLocaleExtent];
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const LocaleInfo
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *locale_info;
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *exception;
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((tag == (const char *) NULL) || (*tag == '\0'))
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(tag);
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  exception=AcquireExceptionInfo();
75921967fb1fb285c755c58b183e45b7b70c4d1978acristy  (void) FormatLocaleString(name,MagickLocaleExtent,"%s/",tag);
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  locale_info=GetLocaleInfo_(name,exception);
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  exception=DestroyExceptionInfo(exception);
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (locale_info != (const LocaleInfo *) NULL)
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(locale_info->message);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(tag);
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  G e t L o c a l e O p t i o n s                                            %
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetLocaleOptions() returns any Magick configuration messages associated
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  with the specified filename.
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetLocaleOptions method is:
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      LinkedListInfo *GetLocaleOptions(const char *filename,
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        ExceptionInfo *exception)
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o filename: the locale file tag.
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport LinkedListInfo *GetLocaleOptions(const char *filename,
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
797151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    path[MagickPathExtent];
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *element;
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LinkedListInfo
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *messages,
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *paths;
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringInfo
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *xml;
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(filename != (const char *) NULL);
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
812151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(path,filename,MagickPathExtent);
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Load XML from configuration files to linked-list.
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  messages=NewLinkedList(0);
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  paths=GetConfigurePaths(filename,exception);
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (paths != (LinkedListInfo *) NULL)
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ResetLinkedListIterator(paths);
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      element=(const char *) GetNextValueInLinkedList(paths);
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (element != (const char *) NULL)
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
82421967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) FormatLocaleString(path,MagickPathExtent,"%s%s",element,
82521967fb1fb285c755c58b183e45b7b70c4d1978acristy          filename);
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "Searching for locale file: \"%s\"",path);
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        xml=ConfigureFileToStringInfo(path);
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (xml != (StringInfo *) NULL)
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) AppendValueToLinkedList(messages,xml);
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        element=(const char *) GetNextValueInLinkedList(paths);
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      paths=DestroyLinkedList(paths,RelinquishMagickMemory);
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8350157aeadef2fce908277168097a160a8f15a6952cristy#if defined(MAGICKCORE_WINDOWS_SUPPORT)
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    char
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *blob;
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    blob=(char *) NTResourceToBlob(filename);
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (blob != (char *) NULL)
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
84385d6de50bbee8b1c2a772bc9dcf38e0e7155d041cristy        xml=AcquireStringInfo(0);
84485d6de50bbee8b1c2a772bc9dcf38e0e7155d041cristy        SetStringInfoLength(xml,strlen(blob)+1);
845d61c7adb5d6f81182c79dca8ff608c1701aac8f8dirk        SetStringInfoDatum(xml,(const unsigned char *) blob);
846732d7849f114281314c3a287a1ed131add137764cristy        blob=(char *) RelinquishMagickMemory(blob);
84785d6de50bbee8b1c2a772bc9dcf38e0e7155d041cristy        SetStringInfoPath(xml,filename);
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) AppendValueToLinkedList(messages,xml);
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ResetLinkedListIterator(messages);
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(messages);
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   G e t L o c a l e V a l u e                                               %
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  GetLocaleValue() returns the message associated with the locale info.
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the GetLocaleValue method is:
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      const char *GetLocaleValue(const LocaleInfo *locale_info)
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o locale_info:  The locale info.
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport const char *GetLocaleValue(const LocaleInfo *locale_info)
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(locale_info != (LocaleInfo *) NULL);
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(locale_info->signature == MagickSignature);
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(locale_info->message);
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
891904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy+   I s L o c a l e T r e e I n s t a n t i a t e d                           %
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
897904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy%  IsLocaleTreeInstantiated() determines if the locale tree is instantiated.
898904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy%  If not, it instantiates the tree and returns it.
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
900904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy%  The format of the IsLocaleInstantiated method is:
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
902904e591bcf6bce4c0086cc200d0efe7fdd3834aecristy%      MagickBooleanType IsLocaleTreeInstantiated(ExceptionInfo *exception)
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
909904e591bcf6bce4c0086cc200d0efe7fdd3834aecristystatic MagickBooleanType IsLocaleTreeInstantiated(ExceptionInfo *exception)
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
91186e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  if (locale_cache == (SplayTreeInfo *) NULL)
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
913cd2cd1803dda951bcfff101c44032ae17e52655fcristy      if (locale_semaphore == (SemaphoreInfo *) NULL)
914cd2cd1803dda951bcfff101c44032ae17e52655fcristy        ActivateSemaphoreInfo(&locale_semaphore);
915cd2cd1803dda951bcfff101c44032ae17e52655fcristy      LockSemaphoreInfo(locale_semaphore);
916cd2cd1803dda951bcfff101c44032ae17e52655fcristy      if (locale_cache == (SplayTreeInfo *) NULL)
917cd2cd1803dda951bcfff101c44032ae17e52655fcristy        {
918cd2cd1803dda951bcfff101c44032ae17e52655fcristy          char
919cd2cd1803dda951bcfff101c44032ae17e52655fcristy            *locale;
920cd2cd1803dda951bcfff101c44032ae17e52655fcristy
921cd2cd1803dda951bcfff101c44032ae17e52655fcristy          register const char
922cd2cd1803dda951bcfff101c44032ae17e52655fcristy            *p;
923cd2cd1803dda951bcfff101c44032ae17e52655fcristy
924cd2cd1803dda951bcfff101c44032ae17e52655fcristy          locale=(char *) NULL;
925cd2cd1803dda951bcfff101c44032ae17e52655fcristy          p=setlocale(LC_CTYPE,(const char *) NULL);
926cd2cd1803dda951bcfff101c44032ae17e52655fcristy          if (p != (const char *) NULL)
927cd2cd1803dda951bcfff101c44032ae17e52655fcristy            locale=ConstantString(p);
928cd2cd1803dda951bcfff101c44032ae17e52655fcristy          if (locale == (char *) NULL)
929cd2cd1803dda951bcfff101c44032ae17e52655fcristy            locale=GetEnvironmentValue("LC_ALL");
930cd2cd1803dda951bcfff101c44032ae17e52655fcristy          if (locale == (char *) NULL)
931cd2cd1803dda951bcfff101c44032ae17e52655fcristy            locale=GetEnvironmentValue("LC_MESSAGES");
932cd2cd1803dda951bcfff101c44032ae17e52655fcristy          if (locale == (char *) NULL)
933cd2cd1803dda951bcfff101c44032ae17e52655fcristy            locale=GetEnvironmentValue("LC_CTYPE");
934cd2cd1803dda951bcfff101c44032ae17e52655fcristy          if (locale == (char *) NULL)
935cd2cd1803dda951bcfff101c44032ae17e52655fcristy            locale=GetEnvironmentValue("LANG");
936cd2cd1803dda951bcfff101c44032ae17e52655fcristy          if (locale == (char *) NULL)
937cd2cd1803dda951bcfff101c44032ae17e52655fcristy            locale=ConstantString("C");
938cd2cd1803dda951bcfff101c44032ae17e52655fcristy          locale_cache=AcquireLocaleSplayTree(LocaleFilename,locale,exception);
939cd2cd1803dda951bcfff101c44032ae17e52655fcristy          locale=DestroyString(locale);
940cd2cd1803dda951bcfff101c44032ae17e52655fcristy        }
941cd2cd1803dda951bcfff101c44032ae17e52655fcristy      UnlockSemaphoreInfo(locale_semaphore);
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
94386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  return(locale_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94841c3c77d6f4e3131bf2be0b35277c086b69ce492cristy%                                                                             %
94941c3c77d6f4e3131bf2be0b35277c086b69ce492cristy%                                                                             %
95041c3c77d6f4e3131bf2be0b35277c086b69ce492cristy%                                                                             %
951c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy+   I n t e r p r e t L o c a l e V a l u e                                   %
952c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%                                                                             %
953c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%                                                                             %
954c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%                                                                             %
955c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%
957c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%  InterpretLocaleValue() interprets the string as a floating point number in
958c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%  the "C" locale and returns its value as a double. If sentinal is not a null
959c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%  pointer, the method also sets the value pointed by sentinal to point to the
960c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%  first character after the number.
961c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%
962c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%  The format of the InterpretLocaleValue method is:
963c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%
964c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%      double InterpretLocaleValue(const char *value,char **sentinal)
965c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%
966c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%  A description of each parameter follows:
967c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%
968c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%    o value: the string value.
969c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%
970c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%    o sentinal:  if sentinal is not NULL, a pointer to the character after the
971c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%      last character used in the conversion is stored in the location
972c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%      referenced by sentinal.
973c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%
974c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy*/
975ba56db507fc807dbf2edd6b5222d9a6184ba26cacristyMagickExport double InterpretLocaleValue(const char *restrict string,
976ba56db507fc807dbf2edd6b5222d9a6184ba26cacristy  char **restrict sentinal)
977c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy{
978670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy  char
979670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy    *q;
980670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy
981c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy  double
982c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy    value;
983c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy
984670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy  if ((*string == '0') && ((string[1] | 0x20)=='x'))
985670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy    value=(double) strtoul(string,&q,16);
986670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy  else
987670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy    {
9885cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H) && defined(MAGICKCORE_HAVE_STRTOD_L)
989670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy      locale_t
990670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy        locale;
991670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy
992670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy      locale=AcquireCLocale();
993670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy      if (locale == (locale_t) NULL)
994670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy        value=strtod(string,&q);
995670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy      else
996670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy        value=strtod_l(string,&q,locale);
997c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy#else
998670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy      value=strtod(string,&q);
999c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy#endif
1000670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy    }
1001670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy  if (sentinal != (char **) NULL)
1002670aa3c328eb7d97a3edd44ef7b4244d2effa935cristy    *sentinal=q;
1003c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy  return(value);
1004c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy}
1005c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy
1006c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy/*
1007c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%                                                                             %
1009c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%                                                                             %
1010c1acd8495db5b00e9ced313e86dfdbe8c60c111dcristy%                                                                             %
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  L i s t L o c a l e I n f o                                                %
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ListLocaleInfo() lists the locale info to a file.
10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ListLocaleInfo method is:
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType ListLocaleInfo(FILE *file,ExceptionInfo *exception)
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
10243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o file:  An pointer to a FILE.
10263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
10283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
10303ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType ListLocaleInfo(FILE *file,
10313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  ExceptionInfo *exception)
10323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
10333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
10343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *path;
10353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const LocaleInfo
10373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    **locale_info;
10383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1039bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
10403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i;
10413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1042bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
10433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_messages;
10443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (file == (const FILE *) NULL)
10463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    file=stdout;
10473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  number_messages=0;
10483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  locale_info=GetLocaleInfoList("*",&number_messages,exception);
10493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (locale_info == (const LocaleInfo **) NULL)
10503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
10513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  path=(const char *) NULL;
1052bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (i=0; i < (ssize_t) number_messages; i++)
10533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
10543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (locale_info[i]->stealth != MagickFalse)
10553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
10563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if ((path == (const char *) NULL) ||
10573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (LocaleCompare(path,locale_info[i]->path) != 0))
10583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
10593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (locale_info[i]->path != (char *) NULL)
1060b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy          (void) FormatLocaleFile(file,"\nPath: %s\n\n",locale_info[i]->path);
1061b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy        (void) FormatLocaleFile(file,"Tag/Message\n");
10621e604812fad85bb96f757a2393015ae3d061c39acristy        (void) FormatLocaleFile(file,
10631e604812fad85bb96f757a2393015ae3d061c39acristy          "-------------------------------------------------"
10643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          "------------------------------\n");
10653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
10663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    path=locale_info[i]->path;
1067b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    (void) FormatLocaleFile(file,"%s\n",locale_info[i]->tag);
10683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (locale_info[i]->message != (char *) NULL)
1069b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy      (void) FormatLocaleFile(file,"  %s",locale_info[i]->message);
1070b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    (void) FormatLocaleFile(file,"\n");
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) fflush(file);
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  locale_info=(const LocaleInfo **)
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    RelinquishMagickMemory((void *) locale_info);
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+   L o a d L o c a l e L i s t                                               %
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
108986e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%  LoadLocaleCache() loads the locale configurations which provides a mapping
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  between locale attributes and a locale name.
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
109286e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy%  The format of the LoadLocaleCache method is:
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1094cd2cd1803dda951bcfff101c44032ae17e52655fcristy%      MagickBooleanType LoadLocaleCache(SplayTreeInfo *locale_cache,
1095cd2cd1803dda951bcfff101c44032ae17e52655fcristy%        const char *xml,const char *filename,const size_t depth,
1096cd2cd1803dda951bcfff101c44032ae17e52655fcristy%        ExceptionInfo *exception)
10973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
10983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o xml:  The locale list in XML format.
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o filename:  The locale list filename.
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o depth: depth of <include /> statements.
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
11093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1110bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristystatic void ChopLocaleComponents(char *path,const size_t components)
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register char
11133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11159d314ff2c17a77996c05413c2013880387e50f0ecristy  ssize_t
11169d314ff2c17a77996c05413c2013880387e50f0ecristy    count;
11179d314ff2c17a77996c05413c2013880387e50f0ecristy
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*path == '\0')
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return;
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=path+strlen(path)-1;
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (*p == '/')
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p='\0';
1123bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (count=0; (count < (ssize_t) components) && (p > path); p--)
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (*p == '/')
11253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p='\0';
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count++;
11283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
1129bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  if (count < (ssize_t) components)
11303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *path='\0';
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11332359e74755f994c60e7a3bd7d2828b45d7680675cristystatic void LocaleFatalErrorHandler(
11342359e74755f994c60e7a3bd7d2828b45d7680675cristy  const ExceptionType magick_unused(severity),
11352359e74755f994c60e7a3bd7d2828b45d7680675cristy  const char *reason,const char *description)
11362359e74755f994c60e7a3bd7d2828b45d7680675cristy{
11372359e74755f994c60e7a3bd7d2828b45d7680675cristy  if (reason == (char *) NULL)
11382359e74755f994c60e7a3bd7d2828b45d7680675cristy    return;
1139b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  (void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason);
11402359e74755f994c60e7a3bd7d2828b45d7680675cristy  if (description != (char *) NULL)
1141b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy    (void) FormatLocaleFile(stderr," (%s)",description);
1142b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  (void) FormatLocaleFile(stderr,".\n");
11432359e74755f994c60e7a3bd7d2828b45d7680675cristy  (void) fflush(stderr);
11442359e74755f994c60e7a3bd7d2828b45d7680675cristy  exit(1);
11452359e74755f994c60e7a3bd7d2828b45d7680675cristy}
11462359e74755f994c60e7a3bd7d2828b45d7680675cristy
1147cd2cd1803dda951bcfff101c44032ae17e52655fcristystatic MagickBooleanType LoadLocaleCache(SplayTreeInfo *locale_cache,
1148cd2cd1803dda951bcfff101c44032ae17e52655fcristy  const char *xml,const char *filename,const char *locale,const size_t depth,
1149cd2cd1803dda951bcfff101c44032ae17e52655fcristy  ExceptionInfo *exception)
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
115221967fb1fb285c755c58b183e45b7b70c4d1978acristy    keyword[MagickLocaleExtent],
115321967fb1fb285c755c58b183e45b7b70c4d1978acristy    message[MagickLocaleExtent],
115421967fb1fb285c755c58b183e45b7b70c4d1978acristy    tag[MagickLocaleExtent],
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *token;
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1160909b647caa79e7dd752f7daae08177ec74fb841acristy  FatalErrorHandler
1161909b647caa79e7dd752f7daae08177ec74fb841acristy    fatal_handler;
1162909b647caa79e7dd752f7daae08177ec74fb841acristy
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  LocaleInfo
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *locale_info;
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1166759ba919e9fe454989454f481f4055fd38b32307cristy  MagickStatusType
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register char
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read the locale configure file.
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "Loading locale configure file \"%s\" ...",filename);
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (xml == (const char *) NULL)
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=MagickTrue;
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  locale_info=(LocaleInfo *) NULL;
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *tag='\0';
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *message='\0';
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  *keyword='\0';
11842359e74755f994c60e7a3bd7d2828b45d7680675cristy  fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token=AcquireString(xml);
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  for (q=(char *) xml; *q != '\0'; )
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    /*
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Interpret XML.
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    */
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    GetMagickToken(q,&q,token);
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (*token == '\0')
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
119421967fb1fb285c755c58b183e45b7b70c4d1978acristy    (void) CopyMagickString(keyword,token,MagickLocaleExtent);
11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
11963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Doctype element.
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while (isspace((int) ((unsigned char) *q)) != 0)
12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleNCompare(keyword,"<!--",4) == 0)
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Comment element.
12123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          while (isspace((int) ((unsigned char) *q)) != 0)
12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            q++;
12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(keyword,"<include") == 0)
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Include element.
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
122821967fb1fb285c755c58b183e45b7b70c4d1978acristy          (void) CopyMagickString(keyword,token,MagickLocaleExtent);
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*token != '=')
12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (LocaleCompare(keyword,"locale") == 0)
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (LocaleCompare(locale,token) != 0)
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                break;
12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              continue;
12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (LocaleCompare(keyword,"file") == 0)
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (depth > 200)
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                (void) ThrowMagickException(exception,GetMagickModule(),
1243efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy                  ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  char
1247151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy                    path[MagickPathExtent],
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    *xml;
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  *path='\0';
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  GetPathComponent(filename,HeadPath,path);
12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (*path != '\0')
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    (void) ConcatenateMagickString(path,DirectorySeparator,
1254151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy                      MagickPathExtent);
12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (*token == *DirectorySeparator)
1256151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy                    (void) CopyMagickString(path,token,MagickPathExtent);
12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  else
1258151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy                    (void) ConcatenateMagickString(path,token,MagickPathExtent);
12593291f51a77fdd817efb58d652c78c407cbfdf7d1cristy                  xml=FileToXML(path,~0UL);
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  if (xml != (char *) NULL)
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    {
1262cd2cd1803dda951bcfff101c44032ae17e52655fcristy                      status&=LoadLocaleCache(locale_cache,xml,path,locale,
1263cd2cd1803dda951bcfff101c44032ae17e52655fcristy                        depth+1,exception);
12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                      xml=(char *) RelinquishMagickMemory(xml);
12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    }
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(keyword,"<locale") == 0)
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Locale element.
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((*token != '>') && (*q != '\0'))
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
127821967fb1fb285c755c58b183e45b7b70c4d1978acristy          (void) CopyMagickString(keyword,token,MagickLocaleExtent);
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*token != '=')
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(keyword,"</locale>") == 0)
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ChopLocaleComponents(tag,1);
128921967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) ConcatenateMagickString(tag,"/",MagickLocaleExtent);
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(keyword,"<localemap>") == 0)
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(keyword,"</localemap>") == 0)
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(keyword,"<message") == 0)
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
12983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
12993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Message element.
13003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
13013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((*token != '>') && (*q != '\0'))
13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
130321967fb1fb285c755c58b183e45b7b70c4d1978acristy          (void) CopyMagickString(keyword,token,MagickLocaleExtent);
13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (*token != '=')
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          GetMagickToken(q,&q,token);
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (LocaleCompare(keyword,"name") == 0)
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
131021967fb1fb285c755c58b183e45b7b70c4d1978acristy              (void) ConcatenateMagickString(tag,token,MagickLocaleExtent);
131121967fb1fb285c755c58b183e45b7b70c4d1978acristy              (void) ConcatenateMagickString(tag,"/",MagickLocaleExtent);
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        for (p=(char *) q; (*q != '<') && (*q != '\0'); q++) ;
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while (isspace((int) ((unsigned char) *p)) != 0)
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q--;
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          q--;
1320fb34f5cabef5c07f924c3c8266cbbefc64fda5d3cristy        (void) CopyMagickString(message,p,MagickMin((size_t) (q-p+2),
132121967fb1fb285c755c58b183e45b7b70c4d1978acristy          MagickLocaleExtent));
132273bd4a51b419e914565bdf204bf1540dc4c8ee26cristy        locale_info=(LocaleInfo *) AcquireMagickMemory(sizeof(*locale_info));
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (locale_info == (LocaleInfo *) NULL)
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) ResetMagickMemory(locale_info,0,sizeof(*locale_info));
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        locale_info->path=ConstantString(filename);
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        locale_info->tag=ConstantString(tag);
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        locale_info->message=ConstantString(message);
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        locale_info->signature=MagickSignature;
133086e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy        status=AddValueToSplayTree(locale_cache,locale_info->tag,locale_info);
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) ThrowMagickException(exception,GetMagickModule(),
1333efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy            ResourceLimitError,"MemoryAllocationFailed","`%s'",
13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            locale_info->tag);
133521967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) ConcatenateMagickString(tag,message,MagickLocaleExtent);
133621967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) ConcatenateMagickString(tag,"\n",MagickLocaleExtent);
13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q++;
13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare(keyword,"</message>") == 0)
13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ChopLocaleComponents(tag,2);
134321967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) ConcatenateMagickString(tag,"/",MagickLocaleExtent);
13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (*keyword == '<')
13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Subpath element.
13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (*(keyword+1) == '?')
13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          continue;
13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (*(keyword+1) == '/')
13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            ChopLocaleComponents(tag,1);
13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (*tag != '\0')
135721967fb1fb285c755c58b183e45b7b70c4d1978acristy              (void) ConcatenateMagickString(tag,"/",MagickLocaleExtent);
13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            continue;
13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        token[strlen(token)-1]='\0';
136121967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) CopyMagickString(token,token+1,MagickLocaleExtent);
136221967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) ConcatenateMagickString(tag,token,MagickLocaleExtent);
136321967fb1fb285c755c58b183e45b7b70c4d1978acristy        (void) ConcatenateMagickString(tag,"/",MagickLocaleExtent);
13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        continue;
13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    GetMagickToken(q,(const char **) NULL,token);
13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (*token != '=')
13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      continue;
13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  token=(char *) RelinquishMagickMemory(token);
1371909b647caa79e7dd752f7daae08177ec74fb841acristy  (void) SetFatalErrorHandler(fatal_handler);
1372759ba919e9fe454989454f481f4055fd38b32307cristy  return(status != 0 ? MagickTrue : MagickFalse);
13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1380f34a145c545cb86152ad42a787f6d5fffea6b77ccristy+   L o c a l e C o m p o n e n t G e n e s i s                               %
1381f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1382f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1383f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1384f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1385f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1386f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%  LocaleComponentGenesis() instantiates the locale component.
1387f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1388f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%  The format of the LocaleComponentGenesis method is:
1389f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1390f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%      MagickBooleanType LocaleComponentGenesis(void)
1391f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1392f34a145c545cb86152ad42a787f6d5fffea6b77ccristy*/
13935ff4eaf57b3cd47d0371f204f865cbba614674a0cristyMagickPrivate MagickBooleanType LocaleComponentGenesis(void)
1394f34a145c545cb86152ad42a787f6d5fffea6b77ccristy{
13957c9770650f31145e0fe8811d10b2e0ecd47697c8cristy  if (locale_semaphore == (SemaphoreInfo *) NULL)
13967c9770650f31145e0fe8811d10b2e0ecd47697c8cristy    locale_semaphore=AcquireSemaphoreInfo();
1397f34a145c545cb86152ad42a787f6d5fffea6b77ccristy  return(MagickTrue);
1398f34a145c545cb86152ad42a787f6d5fffea6b77ccristy}
1399f34a145c545cb86152ad42a787f6d5fffea6b77ccristy
1400f34a145c545cb86152ad42a787f6d5fffea6b77ccristy/*
1401f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1402f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1403f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1404f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1405f34a145c545cb86152ad42a787f6d5fffea6b77ccristy+   L o c a l e C o m p o n e n t T e r m i n u s                             %
1406f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1407f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1408f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%                                                                             %
1409f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1410f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1411f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%  LocaleComponentTerminus() destroys the locale component.
1412f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1413f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%  The format of the LocaleComponentTerminus method is:
1414f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1415f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%      LocaleComponentTerminus(void)
1416f34a145c545cb86152ad42a787f6d5fffea6b77ccristy%
1417f34a145c545cb86152ad42a787f6d5fffea6b77ccristy*/
14185ff4eaf57b3cd47d0371f204f865cbba614674a0cristyMagickPrivate void LocaleComponentTerminus(void)
1419f34a145c545cb86152ad42a787f6d5fffea6b77ccristy{
142018b17443128598500357da7bff2f01683cf32890cristy  if (locale_semaphore == (SemaphoreInfo *) NULL)
142104b11db5504ecdf205114ae7e9e68774a1ff0b9bcristy    ActivateSemaphoreInfo(&locale_semaphore);
1422f84a193d5f435588cd78d521fff3f1f852e227f8cristy  LockSemaphoreInfo(locale_semaphore);
142386e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy  if (locale_cache != (SplayTreeInfo *) NULL)
142486e5ac9bd8a1d10f4fc55dae95585db303b6a1e7cristy    locale_cache=DestroySplayTree(locale_cache);
14255cd9a679bfdcfab16665175604c2e3ed9542da88cristy#if defined(MAGICKCORE_HAVE_LOCALE_H)
1426b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy  DestroyCLocale();
1427a723b6a0656cce17bf5495a3e6bc2780f0b7aed5cristy#endif
1428f84a193d5f435588cd78d521fff3f1f852e227f8cristy  UnlockSemaphoreInfo(locale_semaphore);
14293d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy  RelinquishSemaphoreInfo(&locale_semaphore);
1430f34a145c545cb86152ad42a787f6d5fffea6b77ccristy}
1431