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
70#if defined(MAGICKCORE_WINDOWS_SUPPORT)
71# if !defined(locale_t)
72# define locale_t _locale_t
76#define LocaleFilename "locale.xml"
83 "<?xml version=\"1.0\"?>"
85 " <locale name=\"C\">"
87 " <Message name=\"\">"
94#define asciimap AsciiMap
96#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
97static const unsigned char
100 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
101 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
102 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
103 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
104 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
105 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
106 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
107 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
108 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
109 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
110 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
111 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
112 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
113 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
114 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
115 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
116 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
117 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
118 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
119 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
120 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
121 0xfc, 0xfd, 0xfe, 0xff,
129 *locale_cache = (SplayTreeInfo *) NULL;
131#if defined(MAGICKCORE_LOCALE_SUPPORT)
132static volatile locale_t
133 c_locale = (locale_t) NULL;
139static MagickBooleanType
140 IsLocaleTreeInstantiated(ExceptionInfo *),
141 LoadLocaleCache(SplayTreeInfo *,
const char *,
const char *,
const char *,
142 const size_t,ExceptionInfo *);
144#if defined(MAGICKCORE_LOCALE_SUPPORT)
164static locale_t AcquireCLocale(
void)
166#if defined(MAGICKCORE_HAVE_NEWLOCALE)
167 if (c_locale == (locale_t) NULL)
168 c_locale=newlocale(LC_ALL_MASK,
"C",(locale_t) 0);
169#elif defined(MAGICKCORE_WINDOWS_SUPPORT) && !defined(__MINGW32__)
170 if (c_locale == (locale_t) NULL)
171 c_locale=_create_locale(LC_ALL,
"C");
206static void *DestroyLocaleNode(
void *locale_info)
211 p=(LocaleInfo *) locale_info;
212 if (p->path != (
char *) NULL)
213 p->path=DestroyString(p->path);
214 if (p->tag != (
char *) NULL)
215 p->tag=DestroyString(p->tag);
216 if (p->message != (
char *) NULL)
217 p->message=DestroyString(p->message);
218 return(RelinquishMagickMemory(p));
221static SplayTreeInfo *AcquireLocaleSplayTree(
const char *filename,
222 const char *locale,ExceptionInfo *exception)
227 cache=NewSplayTree(CompareSplayTreeString,(
void *(*)(
void *)) NULL,
229#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
237 options=GetLocaleOptions(filename,exception);
238 option=(
const StringInfo *) GetNextValueInLinkedList(options);
239 while (option != (
const StringInfo *) NULL)
241 (void) LoadLocaleCache(cache,(
const char *) GetStringInfoDatum(option),
242 GetStringInfoPath(option),locale,0,exception);
243 option=(
const StringInfo *) GetNextValueInLinkedList(options);
245 options=DestroyLocaleOptions(options);
246 if (GetNumberOfNodesInSplayTree(cache) == 0)
248 options=GetLocaleOptions(
"english.xml",exception);
249 option=(
const StringInfo *) GetNextValueInLinkedList(options);
250 while (option != (
const StringInfo *) NULL)
252 (void) LoadLocaleCache(cache,(
const char *)
253 GetStringInfoDatum(option),GetStringInfoPath(option),locale,0,
255 option=(
const StringInfo *) GetNextValueInLinkedList(options);
257 options=DestroyLocaleOptions(options);
261 if (GetNumberOfNodesInSplayTree(cache) == 0)
262 (void) LoadLocaleCache(cache,LocaleMap,
"built-in",locale,0,exception);
266#if defined(MAGICKCORE_LOCALE_SUPPORT)
286static void DestroyCLocale(
void)
288 if (c_locale != (locale_t) NULL)
289#if defined(MAGICKCORE_WINDOWS_SUPPORT)
290 _free_locale(c_locale);
292 freelocale(c_locale);
294 c_locale=(locale_t) NULL;
322static void *DestroyOptions(
void *message)
324 return(DestroyStringInfo((StringInfo *) message));
327MagickExport LinkedListInfo *DestroyLocaleOptions(LinkedListInfo *messages)
329 assert(messages != (LinkedListInfo *) NULL);
330 if (IsEventLogging() != MagickFalse)
331 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
332 return(DestroyLinkedList(messages,DestroyOptions));
362MagickExport ssize_t FormatLocaleFileList(FILE *file,
363 const char *magick_restrict format,va_list operands)
368#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VFPRINTF_L)
373 locale=AcquireCLocale();
374 if (locale == (locale_t) NULL)
375 n=(ssize_t) vfprintf(file,format,operands);
377#if defined(MAGICKCORE_WINDOWS_SUPPORT)
378 n=(ssize_t) _vfprintf_l(file,format,locale,operands);
380 n=(ssize_t) vfprintf_l(file,locale,format,operands);
384#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
390 locale=AcquireCLocale();
391 if (locale == (locale_t) NULL)
392 n=(ssize_t) vfprintf(file,format,operands);
395 previous_locale=uselocale(locale);
396 n=(ssize_t) vfprintf(file,format,operands);
397 uselocale(previous_locale);
401 n=(ssize_t) vfprintf(file,format,operands);
407MagickExport ssize_t FormatLocaleFile(FILE *file,
408 const char *magick_restrict format,...)
416 va_start(operands,format);
417 n=FormatLocaleFileList(file,format,operands);
453MagickExport ssize_t FormatLocaleStringList(
char *magick_restrict
string,
454 const size_t length,
const char *magick_restrict format,va_list operands)
459#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VSNPRINTF_L)
464 locale=AcquireCLocale();
465 if (locale == (locale_t) NULL)
466 n=(ssize_t) vsnprintf(
string,length,format,operands);
468#if defined(MAGICKCORE_WINDOWS_SUPPORT)
469 n=(ssize_t) _vsnprintf_l(
string,length,format,locale,operands);
471 n=(ssize_t) vsnprintf_l(
string,length,locale,format,operands);
474#elif defined(MAGICKCORE_HAVE_VSNPRINTF)
475#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
481 locale=AcquireCLocale();
482 if (locale == (locale_t) NULL)
483 n=(ssize_t) vsnprintf(
string,length,format,operands);
486 previous_locale=uselocale(locale);
487 n=(ssize_t) vsnprintf(
string,length,format,operands);
488 uselocale(previous_locale);
492 n=(ssize_t) vsnprintf(
string,length,format,operands);
495 n=(ssize_t) vsprintf(
string,format,operands);
498 string[length-1]=
'\0';
502MagickExport ssize_t FormatLocaleString(
char *magick_restrict
string,
503 const size_t length,
const char *magick_restrict format,...)
511 va_start(operands,format);
512 n=FormatLocaleStringList(
string,length,format,operands);
543MagickExport
const LocaleInfo *GetLocaleInfo_(
const char *tag,
544 ExceptionInfo *exception)
549 assert(exception != (ExceptionInfo *) NULL);
550 if (IsLocaleTreeInstantiated(exception) == MagickFalse)
551 return((
const LocaleInfo *) NULL);
552 LockSemaphoreInfo(locale_semaphore);
553 if ((tag == (
const char *) NULL) || (LocaleCompare(tag,
"*") == 0))
555 ResetSplayTreeIterator(locale_cache);
556 locale_info=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
557 UnlockSemaphoreInfo(locale_semaphore);
560 locale_info=(
const LocaleInfo *) GetValueFromSplayTree(locale_cache,tag);
561 UnlockSemaphoreInfo(locale_semaphore);
595#if defined(__cplusplus) || defined(c_plusplus)
599static int LocaleInfoCompare(
const void *x,
const void *y)
605 p=(
const LocaleInfo **) x,
606 q=(
const LocaleInfo **) y;
607 if (LocaleCompare((*p)->path,(*q)->path) == 0)
608 return(LocaleCompare((*p)->tag,(*q)->tag));
609 return(LocaleCompare((*p)->path,(*q)->path));
612#if defined(__cplusplus) || defined(c_plusplus)
616MagickExport
const LocaleInfo **GetLocaleInfoList(
const char *pattern,
617 size_t *number_messages,ExceptionInfo *exception)
631 assert(pattern != (
char *) NULL);
632 assert(number_messages != (
size_t *) NULL);
633 if (IsEventLogging() != MagickFalse)
634 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
636 p=GetLocaleInfo_(
"*",exception);
637 if (p == (
const LocaleInfo *) NULL)
638 return((
const LocaleInfo **) NULL);
639 messages=(
const LocaleInfo **) AcquireQuantumMemory((
size_t)
640 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
641 if (messages == (
const LocaleInfo **) NULL)
642 return((
const LocaleInfo **) NULL);
646 LockSemaphoreInfo(locale_semaphore);
647 ResetSplayTreeIterator(locale_cache);
648 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
649 for (i=0; p != (
const LocaleInfo *) NULL; )
651 if ((p->stealth == MagickFalse) &&
652 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
654 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
656 UnlockSemaphoreInfo(locale_semaphore);
657 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleInfoCompare);
658 messages[i]=(LocaleInfo *) NULL;
659 *number_messages=(size_t) i;
693#if defined(__cplusplus) || defined(c_plusplus)
697static int LocaleTagCompare(
const void *x,
const void *y)
705 return(LocaleCompare(*p,*q));
708#if defined(__cplusplus) || defined(c_plusplus)
712MagickExport
char **GetLocaleList(
const char *pattern,
713 size_t *number_messages,ExceptionInfo *exception)
727 assert(pattern != (
char *) NULL);
728 assert(number_messages != (
size_t *) NULL);
729 if (IsEventLogging() != MagickFalse)
730 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
732 p=GetLocaleInfo_(
"*",exception);
733 if (p == (
const LocaleInfo *) NULL)
734 return((
char **) NULL);
735 messages=(
char **) AcquireQuantumMemory((
size_t)
736 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
737 if (messages == (
char **) NULL)
738 return((
char **) NULL);
739 LockSemaphoreInfo(locale_semaphore);
740 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
741 for (i=0; p != (
const LocaleInfo *) NULL; )
743 if ((p->stealth == MagickFalse) &&
744 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
745 messages[i++]=ConstantString(p->tag);
746 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
748 UnlockSemaphoreInfo(locale_semaphore);
749 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleTagCompare);
750 messages[i]=(
char *) NULL;
751 *number_messages=(size_t) i;
778MagickExport
const char *GetLocaleMessage(
const char *tag)
789 if ((tag == (
const char *) NULL) || (*tag ==
'\0'))
791 exception=AcquireExceptionInfo();
792 (void) FormatLocaleString(name,MaxTextExtent,
"%s/",tag);
793 locale_info=GetLocaleInfo_(name,exception);
794 exception=DestroyExceptionInfo(exception);
795 if (locale_info != (
const LocaleInfo *) NULL)
796 return(locale_info->message);
826MagickExport LinkedListInfo *GetLocaleOptions(
const char *filename,
827 ExceptionInfo *exception)
842 assert(filename != (
const char *) NULL);
843 assert(exception != (ExceptionInfo *) NULL);
844 if (IsEventLogging() != MagickFalse)
845 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
846 (void) CopyMagickString(path,filename,MaxTextExtent);
850 messages=NewLinkedList(0);
851 paths=GetConfigurePaths(filename,exception);
852 if (paths != (LinkedListInfo *) NULL)
854 ResetLinkedListIterator(paths);
855 element=(
const char *) GetNextValueInLinkedList(paths);
856 while (element != (
const char *) NULL)
858 (void) FormatLocaleString(path,MaxTextExtent,
"%s%s",element,filename);
859 (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
860 "Searching for locale file: \"%s\"",path);
861 xml=ConfigureFileToStringInfo(path);
862 if (xml != (StringInfo *) NULL)
863 (void) AppendValueToLinkedList(messages,xml);
864 element=(
const char *) GetNextValueInLinkedList(paths);
866 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
868#if defined(MAGICKCORE_WINDOWS_SUPPORT)
873 blob=(
char *) NTResourceToBlob(filename);
874 if (blob != (
char *) NULL)
876 xml=AcquireStringInfo(0);
877 SetStringInfoLength(xml,strlen(blob)+1);
878 SetStringInfoDatum(xml,(
const unsigned char *) blob);
879 blob=(
char *) RelinquishMagickMemory(blob);
880 SetStringInfoPath(xml,filename);
881 (void) AppendValueToLinkedList(messages,xml);
885 ResetLinkedListIterator(messages);
911MagickExport
const char *GetLocaleValue(
const LocaleInfo *locale_info)
913 if (IsEventLogging() != MagickFalse)
914 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
915 assert(locale_info != (LocaleInfo *) NULL);
916 assert(locale_info->signature == MagickCoreSignature);
917 return(locale_info->message);
943static MagickBooleanType IsLocaleTreeInstantiated(ExceptionInfo *exception)
945 if (locale_cache == (SplayTreeInfo *) NULL)
948 ActivateSemaphoreInfo(&locale_semaphore);
949 LockSemaphoreInfo(locale_semaphore);
950 if (locale_cache == (SplayTreeInfo *) NULL)
958 locale=(
char *) NULL;
959 p=setlocale(LC_CTYPE,(
const char *) NULL);
960 if (p != (
const char *) NULL)
961 locale=ConstantString(p);
962 if (locale == (
char *) NULL)
963 locale=GetEnvironmentValue(
"LC_ALL");
964 if (locale == (
char *) NULL)
965 locale=GetEnvironmentValue(
"LC_MESSAGES");
966 if (locale == (
char *) NULL)
967 locale=GetEnvironmentValue(
"LC_CTYPE");
968 if (locale == (
char *) NULL)
969 locale=GetEnvironmentValue(
"LANG");
970 if (locale == (
char *) NULL)
971 locale=ConstantString(
"C");
972 locale_cache=AcquireLocaleSplayTree(LocaleFilename,locale,exception);
973 locale=DestroyString(locale);
975 UnlockSemaphoreInfo(locale_semaphore);
977 return(locale_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1009MagickExport
double InterpretLocaleValue(
const char *magick_restrict
string,
1010 char **magick_restrict sentinal)
1018 if ((*
string ==
'0') && ((
string[1] | 0x20)==
'x'))
1019 value=(double) strtoul(
string,&q,16);
1022#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_STRTOD_L)
1026 locale=AcquireCLocale();
1027 if (locale == (locale_t) NULL)
1028 value=strtod(
string,&q);
1030#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1031 value=_strtod_l(
string,&q,locale);
1033 value=strtod_l(
string,&q,locale);
1036 value=strtod(
string,&q);
1039 if (sentinal != (
char **) NULL)
1068MagickExport MagickBooleanType ListLocaleInfo(FILE *file,
1069 ExceptionInfo *exception)
1083 if (file == (
const FILE *) NULL)
1086 locale_info=GetLocaleInfoList(
"*",&number_messages,exception);
1087 if (locale_info == (
const LocaleInfo **) NULL)
1088 return(MagickFalse);
1089 path=(
const char *) NULL;
1090 for (i=0; i < (ssize_t) number_messages; i++)
1092 if (locale_info[i]->stealth != MagickFalse)
1094 if ((path == (
const char *) NULL) ||
1095 (LocaleCompare(path,locale_info[i]->path) != 0))
1097 if (locale_info[i]->path != (
char *) NULL)
1098 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",locale_info[i]->path);
1099 (void) FormatLocaleFile(file,
"Tag/Message\n");
1100 (void) FormatLocaleFile(file,
1101 "-------------------------------------------------"
1102 "------------------------------\n");
1104 path=locale_info[i]->path;
1105 (void) FormatLocaleFile(file,
"%s\n",locale_info[i]->tag);
1106 if (locale_info[i]->message != (
char *) NULL)
1107 (void) FormatLocaleFile(file,
" %s",locale_info[i]->message);
1108 (void) FormatLocaleFile(file,
"\n");
1110 (void) fflush(file);
1111 locale_info=(
const LocaleInfo **)
1112 RelinquishMagickMemory((
void *) locale_info);
1147static void ChopLocaleComponents(
char *path,
const size_t components)
1157 p=path+strlen(path)-1;
1160 for (count=0; (count < (ssize_t) components) && (p > path); p--)
1166 if (count < (ssize_t) components)
1170static void LocaleFatalErrorHandler(
const ExceptionType severity,
1171 const char *reason,
const char *description) magick_attribute((__noreturn__));
1173static void LocaleFatalErrorHandler(
1174 const ExceptionType magick_unused(severity),
1175 const char *reason,
const char *description)
1177 magick_unreferenced(severity);
1179 (void) FormatLocaleFile(stderr,
"%s:",GetClientName());
1180 if (reason != (
char *) NULL)
1181 (void) FormatLocaleFile(stderr,
" %s",reason);
1182 if (description != (
char *) NULL)
1183 (void) FormatLocaleFile(stderr,
" (%s)",description);
1184 (void) FormatLocaleFile(stderr,
".\n");
1185 (void) fflush(stderr);
1189static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,
const char *xml,
1190 const char *filename,
const char *locale,
const size_t depth,
1191 ExceptionInfo *exception)
1194 keyword[MaxTextExtent],
1195 message[MaxTextExtent],
1220 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1221 "Loading locale configure file \"%s\" ...",filename);
1222 if (xml == (
const char *) NULL)
1223 return(MagickFalse);
1225 locale_info=(LocaleInfo *) NULL;
1229 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
1230 token=AcquireString(xml);
1231 extent=strlen(token)+MaxTextExtent;
1232 for (q=(
char *) xml; *q !=
'\0'; )
1237 (void) GetNextToken(q,&q,extent,token);
1240 (void) CopyMagickString(keyword,token,MaxTextExtent);
1241 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1246 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1248 (void) GetNextToken(q,&q,extent,token);
1249 while (isspace((
int) ((
unsigned char) *q)) != 0)
1254 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1259 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1261 (void) GetNextToken(q,&q,extent,token);
1262 while (isspace((
int) ((
unsigned char) *q)) != 0)
1267 if (LocaleCompare(keyword,
"<include") == 0)
1272 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1274 (void) CopyMagickString(keyword,token,MaxTextExtent);
1275 (void) GetNextToken(q,&q,extent,token);
1278 (void) GetNextToken(q,&q,extent,token);
1279 if (LocaleCompare(keyword,
"locale") == 0)
1281 if (LocaleCompare(locale,token) != 0)
1285 if (LocaleCompare(keyword,
"file") == 0)
1287 if (depth > MagickMaxRecursionDepth)
1288 (void) ThrowMagickException(exception,GetMagickModule(),
1289 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1293 path[MaxTextExtent],
1297 GetPathComponent(filename,HeadPath,path);
1299 (void) ConcatenateMagickString(path,DirectorySeparator,
1301 if (*token == *DirectorySeparator)
1302 (void) CopyMagickString(path,token,MaxTextExtent);
1304 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
1305 xml=FileToXML(path,~0UL);
1306 if (xml != (
char *) NULL)
1308 status&=LoadLocaleCache(cache,xml,path,locale,
1310 xml=(
char *) RelinquishMagickMemory(xml);
1317 if (LocaleCompare(keyword,
"<locale") == 0)
1322 while ((*token !=
'>') && (*q !=
'\0'))
1324 (void) CopyMagickString(keyword,token,MaxTextExtent);
1325 (void) GetNextToken(q,&q,extent,token);
1328 (void) GetNextToken(q,&q,extent,token);
1332 if (LocaleCompare(keyword,
"</locale>") == 0)
1334 ChopLocaleComponents(tag,1);
1335 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1338 if (LocaleCompare(keyword,
"<localemap>") == 0)
1340 if (LocaleCompare(keyword,
"</localemap>") == 0)
1342 if (LocaleCompare(keyword,
"<message") == 0)
1347 while ((*token !=
'>') && (*q !=
'\0'))
1349 (void) CopyMagickString(keyword,token,MaxTextExtent);
1350 (void) GetNextToken(q,&q,extent,token);
1353 (void) GetNextToken(q,&q,extent,token);
1354 if (LocaleCompare(keyword,
"name") == 0)
1356 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1357 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1360 for (p=(
char *) q; (*q !=
'<') && (*q !=
'\0'); q++) ;
1361 while (isspace((
int) ((
unsigned char) *p)) != 0)
1364 while ((isspace((
int) ((
unsigned char) *q)) != 0) && (q > p))
1366 (void) CopyMagickString(message,p,MagickMin((
size_t) (q-p+2),
1368 locale_info=(LocaleInfo *) AcquireMagickMemory(
sizeof(*locale_info));
1369 if (locale_info == (LocaleInfo *) NULL)
1370 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1371 (void) memset(locale_info,0,
sizeof(*locale_info));
1372 locale_info->path=ConstantString(filename);
1373 locale_info->tag=ConstantString(tag);
1374 locale_info->message=ConstantString(message);
1375 locale_info->signature=MagickCoreSignature;
1376 status=AddValueToSplayTree(cache,locale_info->tag,locale_info);
1377 if (status == MagickFalse)
1378 (void) ThrowMagickException(exception,GetMagickModule(),
1379 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1381 (void) ConcatenateMagickString(tag,message,MaxTextExtent);
1382 (void) ConcatenateMagickString(tag,
"\n",MaxTextExtent);
1386 if (LocaleCompare(keyword,
"</message>") == 0)
1388 ChopLocaleComponents(tag,2);
1389 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1392 if (*keyword ==
'<')
1397 if (*(keyword+1) ==
'?')
1399 if (*(keyword+1) ==
'/')
1401 ChopLocaleComponents(tag,1);
1403 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1406 token[strlen(token)-1]=
'\0';
1407 (void) CopyMagickString(token,token+1,MaxTextExtent);
1408 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1409 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1412 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1416 token=(
char *) RelinquishMagickMemory(token);
1417 (void) SetFatalErrorHandler(fatal_handler);
1418 return(status != 0 ? MagickTrue : MagickFalse);
1451MagickExport
int LocaleCompare(
const char *p,
const char *q)
1453 if (p == (
char *) NULL)
1455 if (q == (
char *) NULL)
1459 if (q == (
char *) NULL)
1461#if defined(MAGICKCORE_HAVE_STRCASECMP)
1462 return(strcasecmp(p,q));
1471 c=(int) *((
unsigned char *) p);
1472 d=(int) *((
unsigned char *) q);
1473 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
1478 return(AsciiMap[c]-(
int) AsciiMap[d]);
1506MagickExport
void LocaleLower(
char *
string)
1511 assert(
string != (
char *) NULL);
1512 for (q=
string; *q !=
'\0'; q++)
1513 *q=(
char) LocaleToLowercase((
int) *q);
1538MagickExport
int LocaleLowercase(
const int c)
1540 return(LocaleToLowercase(c));
1580MagickExport
int LocaleNCompare(
const char *p,
const char *q,
const size_t length)
1582 if (p == (
char *) NULL)
1584 if (q == (
char *) NULL)
1588 if (q == (
char *) NULL)
1590#if defined(MAGICKCORE_HAVE_STRNCASECMP)
1591 return(strncasecmp(p,q,length));
1601 for (i=length; i != 0; i--)
1603 c=(int) *((
unsigned char *) p);
1604 d=(int) *((
unsigned char *) q);
1605 if (AsciiMap[c] != AsciiMap[d])
1606 return(AsciiMap[c]-(
int) AsciiMap[d]);
1640MagickExport
void LocaleUpper(
char *
string)
1645 assert(
string != (
char *) NULL);
1646 for (q=
string; *q !=
'\0'; q++)
1647 *q=(
char) LocaleToUppercase((
int) *q);
1672MagickExport
int LocaleUppercase(
const int c)
1674 return(LocaleToUppercase(c));
1695MagickExport MagickBooleanType LocaleComponentGenesis(
void)
1698 locale_semaphore=AllocateSemaphoreInfo();
1699#if defined(MAGICKCORE_LOCALE_SUPPORT)
1700 (void) AcquireCLocale();
1723MagickExport
void LocaleComponentTerminus(
void)
1726 ActivateSemaphoreInfo(&locale_semaphore);
1727 LockSemaphoreInfo(locale_semaphore);
1728 if (locale_cache != (SplayTreeInfo *) NULL)
1729 locale_cache=DestroySplayTree(locale_cache);
1730#if defined(MAGICKCORE_LOCALE_SUPPORT)
1733 UnlockSemaphoreInfo(locale_semaphore);
1734 DestroySemaphoreInfo(&locale_semaphore);