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)
91 static 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)
126 static volatile locale_t
127 c_locale = (locale_t) NULL;
133 static MagickBooleanType
135 LoadLocaleCache(
SplayTreeInfo *,
const char *,
const char *,
const char *,
138 #if defined(MAGICKCORE_LOCALE_SUPPORT)
158 static 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");
200 static 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));
215 static SplayTreeInfo *AcquireLocaleSplayTree(
const char *filename,
224 cache=NewSplayTree(CompareSplayTreeString,(
void *(*)(
void *)) NULL,
227 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
229 #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
237 options=GetLocaleOptions(filename,exception);
238 option=(
const StringInfo *) GetNextValueInLinkedList(options);
241 status&=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);
252 status&=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 status&=LoadLocaleCache(cache,LocaleMap,
"built-in",locale,0,
267 #if defined(MAGICKCORE_LOCALE_SUPPORT)
287 static void DestroyCLocale(
void)
289 if (c_locale != (locale_t) NULL)
290 freelocale(c_locale);
291 c_locale=(locale_t) NULL;
319 static void *DestroyOptions(
void *message)
321 return(DestroyStringInfo((
StringInfo *) message));
327 if (IsEventLogging() != MagickFalse)
328 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
329 return(DestroyLinkedList(messages,DestroyOptions));
359 MagickExport ssize_t FormatLocaleFileList(FILE *file,
360 const char *magick_restrict format,va_list operands)
365 #if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VFPRINTF_L)
370 locale=AcquireCLocale();
371 if (locale == (locale_t) NULL)
372 n=(ssize_t) vfprintf(file,format,operands);
374 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
375 n=(ssize_t) vfprintf_l(file,format,locale,operands);
377 n=(ssize_t) vfprintf_l(file,locale,format,operands);
381 #if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
387 locale=AcquireCLocale();
388 if (locale == (locale_t) NULL)
389 n=(ssize_t) vfprintf(file,format,operands);
392 previous_locale=uselocale(locale);
393 n=(ssize_t) vfprintf(file,format,operands);
394 uselocale(previous_locale);
398 n=(ssize_t) vfprintf(file,format,operands);
404 MagickExport ssize_t FormatLocaleFile(FILE *file,
405 const char *magick_restrict format,...)
413 va_start(operands,format);
414 n=FormatLocaleFileList(file,format,operands);
450 MagickExport ssize_t FormatLocaleStringList(
char *magick_restrict
string,
451 const size_t length,
const char *magick_restrict format,va_list operands)
456 #if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_VSNPRINTF_L)
461 locale=AcquireCLocale();
462 if (locale == (locale_t) NULL)
463 n=(ssize_t) vsnprintf(
string,length,format,operands);
465 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
466 n=(ssize_t) vsnprintf_l(
string,length,format,locale,operands);
468 n=(ssize_t) vsnprintf_l(
string,length,locale,format,operands);
471 #elif defined(MAGICKCORE_HAVE_VSNPRINTF)
472 #if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_USELOCALE)
478 locale=AcquireCLocale();
479 if (locale == (locale_t) NULL)
480 n=(ssize_t) vsnprintf(
string,length,format,operands);
483 previous_locale=uselocale(locale);
484 n=(ssize_t) vsnprintf(
string,length,format,operands);
485 uselocale(previous_locale);
489 n=(ssize_t) vsnprintf(
string,length,format,operands);
492 n=(ssize_t) vsprintf(
string,format,operands);
495 string[length-1]=
'\0';
499 MagickExport ssize_t FormatLocaleString(
char *magick_restrict
string,
500 const size_t length,
const char *magick_restrict format,...)
508 va_start(operands,format);
509 n=FormatLocaleStringList(
string,length,format,operands);
540 MagickExport
const LocaleInfo *GetLocaleInfo_(
const char *tag,
547 if (IsLocaleTreeInstantiated(exception) == MagickFalse)
549 LockSemaphoreInfo(locale_semaphore);
550 if ((tag == (
const char *) NULL) || (LocaleCompare(tag,
"*") == 0))
552 ResetSplayTreeIterator(locale_cache);
553 locale_info=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
554 UnlockSemaphoreInfo(locale_semaphore);
557 locale_info=(
const LocaleInfo *) GetValueFromSplayTree(locale_cache,tag);
558 UnlockSemaphoreInfo(locale_semaphore);
592 #if defined(__cplusplus) || defined(c_plusplus)
596 static int LocaleInfoCompare(
const void *x,
const void *y)
604 if (LocaleCompare((*p)->path,(*q)->path) == 0)
605 return(LocaleCompare((*p)->tag,(*q)->tag));
606 return(LocaleCompare((*p)->path,(*q)->path));
609 #if defined(__cplusplus) || defined(c_plusplus)
613 MagickExport
const LocaleInfo **GetLocaleInfoList(
const char *pattern,
628 assert(pattern != (
char *) NULL);
629 assert(number_messages != (
size_t *) NULL);
630 if (IsEventLogging() != MagickFalse)
631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
633 p=GetLocaleInfo_(
"*",exception);
636 messages=(
const LocaleInfo **) AcquireQuantumMemory((
size_t)
637 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
643 LockSemaphoreInfo(locale_semaphore);
644 ResetSplayTreeIterator(locale_cache);
645 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
648 if ((p->stealth == MagickFalse) &&
649 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
651 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
653 UnlockSemaphoreInfo(locale_semaphore);
654 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleInfoCompare);
656 *number_messages=(size_t) i;
690 #if defined(__cplusplus) || defined(c_plusplus)
694 static int LocaleTagCompare(
const void *x,
const void *y)
702 return(LocaleCompare(*p,*q));
705 #if defined(__cplusplus) || defined(c_plusplus)
709 MagickExport
char **GetLocaleList(
const char *pattern,
724 assert(pattern != (
char *) NULL);
725 assert(number_messages != (
size_t *) NULL);
726 if (IsEventLogging() != MagickFalse)
727 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
729 p=GetLocaleInfo_(
"*",exception);
731 return((
char **) NULL);
732 messages=(
char **) AcquireQuantumMemory((
size_t)
733 GetNumberOfNodesInSplayTree(locale_cache)+1UL,
sizeof(*messages));
734 if (messages == (
char **) NULL)
735 return((
char **) NULL);
736 LockSemaphoreInfo(locale_semaphore);
737 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
740 if ((p->stealth == MagickFalse) &&
741 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
742 messages[i++]=ConstantString(p->tag);
743 p=(
const LocaleInfo *) GetNextValueInSplayTree(locale_cache);
745 UnlockSemaphoreInfo(locale_semaphore);
746 qsort((
void *) messages,(
size_t) i,
sizeof(*messages),LocaleTagCompare);
747 messages[i]=(
char *) NULL;
748 *number_messages=(size_t) i;
775 MagickExport
const char *GetLocaleMessage(
const char *tag)
786 if ((tag == (
const char *) NULL) || (*tag ==
'\0'))
788 exception=AcquireExceptionInfo();
789 (void) FormatLocaleString(name,MaxTextExtent,
"%s/",tag);
790 locale_info=GetLocaleInfo_(name,exception);
791 exception=DestroyExceptionInfo(exception);
793 return(locale_info->message);
823 MagickExport
LinkedListInfo *GetLocaleOptions(
const char *filename,
839 assert(filename != (
const char *) NULL);
841 if (IsEventLogging() != MagickFalse)
842 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",filename);
843 (void) CopyMagickString(path,filename,MaxTextExtent);
847 messages=NewLinkedList(0);
848 paths=GetConfigurePaths(filename,exception);
851 ResetLinkedListIterator(paths);
852 element=(
const char *) GetNextValueInLinkedList(paths);
853 while (element != (
const char *) NULL)
855 (void) FormatLocaleString(path,MaxTextExtent,
"%s%s",element,filename);
856 (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
857 "Searching for locale file: \"%s\"",path);
858 xml=ConfigureFileToStringInfo(path);
860 (void) AppendValueToLinkedList(messages,xml);
861 element=(
const char *) GetNextValueInLinkedList(paths);
863 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
865 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
870 blob=(
char *) NTResourceToBlob(filename);
871 if (blob != (
char *) NULL)
873 xml=AcquireStringInfo(0);
874 SetStringInfoLength(xml,strlen(blob)+1);
875 SetStringInfoDatum(xml,(
const unsigned char *) blob);
876 blob=(
char *) RelinquishMagickMemory(blob);
877 SetStringInfoPath(xml,filename);
878 (void) AppendValueToLinkedList(messages,xml);
882 ResetLinkedListIterator(messages);
908 MagickExport
const char *GetLocaleValue(
const LocaleInfo *locale_info)
910 if (IsEventLogging() != MagickFalse)
911 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
913 assert(locale_info->signature == MagickCoreSignature);
914 return(locale_info->message);
940 static MagickBooleanType IsLocaleTreeInstantiated(
ExceptionInfo *exception)
945 ActivateSemaphoreInfo(&locale_semaphore);
946 LockSemaphoreInfo(locale_semaphore);
955 locale=(
char *) NULL;
956 p=setlocale(LC_CTYPE,(
const char *) NULL);
957 if (p != (
const char *) NULL)
958 locale=ConstantString(p);
959 if (locale == (
char *) NULL)
960 locale=GetEnvironmentValue(
"LC_ALL");
961 if (locale == (
char *) NULL)
962 locale=GetEnvironmentValue(
"LC_MESSAGES");
963 if (locale == (
char *) NULL)
964 locale=GetEnvironmentValue(
"LC_CTYPE");
965 if (locale == (
char *) NULL)
966 locale=GetEnvironmentValue(
"LANG");
967 if (locale == (
char *) NULL)
968 locale=ConstantString(
"C");
969 locale_cache=AcquireLocaleSplayTree(LocaleFilename,locale,exception);
970 locale=DestroyString(locale);
972 UnlockSemaphoreInfo(locale_semaphore);
974 return(locale_cache != (
SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1006 MagickExport
double InterpretLocaleValue(
const char *magick_restrict
string,
1007 char **magick_restrict sentinal)
1015 if ((*
string ==
'0') && ((
string[1] | 0x20)==
'x'))
1016 value=(double) strtoul(
string,&q,16);
1019 #if defined(MAGICKCORE_LOCALE_SUPPORT) && defined(MAGICKCORE_HAVE_STRTOD_L)
1023 locale=AcquireCLocale();
1024 if (locale == (locale_t) NULL)
1025 value=strtod(
string,&q);
1027 value=strtod_l(
string,&q,locale);
1029 value=strtod(
string,&q);
1032 if (sentinal != (
char **) NULL)
1061 MagickExport MagickBooleanType ListLocaleInfo(FILE *file,
1076 if (file == (
const FILE *) NULL)
1079 locale_info=GetLocaleInfoList(
"*",&number_messages,exception);
1080 if (locale_info == (
const LocaleInfo **) NULL)
1081 return(MagickFalse);
1082 path=(
const char *) NULL;
1083 for (i=0; i < (ssize_t) number_messages; i++)
1085 if (locale_info[i]->stealth != MagickFalse)
1087 if ((path == (
const char *) NULL) ||
1088 (LocaleCompare(path,locale_info[i]->path) != 0))
1090 if (locale_info[i]->path != (
char *) NULL)
1091 (
void) FormatLocaleFile(file,
"\nPath: %s\n\n",locale_info[i]->path);
1092 (void) FormatLocaleFile(file,
"Tag/Message\n");
1093 (void) FormatLocaleFile(file,
1094 "-------------------------------------------------"
1095 "------------------------------\n");
1097 path=locale_info[i]->path;
1098 (void) FormatLocaleFile(file,
"%s\n",locale_info[i]->tag);
1099 if (locale_info[i]->message != (
char *) NULL)
1100 (
void) FormatLocaleFile(file,
" %s",locale_info[i]->message);
1101 (void) FormatLocaleFile(file,
"\n");
1103 (void) fflush(file);
1105 RelinquishMagickMemory((
void *) locale_info);
1140 static void ChopLocaleComponents(
char *path,
const size_t components)
1150 p=path+strlen(path)-1;
1153 for (count=0; (count < (ssize_t) components) && (p > path); p--)
1159 if (count < (ssize_t) components)
1163 static void LocaleFatalErrorHandler(
const ExceptionType severity,
1164 const char *reason,
const char *description) magick_attribute((__noreturn__));
1166 static void LocaleFatalErrorHandler(
1167 const ExceptionType magick_unused(severity),
1168 const char *reason,
const char *description)
1170 magick_unreferenced(severity);
1172 (void) FormatLocaleFile(stderr,
"%s:",GetClientName());
1173 if (reason != (
char *) NULL)
1174 (
void) FormatLocaleFile(stderr,
" %s",reason);
1175 if (description != (
char *) NULL)
1176 (void) FormatLocaleFile(stderr,
" (%s)",description);
1177 (void) FormatLocaleFile(stderr,
".\n");
1178 (void) fflush(stderr);
1182 static MagickBooleanType LoadLocaleCache(
SplayTreeInfo *cache,
const char *xml,
1183 const char *filename,
const char *locale,
const size_t depth,
1187 keyword[MaxTextExtent],
1188 message[MaxTextExtent],
1213 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1214 "Loading locale configure file \"%s\" ...",filename);
1215 if (xml == (
const char *) NULL)
1216 return(MagickFalse);
1222 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
1223 token=AcquireString(xml);
1224 extent=strlen(token)+MaxTextExtent;
1225 for (q=(
char *) xml; *q !=
'\0'; )
1230 (void) GetNextToken(q,&q,extent,token);
1233 (void) CopyMagickString(keyword,token,MaxTextExtent);
1234 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1239 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1241 (void) GetNextToken(q,&q,extent,token);
1242 while (isspace((
int) ((
unsigned char) *q)) != 0)
1247 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1252 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1254 (void) GetNextToken(q,&q,extent,token);
1255 while (isspace((
int) ((
unsigned char) *q)) != 0)
1260 if (LocaleCompare(keyword,
"<include") == 0)
1265 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1267 (void) CopyMagickString(keyword,token,MaxTextExtent);
1268 (void) GetNextToken(q,&q,extent,token);
1271 (void) GetNextToken(q,&q,extent,token);
1272 if (LocaleCompare(keyword,
"locale") == 0)
1274 if (LocaleCompare(locale,token) != 0)
1278 if (LocaleCompare(keyword,
"file") == 0)
1280 if (depth > MagickMaxRecursionDepth)
1281 (void) ThrowMagickException(exception,GetMagickModule(),
1282 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1286 path[MaxTextExtent],
1290 GetPathComponent(filename,HeadPath,path);
1292 (void) ConcatenateMagickString(path,DirectorySeparator,
1294 if (*token == *DirectorySeparator)
1295 (void) CopyMagickString(path,token,MaxTextExtent);
1297 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
1298 xml=FileToXML(path,~0UL);
1299 if (xml != (
char *) NULL)
1301 status&=LoadLocaleCache(cache,xml,path,locale,
1303 xml=(
char *) RelinquishMagickMemory(xml);
1310 if (LocaleCompare(keyword,
"<locale") == 0)
1315 while ((*token !=
'>') && (*q !=
'\0'))
1317 (void) CopyMagickString(keyword,token,MaxTextExtent);
1318 (void) GetNextToken(q,&q,extent,token);
1321 (void) GetNextToken(q,&q,extent,token);
1325 if (LocaleCompare(keyword,
"</locale>") == 0)
1327 ChopLocaleComponents(tag,1);
1328 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1331 if (LocaleCompare(keyword,
"<localemap>") == 0)
1333 if (LocaleCompare(keyword,
"</localemap>") == 0)
1335 if (LocaleCompare(keyword,
"<message") == 0)
1340 while ((*token !=
'>') && (*q !=
'\0'))
1342 (void) CopyMagickString(keyword,token,MaxTextExtent);
1343 (void) GetNextToken(q,&q,extent,token);
1346 (void) GetNextToken(q,&q,extent,token);
1347 if (LocaleCompare(keyword,
"name") == 0)
1349 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1350 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1353 for (p=(
char *) q; (*q !=
'<') && (*q !=
'\0'); q++) ;
1354 while (isspace((
int) ((
unsigned char) *p)) != 0)
1357 while ((isspace((
int) ((
unsigned char) *q)) != 0) && (q > p))
1359 (void) CopyMagickString(message,p,MagickMin((
size_t) (q-p+2),
1361 locale_info=(
LocaleInfo *) AcquireMagickMemory(
sizeof(*locale_info));
1363 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1364 (void) memset(locale_info,0,
sizeof(*locale_info));
1365 locale_info->path=ConstantString(filename);
1366 locale_info->tag=ConstantString(tag);
1367 locale_info->message=ConstantString(message);
1368 locale_info->signature=MagickCoreSignature;
1369 status=AddValueToSplayTree(cache,locale_info->tag,locale_info);
1370 if (status == MagickFalse)
1371 (void) ThrowMagickException(exception,GetMagickModule(),
1372 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1374 (void) ConcatenateMagickString(tag,message,MaxTextExtent);
1375 (void) ConcatenateMagickString(tag,
"\n",MaxTextExtent);
1379 if (LocaleCompare(keyword,
"</message>") == 0)
1381 ChopLocaleComponents(tag,2);
1382 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1385 if (*keyword ==
'<')
1390 if (*(keyword+1) ==
'?')
1392 if (*(keyword+1) ==
'/')
1394 ChopLocaleComponents(tag,1);
1396 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1399 token[strlen(token)-1]=
'\0';
1400 (void) CopyMagickString(token,token+1,MaxTextExtent);
1401 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1402 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1405 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1409 token=(
char *) RelinquishMagickMemory(token);
1410 (void) SetFatalErrorHandler(fatal_handler);
1411 return(status != 0 ? MagickTrue : MagickFalse);
1444 MagickExport
int LocaleCompare(
const char *p,
const char *q)
1446 if (p == (
char *) NULL)
1448 if (q == (
char *) NULL)
1452 if (q == (
char *) NULL)
1454 #if defined(MAGICKCORE_HAVE_STRCASECMP)
1455 return(strcasecmp(p,q));
1464 c=(int) *((
unsigned char *) p);
1465 d=(int) *((
unsigned char *) q);
1466 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
1471 return(AsciiMap[c]-(
int) AsciiMap[d]);
1499 MagickExport
void LocaleLower(
char *
string)
1504 assert(
string != (
char *) NULL);
1505 for (q=
string; *q !=
'\0'; q++)
1506 *q=(
char) LocaleToLowercase((
int) *q);
1531 MagickExport
int LocaleLowercase(
const int c)
1533 return(LocaleToLowercase(c));
1573 MagickExport
int LocaleNCompare(
const char *p,
const char *q,
const size_t length)
1575 if (p == (
char *) NULL)
1577 if (q == (
char *) NULL)
1581 if (q == (
char *) NULL)
1583 #if defined(MAGICKCORE_HAVE_STRNCASECMP)
1584 return(strncasecmp(p,q,length));
1594 for (i=length; i != 0; i--)
1596 c=(int) *((
unsigned char *) p);
1597 d=(int) *((
unsigned char *) q);
1598 if (AsciiMap[c] != AsciiMap[d])
1599 return(AsciiMap[c]-(
int) AsciiMap[d]);
1633 MagickExport
void LocaleUpper(
char *
string)
1638 assert(
string != (
char *) NULL);
1639 for (q=
string; *q !=
'\0'; q++)
1640 *q=(
char) LocaleToUppercase((
int) *q);
1665 MagickExport
int LocaleUppercase(
const int c)
1667 return(LocaleToUppercase(c));
1688 MagickExport MagickBooleanType LocaleComponentGenesis(
void)
1691 locale_semaphore=AllocateSemaphoreInfo();
1692 #if defined(MAGICKCORE_LOCALE_SUPPORT)
1693 (void) AcquireCLocale();
1716 MagickExport
void LocaleComponentTerminus(
void)
1719 ActivateSemaphoreInfo(&locale_semaphore);
1720 LockSemaphoreInfo(locale_semaphore);
1722 locale_cache=DestroySplayTree(locale_cache);
1723 #if defined(MAGICKCORE_LOCALE_SUPPORT)
1726 UnlockSemaphoreInfo(locale_semaphore);
1727 DestroySemaphoreInfo(&locale_semaphore);