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_HAVE_VSNPRINTF)
457#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
463 locale=AcquireCLocale();
464 if (locale == (locale_t) NULL)
465 n=(ssize_t) vsnprintf(
string,length,format,operands);
468 previous_locale=uselocale(locale);
469 n=(ssize_t) vsnprintf(
string,length,format,operands);
470 uselocale(previous_locale);
474 n=(ssize_t) vsnprintf(
string,length,format,operands);
477 n=(ssize_t) vsprintf(
string,format,operands);
480 string[length-1]=
'\0';
484MagickExport ssize_t FormatLocaleString(
char *magick_restrict
string,
485 const size_t length,
const char *magick_restrict format,...)
493 va_start(operands,format);
494 n=FormatLocaleStringList(
string,length,format,operands);
525MagickExport
const LocaleInfo *GetLocaleInfo_(
const char *tag,
526 ExceptionInfo *exception)
531 assert(exception != (ExceptionInfo *) NULL);
532 if (IsLocaleTreeInstantiated(exception) == MagickFalse)
533 return((
const LocaleInfo *) NULL);
534 LockSemaphoreInfo(locale_semaphore);
535 if ((tag == (
const char *) NULL) || (LocaleCompare(tag,
"*") == 0))
537 ResetSplayTreeIterator(locale_cache);
538 locale_info=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
539 UnlockSemaphoreInfo(locale_semaphore);
542 locale_info=(
const LocaleInfo *) GetValueFromSplayTree(locale_cache,tag);
543 UnlockSemaphoreInfo(locale_semaphore);
577#if defined(__cplusplus) || defined(c_plusplus)
581static int LocaleInfoCompare(
const void *x,
const void *y)
587 p=(
const LocaleInfo **) x,
588 q=(
const LocaleInfo **) y;
589 if (LocaleCompare((*p)->path,(*q)->path) == 0)
590 return(LocaleCompare((*p)->tag,(*q)->tag));
591 return(LocaleCompare((*p)->path,(*q)->path));
594#if defined(__cplusplus) || defined(c_plusplus)
598MagickExport
const LocaleInfo **GetLocaleInfoList(
const char *pattern,
599 size_t *number_messages,ExceptionInfo *exception)
613 assert(pattern != (
char *) NULL);
614 assert(number_messages != (
size_t *) NULL);
615 if (IsEventLogging() != MagickFalse)
616 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
618 p=GetLocaleInfo_(
"*",exception);
619 if (p == (
const LocaleInfo *) NULL)
620 return((
const LocaleInfo **) NULL);
621 messages=(
const LocaleInfo **) AcquireQuantumMemory((
size_t)
622 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
623 if (messages == (
const LocaleInfo **) NULL)
624 return((
const LocaleInfo **) NULL);
628 LockSemaphoreInfo(locale_semaphore);
629 ResetSplayTreeIterator(locale_cache);
630 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
631 for (i=0; p != (
const LocaleInfo *) NULL; )
633 if ((p->stealth == MagickFalse) &&
634 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
636 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
638 UnlockSemaphoreInfo(locale_semaphore);
639 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleInfoCompare);
640 messages[i]=(LocaleInfo *) NULL;
641 *number_messages=(size_t) i;
675#if defined(__cplusplus) || defined(c_plusplus)
679static int LocaleTagCompare(
const void *x,
const void *y)
687 return(LocaleCompare(*p,*q));
690#if defined(__cplusplus) || defined(c_plusplus)
694MagickExport
char **GetLocaleList(
const char *pattern,
size_t *number_messages,
695 ExceptionInfo *exception)
709 assert(pattern != (
char *) NULL);
710 assert(number_messages != (
size_t *) NULL);
711 if (IsEventLogging() != MagickFalse)
712 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
714 p=GetLocaleInfo_(
"*",exception);
715 if (p == (
const LocaleInfo *) NULL)
716 return((
char **) NULL);
717 messages=(
char **) AcquireQuantumMemory((
size_t)
718 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
719 if (messages == (
char **) NULL)
720 return((
char **) NULL);
721 LockSemaphoreInfo(locale_semaphore);
722 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
723 for (i=0; p != (
const LocaleInfo *) NULL; )
725 if ((p->stealth == MagickFalse) &&
726 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
727 messages[i++]=ConstantString(p->tag);
728 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
730 UnlockSemaphoreInfo(locale_semaphore);
731 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleTagCompare);
732 messages[i]=(
char *) NULL;
733 *number_messages=(size_t) i;
760MagickExport
const char *GetLocaleMessage(
const char *tag)
763 name[MagickLocaleExtent];
771 if ((tag == (
const char *) NULL) || (*tag ==
'\0'))
773 exception=AcquireExceptionInfo();
774 (void) FormatLocaleString(name,MagickLocaleExtent,
"%s/",tag);
775 locale_info=GetLocaleInfo_(name,exception);
776 exception=DestroyExceptionInfo(exception);
777 if (locale_info != (
const LocaleInfo *) NULL)
778 return(locale_info->message);
808MagickExport LinkedListInfo *GetLocaleOptions(
const char *filename,
809 ExceptionInfo *exception)
812 path[MagickPathExtent];
824 assert(filename != (
const char *) NULL);
825 assert(exception != (ExceptionInfo *) NULL);
826 if (IsEventLogging() != MagickFalse)
827 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
828 (void) CopyMagickString(path,filename,MagickPathExtent);
832 messages=NewLinkedList(0);
833 paths=GetConfigurePaths(filename,exception);
834 if (paths != (LinkedListInfo *) NULL)
836 ResetLinkedListIterator(paths);
837 element=(
const char *) GetNextValueInLinkedList(paths);
838 while (element != (
const char *) NULL)
840 (void) FormatLocaleString(path,MagickPathExtent,
"%s%s",element,
842 (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
843 "Searching for locale file: \"%s\"",path);
844 xml=ConfigureFileToStringInfo(path);
845 if (xml != (StringInfo *) NULL)
846 (void) AppendValueToLinkedList(messages,xml);
847 element=(
const char *) GetNextValueInLinkedList(paths);
849 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
851#if defined(MAGICKCORE_WINDOWS_SUPPORT)
856 blob=(
char *) NTResourceToBlob(filename);
857 if (blob != (
char *) NULL)
859 xml=AcquireStringInfo(0);
860 SetStringInfoLength(xml,strlen(blob)+1);
861 SetStringInfoDatum(xml,(
const unsigned char *) blob);
862 blob=(
char *) RelinquishMagickMemory(blob);
863 SetStringInfoPath(xml,filename);
864 (void) AppendValueToLinkedList(messages,xml);
868 ResetLinkedListIterator(messages);
894MagickExport
const char *GetLocaleValue(
const LocaleInfo *locale_info)
896 if (IsEventLogging() != MagickFalse)
897 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
898 assert(locale_info != (LocaleInfo *) NULL);
899 assert(locale_info->signature == MagickCoreSignature);
900 return(locale_info->message);
926static MagickBooleanType IsLocaleTreeInstantiated(ExceptionInfo *exception)
928 if (locale_cache == (SplayTreeInfo *) NULL)
931 ActivateSemaphoreInfo(&locale_semaphore);
932 LockSemaphoreInfo(locale_semaphore);
933 if (locale_cache == (SplayTreeInfo *) NULL)
941 locale=(
char *) NULL;
942 p=setlocale(LC_CTYPE,(
const char *) NULL);
943 if (p != (
const char *) NULL)
944 locale=ConstantString(p);
945 if (locale == (
char *) NULL)
946 locale=GetEnvironmentValue(
"LC_ALL");
947 if (locale == (
char *) NULL)
948 locale=GetEnvironmentValue(
"LC_MESSAGES");
949 if (locale == (
char *) NULL)
950 locale=GetEnvironmentValue(
"LC_CTYPE");
951 if (locale == (
char *) NULL)
952 locale=GetEnvironmentValue(
"LANG");
953 if (locale == (
char *) NULL)
954 locale=ConstantString(
"C");
955 locale_cache=AcquireLocaleSplayTree(LocaleFilename,locale,exception);
956 locale=DestroyString(locale);
958 UnlockSemaphoreInfo(locale_semaphore);
960 return(locale_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
992MagickExport
double InterpretLocaleValue(
const char *magick_restrict
string,
993 char *magick_restrict *sentinel)
1001 if ((*
string ==
'0') && ((
string[1] | 0x20)==
'x'))
1002 value=(double) strtoul(
string,&q,16);
1005#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_STRTOD_L)
1009 locale=AcquireCLocale();
1010 if (locale == (locale_t) NULL)
1011 value=strtod(
string,&q);
1013#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1014 value=_strtod_l(
string,&q,locale);
1016 value=strtod_l(
string,&q,locale);
1019 value=strtod(
string,&q);
1022 if (sentinel != (
char **) NULL)
1051MagickExport MagickBooleanType ListLocaleInfo(FILE *file,
1052 ExceptionInfo *exception)
1066 if (file == (
const FILE *) NULL)
1069 locale_info=GetLocaleInfoList(
"*",&number_messages,exception);
1070 if (locale_info == (
const LocaleInfo **) NULL)
1071 return(MagickFalse);
1072 path=(
const char *) NULL;
1073 for (i=0; i < (ssize_t) number_messages; i++)
1075 if (locale_info[i]->stealth != MagickFalse)
1077 if ((path == (
const char *) NULL) ||
1078 (LocaleCompare(path,locale_info[i]->path) != 0))
1080 if (locale_info[i]->path != (
char *) NULL)
1081 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",locale_info[i]->path);
1082 (void) FormatLocaleFile(file,
"Tag/Message\n");
1083 (void) FormatLocaleFile(file,
1084 "-------------------------------------------------"
1085 "------------------------------\n");
1087 path=locale_info[i]->path;
1088 (void) FormatLocaleFile(file,
"%s\n",locale_info[i]->tag);
1089 if (locale_info[i]->message != (
char *) NULL)
1090 (void) FormatLocaleFile(file,
" %s",locale_info[i]->message);
1091 (void) FormatLocaleFile(file,
"\n");
1093 (void) fflush(file);
1094 locale_info=(
const LocaleInfo **)
1095 RelinquishMagickMemory((
void *) locale_info);
1130static void ChopLocaleComponents(
char *path,
const size_t components)
1140 p=path+strlen(path)-1;
1143 for (count=0; (count < (ssize_t) components) && (p > path); p--)
1149 if (count < (ssize_t) components)
1154static void LocaleFatalErrorHandler(
const ExceptionType severity,
1155 const char *reason,
const char *description) magick_attribute((__noreturn__));
1157static void LocaleFatalErrorHandler(
1158 const ExceptionType magick_unused(severity),
1159 const char *reason,
const char *description)
1161 magick_unreferenced(severity);
1163 (void) FormatLocaleFile(stderr,
"%s: ",GetClientName());
1164 if (reason != (
char *) NULL)
1165 (void) FormatLocaleFile(stderr,
" %s",reason);
1166 if (description != (
char *) NULL)
1167 (void) FormatLocaleFile(stderr,
" (%s)",description);
1168 (void) FormatLocaleFile(stderr,
".\n");
1169 (void) fflush(stderr);
1173static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,
const char *xml,
1174 const char *filename,
const char *locale,
const size_t depth,ExceptionInfo *exception)
1177 keyword[MagickLocaleExtent],
1178 message[MagickLocaleExtent],
1179 tag[MagickLocaleExtent],
1203 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1204 "Loading locale configure file \"%s\" ...",filename);
1205 if (xml == (
const char *) NULL)
1206 return(MagickFalse);
1208 locale_info=(LocaleInfo *) NULL;
1212 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
1213 token=AcquireString(xml);
1214 extent=strlen(token)+MagickPathExtent;
1215 for (q=(
char *) xml; *q !=
'\0'; )
1220 (void) GetNextToken(q,&q,extent,token);
1223 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1224 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1229 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1231 (void) GetNextToken(q,&q,extent,token);
1232 while (isspace((
int) ((
unsigned char) *q)) != 0)
1237 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1242 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1244 (void) GetNextToken(q,&q,extent,token);
1245 while (isspace((
int) ((
unsigned char) *q)) != 0)
1250 if (LocaleCompare(keyword,
"<include") == 0)
1255 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1257 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1258 (void) GetNextToken(q,&q,extent,token);
1261 (void) GetNextToken(q,&q,extent,token);
1262 if (LocaleCompare(keyword,
"locale") == 0)
1264 if (LocaleCompare(locale,token) != 0)
1268 if (LocaleCompare(keyword,
"file") == 0)
1270 if (depth > MagickMaxRecursionDepth)
1271 (void) ThrowMagickException(exception,GetMagickModule(),
1272 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1276 path[MagickPathExtent],
1280 GetPathComponent(filename,HeadPath,path);
1282 (void) ConcatenateMagickString(path,DirectorySeparator,
1284 if (*token == *DirectorySeparator)
1285 (void) CopyMagickString(path,token,MagickPathExtent);
1287 (
void) ConcatenateMagickString(path,token,MagickPathExtent);
1288 file_xml=FileToXML(path,~0UL);
1289 if (file_xml != (
char *) NULL)
1291 status&=(MagickStatusType) LoadLocaleCache(cache,file_xml,
1292 path,locale,depth+1,exception);
1293 file_xml=DestroyString(file_xml);
1300 if (LocaleCompare(keyword,
"<locale") == 0)
1305 while ((*token !=
'>') && (*q !=
'\0'))
1307 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1308 (void) GetNextToken(q,&q,extent,token);
1311 (void) GetNextToken(q,&q,extent,token);
1315 if (LocaleCompare(keyword,
"</locale>") == 0)
1317 ChopLocaleComponents(tag,1);
1318 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1321 if (LocaleCompare(keyword,
"<localemap>") == 0)
1323 if (LocaleCompare(keyword,
"</localemap>") == 0)
1325 if (LocaleCompare(keyword,
"<message") == 0)
1330 while ((*token !=
'>') && (*q !=
'\0'))
1332 (void) CopyMagickString(keyword,token,MagickLocaleExtent);
1333 (void) GetNextToken(q,&q,extent,token);
1336 (void) GetNextToken(q,&q,extent,token);
1337 if (LocaleCompare(keyword,
"name") == 0)
1339 (void) ConcatenateMagickString(tag,token,MagickLocaleExtent);
1340 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1343 for (p=(
char *) q; (*q !=
'<') && (*q !=
'\0'); q++) ;
1344 while (isspace((
int) ((
unsigned char) *p)) != 0)
1347 while ((isspace((
int) ((
unsigned char) *q)) != 0) && (q > p))
1349 (void) CopyMagickString(message,p,MagickMin((
size_t) (q-p+2),
1350 MagickLocaleExtent));
1351 locale_info=(LocaleInfo *) AcquireCriticalMemory(
sizeof(*locale_info));
1352 (void) memset(locale_info,0,
sizeof(*locale_info));
1353 locale_info->path=ConstantString(filename);
1354 locale_info->tag=ConstantString(tag);
1355 locale_info->message=ConstantString(message);
1356 locale_info->signature=MagickCoreSignature;
1357 status=AddValueToSplayTree(cache,locale_info->tag,locale_info);
1358 if (status == MagickFalse)
1359 (void) ThrowMagickException(exception,GetMagickModule(),
1360 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1362 (void) ConcatenateMagickString(tag,message,MagickLocaleExtent);
1363 (void) ConcatenateMagickString(tag,
"\n",MagickLocaleExtent);
1367 if (LocaleCompare(keyword,
"</message>") == 0)
1369 ChopLocaleComponents(tag,2);
1370 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1373 if (*keyword ==
'<')
1378 if (*(keyword+1) ==
'?')
1380 if (*(keyword+1) ==
'/')
1382 ChopLocaleComponents(tag,1);
1384 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1387 token[strlen(token)-1]=
'\0';
1388 (void) CopyMagickString(token,token+1,MagickLocaleExtent);
1389 (void) ConcatenateMagickString(tag,token,MagickLocaleExtent);
1390 (void) ConcatenateMagickString(tag,
"/",MagickLocaleExtent);
1393 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1397 token=(
char *) RelinquishMagickMemory(token);
1398 (void) SetFatalErrorHandler(fatal_handler);
1399 return(status != 0 ? MagickTrue : MagickFalse);
1432MagickExport
int LocaleCompare(
const char *p,
const char *q)
1434 if (p == (
char *) NULL)
1436 if (q == (
char *) NULL)
1440 if (q == (
char *) NULL)
1444 *r = (
const unsigned char *) p,
1445 *s = (
const unsigned char *) q;
1447 for ( ; (*r !=
'\0') && (*s !=
'\0') && ((*r == *s) ||
1448 (LocaleToLowercase((
int) *r) == LocaleToLowercase((
int) *s))); r++, s++);
1449 return(LocaleToLowercase((
int) *r)-LocaleToLowercase((
int) *s));
1476MagickExport
void LocaleLower(
char *
string)
1481 assert(
string != (
char *) NULL);
1482 for (q=
string; *q !=
'\0'; q++)
1483 *q=(
char) LocaleToLowercase((
int) *q);
1508MagickExport
int LocaleLowercase(
const int c)
1510 return(LocaleToLowercase(c));
1550MagickExport
int LocaleNCompare(
const char *p,
const char *q,
const size_t length)
1552 if (p == (
char *) NULL)
1554 if (q == (
char *) NULL)
1558 if (q == (
char *) NULL)
1564 *s = (
const unsigned char *) p,
1565 *t = (
const unsigned char *) q;
1570 for (n--; (*s !=
'\0') && (*t !=
'\0') && (n != 0) && ((*s == *t) ||
1571 (LocaleToLowercase((
int) *s) == LocaleToLowercase((
int) *t))); s++, t++, n--);
1572 return(LocaleToLowercase((
int) *s)-LocaleToLowercase((
int) *t));
1599MagickExport
void LocaleUpper(
char *
string)
1604 assert(
string != (
char *) NULL);
1605 for (q=
string; *q !=
'\0'; q++)
1606 *q=(
char) LocaleToUppercase((
int) *q);
1631MagickExport
int LocaleUppercase(
const int c)
1633 return(LocaleToUppercase(c));
1654MagickPrivate MagickBooleanType LocaleComponentGenesis(
void)
1657 locale_semaphore=AcquireSemaphoreInfo();
1658#if defined(MAGICKCORE_LOCALE_SUPPORT)
1659 (void) AcquireCLocale();
1682MagickPrivate
void LocaleComponentTerminus(
void)
1685 ActivateSemaphoreInfo(&locale_semaphore);
1686 LockSemaphoreInfo(locale_semaphore);
1687 if (locale_cache != (SplayTreeInfo *) NULL)
1688 locale_cache=DestroySplayTree(locale_cache);
1689#if defined(MAGICKCORE_LOCALE_SUPPORT)
1692 UnlockSemaphoreInfo(locale_semaphore);
1693 RelinquishSemaphoreInfo(&locale_semaphore);