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_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
480 locale=AcquireCLocale();
481 if (locale == (locale_t) NULL)
482 n=(ssize_t) vsnprintf(
string,length,format,operands);
485 previous_locale=uselocale(locale);
486 n=(ssize_t) vsnprintf(
string,length,format,operands);
487 uselocale(previous_locale);
491 n=(ssize_t) vsnprintf(
string,length,format,operands);
494 string[length-1]=
'\0';
498MagickExport ssize_t FormatLocaleString(
char *magick_restrict
string,
499 const size_t length,
const char *magick_restrict format,...)
507 va_start(operands,format);
508 n=FormatLocaleStringList(
string,length,format,operands);
539MagickExport
const LocaleInfo *GetLocaleInfo_(
const char *tag,
540 ExceptionInfo *exception)
545 assert(exception != (ExceptionInfo *) NULL);
546 if (IsLocaleTreeInstantiated(exception) == MagickFalse)
547 return((
const LocaleInfo *) NULL);
548 LockSemaphoreInfo(locale_semaphore);
549 if ((tag == (
const char *) NULL) || (LocaleCompare(tag,
"*") == 0))
551 ResetSplayTreeIterator(locale_cache);
552 locale_info=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
553 UnlockSemaphoreInfo(locale_semaphore);
556 locale_info=(
const LocaleInfo *) GetValueFromSplayTree(locale_cache,tag);
557 UnlockSemaphoreInfo(locale_semaphore);
591#if defined(__cplusplus) || defined(c_plusplus)
595static int LocaleInfoCompare(
const void *x,
const void *y)
601 p=(
const LocaleInfo **) x,
602 q=(
const LocaleInfo **) y;
603 if (LocaleCompare((*p)->path,(*q)->path) == 0)
604 return(LocaleCompare((*p)->tag,(*q)->tag));
605 return(LocaleCompare((*p)->path,(*q)->path));
608#if defined(__cplusplus) || defined(c_plusplus)
612MagickExport
const LocaleInfo **GetLocaleInfoList(
const char *pattern,
613 size_t *number_messages,ExceptionInfo *exception)
627 assert(pattern != (
char *) NULL);
628 assert(number_messages != (
size_t *) NULL);
629 if (IsEventLogging() != MagickFalse)
630 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
632 p=GetLocaleInfo_(
"*",exception);
633 if (p == (
const LocaleInfo *) NULL)
634 return((
const LocaleInfo **) NULL);
635 messages=(
const LocaleInfo **) AcquireQuantumMemory((
size_t)
636 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
637 if (messages == (
const LocaleInfo **) NULL)
638 return((
const LocaleInfo **) NULL);
642 LockSemaphoreInfo(locale_semaphore);
643 ResetSplayTreeIterator(locale_cache);
644 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
645 for (i=0; p != (
const LocaleInfo *) NULL; )
647 if ((p->stealth == MagickFalse) &&
648 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
650 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
652 UnlockSemaphoreInfo(locale_semaphore);
653 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleInfoCompare);
654 messages[i]=(LocaleInfo *) NULL;
655 *number_messages=(size_t) i;
689#if defined(__cplusplus) || defined(c_plusplus)
693static int LocaleTagCompare(
const void *x,
const void *y)
701 return(LocaleCompare(*p,*q));
704#if defined(__cplusplus) || defined(c_plusplus)
708MagickExport
char **GetLocaleList(
const char *pattern,
709 size_t *number_messages,ExceptionInfo *exception)
723 assert(pattern != (
char *) NULL);
724 assert(number_messages != (
size_t *) NULL);
725 if (IsEventLogging() != MagickFalse)
726 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
728 p=GetLocaleInfo_(
"*",exception);
729 if (p == (
const LocaleInfo *) NULL)
730 return((
char **) NULL);
731 messages=(
char **) AcquireQuantumMemory((
size_t)
732 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
733 if (messages == (
char **) NULL)
734 return((
char **) NULL);
735 LockSemaphoreInfo(locale_semaphore);
736 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
737 for (i=0; p != (
const LocaleInfo *) NULL; )
739 if ((p->stealth == MagickFalse) &&
740 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
741 messages[i++]=ConstantString(p->tag);
742 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
744 UnlockSemaphoreInfo(locale_semaphore);
745 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleTagCompare);
746 messages[i]=(
char *) NULL;
747 *number_messages=(size_t) i;
774MagickExport
const char *GetLocaleMessage(
const char *tag)
785 if ((tag == (
const char *) NULL) || (*tag ==
'\0'))
787 exception=AcquireExceptionInfo();
788 (void) FormatLocaleString(name,MaxTextExtent,
"%s/",tag);
789 locale_info=GetLocaleInfo_(name,exception);
790 exception=DestroyExceptionInfo(exception);
791 if (locale_info != (
const LocaleInfo *) NULL)
792 return(locale_info->message);
822MagickExport LinkedListInfo *GetLocaleOptions(
const char *filename,
823 ExceptionInfo *exception)
838 assert(filename != (
const char *) NULL);
839 assert(exception != (ExceptionInfo *) NULL);
840 if (IsEventLogging() != MagickFalse)
841 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
842 (void) CopyMagickString(path,filename,MaxTextExtent);
846 messages=NewLinkedList(0);
847 paths=GetConfigurePaths(filename,exception);
848 if (paths != (LinkedListInfo *) NULL)
850 ResetLinkedListIterator(paths);
851 element=(
const char *) GetNextValueInLinkedList(paths);
852 while (element != (
const char *) NULL)
854 (void) FormatLocaleString(path,MaxTextExtent,
"%s%s",element,filename);
855 (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
856 "Searching for locale file: \"%s\"",path);
857 xml=ConfigureFileToStringInfo(path);
858 if (xml != (StringInfo *) NULL)
859 (void) AppendValueToLinkedList(messages,xml);
860 element=(
const char *) GetNextValueInLinkedList(paths);
862 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
864#if defined(MAGICKCORE_WINDOWS_SUPPORT)
869 blob=(
char *) NTResourceToBlob(filename);
870 if (blob != (
char *) NULL)
872 xml=AcquireStringInfo(0);
873 SetStringInfoLength(xml,strlen(blob)+1);
874 SetStringInfoDatum(xml,(
const unsigned char *) blob);
875 blob=(
char *) RelinquishMagickMemory(blob);
876 SetStringInfoPath(xml,filename);
877 (void) AppendValueToLinkedList(messages,xml);
881 ResetLinkedListIterator(messages);
907MagickExport
const char *GetLocaleValue(
const LocaleInfo *locale_info)
909 if (IsEventLogging() != MagickFalse)
910 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
911 assert(locale_info != (LocaleInfo *) NULL);
912 assert(locale_info->signature == MagickCoreSignature);
913 return(locale_info->message);
939static MagickBooleanType IsLocaleTreeInstantiated(ExceptionInfo *exception)
941 if (locale_cache == (SplayTreeInfo *) NULL)
944 ActivateSemaphoreInfo(&locale_semaphore);
945 LockSemaphoreInfo(locale_semaphore);
946 if (locale_cache == (SplayTreeInfo *) NULL)
954 locale=(
char *) NULL;
955 p=setlocale(LC_CTYPE,(
const char *) NULL);
956 if (p != (
const char *) NULL)
957 locale=ConstantString(p);
958 if (locale == (
char *) NULL)
959 locale=GetEnvironmentValue(
"LC_ALL");
960 if (locale == (
char *) NULL)
961 locale=GetEnvironmentValue(
"LC_MESSAGES");
962 if (locale == (
char *) NULL)
963 locale=GetEnvironmentValue(
"LC_CTYPE");
964 if (locale == (
char *) NULL)
965 locale=GetEnvironmentValue(
"LANG");
966 if (locale == (
char *) NULL)
967 locale=ConstantString(
"C");
968 locale_cache=AcquireLocaleSplayTree(LocaleFilename,locale,exception);
969 locale=DestroyString(locale);
971 UnlockSemaphoreInfo(locale_semaphore);
973 return(locale_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1005MagickExport
double InterpretLocaleValue(
const char *magick_restrict
string,
1006 char **magick_restrict sentinal)
1014 if ((*
string ==
'0') && ((
string[1] | 0x20)==
'x'))
1015 value=(double) strtoul(
string,&q,16);
1018#if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_STRTOD_L)
1022 locale=AcquireCLocale();
1023 if (locale == (locale_t) NULL)
1024 value=strtod(
string,&q);
1026#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1027 value=_strtod_l(
string,&q,locale);
1029 value=strtod_l(
string,&q,locale);
1032 value=strtod(
string,&q);
1035 if (sentinal != (
char **) NULL)
1064MagickExport MagickBooleanType ListLocaleInfo(FILE *file,
1065 ExceptionInfo *exception)
1079 if (file == (
const FILE *) NULL)
1082 locale_info=GetLocaleInfoList(
"*",&number_messages,exception);
1083 if (locale_info == (
const LocaleInfo **) NULL)
1084 return(MagickFalse);
1085 path=(
const char *) NULL;
1086 for (i=0; i < (ssize_t) number_messages; i++)
1088 if (locale_info[i]->stealth != MagickFalse)
1090 if ((path == (
const char *) NULL) ||
1091 (LocaleCompare(path,locale_info[i]->path) != 0))
1093 if (locale_info[i]->path != (
char *) NULL)
1094 (void) FormatLocaleFile(file,
"\nPath: %s\n\n",locale_info[i]->path);
1095 (void) FormatLocaleFile(file,
"Tag/Message\n");
1096 (void) FormatLocaleFile(file,
1097 "-------------------------------------------------"
1098 "------------------------------\n");
1100 path=locale_info[i]->path;
1101 (void) FormatLocaleFile(file,
"%s\n",locale_info[i]->tag);
1102 if (locale_info[i]->message != (
char *) NULL)
1103 (void) FormatLocaleFile(file,
" %s",locale_info[i]->message);
1104 (void) FormatLocaleFile(file,
"\n");
1106 (void) fflush(file);
1107 locale_info=(
const LocaleInfo **)
1108 RelinquishMagickMemory((
void *) locale_info);
1143static void ChopLocaleComponents(
char *path,
const size_t components)
1153 p=path+strlen(path)-1;
1156 for (count=0; (count < (ssize_t) components) && (p > path); p--)
1162 if (count < (ssize_t) components)
1166static void LocaleFatalErrorHandler(
const ExceptionType severity,
1167 const char *reason,
const char *description) magick_attribute((__noreturn__));
1169static void LocaleFatalErrorHandler(
1170 const ExceptionType magick_unused(severity),
1171 const char *reason,
const char *description)
1173 magick_unreferenced(severity);
1175 (void) FormatLocaleFile(stderr,
"%s:",GetClientName());
1176 if (reason != (
char *) NULL)
1177 (void) FormatLocaleFile(stderr,
" %s",reason);
1178 if (description != (
char *) NULL)
1179 (void) FormatLocaleFile(stderr,
" (%s)",description);
1180 (void) FormatLocaleFile(stderr,
".\n");
1181 (void) fflush(stderr);
1185static MagickBooleanType LoadLocaleCache(SplayTreeInfo *cache,
const char *xml,
1186 const char *filename,
const char *locale,
const size_t depth,
1187 ExceptionInfo *exception)
1190 keyword[MaxTextExtent],
1191 message[MaxTextExtent],
1216 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1217 "Loading locale configure file \"%s\" ...",filename);
1218 if (xml == (
const char *) NULL)
1219 return(MagickFalse);
1221 locale_info=(LocaleInfo *) NULL;
1225 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
1226 token=AcquireString(xml);
1227 extent=strlen(token)+MaxTextExtent;
1228 for (q=(
char *) xml; *q !=
'\0'; )
1233 (void) GetNextToken(q,&q,extent,token);
1236 (void) CopyMagickString(keyword,token,MaxTextExtent);
1237 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 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 (LocaleNCompare(keyword,
"<!--",4) == 0)
1255 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1257 (void) GetNextToken(q,&q,extent,token);
1258 while (isspace((
int) ((
unsigned char) *q)) != 0)
1263 if (LocaleCompare(keyword,
"<include") == 0)
1268 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1270 (void) CopyMagickString(keyword,token,MaxTextExtent);
1271 (void) GetNextToken(q,&q,extent,token);
1274 (void) GetNextToken(q,&q,extent,token);
1275 if (LocaleCompare(keyword,
"locale") == 0)
1277 if (LocaleCompare(locale,token) != 0)
1281 if (LocaleCompare(keyword,
"file") == 0)
1283 if (depth > MagickMaxRecursionDepth)
1284 (void) ThrowMagickException(exception,GetMagickModule(),
1285 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1289 path[MaxTextExtent],
1293 GetPathComponent(filename,HeadPath,path);
1295 (void) ConcatenateMagickString(path,DirectorySeparator,
1297 if (*token == *DirectorySeparator)
1298 (void) CopyMagickString(path,token,MaxTextExtent);
1300 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
1301 xml=FileToXML(path,~0UL);
1302 if (xml != (
char *) NULL)
1304 status&=LoadLocaleCache(cache,xml,path,locale,
1306 xml=(
char *) RelinquishMagickMemory(xml);
1313 if (LocaleCompare(keyword,
"<locale") == 0)
1318 while ((*token !=
'>') && (*q !=
'\0'))
1320 (void) CopyMagickString(keyword,token,MaxTextExtent);
1321 (void) GetNextToken(q,&q,extent,token);
1324 (void) GetNextToken(q,&q,extent,token);
1328 if (LocaleCompare(keyword,
"</locale>") == 0)
1330 ChopLocaleComponents(tag,1);
1331 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1334 if (LocaleCompare(keyword,
"<localemap>") == 0)
1336 if (LocaleCompare(keyword,
"</localemap>") == 0)
1338 if (LocaleCompare(keyword,
"<message") == 0)
1343 while ((*token !=
'>') && (*q !=
'\0'))
1345 (void) CopyMagickString(keyword,token,MaxTextExtent);
1346 (void) GetNextToken(q,&q,extent,token);
1349 (void) GetNextToken(q,&q,extent,token);
1350 if (LocaleCompare(keyword,
"name") == 0)
1352 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1353 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1356 for (p=(
char *) q; (*q !=
'<') && (*q !=
'\0'); q++) ;
1357 while (isspace((
int) ((
unsigned char) *p)) != 0)
1360 while ((isspace((
int) ((
unsigned char) *q)) != 0) && (q > p))
1362 (void) CopyMagickString(message,p,MagickMin((
size_t) (q-p+2),
1364 locale_info=(LocaleInfo *) AcquireMagickMemory(
sizeof(*locale_info));
1365 if (locale_info == (LocaleInfo *) NULL)
1366 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1367 (void) memset(locale_info,0,
sizeof(*locale_info));
1368 locale_info->path=ConstantString(filename);
1369 locale_info->tag=ConstantString(tag);
1370 locale_info->message=ConstantString(message);
1371 locale_info->signature=MagickCoreSignature;
1372 status=AddValueToSplayTree(cache,locale_info->tag,locale_info);
1373 if (status == MagickFalse)
1374 (void) ThrowMagickException(exception,GetMagickModule(),
1375 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1377 (void) ConcatenateMagickString(tag,message,MaxTextExtent);
1378 (void) ConcatenateMagickString(tag,
"\n",MaxTextExtent);
1382 if (LocaleCompare(keyword,
"</message>") == 0)
1384 ChopLocaleComponents(tag,2);
1385 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1388 if (*keyword ==
'<')
1393 if (*(keyword+1) ==
'?')
1395 if (*(keyword+1) ==
'/')
1397 ChopLocaleComponents(tag,1);
1399 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1402 token[strlen(token)-1]=
'\0';
1403 (void) CopyMagickString(token,token+1,MaxTextExtent);
1404 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1405 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1408 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1412 token=(
char *) RelinquishMagickMemory(token);
1413 (void) SetFatalErrorHandler(fatal_handler);
1414 return(status != 0 ? MagickTrue : MagickFalse);
1447MagickExport
int LocaleCompare(
const char *p,
const char *q)
1449 if (p == (
char *) NULL)
1451 if (q == (
char *) NULL)
1455 if (q == (
char *) NULL)
1457#if defined(MAGICKCORE_HAVE_STRCASECMP)
1458 return(strcasecmp(p,q));
1467 c=(int) *((
unsigned char *) p);
1468 d=(int) *((
unsigned char *) q);
1469 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
1474 return(AsciiMap[c]-(
int) AsciiMap[d]);
1502MagickExport
void LocaleLower(
char *
string)
1507 assert(
string != (
char *) NULL);
1508 for (q=
string; *q !=
'\0'; q++)
1509 *q=(
char) LocaleToLowercase((
int) *q);
1534MagickExport
int LocaleLowercase(
const int c)
1536 return(LocaleToLowercase(c));
1576MagickExport
int LocaleNCompare(
const char *p,
const char *q,
const size_t length)
1578 if (p == (
char *) NULL)
1580 if (q == (
char *) NULL)
1584 if (q == (
char *) NULL)
1586#if defined(MAGICKCORE_HAVE_STRNCASECMP)
1587 return(strncasecmp(p,q,length));
1597 for (i=length; i != 0; i--)
1599 c=(int) *((
unsigned char *) p);
1600 d=(int) *((
unsigned char *) q);
1601 if (AsciiMap[c] != AsciiMap[d])
1602 return(AsciiMap[c]-(
int) AsciiMap[d]);
1636MagickExport
void LocaleUpper(
char *
string)
1641 assert(
string != (
char *) NULL);
1642 for (q=
string; *q !=
'\0'; q++)
1643 *q=(
char) LocaleToUppercase((
int) *q);
1668MagickExport
int LocaleUppercase(
const int c)
1670 return(LocaleToUppercase(c));
1691MagickExport MagickBooleanType LocaleComponentGenesis(
void)
1694 locale_semaphore=AllocateSemaphoreInfo();
1695#if defined(MAGICKCORE_LOCALE_SUPPORT)
1696 (void) AcquireCLocale();
1719MagickExport
void LocaleComponentTerminus(
void)
1722 ActivateSemaphoreInfo(&locale_semaphore);
1723 LockSemaphoreInfo(locale_semaphore);
1724 if (locale_cache != (SplayTreeInfo *) NULL)
1725 locale_cache=DestroySplayTree(locale_cache);
1726#if defined(MAGICKCORE_LOCALE_SUPPORT)
1729 UnlockSemaphoreInfo(locale_semaphore);
1730 DestroySemaphoreInfo(&locale_semaphore);