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(
1164 const ExceptionType magick_unused(severity),
1165 const char *reason,
const char *description)
1167 magick_unreferenced(severity);
1169 if (reason == (
char *) NULL)
1171 (void) FormatLocaleFile(stderr,
"%s: %s",GetClientName(),reason);
1172 if (description != (
char *) NULL)
1173 (
void) FormatLocaleFile(stderr,
" (%s)",description);
1174 (void) FormatLocaleFile(stderr,
".\n");
1175 (void) fflush(stderr);
1179 static MagickBooleanType LoadLocaleCache(
SplayTreeInfo *cache,
const char *xml,
1180 const char *filename,
const char *locale,
const size_t depth,
1184 keyword[MaxTextExtent],
1185 message[MaxTextExtent],
1210 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1211 "Loading locale configure file \"%s\" ...",filename);
1212 if (xml == (
const char *) NULL)
1213 return(MagickFalse);
1219 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler);
1220 token=AcquireString(xml);
1221 extent=strlen(token)+MaxTextExtent;
1222 for (q=(
char *) xml; *q !=
'\0'; )
1227 (void) GetNextToken(q,&q,extent,token);
1230 (void) CopyMagickString(keyword,token,MaxTextExtent);
1231 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1236 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1238 (void) GetNextToken(q,&q,extent,token);
1239 while (isspace((
int) ((
unsigned char) *q)) != 0)
1244 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1249 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1251 (void) GetNextToken(q,&q,extent,token);
1252 while (isspace((
int) ((
unsigned char) *q)) != 0)
1257 if (LocaleCompare(keyword,
"<include") == 0)
1262 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1264 (void) CopyMagickString(keyword,token,MaxTextExtent);
1265 (void) GetNextToken(q,&q,extent,token);
1268 (void) GetNextToken(q,&q,extent,token);
1269 if (LocaleCompare(keyword,
"locale") == 0)
1271 if (LocaleCompare(locale,token) != 0)
1275 if (LocaleCompare(keyword,
"file") == 0)
1277 if (depth > MagickMaxRecursionDepth)
1278 (void) ThrowMagickException(exception,GetMagickModule(),
1279 ConfigureError,
"IncludeElementNestedTooDeeply",
"`%s'",token);
1283 path[MaxTextExtent],
1287 GetPathComponent(filename,HeadPath,path);
1289 (void) ConcatenateMagickString(path,DirectorySeparator,
1291 if (*token == *DirectorySeparator)
1292 (void) CopyMagickString(path,token,MaxTextExtent);
1294 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
1295 xml=FileToXML(path,~0UL);
1296 if (xml != (
char *) NULL)
1298 status&=LoadLocaleCache(cache,xml,path,locale,
1300 xml=(
char *) RelinquishMagickMemory(xml);
1307 if (LocaleCompare(keyword,
"<locale") == 0)
1312 while ((*token !=
'>') && (*q !=
'\0'))
1314 (void) CopyMagickString(keyword,token,MaxTextExtent);
1315 (void) GetNextToken(q,&q,extent,token);
1318 (void) GetNextToken(q,&q,extent,token);
1322 if (LocaleCompare(keyword,
"</locale>") == 0)
1324 ChopLocaleComponents(tag,1);
1325 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1328 if (LocaleCompare(keyword,
"<localemap>") == 0)
1330 if (LocaleCompare(keyword,
"</localemap>") == 0)
1332 if (LocaleCompare(keyword,
"<message") == 0)
1337 while ((*token !=
'>') && (*q !=
'\0'))
1339 (void) CopyMagickString(keyword,token,MaxTextExtent);
1340 (void) GetNextToken(q,&q,extent,token);
1343 (void) GetNextToken(q,&q,extent,token);
1344 if (LocaleCompare(keyword,
"name") == 0)
1346 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1347 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1350 for (p=(
char *) q; (*q !=
'<') && (*q !=
'\0'); q++) ;
1351 while (isspace((
int) ((
unsigned char) *p)) != 0)
1354 while ((isspace((
int) ((
unsigned char) *q)) != 0) && (q > p))
1356 (void) CopyMagickString(message,p,MagickMin((
size_t) (q-p+2),
1358 locale_info=(
LocaleInfo *) AcquireMagickMemory(
sizeof(*locale_info));
1360 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1361 (void) memset(locale_info,0,
sizeof(*locale_info));
1362 locale_info->path=ConstantString(filename);
1363 locale_info->tag=ConstantString(tag);
1364 locale_info->message=ConstantString(message);
1365 locale_info->signature=MagickCoreSignature;
1366 status=AddValueToSplayTree(cache,locale_info->tag,locale_info);
1367 if (status == MagickFalse)
1368 (void) ThrowMagickException(exception,GetMagickModule(),
1369 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",
1371 (void) ConcatenateMagickString(tag,message,MaxTextExtent);
1372 (void) ConcatenateMagickString(tag,
"\n",MaxTextExtent);
1376 if (LocaleCompare(keyword,
"</message>") == 0)
1378 ChopLocaleComponents(tag,2);
1379 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1382 if (*keyword ==
'<')
1387 if (*(keyword+1) ==
'?')
1389 if (*(keyword+1) ==
'/')
1391 ChopLocaleComponents(tag,1);
1393 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1396 token[strlen(token)-1]=
'\0';
1397 (void) CopyMagickString(token,token+1,MaxTextExtent);
1398 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
1399 (void) ConcatenateMagickString(tag,
"/",MaxTextExtent);
1402 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1406 token=(
char *) RelinquishMagickMemory(token);
1407 (void) SetFatalErrorHandler(fatal_handler);
1408 return(status != 0 ? MagickTrue : MagickFalse);
1441 MagickExport
int LocaleCompare(
const char *p,
const char *q)
1443 if (p == (
char *) NULL)
1445 if (q == (
char *) NULL)
1449 if (q == (
char *) NULL)
1451 #if defined(MAGICKCORE_HAVE_STRCASECMP)
1452 return(strcasecmp(p,q));
1461 c=(int) *((
unsigned char *) p);
1462 d=(int) *((
unsigned char *) q);
1463 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
1468 return(AsciiMap[c]-(
int) AsciiMap[d]);
1496 MagickExport
void LocaleLower(
char *
string)
1501 assert(
string != (
char *) NULL);
1502 for (q=
string; *q !=
'\0'; q++)
1503 *q=(
char) LocaleToLowercase((
int) *q);
1528 MagickExport
int LocaleLowercase(
const int c)
1530 return(LocaleToLowercase(c));
1570 MagickExport
int LocaleNCompare(
const char *p,
const char *q,
const size_t length)
1572 if (p == (
char *) NULL)
1574 if (q == (
char *) NULL)
1578 if (q == (
char *) NULL)
1580 #if defined(MAGICKCORE_HAVE_STRNCASECMP)
1581 return(strncasecmp(p,q,length));
1591 for (i=length; i != 0; i--)
1593 c=(int) *((
unsigned char *) p);
1594 d=(int) *((
unsigned char *) q);
1595 if (AsciiMap[c] != AsciiMap[d])
1596 return(AsciiMap[c]-(
int) AsciiMap[d]);
1630 MagickExport
void LocaleUpper(
char *
string)
1635 assert(
string != (
char *) NULL);
1636 for (q=
string; *q !=
'\0'; q++)
1637 *q=(
char) LocaleToUppercase((
int) *q);
1662 MagickExport
int LocaleUppercase(
const int c)
1664 return(LocaleToUppercase(c));
1685 MagickExport MagickBooleanType LocaleComponentGenesis(
void)
1688 locale_semaphore=AllocateSemaphoreInfo();
1689 #if defined(MAGICKCORE_LOCALE_SUPPORT)
1690 (void) AcquireCLocale();
1713 MagickExport
void LocaleComponentTerminus(
void)
1716 ActivateSemaphoreInfo(&locale_semaphore);
1717 LockSemaphoreInfo(locale_semaphore);
1719 locale_cache=DestroySplayTree(locale_cache);
1720 #if defined(MAGICKCORE_LOCALE_SUPPORT)
1723 UnlockSemaphoreInfo(locale_semaphore);
1724 DestroySemaphoreInfo(&locale_semaphore);