42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/client.h"
45#include "magick/configure.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/hashmap.h"
49#include "magick/image-private.h"
50#include "magick/locale_.h"
51#include "magick/locale-private.h"
52#include "magick/log.h"
53#include "magick/memory_.h"
54#include "magick/nt-base-private.h"
55#include "magick/semaphore.h"
56#include "magick/splay-tree.h"
57#include "magick/string_.h"
58#include "magick/token.h"
59#include "magick/utility.h"
60#include "magick/xml-tree.h"
61#include "magick/xml-tree-private.h"
66#if (defined(MAGICKCORE_HAVE_NEWLOCALE) || defined(MAGICKCORE_WINDOWS_SUPPORT)) && !defined(__MINGW32__)
67# define MAGICKCORE_LOCALE_SUPPORT
69#define LocaleFilename "locale.xml"
70#define MaxRecursionDepth 200
77 "<?xml version=\"1.0\"?>"
79 " <locale name=\"C\">"
81 " <Message name=\"\">"
88#define asciimap AsciiMap
90#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
91static const unsigned char
94 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
95 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
96 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
97 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
98 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
99 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
100 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
101 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
102 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
103 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
104 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
105 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
106 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
107 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
108 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
109 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
110 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
111 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
112 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
113 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
114 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
115 0xfc, 0xfd, 0xfe, 0xff,
125#if defined(MAGICKCORE_LOCALE_SUPPORT)
126static volatile locale_t
127 c_locale = (locale_t) NULL;
133static MagickBooleanType
135 LoadLocaleCache(
SplayTreeInfo *,
const char *,
const char *,
const char *,
138#if defined(MAGICKCORE_LOCALE_SUPPORT)
158static locale_t AcquireCLocale(
void)
160#if defined(MAGICKCORE_HAVE_NEWLOCALE)
161 if (c_locale == (locale_t) NULL)
162 c_locale=newlocale(LC_ALL_MASK,
"C",(locale_t) 0);
163#elif defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
164 if (c_locale == (locale_t) NULL)
165 c_locale=_create_locale(LC_ALL,
"C");
200static void *DestroyLocaleNode(
void *locale_info)
206 if (p->path != (
char *) NULL)
207 p->path=DestroyString(p->path);
208 if (p->tag != (
char *) NULL)
209 p->tag=DestroyString(p->tag);
210 if (p->message != (
char *) NULL)
211 p->message=DestroyString(p->message);
212 return(RelinquishMagickMemory(p));
215static SplayTreeInfo *AcquireLocaleSplayTree(
const char *filename,
221 cache=NewSplayTree(CompareSplayTreeString,(
void *(*)(
void *)) NULL,
223#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
231 options=GetLocaleOptions(filename,exception);
232 option=(
const StringInfo *) GetNextValueInLinkedList(options);
235 (void) LoadLocaleCache(cache,(
const char *) GetStringInfoDatum(option),
236 GetStringInfoPath(option),locale,0,exception);
237 option=(
const StringInfo *) GetNextValueInLinkedList(options);
239 options=DestroyLocaleOptions(options);
240 if (GetNumberOfNodesInSplayTree(cache) == 0)
242 options=GetLocaleOptions(
"english.xml",exception);
243 option=(
const StringInfo *) GetNextValueInLinkedList(options);
246 (void) LoadLocaleCache(cache,(
const char *)
247 GetStringInfoDatum(option),GetStringInfoPath(option),locale,0,
249 option=(
const StringInfo *) GetNextValueInLinkedList(options);
251 options=DestroyLocaleOptions(options);
255 if (GetNumberOfNodesInSplayTree(cache) == 0)
256 (void) LoadLocaleCache(cache,LocaleMap,
"built-in",locale,0,exception);
260#if defined(MAGICKCORE_LOCALE_SUPPORT)
280static void DestroyCLocale(
void)
282 if (c_locale != (locale_t) NULL)
283 freelocale(c_locale);
284 c_locale=(locale_t) NULL;
312static void *DestroyOptions(
void *message)
314 return(DestroyStringInfo((
StringInfo *) message));
320 if (IsEventLogging() != MagickFalse)
321 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
322 return(DestroyLinkedList(messages,DestroyOptions));
352MagickExport ssize_t FormatLocaleFileList(FILE *file,
353 const char *magick_restrict format,va_list operands)
358#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VFPRINTF_L)
363 locale=AcquireCLocale();
364 if (locale == (locale_t) NULL)
365 n=(ssize_t) vfprintf(file,format,operands);
367#if defined(MAGICKCORE_WINDOWS_SUPPORT)
368 n=(ssize_t) vfprintf_l(file,format,locale,operands);
370 n=(ssize_t) vfprintf_l(file,locale,format,operands);
374#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
380 locale=AcquireCLocale();
381 if (locale == (locale_t) NULL)
382 n=(ssize_t) vfprintf(file,format,operands);
385 previous_locale=uselocale(locale);
386 n=(ssize_t) vfprintf(file,format,operands);
387 uselocale(previous_locale);
391 n=(ssize_t) vfprintf(file,format,operands);
397MagickExport ssize_t FormatLocaleFile(FILE *file,
398 const char *magick_restrict format,...)
406 va_start(operands,format);
407 n=FormatLocaleFileList(file,format,operands);
443MagickExport ssize_t FormatLocaleStringList(
char *magick_restrict
string,
444 const size_t length,
const char *magick_restrict format,va_list operands)
449#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VSNPRINTF_L)
454 locale=AcquireCLocale();
455 if (locale == (locale_t) NULL)
456 n=(ssize_t) vsnprintf(
string,length,format,operands);
458#if defined(MAGICKCORE_WINDOWS_SUPPORT)
459 n=(ssize_t) vsnprintf_l(
string,length,format,locale,operands);
461 n=(ssize_t) vsnprintf_l(
string,length,locale,format,operands);
464#elif defined(MAGICKCORE_HAVE_VSNPRINTF)
465#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
471 locale=AcquireCLocale();
472 if (locale == (locale_t) NULL)
473 n=(ssize_t) vsnprintf(
string,length,format,operands);
476 previous_locale=uselocale(locale);
477 n=(ssize_t) vsnprintf(
string,length,format,operands);
478 uselocale(previous_locale);
482 n=(ssize_t) vsnprintf(
string,length,format,operands);
485 n=(ssize_t) vsprintf(
string,format,operands);
488 string[length-1]=
'\0';
492MagickExport ssize_t FormatLocaleString(
char *magick_restrict
string,
493 const size_t length,
const char *magick_restrict format,...)
501 va_start(operands,format);
502 n=FormatLocaleStringList(
string,length,format,operands);
533MagickExport
const LocaleInfo *GetLocaleInfo_(
const char *tag,
540 if (IsLocaleTreeInstantiated(exception) == MagickFalse)
542 LockSemaphoreInfo(locale_semaphore);
543 if ((tag == (
const char *) NULL) || (LocaleCompare(tag,
"*") == 0))
545 ResetSplayTreeIterator(locale_cache);
546 locale_info=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
547 UnlockSemaphoreInfo(locale_semaphore);
550 locale_info=(
const LocaleInfo *) GetValueFromSplayTree(locale_cache,tag);
551 UnlockSemaphoreInfo(locale_semaphore);
585#if defined(__cplusplus) || defined(c_plusplus)
589static int LocaleInfoCompare(
const void *x,
const void *y)
597 if (LocaleCompare((*p)->path,(*q)->path) == 0)
598 return(LocaleCompare((*p)->tag,(*q)->tag));
599 return(LocaleCompare((*p)->path,(*q)->path));
602#if defined(__cplusplus) || defined(c_plusplus)
606MagickExport
const LocaleInfo **GetLocaleInfoList(
const char *pattern,
621 assert(pattern != (
char *) NULL);
622 assert(number_messages != (
size_t *) NULL);
623 if (IsEventLogging() != MagickFalse)
624 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
626 p=GetLocaleInfo_(
"*",exception);
629 messages=(
const LocaleInfo **) AcquireQuantumMemory((
size_t)
630 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
636 LockSemaphoreInfo(locale_semaphore);
637 ResetSplayTreeIterator(locale_cache);
638 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
641 if ((p->stealth == MagickFalse) &&
642 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
644 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
646 UnlockSemaphoreInfo(locale_semaphore);
647 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleInfoCompare);
649 *number_messages=(size_t) i;
683#if defined(__cplusplus) || defined(c_plusplus)
687static int LocaleTagCompare(
const void *x,
const void *y)
695 return(LocaleCompare(*p,*q));
698#if defined(__cplusplus) || defined(c_plusplus)
702MagickExport
char **GetLocaleList(
const char *pattern,
717 assert(pattern != (
char *) NULL);
718 assert(number_messages != (
size_t *) NULL);
719 if (IsEventLogging() != MagickFalse)
720 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
722 p=GetLocaleInfo_(
"*",exception);
724 return((
char **) NULL);
725 messages=(
char **) AcquireQuantumMemory((
size_t)
726 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
727 if (messages == (
char **) NULL)
728 return((
char **) NULL);
729 LockSemaphoreInfo(locale_semaphore);
730 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
733 if ((p->stealth == MagickFalse) &&
734 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
735 messages[i++]=ConstantString(p->tag);
736 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
738 UnlockSemaphoreInfo(locale_semaphore);
739 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleTagCompare);
740 messages[i]=(
char *) NULL;
741 *number_messages=(size_t) i;
768MagickExport
const char *GetLocaleMessage(
const char *tag)
779 if ((tag == (
const char *) NULL) || (*tag ==
'\0'))
781 exception=AcquireExceptionInfo();
782 (void) FormatLocaleString(name,MaxTextExtent,
"%s/",tag);
783 locale_info=GetLocaleInfo_(name,exception);
784 exception=DestroyExceptionInfo(exception);
786 return(locale_info->message);
816MagickExport
LinkedListInfo *GetLocaleOptions(
const char *filename,
832 assert(filename != (
const char *) NULL);
834 if (IsEventLogging() != MagickFalse)
835 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
836 (void) CopyMagickString(path,filename,MaxTextExtent);
840 messages=NewLinkedList(0);
841 paths=GetConfigurePaths(filename,exception);
844 ResetLinkedListIterator(paths);
845 element=(
const char *) GetNextValueInLinkedList(paths);
846 while (element != (
const char *) NULL)
848 (void) FormatLocaleString(path,MaxTextExtent,
"%s%s",element,filename);
849 (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
850 "Searching for locale file: \"%s\"",path);
851 xml=ConfigureFileToStringInfo(path);
853 (void) AppendValueToLinkedList(messages,xml);
854 element=(
const char *) GetNextValueInLinkedList(paths);
856 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
858#if defined(MAGICKCORE_WINDOWS_SUPPORT)
863 blob=(
char *) NTResourceToBlob(filename);
864 if (blob != (
char *) NULL)
866 xml=AcquireStringInfo(0);
867 SetStringInfoLength(xml,strlen(blob)+1);
868 SetStringInfoDatum(xml,(
const unsigned char *) blob);
869 blob=(
char *) RelinquishMagickMemory(blob);
870 SetStringInfoPath(xml,filename);
871 (void) AppendValueToLinkedList(messages,xml);
875 ResetLinkedListIterator(messages);
901MagickExport
const char *GetLocaleValue(
const LocaleInfo *locale_info)
903 if (IsEventLogging() != MagickFalse)
904 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
906 assert(locale_info->signature == MagickCoreSignature);
907 return(locale_info->message);
933static MagickBooleanType IsLocaleTreeInstantiated(
ExceptionInfo *exception)
938 ActivateSemaphoreInfo(&locale_semaphore);
939 LockSemaphoreInfo(locale_semaphore);
948 locale=(
char *) NULL;
949 p=setlocale(LC_CTYPE,(
const char *) NULL);
950 if (p != (
const char *) NULL)
951 locale=ConstantString(p);
952 if (locale == (
char *) NULL)
953 locale=GetEnvironmentValue(
"LC_ALL");
954 if (locale == (
char *) NULL)
955 locale=GetEnvironmentValue(
"LC_MESSAGES");
956 if (locale == (
char *) NULL)
957 locale=GetEnvironmentValue(
"LC_CTYPE");
958 if (locale == (
char *) NULL)
959 locale=GetEnvironmentValue(
"LANG");
960 if (locale == (
char *) NULL)
961 locale=ConstantString(
"C");
962 locale_cache=AcquireLocaleSplayTree(LocaleFilename,locale,exception);
963 locale=DestroyString(locale);
965 UnlockSemaphoreInfo(locale_semaphore);
967 return(locale_cache != (
SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
999MagickExport
double InterpretLocaleValue(
const char *magick_restrict
string,
1000 char **magick_restrict sentinal)
1008 if ((*
string ==
'0') && ((
string[1] | 0x20)==
'x'))
1009 value=(double) strtoul(
string,&q,16);
1012#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_STRTOD_L)
1016 locale=AcquireCLocale();
1017 if (locale == (locale_t) NULL)
1018 value=strtod(
string,&q);
1020 value=strtod_l(
string,&q,locale);
1022 value=strtod(
string,&q);
1025 if (sentinal != (
char **) NULL)
1054MagickExport MagickBooleanType ListLocaleInfo(FILE *file,
1069 if (file == (
const FILE *) NULL)
1072 locale_info=GetLocaleInfoList(
"*",&number_messages,exception);
1073 if (locale_info == (
const LocaleInfo **) NULL)
1074 return(MagickFalse);
1075 path=(
const char *) NULL;
1076 for (i=0; i < (ssize_t) number_messages; i++)
1078 if (locale_info[i]->stealth != MagickFalse)
1080 if ((path == (
const char *) NULL) ||
1081 (LocaleCompare(path,locale_info[i]->path) != 0))
1083 if (locale_info[i]->path != (
char *) NULL)
1084 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",locale_info[i]->path);
1085 (void) FormatLocaleFile(file,
"Tag/Message\n");
1086 (void) FormatLocaleFile(file,
1087 "-------------------------------------------------"
1088 "------------------------------\n");
1090 path=locale_info[i]->path;
1091 (void) FormatLocaleFile(file,
"%s\n",locale_info[i]->tag);
1092 if (locale_info[i]->message != (
char *) NULL)
1093 (void) FormatLocaleFile(file,
" %s",locale_info[i]->message);
1094 (void) FormatLocaleFile(file,
"\n");
1096 (void) fflush(file);
1098 RelinquishMagickMemory((
void *) locale_info);
1133static void ChopLocaleComponents(
char *path,
const size_t components)
1143 p=path+strlen(path)-1;
1146 for (count=0; (count < (ssize_t) components) && (p > path); p--)
1152 if (count < (ssize_t) components)
1156static void LocaleFatalErrorHandler(
const ExceptionType severity,
1157 const char *reason,
const char *description) magick_attribute((__noreturn__));
1159static void LocaleFatalErrorHandler(
1160 const ExceptionType magick_unused(severity),
1161 const char *reason,
const char *description)
1163 magick_unreferenced(severity);
1165 (void) FormatLocaleFile(stderr,
"%s:",GetClientName());
1166 if (reason != (
char *) NULL)
1167 (void) FormatLocaleFile(stderr,
" %s",reason);
1168 if (description != (
char *) NULL)
1169 (void) FormatLocaleFile(stderr,
" (%s)",description);
1170 (void) FormatLocaleFile(stderr,
".\n");
1171 (void) fflush(stderr);
1175static MagickBooleanType LoadLocaleCache(
SplayTreeInfo *cache,
const char *xml,
1176 const char *filename,
const char *locale,
const size_t depth,
1180 keyword[MaxTextExtent],
1181 message[MaxTextExtent],
1206 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1207 "Loading locale configure file \"%s\" ...",filename);
1208 if (xml == (
const char *) NULL)
1209 return(MagickFalse);
1215 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
1216 token=AcquireString(xml);
1217 extent=strlen(token)+MaxTextExtent;
1218 for (q=(
char *) xml; *q !=
'\0'; )
1223 (void) GetNextToken(q,&q,extent,token);
1226 (void) CopyMagickString(keyword,token,MaxTextExtent);
1227 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1232 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1234 (void) GetNextToken(q,&q,extent,token);
1235 while (isspace((
int) ((
unsigned char) *q)) != 0)
1240 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1245 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1247 (void) GetNextToken(q,&q,extent,token);
1248 while (isspace((
int) ((
unsigned char) *q)) != 0)
1253 if (LocaleCompare(keyword,
"<include") == 0)
1258 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1260 (void) CopyMagickString(keyword,token,MaxTextExtent);
1261 (void) GetNextToken(q,&q,extent,token);
1264 (void) GetNextToken(q,&q,extent,token);
1265 if (LocaleCompare(keyword,
"locale") == 0)
1267 if (LocaleCompare(locale,token) != 0)
1271 if (LocaleCompare(keyword,
"file") == 0)
1273 if (depth > MagickMaxRecursionDepth)
1274 (void) ThrowMagickException(exception,GetMagickModule(),
1275 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1279 path[MaxTextExtent],
1283 GetPathComponent(filename,HeadPath,path);
1285 (void) ConcatenateMagickString(path,DirectorySeparator,
1287 if (*token == *DirectorySeparator)
1288 (void) CopyMagickString(path,token,MaxTextExtent);
1290 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
1291 xml=FileToXML(path,~0UL);
1292 if (xml != (
char *) NULL)
1294 status&=LoadLocaleCache(cache,xml,path,locale,
1296 xml=(
char *) RelinquishMagickMemory(xml);
1303 if (LocaleCompare(keyword,
"<locale") == 0)
1308 while ((*token !=
'>') && (*q !=
'\0'))
1310 (void) CopyMagickString(keyword,token,MaxTextExtent);
1311 (void) GetNextToken(q,&q,extent,token);
1314 (void) GetNextToken(q,&q,extent,token);
1318 if (LocaleCompare(keyword,
"</locale>") == 0)
1320 ChopLocaleComponents(tag,1);
1321 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1324 if (LocaleCompare(keyword,
"<localemap>") == 0)
1326 if (LocaleCompare(keyword,
"</localemap>") == 0)
1328 if (LocaleCompare(keyword,
"<message") == 0)
1333 while ((*token !=
'>') && (*q !=
'\0'))
1335 (void) CopyMagickString(keyword,token,MaxTextExtent);
1336 (void) GetNextToken(q,&q,extent,token);
1339 (void) GetNextToken(q,&q,extent,token);
1340 if (LocaleCompare(keyword,
"name") == 0)
1342 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1343 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1346 for (p=(
char *) q; (*q !=
'<') && (*q !=
'\0'); q++) ;
1347 while (isspace((
int) ((
unsigned char) *p)) != 0)
1350 while ((isspace((
int) ((
unsigned char) *q)) != 0) && (q > p))
1352 (void) CopyMagickString(message,p,MagickMin((
size_t) (q-p+2),
1354 locale_info=(
LocaleInfo *) AcquireMagickMemory(
sizeof(*locale_info));
1356 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1357 (void) memset(locale_info,0,
sizeof(*locale_info));
1358 locale_info->path=ConstantString(filename);
1359 locale_info->tag=ConstantString(tag);
1360 locale_info->message=ConstantString(message);
1361 locale_info->signature=MagickCoreSignature;
1362 status=AddValueToSplayTree(cache,locale_info->tag,locale_info);
1363 if (status == MagickFalse)
1364 (void) ThrowMagickException(exception,GetMagickModule(),
1365 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1367 (void) ConcatenateMagickString(tag,message,MaxTextExtent);
1368 (void) ConcatenateMagickString(tag,
"\n",MaxTextExtent);
1372 if (LocaleCompare(keyword,
"</message>") == 0)
1374 ChopLocaleComponents(tag,2);
1375 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1378 if (*keyword ==
'<')
1383 if (*(keyword+1) ==
'?')
1385 if (*(keyword+1) ==
'/')
1387 ChopLocaleComponents(tag,1);
1389 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1392 token[strlen(token)-1]=
'\0';
1393 (void) CopyMagickString(token,token+1,MaxTextExtent);
1394 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1395 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1398 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1402 token=(
char *) RelinquishMagickMemory(token);
1403 (void) SetFatalErrorHandler(fatal_handler);
1404 return(status != 0 ? MagickTrue : MagickFalse);
1437MagickExport
int LocaleCompare(
const char *p,
const char *q)
1439 if (p == (
char *) NULL)
1441 if (q == (
char *) NULL)
1445 if (q == (
char *) NULL)
1447#if defined(MAGICKCORE_HAVE_STRCASECMP)
1448 return(strcasecmp(p,q));
1457 c=(int) *((
unsigned char *) p);
1458 d=(int) *((
unsigned char *) q);
1459 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
1464 return(AsciiMap[c]-(
int) AsciiMap[d]);
1492MagickExport
void LocaleLower(
char *
string)
1497 assert(
string != (
char *) NULL);
1498 for (q=
string; *q !=
'\0'; q++)
1499 *q=(
char) LocaleToLowercase((
int) *q);
1524MagickExport
int LocaleLowercase(
const int c)
1526 return(LocaleToLowercase(c));
1566MagickExport
int LocaleNCompare(
const char *p,
const char *q,
const size_t length)
1568 if (p == (
char *) NULL)
1570 if (q == (
char *) NULL)
1574 if (q == (
char *) NULL)
1576#if defined(MAGICKCORE_HAVE_STRNCASECMP)
1577 return(strncasecmp(p,q,length));
1587 for (i=length; i != 0; i--)
1589 c=(int) *((
unsigned char *) p);
1590 d=(int) *((
unsigned char *) q);
1591 if (AsciiMap[c] != AsciiMap[d])
1592 return(AsciiMap[c]-(
int) AsciiMap[d]);
1626MagickExport
void LocaleUpper(
char *
string)
1631 assert(
string != (
char *) NULL);
1632 for (q=
string; *q !=
'\0'; q++)
1633 *q=(
char) LocaleToUppercase((
int) *q);
1658MagickExport
int LocaleUppercase(
const int c)
1660 return(LocaleToUppercase(c));
1681MagickExport MagickBooleanType LocaleComponentGenesis(
void)
1684 locale_semaphore=AllocateSemaphoreInfo();
1685#if defined(MAGICKCORE_LOCALE_SUPPORT)
1686 (void) AcquireCLocale();
1709MagickExport
void LocaleComponentTerminus(
void)
1712 ActivateSemaphoreInfo(&locale_semaphore);
1713 LockSemaphoreInfo(locale_semaphore);
1715 locale_cache=DestroySplayTree(locale_cache);
1716#if defined(MAGICKCORE_LOCALE_SUPPORT)
1719 UnlockSemaphoreInfo(locale_semaphore);
1720 DestroySemaphoreInfo(&locale_semaphore);