42#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/client.h"
45#include "MagickCore/configure.h"
46#include "MagickCore/exception.h"
47#include "MagickCore/exception-private.h"
48#include "MagickCore/image-private.h"
49#include "MagickCore/linked-list.h"
50#include "MagickCore/locale_.h"
51#include "MagickCore/locale-private.h"
52#include "MagickCore/log.h"
53#include "MagickCore/memory_.h"
54#include "MagickCore/memory-private.h"
55#include "MagickCore/nt-base-private.h"
56#include "MagickCore/semaphore.h"
57#include "MagickCore/splay-tree.h"
58#include "MagickCore/string_.h"
59#include "MagickCore/string-private.h"
60#include "MagickCore/token.h"
61#include "MagickCore/utility.h"
62#include "MagickCore/utility-private.h"
63#include "MagickCore/xml-tree.h"
64#include "MagickCore/xml-tree-private.h"
69#if (defined(MAGICKCORE_HAVE_NEWLOCALE) || defined(MAGICKCORE_WINDOWS_SUPPORT)) && !defined(__MINGW32__)
70# define MAGICKCORE_LOCALE_SUPPORT
73#if defined(MAGICKCORE_WINDOWS_SUPPORT)
74# if !defined(locale_t)
75# define locale_t _locale_t
79#define LocaleFilename "locale.xml"
86 "<?xml version=\"1.0\"?>"
88 " <locale name=\"C\">"
90 " <Message name=\"\">"
100 *locale_cache = (SplayTreeInfo *) NULL;
102#if defined(MAGICKCORE_LOCALE_SUPPORT)
103static volatile locale_t
104 c_locale = (locale_t) NULL;
110static MagickBooleanType
111 IsLocaleTreeInstantiated(ExceptionInfo *),
112 LoadLocaleCache(SplayTreeInfo *,
const char *,
const char *,
const char *,
113 const size_t,ExceptionInfo *);
115#if defined(MAGICKCORE_LOCALE_SUPPORT)
135static locale_t AcquireCLocale(
void)
137#if defined(MAGICKCORE_HAVE_NEWLOCALE)
138 if (c_locale == (locale_t) NULL)
139 c_locale=newlocale(LC_ALL_MASK,
"C",(locale_t) 0);
140#elif defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
141 if (c_locale == (locale_t) NULL)
142 c_locale=_create_locale(LC_ALL,
"C");
177static void *DestroyLocaleNode(
void *locale_info)
182 p=(LocaleInfo *) locale_info;
183 if (p->path != (
char *) NULL)
184 p->path=DestroyString(p->path);
185 if (p->tag != (
char *) NULL)
186 p->tag=DestroyString(p->tag);
187 if (p->message != (
char *) NULL)
188 p->message=DestroyString(p->message);
189 return(RelinquishMagickMemory(p));
192static SplayTreeInfo *AcquireLocaleSplayTree(
const char *filename,
193 const char *locale,ExceptionInfo *exception)
198 cache=NewSplayTree(CompareSplayTreeString,(
void *(*)(
void *)) NULL,
200#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
208 options=GetLocaleOptions(filename,exception);
209 option=(
const StringInfo *) GetNextValueInLinkedList(options);
210 while (option != (
const StringInfo *) NULL)
212 (void) LoadLocaleCache(cache,(
const char *)
213 GetStringInfoDatum(option),GetStringInfoPath(option),locale,0,
215 option=(
const StringInfo *) GetNextValueInLinkedList(options);
217 options=DestroyLocaleOptions(options);
218 if (GetNumberOfNodesInSplayTree(cache) == 0)
220 options=GetLocaleOptions(
"english.xml",exception);
221 option=(
const StringInfo *) GetNextValueInLinkedList(options);
222 while (option != (
const StringInfo *) NULL)
224 (void) LoadLocaleCache(cache,(
const char *)
225 GetStringInfoDatum(option),GetStringInfoPath(option),locale,0,
227 option=(
const StringInfo *) GetNextValueInLinkedList(options);
229 options=DestroyLocaleOptions(options);
233 magick_unreferenced(filename);
235 if (GetNumberOfNodesInSplayTree(cache) == 0)
236 (void) LoadLocaleCache(cache,LocaleMap,
"built-in",locale,0,
241#if defined(MAGICKCORE_LOCALE_SUPPORT)
261static void DestroyCLocale(
void)
263 if (c_locale != (locale_t) NULL)
264#if defined(MAGICKCORE_WINDOWS_SUPPORT)
265 _free_locale(c_locale);
267 freelocale(c_locale);
269 c_locale=(locale_t) NULL;
297static void *DestroyOptions(
void *message)
299 return(DestroyStringInfo((StringInfo *) message));
302MagickExport LinkedListInfo *DestroyLocaleOptions(LinkedListInfo *messages)
304 assert(messages != (LinkedListInfo *) NULL);
305 if (IsEventLogging() != MagickFalse)
306 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
307 return(DestroyLinkedList(messages,DestroyOptions));
337MagickPrivate ssize_t FormatLocaleFileList(FILE *file,
338 const char *magick_restrict format,va_list operands)
343#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VFPRINTF_L)
348 locale=AcquireCLocale();
349 if (locale == (locale_t) NULL)
350 n=(ssize_t) vfprintf(file,format,operands);
352#if defined(MAGICKCORE_WINDOWS_SUPPORT)
353 n=(ssize_t) _vfprintf_l(file,format,locale,operands);
355 n=(ssize_t) vfprintf_l(file,locale,format,operands);
359#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
365 locale=AcquireCLocale();
366 if (locale == (locale_t) NULL)
367 n=(ssize_t) vfprintf(file,format,operands);
370 previous_locale=uselocale(locale);
371 n=(ssize_t) vfprintf(file,format,operands);
372 uselocale(previous_locale);
376 n=(ssize_t) vfprintf(file,format,operands);
382MagickExport ssize_t FormatLocaleFile(FILE *file,
383 const char *magick_restrict format,...)
391 va_start(operands,format);
392 n=FormatLocaleFileList(file,format,operands);
428MagickPrivate ssize_t FormatLocaleStringList(
char *magick_restrict
string,
429 const size_t length,
const char *magick_restrict format,va_list operands)
434#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VSNPRINTF_L)
439 locale=AcquireCLocale();
440 if (locale == (locale_t) NULL)
441 n=(ssize_t) vsnprintf(
string,length,format,operands);
443#if defined(MAGICKCORE_WINDOWS_SUPPORT)
445 #pragma warning(push)
446 #pragma warning(disable:4996)
448 n=(ssize_t) _vsnprintf_l(
string,length,format,locale,operands);
453 n=(ssize_t) vsnprintf_l(
string,length,locale,format,operands);
456#elif defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
462 locale=AcquireCLocale();
463 if (locale == (locale_t) NULL)
464 n=(ssize_t) vsnprintf(
string,length,format,operands);
467 previous_locale=uselocale(locale);
468 n=(ssize_t) vsnprintf(
string,length,format,operands);
469 uselocale(previous_locale);
473 n=(ssize_t) vsnprintf(
string,length,format,operands);
476 string[length-1]=
'\0';
480MagickExport ssize_t FormatLocaleString(
char *magick_restrict
string,
481 const size_t length,
const char *magick_restrict format,...)
489 va_start(operands,format);
490 n=FormatLocaleStringList(
string,length,format,operands);
521MagickExport
const LocaleInfo *GetLocaleInfo_(
const char *tag,
522 ExceptionInfo *exception)
527 assert(exception != (ExceptionInfo *) NULL);
528 if (IsLocaleTreeInstantiated(exception) == MagickFalse)
529 return((
const LocaleInfo *) NULL);
530 LockSemaphoreInfo(locale_semaphore);
531 if ((tag == (
const char *) NULL) || (LocaleCompare(tag,
"*") == 0))
533 ResetSplayTreeIterator(locale_cache);
534 locale_info=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
535 UnlockSemaphoreInfo(locale_semaphore);
538 locale_info=(
const LocaleInfo *) GetValueFromSplayTree(locale_cache,tag);
539 UnlockSemaphoreInfo(locale_semaphore);
573#if defined(__cplusplus) || defined(c_plusplus)
577static int LocaleInfoCompare(
const void *x,
const void *y)
583 p=(
const LocaleInfo **) x,
584 q=(
const LocaleInfo **) y;
585 if (LocaleCompare((*p)->path,(*q)->path) == 0)
586 return(LocaleCompare((*p)->tag,(*q)->tag));
587 return(LocaleCompare((*p)->path,(*q)->path));
590#if defined(__cplusplus) || defined(c_plusplus)
594MagickExport
const LocaleInfo **GetLocaleInfoList(
const char *pattern,
595 size_t *number_messages,ExceptionInfo *exception)
609 assert(pattern != (
char *) NULL);
610 assert(number_messages != (
size_t *) NULL);
611 if (IsEventLogging() != MagickFalse)
612 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
614 p=GetLocaleInfo_(
"*",exception);
615 if (p == (
const LocaleInfo *) NULL)
616 return((
const LocaleInfo **) NULL);
617 messages=(
const LocaleInfo **) AcquireQuantumMemory((
size_t)
618 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
619 if (messages == (
const LocaleInfo **) NULL)
620 return((
const LocaleInfo **) NULL);
624 LockSemaphoreInfo(locale_semaphore);
625 ResetSplayTreeIterator(locale_cache);
626 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
627 for (i=0; p != (
const LocaleInfo *) NULL; )
629 if ((p->stealth == MagickFalse) &&
630 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
632 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
634 UnlockSemaphoreInfo(locale_semaphore);
635 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleInfoCompare);
636 messages[i]=(LocaleInfo *) NULL;
637 *number_messages=(size_t) i;
671#if defined(__cplusplus) || defined(c_plusplus)
675static int LocaleTagCompare(
const void *x,
const void *y)
683 return(LocaleCompare(*p,*q));
686#if defined(__cplusplus) || defined(c_plusplus)
690MagickExport
char **GetLocaleList(
const char *pattern,
size_t *number_messages,
691 ExceptionInfo *exception)
705 assert(pattern != (
char *) NULL);
706 assert(number_messages != (
size_t *) NULL);
707 if (IsEventLogging() != MagickFalse)
708 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
710 p=GetLocaleInfo_(
"*",exception);
711 if (p == (
const LocaleInfo *) NULL)
712 return((
char **) NULL);
713 messages=(
char **) AcquireQuantumMemory((
size_t)
714 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
715 if (messages == (
char **) NULL)
716 return((
char **) NULL);
717 LockSemaphoreInfo(locale_semaphore);
718 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
719 for (i=0; p != (
const LocaleInfo *) NULL; )
721 if ((p->stealth == MagickFalse) &&
722 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
723 messages[i++]=ConstantString(p->tag);
724 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
726 UnlockSemaphoreInfo(locale_semaphore);
727 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleTagCompare);
728 messages[i]=(
char *) NULL;
729 *number_messages=(size_t) i;
756MagickExport
const char *GetLocaleMessage(
const char *tag)
759 name[MagickLocaleExtent];
767 if ((tag == (
const char *) NULL) || (*tag ==
'\0'))
769 exception=AcquireExceptionInfo();
770 (void) FormatLocaleString(name,MagickLocaleExtent,
"%s/",tag);
771 locale_info=GetLocaleInfo_(name,exception);
772 exception=DestroyExceptionInfo(exception);
773 if (locale_info != (
const LocaleInfo *) NULL)
774 return(locale_info->message);
804MagickExport LinkedListInfo *GetLocaleOptions(
const char *filename,
805 ExceptionInfo *exception)
808 path[MagickPathExtent];
820 assert(filename != (
const char *) NULL);
821 assert(exception != (ExceptionInfo *) NULL);
822 if (IsEventLogging() != MagickFalse)
823 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
824 (void) CopyMagickString(path,filename,MagickPathExtent);
828 messages=NewLinkedList(0);
829 paths=GetConfigurePaths(filename,exception);
830 if (paths != (LinkedListInfo *) NULL)
832 ResetLinkedListIterator(paths);
833 element=(
const char *) GetNextValueInLinkedList(paths);
834 while (element != (
const char *) NULL)
836 (void) FormatLocaleString(path,MagickPathExtent,
"%s%s",element,
838 (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
839 "Searching for locale file: \"%s\"",path);
840 xml=ConfigureFileToStringInfo(path);
841 if (xml != (StringInfo *) NULL)
842 (void) AppendValueToLinkedList(messages,xml);
843 element=(
const char *) GetNextValueInLinkedList(paths);
845 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
847#if defined(MAGICKCORE_WINDOWS_SUPPORT)
852 blob=(
char *) NTResourceToBlob(filename);
853 if (blob != (
char *) NULL)
855 xml=AcquireStringInfo(0);
856 SetStringInfoLength(xml,strlen(blob)+1);
857 SetStringInfoDatum(xml,(
const unsigned char *) blob);
858 blob=(
char *) RelinquishMagickMemory(blob);
859 SetStringInfoPath(xml,filename);
860 (void) AppendValueToLinkedList(messages,xml);
864 ResetLinkedListIterator(messages);
890MagickExport
const char *GetLocaleValue(
const LocaleInfo *locale_info)
892 if (IsEventLogging() != MagickFalse)
893 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
894 assert(locale_info != (LocaleInfo *) NULL);
895 assert(locale_info->signature == MagickCoreSignature);
896 return(locale_info->message);
922static MagickBooleanType IsLocaleTreeInstantiated(ExceptionInfo *exception)
924 if (locale_cache == (SplayTreeInfo *) NULL)
927 ActivateSemaphoreInfo(&locale_semaphore);
928 LockSemaphoreInfo(locale_semaphore);
929 if (locale_cache == (SplayTreeInfo *) NULL)
937 locale=(
char *) NULL;
938 p=setlocale(LC_CTYPE,(
const char *) NULL);
939 if (p != (
const char *) NULL)
940 locale=ConstantString(p);
941 if (locale == (
char *) NULL)
942 locale=GetEnvironmentValue(
"LC_ALL");
943 if (locale == (
char *) NULL)
944 locale=GetEnvironmentValue(
"LC_MESSAGES");
945 if (locale == (
char *) NULL)
946 locale=GetEnvironmentValue(
"LC_CTYPE");
947 if (locale == (
char *) NULL)
948 locale=GetEnvironmentValue(
"LANG");
949 if (locale == (
char *) NULL)
950 locale=ConstantString(
"C");
951 locale_cache=AcquireLocaleSplayTree(LocaleFilename,locale,exception);
952 locale=DestroyString(locale);
954 UnlockSemaphoreInfo(locale_semaphore);
956 return(locale_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
988MagickExport
double InterpretLocaleValue(
const char *magick_restrict
string,
989 char *magick_restrict *sentinel)
997 if ((*
string ==
'0') && ((
string[1] | 0x20)==
'x'))
998 value=(double) strtoul(
string,&q,16);
1001#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_STRTOD_L)
1005 locale=AcquireCLocale();
1006 if (locale == (locale_t) NULL)
1007 value=strtod(
string,&q);
1009#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1010 value=_strtod_l(
string,&q,locale);
1012 value=strtod_l(
string,&q,locale);
1015 value=strtod(
string,&q);
1018 if (sentinel != (
char **) NULL)
1047MagickExport MagickBooleanType ListLocaleInfo(FILE *file,
1048 ExceptionInfo *exception)
1062 if (file == (
const FILE *) NULL)
1065 locale_info=GetLocaleInfoList(
"*",&number_messages,exception);
1066 if (locale_info == (
const LocaleInfo **) NULL)
1067 return(MagickFalse);
1068 path=(
const char *) NULL;
1069 for (i=0; i < (ssize_t) number_messages; i++)
1071 if (locale_info[i]->stealth != MagickFalse)
1073 if ((path == (
const char *) NULL) ||
1074 (LocaleCompare(path,locale_info[i]->path) != 0))
1076 if (locale_info[i]->path != (
char *) NULL)
1077 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",locale_info[i]->path);
1078 (void) FormatLocaleFile(file,
"Tag/Message\n");
1079 (void) FormatLocaleFile(file,
1080 "-------------------------------------------------"
1081 "------------------------------\n");
1083 path=locale_info[i]->path;
1084 (void) FormatLocaleFile(file,
"%s\n",locale_info[i]->tag);
1085 if (locale_info[i]->message != (
char *) NULL)
1086 (void) FormatLocaleFile(file,
" %s",locale_info[i]->message);
1087 (void) FormatLocaleFile(file,
"\n");
1089 (void) fflush(file);
1090 locale_info=(
const LocaleInfo **)
1091 RelinquishMagickMemory((
void *) locale_info);
1126static void ChopLocaleComponents(
char *path,
const size_t components)
1136 p=path+strlen(path)-1;
1139 for (count=0; (count < (ssize_t) components) && (p > path); p--)
1145 if (count < (ssize_t) components)
1150static void LocaleFatalErrorHandler(
const ExceptionType severity,
1151 const char *reason,
const char *description) magick_attribute((__noreturn__));
1153static void LocaleFatalErrorHandler(
1154 const ExceptionType magick_unused(severity),
1155 const char *reason,
const char *description)
1157 magick_unreferenced(severity);
1159 (void) FormatLocaleFile(stderr,
"%s: ",GetClientName());
1160 if (reason != (
char *) NULL)
1161 (void) FormatLocaleFile(stderr,
" %s",reason);
1162 if (description != (
char *) NULL)
1163 (void) FormatLocaleFile(stderr,
" (%s)",description);
1164 (void) FormatLocaleFile(stderr,
".\n");
1165 (void) fflush(stderr);
1169static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,
const char *xml,
1170 const char *filename,
const char *locale,
const size_t depth,ExceptionInfo *exception)
1173 keyword[MagickLocaleExtent],
1174 message[MagickLocaleExtent],
1175 tag[MagickLocaleExtent],
1199 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1200 "Loading locale configure file \"%s\" ...",filename);
1201 if (xml == (
const char *) NULL)
1202 return(MagickFalse);
1204 locale_info=(LocaleInfo *) NULL;
1208 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
1209 token=AcquireString(xml);
1210 extent=strlen(token)+MagickPathExtent;
1211 for (q=(
char *) xml; *q !=
'\0'; )
1216 (void) GetNextToken(q,&q,extent,token);
1219 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1220 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1225 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1227 (void) GetNextToken(q,&q,extent,token);
1228 while (isspace((
int) ((
unsigned char) *q)) != 0)
1233 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1238 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1240 (void) GetNextToken(q,&q,extent,token);
1241 while (isspace((
int) ((
unsigned char) *q)) != 0)
1246 if (LocaleCompare(keyword,
"<include") == 0)
1251 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1253 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1254 (void) GetNextToken(q,&q,extent,token);
1257 (void) GetNextToken(q,&q,extent,token);
1258 if (LocaleCompare(keyword,
"locale") == 0)
1260 if (LocaleCompare(locale,token) != 0)
1264 if (LocaleCompare(keyword,
"file") == 0)
1266 if (depth > MagickMaxRecursionDepth)
1267 (void) ThrowMagickException(exception,GetMagickModule(),
1268 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1272 path[MagickPathExtent],
1276 GetPathComponent(filename,HeadPath,path);
1278 (void) ConcatenateMagickString(path,DirectorySeparator,
1280 if (*token == *DirectorySeparator)
1281 (void) CopyMagickString(path,token,MagickPathExtent);
1283 (
void) ConcatenateMagickString(path,token,MagickPathExtent);
1284 file_xml=FileToXML(path,~0UL);
1285 if (file_xml != (
char *) NULL)
1287 status&=(MagickStatusType) LoadLocaleCache(cache,file_xml,
1288 path,locale,depth+1,exception);
1289 file_xml=DestroyString(file_xml);
1296 if (LocaleCompare(keyword,
"<locale") == 0)
1301 while ((*token !=
'>') && (*q !=
'\0'))
1303 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1304 (void) GetNextToken(q,&q,extent,token);
1307 (void) GetNextToken(q,&q,extent,token);
1311 if (LocaleCompare(keyword,
"</locale>") == 0)
1313 ChopLocaleComponents(tag,1);
1314 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1317 if (LocaleCompare(keyword,
"<localemap>") == 0)
1319 if (LocaleCompare(keyword,
"</localemap>") == 0)
1321 if (LocaleCompare(keyword,
"<message") == 0)
1326 while ((*token !=
'>') && (*q !=
'\0'))
1328 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1329 (void) GetNextToken(q,&q,extent,token);
1332 (void) GetNextToken(q,&q,extent,token);
1333 if (LocaleCompare(keyword,
"name") == 0)
1335 (void) ConcatenateMagickString(tag,token,MagickLocaleExtent);
1336 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1339 for (p=(
char *) q; (*q !=
'<') && (*q !=
'\0'); q++) ;
1340 while (isspace((
int) ((
unsigned char) *p)) != 0)
1343 while ((isspace((
int) ((
unsigned char) *q)) != 0) && (q > p))
1345 (void) CopyMagickString(message,p,MagickMin((
size_t) (q-p+2),
1346 MagickLocaleExtent));
1347 locale_info=(LocaleInfo *) AcquireCriticalMemory(
sizeof(*locale_info));
1348 (void) memset(locale_info,0,
sizeof(*locale_info));
1349 locale_info->path=ConstantString(filename);
1350 locale_info->tag=ConstantString(tag);
1351 locale_info->message=ConstantString(message);
1352 locale_info->signature=MagickCoreSignature;
1353 status=AddValueToSplayTree(cache,locale_info->tag,locale_info);
1354 if (status == MagickFalse)
1355 (void) ThrowMagickException(exception,GetMagickModule(),
1356 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1358 (void) ConcatenateMagickString(tag,message,MagickLocaleExtent);
1359 (void) ConcatenateMagickString(tag,
"\n",MagickLocaleExtent);
1363 if (LocaleCompare(keyword,
"</message>") == 0)
1365 ChopLocaleComponents(tag,2);
1366 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1369 if (*keyword ==
'<')
1374 if (*(keyword+1) ==
'?')
1376 if (*(keyword+1) ==
'/')
1378 ChopLocaleComponents(tag,1);
1380 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1383 token[strlen(token)-1]=
'\0';
1384 (void) CopyMagickString(token,token+1,MagickLocaleExtent);
1385 (void) ConcatenateMagickString(tag,token,MagickLocaleExtent);
1386 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1389 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1393 token=(
char *) RelinquishMagickMemory(token);
1394 (void) SetFatalErrorHandler(fatal_handler);
1395 return(status != 0 ? MagickTrue : MagickFalse);
1428MagickExport
int LocaleCompare(
const char *p,
const char *q)
1430 if (p == (
char *) NULL)
1432 if (q == (
char *) NULL)
1436 if (q == (
char *) NULL)
1440 *r = (
const unsigned char *) p,
1441 *s = (
const unsigned char *) q;
1443 for ( ; (*r !=
'\0') && (*s !=
'\0') && ((*r == *s) ||
1444 (LocaleToLowercase((
int) *r) == LocaleToLowercase((
int) *s))); r++, s++);
1445 return(LocaleToLowercase((
int) *r)-LocaleToLowercase((
int) *s));
1472MagickExport
void LocaleLower(
char *
string)
1477 assert(
string != (
char *) NULL);
1478 for (q=
string; *q !=
'\0'; q++)
1479 *q=(
char) LocaleToLowercase((
int) *q);
1504MagickExport
int LocaleLowercase(
const int c)
1506 return(LocaleToLowercase(c));
1546MagickExport
int LocaleNCompare(
const char *p,
const char *q,
const size_t length)
1548 if (p == (
char *) NULL)
1550 if (q == (
char *) NULL)
1554 if (q == (
char *) NULL)
1560 *s = (
const unsigned char *) p,
1561 *t = (
const unsigned char *) q;
1566 for (n--; (*s !=
'\0') && (*t !=
'\0') && (n != 0) && ((*s == *t) ||
1567 (LocaleToLowercase((
int) *s) == LocaleToLowercase((
int) *t))); s++, t++, n--);
1568 return(LocaleToLowercase((
int) *s)-LocaleToLowercase((
int) *t));
1595MagickExport
void LocaleUpper(
char *
string)
1600 assert(
string != (
char *) NULL);
1601 for (q=
string; *q !=
'\0'; q++)
1602 *q=(
char) LocaleToUppercase((
int) *q);
1627MagickExport
int LocaleUppercase(
const int c)
1629 return(LocaleToUppercase(c));
1650MagickPrivate MagickBooleanType LocaleComponentGenesis(
void)
1653 locale_semaphore=AcquireSemaphoreInfo();
1654#if defined(MAGICKCORE_LOCALE_SUPPORT)
1655 (void) AcquireCLocale();
1678MagickPrivate
void LocaleComponentTerminus(
void)
1681 ActivateSemaphoreInfo(&locale_semaphore);
1682 LockSemaphoreInfo(locale_semaphore);
1683 if (locale_cache != (SplayTreeInfo *) NULL)
1684 locale_cache=DestroySplayTree(locale_cache);
1685#if defined(MAGICKCORE_LOCALE_SUPPORT)
1688 UnlockSemaphoreInfo(locale_semaphore);
1689 RelinquishSemaphoreInfo(&locale_semaphore);