|
MagickCore
6.7.5
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % L OOO CCCC AAA L EEEEE % 00007 % L O O C A A L E % 00008 % L O O C AAAAA L EEE % 00009 % L O O C A A L E % 00010 % LLLLL OOO CCCC A A LLLLL EEEEE % 00011 % % 00012 % % 00013 % MagickCore Image Locale Methods % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % July 2003 % 00018 % % 00019 % % 00020 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization % 00021 % dedicated to making software imaging solutions freely available. % 00022 % % 00023 % You may not use this file except in compliance with the License. You may % 00024 % obtain a copy of the License at % 00025 % % 00026 % http://www.imagemagick.org/script/license.php % 00027 % % 00028 % Unless required by applicable law or agreed to in writing, software % 00029 % distributed under the License is distributed on an "AS IS" BASIS, % 00030 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00031 % See the License for the specific language governing permissions and % 00032 % limitations under the License. % 00033 % % 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 % 00036 % 00037 */ 00038 00039 /* 00040 Include declarations. 00041 */ 00042 #include "MagickCore/studio.h" 00043 #include "MagickCore/blob.h" 00044 #include "MagickCore/client.h" 00045 #include "MagickCore/configure.h" 00046 #include "MagickCore/exception.h" 00047 #include "MagickCore/exception-private.h" 00048 #include "MagickCore/hashmap.h" 00049 #include "MagickCore/locale_.h" 00050 #include "MagickCore/locale-private.h" 00051 #include "MagickCore/log.h" 00052 #include "MagickCore/memory_.h" 00053 #include "MagickCore/semaphore.h" 00054 #include "MagickCore/splay-tree.h" 00055 #include "MagickCore/string_.h" 00056 #include "MagickCore/string-private.h" 00057 #include "MagickCore/token.h" 00058 #include "MagickCore/utility.h" 00059 #include "MagickCore/utility-private.h" 00060 #include "MagickCore/xml-tree.h" 00061 00062 /* 00063 Define declarations. 00064 */ 00065 #define LocaleFilename "locale.xml" 00066 #define MaxRecursionDepth 200 00067 00068 /* 00069 Typedef declarations. 00070 */ 00071 #if defined(__CYGWIN__) 00072 typedef struct _locale_t *locale_t; 00073 #endif 00074 00075 /* 00076 Static declarations. 00077 */ 00078 static const char 00079 *LocaleMap = 00080 "<?xml version=\"1.0\"?>" 00081 "<localemap>" 00082 " <locale name=\"C\">" 00083 " <Exception>" 00084 " <Message name=\"\">" 00085 " </Message>" 00086 " </Exception>" 00087 " </locale>" 00088 "</localemap>"; 00089 00090 static SemaphoreInfo 00091 *locale_semaphore = (SemaphoreInfo *) NULL; 00092 00093 static SplayTreeInfo 00094 *locale_list = (SplayTreeInfo *) NULL; 00095 00096 #if defined(MAGICKCORE_HAVE_STRTOD_L) 00097 static volatile locale_t 00098 c_locale = (locale_t) NULL; 00099 #endif 00100 00101 static volatile MagickBooleanType 00102 instantiate_locale = MagickFalse; 00103 00104 /* 00105 Forward declarations. 00106 */ 00107 static MagickBooleanType 00108 InitializeLocaleList(ExceptionInfo *), 00109 LoadLocaleLists(const char *,const char *,ExceptionInfo *); 00110 00111 #if defined(MAGICKCORE_HAVE_STRTOD_L) 00112 /* 00113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00114 % % 00115 % % 00116 % % 00117 + A c q u i r e C L o c a l e % 00118 % % 00119 % % 00120 % % 00121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00122 % 00123 % AcquireCLocale() allocates the C locale object, or (locale_t) 0 with 00124 % errno set if it cannot be acquired. 00125 % 00126 % The format of the AcquireCLocale method is: 00127 % 00128 % locale_t AcquireCLocale(void) 00129 % 00130 */ 00131 static locale_t AcquireCLocale(void) 00132 { 00133 #if defined(MAGICKCORE_HAVE_NEWLOCALE) 00134 if (c_locale == (locale_t) NULL) 00135 c_locale=newlocale(LC_ALL_MASK,"C",(locale_t) 0); 00136 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 00137 if (c_locale == (locale_t) NULL) 00138 c_locale=_create_locale(LC_ALL,"C"); 00139 #endif 00140 return(c_locale); 00141 } 00142 #endif 00143 00144 #if defined(MAGICKCORE_HAVE_STRTOD_L) 00145 /* 00146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00147 % % 00148 % % 00149 % % 00150 + D e s t r o y C L o c a l e % 00151 % % 00152 % % 00153 % % 00154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00155 % 00156 % DestroyCLocale() releases the resources allocated for a locale object 00157 % returned by a call to the AcquireCLocale() method. 00158 % 00159 % The format of the DestroyCLocale method is: 00160 % 00161 % void DestroyCLocale(void) 00162 % 00163 */ 00164 static void DestroyCLocale(void) 00165 { 00166 #if defined(MAGICKCORE_HAVE_NEWLOCALE) 00167 if (c_locale != (locale_t) NULL) 00168 freelocale(c_locale); 00169 #elif defined(MAGICKCORE_WINDOWS_SUPPORT) 00170 if (c_locale != (locale_t) NULL) 00171 _free_locale(c_locale); 00172 #endif 00173 c_locale=(locale_t) NULL; 00174 } 00175 #endif 00176 00177 /* 00178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00179 % % 00180 % % 00181 % % 00182 % D e s t r o y L o c a l e O p t i o n s % 00183 % % 00184 % % 00185 % % 00186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00187 % 00188 % DestroyLocaleOptions() releases memory associated with an locale 00189 % messages. 00190 % 00191 % The format of the DestroyProfiles method is: 00192 % 00193 % LinkedListInfo *DestroyLocaleOptions(Image *image) 00194 % 00195 % A description of each parameter follows: 00196 % 00197 % o image: the image. 00198 % 00199 */ 00200 00201 static void *DestroyOptions(void *message) 00202 { 00203 return(DestroyStringInfo((StringInfo *) message)); 00204 } 00205 00206 MagickExport LinkedListInfo *DestroyLocaleOptions(LinkedListInfo *messages) 00207 { 00208 assert(messages != (LinkedListInfo *) NULL); 00209 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00210 return(DestroyLinkedList(messages,DestroyOptions)); 00211 } 00212 00213 /* 00214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00215 % % 00216 % % 00217 % % 00218 + F o r m a t L o c a l e F i l e % 00219 % % 00220 % % 00221 % % 00222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00223 % 00224 % FormatLocaleFile() prints formatted output of a variable argument list to a 00225 % file in the "C" locale. 00226 % 00227 % The format of the FormatLocaleFile method is: 00228 % 00229 % ssize_t FormatLocaleFile(FILE *file,const char *format,...) 00230 % 00231 % A description of each parameter follows. 00232 % 00233 % o file: the file. 00234 % 00235 % o format: A file describing the format to use to write the remaining 00236 % arguments. 00237 % 00238 */ 00239 00240 MagickPrivate ssize_t FormatLocaleFileList(FILE *file, 00241 const char *restrict format,va_list operands) 00242 { 00243 ssize_t 00244 n; 00245 00246 #if defined(MAGICKCORE_HAVE_VFPRINTF_L) 00247 { 00248 locale_t 00249 locale; 00250 00251 locale=AcquireCLocale(); 00252 if (locale == (locale_t) NULL) 00253 n=(ssize_t) vfprintf(file,format,operands); 00254 else 00255 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 00256 n=(ssize_t) vfprintf_l(file,format,locale,operands); 00257 #else 00258 n=(ssize_t) vfprintf_l(file,locale,format,operands); 00259 #endif 00260 } 00261 #else 00262 #if defined(MAGICKCORE_HAVE_USELOCALE) 00263 { 00264 locale_t 00265 locale, 00266 previous_locale; 00267 00268 locale=AcquireCLocale(); 00269 if (locale == (locale_t) NULL) 00270 n=(ssize_t) vfprintf(file,format,operands); 00271 else 00272 { 00273 previous_locale=uselocale(locale); 00274 n=(ssize_t) vfprintf(file,format,operands); 00275 uselocale(previous_locale); 00276 } 00277 } 00278 #else 00279 n=(ssize_t) vfprintf(file,format,operands); 00280 #endif 00281 #endif 00282 return(n); 00283 } 00284 00285 MagickExport ssize_t FormatLocaleFile(FILE *file,const char *restrict format, 00286 ...) 00287 { 00288 ssize_t 00289 n; 00290 00291 va_list 00292 operands; 00293 00294 va_start(operands,format); 00295 n=FormatLocaleFileList(file,format,operands); 00296 va_end(operands); 00297 return(n); 00298 } 00299 00300 /* 00301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00302 % % 00303 % % 00304 % % 00305 + F o r m a t L o c a l e S t r i n g % 00306 % % 00307 % % 00308 % % 00309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00310 % 00311 % FormatLocaleString() prints formatted output of a variable argument list to 00312 % a string buffer in the "C" locale. 00313 % 00314 % The format of the FormatLocaleString method is: 00315 % 00316 % ssize_t FormatLocaleString(char *string,const size_t length, 00317 % const char *format,...) 00318 % 00319 % A description of each parameter follows. 00320 % 00321 % o string: FormatLocaleString() returns the formatted string in this 00322 % character buffer. 00323 % 00324 % o length: the maximum length of the string. 00325 % 00326 % o format: A string describing the format to use to write the remaining 00327 % arguments. 00328 % 00329 */ 00330 00331 MagickPrivate ssize_t FormatLocaleStringList(char *restrict string, 00332 const size_t length,const char *restrict format,va_list operands) 00333 { 00334 ssize_t 00335 n; 00336 00337 #if defined(MAGICKCORE_HAVE_VSNPRINTF_L) 00338 { 00339 locale_t 00340 locale; 00341 00342 locale=AcquireCLocale(); 00343 if (locale == (locale_t) NULL) 00344 n=(ssize_t) vsnprintf(string,length,format,operands); 00345 else 00346 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 00347 n=(ssize_t) vsnprintf_l(string,length,format,locale,operands); 00348 #else 00349 n=(ssize_t) vsnprintf_l(string,length,locale,format,operands); 00350 #endif 00351 } 00352 #elif defined(MAGICKCORE_HAVE_VSNPRINTF) 00353 #if defined(MAGICKCORE_HAVE_USELOCALE) 00354 { 00355 locale_t 00356 locale, 00357 previous_locale; 00358 00359 locale=AcquireCLocale(); 00360 if (locale == (locale_t) NULL) 00361 n=(ssize_t) vsnprintf(string,length,format,operands); 00362 else 00363 { 00364 previous_locale=uselocale(locale); 00365 n=(ssize_t) vsnprintf(string,length,format,operands); 00366 uselocale(previous_locale); 00367 } 00368 } 00369 #else 00370 n=(ssize_t) vsnprintf(string,length,format,operands); 00371 #endif 00372 #else 00373 n=(ssize_t) vsprintf(string,format,operands); 00374 #endif 00375 if (n < 0) 00376 string[length-1]='\0'; 00377 return(n); 00378 } 00379 00380 MagickExport ssize_t FormatLocaleString(char *restrict string, 00381 const size_t length,const char *restrict format,...) 00382 { 00383 ssize_t 00384 n; 00385 00386 va_list 00387 operands; 00388 00389 va_start(operands,format); 00390 n=FormatLocaleStringList(string,length,format,operands); 00391 va_end(operands); 00392 return(n); 00393 } 00394 00395 /* 00396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00397 % % 00398 % % 00399 % % 00400 + G e t L o c a l e I n f o _ % 00401 % % 00402 % % 00403 % % 00404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00405 % 00406 % GetLocaleInfo_() searches the locale list for the specified tag and if 00407 % found returns attributes for that element. 00408 % 00409 % The format of the GetLocaleInfo method is: 00410 % 00411 % const LocaleInfo *GetLocaleInfo_(const char *tag, 00412 % ExceptionInfo *exception) 00413 % 00414 % A description of each parameter follows: 00415 % 00416 % o tag: the locale tag. 00417 % 00418 % o exception: return any errors or warnings in this structure. 00419 % 00420 */ 00421 MagickExport const LocaleInfo *GetLocaleInfo_(const char *tag, 00422 ExceptionInfo *exception) 00423 { 00424 assert(exception != (ExceptionInfo *) NULL); 00425 if ((locale_list == (SplayTreeInfo *) NULL) || 00426 (instantiate_locale == MagickFalse)) 00427 if (InitializeLocaleList(exception) == MagickFalse) 00428 return((const LocaleInfo *) NULL); 00429 if ((locale_list == (SplayTreeInfo *) NULL) || 00430 (GetNumberOfNodesInSplayTree(locale_list) == 0)) 00431 return((const LocaleInfo *) NULL); 00432 if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0)) 00433 { 00434 ResetSplayTreeIterator(locale_list); 00435 return((const LocaleInfo *) GetNextValueInSplayTree(locale_list)); 00436 } 00437 return((const LocaleInfo *) GetValueFromSplayTree(locale_list,tag)); 00438 } 00439 00440 /* 00441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00442 % % 00443 % % 00444 % % 00445 % G e t L o c a l e I n f o L i s t % 00446 % % 00447 % % 00448 % % 00449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00450 % 00451 % GetLocaleInfoList() returns any locale messages that match the 00452 % specified pattern. 00453 % 00454 % The format of the GetLocaleInfoList function is: 00455 % 00456 % const LocaleInfo **GetLocaleInfoList(const char *pattern, 00457 % size_t *number_messages,ExceptionInfo *exception) 00458 % 00459 % A description of each parameter follows: 00460 % 00461 % o pattern: Specifies a pointer to a text string containing a pattern. 00462 % 00463 % o number_messages: This integer returns the number of locale messages in 00464 % the list. 00465 % 00466 % o exception: return any errors or warnings in this structure. 00467 % 00468 */ 00469 00470 #if defined(__cplusplus) || defined(c_plusplus) 00471 extern "C" { 00472 #endif 00473 00474 static int LocaleInfoCompare(const void *x,const void *y) 00475 { 00476 const LocaleInfo 00477 **p, 00478 **q; 00479 00480 p=(const LocaleInfo **) x, 00481 q=(const LocaleInfo **) y; 00482 if (LocaleCompare((*p)->path,(*q)->path) == 0) 00483 return(LocaleCompare((*p)->tag,(*q)->tag)); 00484 return(LocaleCompare((*p)->path,(*q)->path)); 00485 } 00486 00487 #if defined(__cplusplus) || defined(c_plusplus) 00488 } 00489 #endif 00490 00491 MagickExport const LocaleInfo **GetLocaleInfoList(const char *pattern, 00492 size_t *number_messages,ExceptionInfo *exception) 00493 { 00494 const LocaleInfo 00495 **messages; 00496 00497 register const LocaleInfo 00498 *p; 00499 00500 register ssize_t 00501 i; 00502 00503 /* 00504 Allocate locale list. 00505 */ 00506 assert(pattern != (char *) NULL); 00507 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00508 assert(number_messages != (size_t *) NULL); 00509 *number_messages=0; 00510 p=GetLocaleInfo_("*",exception); 00511 if (p == (const LocaleInfo *) NULL) 00512 return((const LocaleInfo **) NULL); 00513 messages=(const LocaleInfo **) AcquireQuantumMemory((size_t) 00514 GetNumberOfNodesInSplayTree(locale_list)+1UL,sizeof(*messages)); 00515 if (messages == (const LocaleInfo **) NULL) 00516 return((const LocaleInfo **) NULL); 00517 /* 00518 Generate locale list. 00519 */ 00520 LockSemaphoreInfo(locale_semaphore); 00521 ResetSplayTreeIterator(locale_list); 00522 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list); 00523 for (i=0; p != (const LocaleInfo *) NULL; ) 00524 { 00525 if ((p->stealth == MagickFalse) && 00526 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse)) 00527 messages[i++]=p; 00528 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list); 00529 } 00530 UnlockSemaphoreInfo(locale_semaphore); 00531 qsort((void *) messages,(size_t) i,sizeof(*messages),LocaleInfoCompare); 00532 messages[i]=(LocaleInfo *) NULL; 00533 *number_messages=(size_t) i; 00534 return(messages); 00535 } 00536 00537 /* 00538 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00539 % % 00540 % % 00541 % % 00542 % G e t L o c a l e L i s t % 00543 % % 00544 % % 00545 % % 00546 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00547 % 00548 % GetLocaleList() returns any locale messages that match the specified 00549 % pattern. 00550 % 00551 % The format of the GetLocaleList function is: 00552 % 00553 % char **GetLocaleList(const char *pattern,size_t *number_messages, 00554 % Exceptioninfo *exception) 00555 % 00556 % A description of each parameter follows: 00557 % 00558 % o pattern: Specifies a pointer to a text string containing a pattern. 00559 % 00560 % o number_messages: This integer returns the number of messages in the 00561 % list. 00562 % 00563 % o exception: return any errors or warnings in this structure. 00564 % 00565 */ 00566 00567 #if defined(__cplusplus) || defined(c_plusplus) 00568 extern "C" { 00569 #endif 00570 00571 static int LocaleTagCompare(const void *x,const void *y) 00572 { 00573 register char 00574 **p, 00575 **q; 00576 00577 p=(char **) x; 00578 q=(char **) y; 00579 return(LocaleCompare(*p,*q)); 00580 } 00581 00582 #if defined(__cplusplus) || defined(c_plusplus) 00583 } 00584 #endif 00585 00586 MagickExport char **GetLocaleList(const char *pattern, 00587 size_t *number_messages,ExceptionInfo *exception) 00588 { 00589 char 00590 **messages; 00591 00592 register const LocaleInfo 00593 *p; 00594 00595 register ssize_t 00596 i; 00597 00598 /* 00599 Allocate locale list. 00600 */ 00601 assert(pattern != (char *) NULL); 00602 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 00603 assert(number_messages != (size_t *) NULL); 00604 *number_messages=0; 00605 p=GetLocaleInfo_("*",exception); 00606 if (p == (const LocaleInfo *) NULL) 00607 return((char **) NULL); 00608 messages=(char **) AcquireQuantumMemory((size_t) 00609 GetNumberOfNodesInSplayTree(locale_list)+1UL,sizeof(*messages)); 00610 if (messages == (char **) NULL) 00611 return((char **) NULL); 00612 LockSemaphoreInfo(locale_semaphore); 00613 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list); 00614 for (i=0; p != (const LocaleInfo *) NULL; ) 00615 { 00616 if ((p->stealth == MagickFalse) && 00617 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse)) 00618 messages[i++]=ConstantString(p->tag); 00619 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list); 00620 } 00621 UnlockSemaphoreInfo(locale_semaphore); 00622 qsort((void *) messages,(size_t) i,sizeof(*messages),LocaleTagCompare); 00623 messages[i]=(char *) NULL; 00624 *number_messages=(size_t) i; 00625 return(messages); 00626 } 00627 00628 /* 00629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00630 % % 00631 % % 00632 % % 00633 % G e t L o c a l e M e s s a g e % 00634 % % 00635 % % 00636 % % 00637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00638 % 00639 % GetLocaleMessage() returns a message in the current locale that matches the 00640 % supplied tag. 00641 % 00642 % The format of the GetLocaleMessage method is: 00643 % 00644 % const char *GetLocaleMessage(const char *tag) 00645 % 00646 % A description of each parameter follows: 00647 % 00648 % o tag: Return a message that matches this tag in the current locale. 00649 % 00650 */ 00651 MagickExport const char *GetLocaleMessage(const char *tag) 00652 { 00653 char 00654 name[MaxTextExtent]; 00655 00656 const LocaleInfo 00657 *locale_info; 00658 00659 ExceptionInfo 00660 *exception; 00661 00662 if ((tag == (const char *) NULL) || (*tag == '\0')) 00663 return(tag); 00664 exception=AcquireExceptionInfo(); 00665 (void) FormatLocaleString(name,MaxTextExtent,"%s/",tag); 00666 locale_info=GetLocaleInfo_(name,exception); 00667 exception=DestroyExceptionInfo(exception); 00668 if (locale_info != (const LocaleInfo *) NULL) 00669 return(locale_info->message); 00670 return(tag); 00671 } 00672 00673 /* 00674 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00675 % % 00676 % % 00677 % % 00678 % G e t L o c a l e O p t i o n s % 00679 % % 00680 % % 00681 % % 00682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00683 % 00684 % GetLocaleOptions() returns any Magick configuration messages associated 00685 % with the specified filename. 00686 % 00687 % The format of the GetLocaleOptions method is: 00688 % 00689 % LinkedListInfo *GetLocaleOptions(const char *filename, 00690 % ExceptionInfo *exception) 00691 % 00692 % A description of each parameter follows: 00693 % 00694 % o filename: the locale file tag. 00695 % 00696 % o exception: return any errors or warnings in this structure. 00697 % 00698 */ 00699 MagickExport LinkedListInfo *GetLocaleOptions(const char *filename, 00700 ExceptionInfo *exception) 00701 { 00702 char 00703 path[MaxTextExtent]; 00704 00705 const char 00706 *element; 00707 00708 LinkedListInfo 00709 *messages, 00710 *paths; 00711 00712 StringInfo 00713 *xml; 00714 00715 assert(filename != (const char *) NULL); 00716 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 00717 assert(exception != (ExceptionInfo *) NULL); 00718 (void) CopyMagickString(path,filename,MaxTextExtent); 00719 /* 00720 Load XML from configuration files to linked-list. 00721 */ 00722 messages=NewLinkedList(0); 00723 paths=GetConfigurePaths(filename,exception); 00724 if (paths != (LinkedListInfo *) NULL) 00725 { 00726 ResetLinkedListIterator(paths); 00727 element=(const char *) GetNextValueInLinkedList(paths); 00728 while (element != (const char *) NULL) 00729 { 00730 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename); 00731 (void) LogMagickEvent(LocaleEvent,GetMagickModule(), 00732 "Searching for locale file: \"%s\"",path); 00733 xml=ConfigureFileToStringInfo(path); 00734 if (xml != (StringInfo *) NULL) 00735 (void) AppendValueToLinkedList(messages,xml); 00736 element=(const char *) GetNextValueInLinkedList(paths); 00737 } 00738 paths=DestroyLinkedList(paths,RelinquishMagickMemory); 00739 } 00740 #if defined(MAGICKCORE_WINDOWS_SUPPORT) 00741 { 00742 char 00743 *blob; 00744 00745 blob=(char *) NTResourceToBlob(filename); 00746 if (blob != (char *) NULL) 00747 { 00748 xml=AcquireStringInfo(0); 00749 SetStringInfoLength(xml,strlen(blob)+1); 00750 SetStringInfoDatum(xml,blob); 00751 SetStringInfoPath(xml,filename); 00752 (void) AppendValueToLinkedList(messages,xml); 00753 } 00754 } 00755 #endif 00756 ResetLinkedListIterator(messages); 00757 return(messages); 00758 } 00759 00760 /* 00761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00762 % % 00763 % % 00764 % % 00765 % G e t L o c a l e V a l u e % 00766 % % 00767 % % 00768 % % 00769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00770 % 00771 % GetLocaleValue() returns the message associated with the locale info. 00772 % 00773 % The format of the GetLocaleValue method is: 00774 % 00775 % const char *GetLocaleValue(const LocaleInfo *locale_info) 00776 % 00777 % A description of each parameter follows: 00778 % 00779 % o locale_info: The locale info. 00780 % 00781 */ 00782 MagickExport const char *GetLocaleValue(const LocaleInfo *locale_info) 00783 { 00784 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00785 assert(locale_info != (LocaleInfo *) NULL); 00786 assert(locale_info->signature == MagickSignature); 00787 return(locale_info->message); 00788 } 00789 00790 /* 00791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00792 % % 00793 % % 00794 % % 00795 + I n i t i a l i z e L o c a l e L i s t % 00796 % % 00797 % % 00798 % % 00799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00800 % 00801 % InitializeLocaleList() initializes the locale list. 00802 % 00803 % The format of the InitializeLocaleList method is: 00804 % 00805 % MagickBooleanType InitializeLocaleList(ExceptionInfo *exception) 00806 % 00807 % A description of each parameter follows. 00808 % 00809 % o exception: return any errors or warnings in this structure. 00810 % 00811 */ 00812 static MagickBooleanType InitializeLocaleList(ExceptionInfo *exception) 00813 { 00814 if ((locale_list == (SplayTreeInfo *) NULL) && 00815 (instantiate_locale == MagickFalse)) 00816 { 00817 if (locale_semaphore == (SemaphoreInfo *) NULL) 00818 AcquireSemaphoreInfo(&locale_semaphore); 00819 LockSemaphoreInfo(locale_semaphore); 00820 if ((locale_list == (SplayTreeInfo *) NULL) && 00821 (instantiate_locale == MagickFalse)) 00822 { 00823 char 00824 *locale; 00825 00826 register const char 00827 *p; 00828 00829 locale=(char *) NULL; 00830 p=setlocale(LC_CTYPE,(const char *) NULL); 00831 if (p != (const char *) NULL) 00832 locale=ConstantString(p); 00833 if (locale == (char *) NULL) 00834 locale=GetEnvironmentValue("LC_ALL"); 00835 if (locale == (char *) NULL) 00836 locale=GetEnvironmentValue("LC_MESSAGES"); 00837 if (locale == (char *) NULL) 00838 locale=GetEnvironmentValue("LC_CTYPE"); 00839 if (locale == (char *) NULL) 00840 locale=GetEnvironmentValue("LANG"); 00841 if (locale == (char *) NULL) 00842 locale=ConstantString("C"); 00843 (void) LoadLocaleLists(LocaleFilename,locale,exception); 00844 locale=DestroyString(locale); 00845 instantiate_locale=MagickTrue; 00846 } 00847 UnlockSemaphoreInfo(locale_semaphore); 00848 } 00849 return(locale_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse); 00850 } 00851 00852 /* 00853 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00854 % % 00855 % % 00856 % % 00857 + I n t e r p r e t L o c a l e V a l u e % 00858 % % 00859 % % 00860 % % 00861 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00862 % 00863 % InterpretLocaleValue() interprets the string as a floating point number in 00864 % the "C" locale and returns its value as a double. If sentinal is not a null 00865 % pointer, the method also sets the value pointed by sentinal to point to the 00866 % first character after the number. 00867 % 00868 % The format of the InterpretLocaleValue method is: 00869 % 00870 % double InterpretLocaleValue(const char *value,char **sentinal) 00871 % 00872 % A description of each parameter follows: 00873 % 00874 % o value: the string value. 00875 % 00876 % o sentinal: if sentinal is not NULL, a pointer to the character after the 00877 % last character used in the conversion is stored in the location 00878 % referenced by sentinal. 00879 % 00880 */ 00881 MagickExport double InterpretLocaleValue(const char *restrict string, 00882 char **restrict sentinal) 00883 { 00884 char 00885 *q; 00886 00887 double 00888 value; 00889 00890 if ((*string == '0') && ((string[1] | 0x20)=='x')) 00891 value=(double) strtoul(string,&q,16); 00892 else 00893 { 00894 #if defined(MAGICKCORE_HAVE_STRTOD_L) 00895 locale_t 00896 locale; 00897 00898 locale=AcquireCLocale(); 00899 if (locale == (locale_t) NULL) 00900 value=strtod(string,&q); 00901 else 00902 value=strtod_l(string,&q,locale); 00903 #else 00904 value=strtod(string,&q); 00905 #endif 00906 } 00907 if (sentinal != (char **) NULL) 00908 *sentinal=q; 00909 return(value); 00910 } 00911 00912 /* 00913 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00914 % % 00915 % % 00916 % % 00917 % L i s t L o c a l e I n f o % 00918 % % 00919 % % 00920 % % 00921 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00922 % 00923 % ListLocaleInfo() lists the locale info to a file. 00924 % 00925 % The format of the ListLocaleInfo method is: 00926 % 00927 % MagickBooleanType ListLocaleInfo(FILE *file,ExceptionInfo *exception) 00928 % 00929 % A description of each parameter follows. 00930 % 00931 % o file: An pointer to a FILE. 00932 % 00933 % o exception: return any errors or warnings in this structure. 00934 % 00935 */ 00936 MagickExport MagickBooleanType ListLocaleInfo(FILE *file, 00937 ExceptionInfo *exception) 00938 { 00939 const char 00940 *path; 00941 00942 const LocaleInfo 00943 **locale_info; 00944 00945 register ssize_t 00946 i; 00947 00948 size_t 00949 number_messages; 00950 00951 if (file == (const FILE *) NULL) 00952 file=stdout; 00953 number_messages=0; 00954 locale_info=GetLocaleInfoList("*",&number_messages,exception); 00955 if (locale_info == (const LocaleInfo **) NULL) 00956 return(MagickFalse); 00957 path=(const char *) NULL; 00958 for (i=0; i < (ssize_t) number_messages; i++) 00959 { 00960 if (locale_info[i]->stealth != MagickFalse) 00961 continue; 00962 if ((path == (const char *) NULL) || 00963 (LocaleCompare(path,locale_info[i]->path) != 0)) 00964 { 00965 if (locale_info[i]->path != (char *) NULL) 00966 (void) FormatLocaleFile(file,"\nPath: %s\n\n",locale_info[i]->path); 00967 (void) FormatLocaleFile(file,"Tag/Message\n"); 00968 (void) FormatLocaleFile(file, 00969 "-------------------------------------------------" 00970 "------------------------------\n"); 00971 } 00972 path=locale_info[i]->path; 00973 (void) FormatLocaleFile(file,"%s\n",locale_info[i]->tag); 00974 if (locale_info[i]->message != (char *) NULL) 00975 (void) FormatLocaleFile(file," %s",locale_info[i]->message); 00976 (void) FormatLocaleFile(file,"\n"); 00977 } 00978 (void) fflush(file); 00979 locale_info=(const LocaleInfo **) 00980 RelinquishMagickMemory((void *) locale_info); 00981 return(MagickTrue); 00982 } 00983 00984 /* 00985 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00986 % % 00987 % % 00988 % % 00989 + L o a d L o c a l e L i s t % 00990 % % 00991 % % 00992 % % 00993 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00994 % 00995 % LoadLocaleList() loads the locale configuration file which provides a mapping 00996 % between locale attributes and a locale name. 00997 % 00998 % The format of the LoadLocaleList method is: 00999 % 01000 % MagickBooleanType LoadLocaleList(const char *xml,const char *filename, 01001 % const size_t depth,ExceptionInfo *exception) 01002 % 01003 % A description of each parameter follows: 01004 % 01005 % o xml: The locale list in XML format. 01006 % 01007 % o filename: The locale list filename. 01008 % 01009 % o depth: depth of <include /> statements. 01010 % 01011 % o exception: return any errors or warnings in this structure. 01012 % 01013 */ 01014 01015 static void ChopLocaleComponents(char *path,const size_t components) 01016 { 01017 register char 01018 *p; 01019 01020 ssize_t 01021 count; 01022 01023 if (*path == '\0') 01024 return; 01025 p=path+strlen(path)-1; 01026 if (*p == '/') 01027 *p='\0'; 01028 for (count=0; (count < (ssize_t) components) && (p > path); p--) 01029 if (*p == '/') 01030 { 01031 *p='\0'; 01032 count++; 01033 } 01034 if (count < (ssize_t) components) 01035 *path='\0'; 01036 } 01037 01038 static void *DestroyLocaleNode(void *locale_info) 01039 { 01040 register LocaleInfo 01041 *p; 01042 01043 p=(LocaleInfo *) locale_info; 01044 if (p->path != (char *) NULL) 01045 p->path=DestroyString(p->path); 01046 if (p->tag != (char *) NULL) 01047 p->tag=DestroyString(p->tag); 01048 if (p->message != (char *) NULL) 01049 p->message=DestroyString(p->message); 01050 return(RelinquishMagickMemory(p)); 01051 } 01052 01053 static void LocaleFatalErrorHandler( 01054 const ExceptionType magick_unused(severity), 01055 const char *reason,const char *description) 01056 { 01057 if (reason == (char *) NULL) 01058 return; 01059 (void) FormatLocaleFile(stderr,"%s: %s",GetClientName(),reason); 01060 if (description != (char *) NULL) 01061 (void) FormatLocaleFile(stderr," (%s)",description); 01062 (void) FormatLocaleFile(stderr,".\n"); 01063 (void) fflush(stderr); 01064 exit(1); 01065 } 01066 01067 01068 static MagickBooleanType LoadLocaleList(const char *xml,const char *filename, 01069 const char *locale,const size_t depth,ExceptionInfo *exception) 01070 { 01071 char 01072 keyword[MaxTextExtent], 01073 message[MaxTextExtent], 01074 tag[MaxTextExtent], 01075 *token; 01076 01077 const char 01078 *q; 01079 01080 FatalErrorHandler 01081 fatal_handler; 01082 01083 LocaleInfo 01084 *locale_info; 01085 01086 MagickBooleanType 01087 status; 01088 01089 register char 01090 *p; 01091 01092 /* 01093 Read the locale configure file. 01094 */ 01095 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 01096 "Loading locale configure file \"%s\" ...",filename); 01097 if (xml == (const char *) NULL) 01098 return(MagickFalse); 01099 if (locale_list == (SplayTreeInfo *) NULL) 01100 { 01101 locale_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, 01102 DestroyLocaleNode); 01103 if (locale_list == (SplayTreeInfo *) NULL) 01104 return(MagickFalse); 01105 } 01106 status=MagickTrue; 01107 locale_info=(LocaleInfo *) NULL; 01108 *tag='\0'; 01109 *message='\0'; 01110 *keyword='\0'; 01111 fatal_handler=SetFatalErrorHandler(LocaleFatalErrorHandler); 01112 token=AcquireString(xml); 01113 for (q=(char *) xml; *q != '\0'; ) 01114 { 01115 /* 01116 Interpret XML. 01117 */ 01118 GetMagickToken(q,&q,token); 01119 if (*token == '\0') 01120 break; 01121 (void) CopyMagickString(keyword,token,MaxTextExtent); 01122 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) 01123 { 01124 /* 01125 Doctype element. 01126 */ 01127 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) 01128 { 01129 GetMagickToken(q,&q,token); 01130 while (isspace((int) ((unsigned char) *q)) != 0) 01131 q++; 01132 } 01133 continue; 01134 } 01135 if (LocaleNCompare(keyword,"<!--",4) == 0) 01136 { 01137 /* 01138 Comment element. 01139 */ 01140 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) 01141 { 01142 GetMagickToken(q,&q,token); 01143 while (isspace((int) ((unsigned char) *q)) != 0) 01144 q++; 01145 } 01146 continue; 01147 } 01148 if (LocaleCompare(keyword,"<include") == 0) 01149 { 01150 /* 01151 Include element. 01152 */ 01153 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) 01154 { 01155 (void) CopyMagickString(keyword,token,MaxTextExtent); 01156 GetMagickToken(q,&q,token); 01157 if (*token != '=') 01158 continue; 01159 GetMagickToken(q,&q,token); 01160 if (LocaleCompare(keyword,"locale") == 0) 01161 { 01162 if (LocaleCompare(locale,token) != 0) 01163 break; 01164 continue; 01165 } 01166 if (LocaleCompare(keyword,"file") == 0) 01167 { 01168 if (depth > 200) 01169 (void) ThrowMagickException(exception,GetMagickModule(), 01170 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); 01171 else 01172 { 01173 char 01174 path[MaxTextExtent], 01175 *xml; 01176 01177 *path='\0'; 01178 GetPathComponent(filename,HeadPath,path); 01179 if (*path != '\0') 01180 (void) ConcatenateMagickString(path,DirectorySeparator, 01181 MaxTextExtent); 01182 if (*token == *DirectorySeparator) 01183 (void) CopyMagickString(path,token,MaxTextExtent); 01184 else 01185 (void) ConcatenateMagickString(path,token,MaxTextExtent); 01186 xml=FileToString(path,~0,exception); 01187 if (xml != (char *) NULL) 01188 { 01189 status=LoadLocaleList(xml,path,locale,depth+1,exception); 01190 xml=(char *) RelinquishMagickMemory(xml); 01191 } 01192 } 01193 } 01194 } 01195 continue; 01196 } 01197 if (LocaleCompare(keyword,"<locale") == 0) 01198 { 01199 /* 01200 Locale element. 01201 */ 01202 while ((*token != '>') && (*q != '\0')) 01203 { 01204 (void) CopyMagickString(keyword,token,MaxTextExtent); 01205 GetMagickToken(q,&q,token); 01206 if (*token != '=') 01207 continue; 01208 GetMagickToken(q,&q,token); 01209 } 01210 continue; 01211 } 01212 if (LocaleCompare(keyword,"</locale>") == 0) 01213 { 01214 ChopLocaleComponents(tag,1); 01215 (void) ConcatenateMagickString(tag,"/",MaxTextExtent); 01216 continue; 01217 } 01218 if (LocaleCompare(keyword,"<localemap>") == 0) 01219 continue; 01220 if (LocaleCompare(keyword,"</localemap>") == 0) 01221 continue; 01222 if (LocaleCompare(keyword,"<message") == 0) 01223 { 01224 /* 01225 Message element. 01226 */ 01227 while ((*token != '>') && (*q != '\0')) 01228 { 01229 (void) CopyMagickString(keyword,token,MaxTextExtent); 01230 GetMagickToken(q,&q,token); 01231 if (*token != '=') 01232 continue; 01233 GetMagickToken(q,&q,token); 01234 if (LocaleCompare(keyword,"name") == 0) 01235 { 01236 (void) ConcatenateMagickString(tag,token,MaxTextExtent); 01237 (void) ConcatenateMagickString(tag,"/",MaxTextExtent); 01238 } 01239 } 01240 for (p=(char *) q; (*q != '<') && (*q != '\0'); q++) ; 01241 while (isspace((int) ((unsigned char) *p)) != 0) 01242 p++; 01243 q--; 01244 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p)) 01245 q--; 01246 (void) CopyMagickString(message,p,(size_t) (q-p+2)); 01247 locale_info=(LocaleInfo *) AcquireMagickMemory(sizeof(*locale_info)); 01248 if (locale_info == (LocaleInfo *) NULL) 01249 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 01250 (void) ResetMagickMemory(locale_info,0,sizeof(*locale_info)); 01251 locale_info->path=ConstantString(filename); 01252 locale_info->tag=ConstantString(tag); 01253 locale_info->message=ConstantString(message); 01254 locale_info->signature=MagickSignature; 01255 status=AddValueToSplayTree(locale_list,locale_info->tag,locale_info); 01256 if (status == MagickFalse) 01257 (void) ThrowMagickException(exception,GetMagickModule(), 01258 ResourceLimitError,"MemoryAllocationFailed","`%s'", 01259 locale_info->tag); 01260 (void) ConcatenateMagickString(tag,message,MaxTextExtent); 01261 (void) ConcatenateMagickString(tag,"\n",MaxTextExtent); 01262 q++; 01263 continue; 01264 } 01265 if (LocaleCompare(keyword,"</message>") == 0) 01266 { 01267 ChopLocaleComponents(tag,2); 01268 (void) ConcatenateMagickString(tag,"/",MaxTextExtent); 01269 continue; 01270 } 01271 if (*keyword == '<') 01272 { 01273 /* 01274 Subpath element. 01275 */ 01276 if (*(keyword+1) == '?') 01277 continue; 01278 if (*(keyword+1) == '/') 01279 { 01280 ChopLocaleComponents(tag,1); 01281 if (*tag != '\0') 01282 (void) ConcatenateMagickString(tag,"/",MaxTextExtent); 01283 continue; 01284 } 01285 token[strlen(token)-1]='\0'; 01286 (void) CopyMagickString(token,token+1,MaxTextExtent); 01287 (void) ConcatenateMagickString(tag,token,MaxTextExtent); 01288 (void) ConcatenateMagickString(tag,"/",MaxTextExtent); 01289 continue; 01290 } 01291 GetMagickToken(q,(const char **) NULL,token); 01292 if (*token != '=') 01293 continue; 01294 } 01295 token=(char *) RelinquishMagickMemory(token); 01296 (void) SetFatalErrorHandler(fatal_handler); 01297 return(status); 01298 } 01299 01300 /* 01301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01302 % % 01303 % % 01304 % % 01305 % L o a d L o c a l e L i s t s % 01306 % % 01307 % % 01308 % % 01309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01310 % 01311 % LoadLocaleList() loads one or more locale configuration file which 01312 % provides a mapping between locale attributes and a locale tag. 01313 % 01314 % The format of the LoadLocaleLists method is: 01315 % 01316 % MagickBooleanType LoadLocaleLists(const char *filename, 01317 % ExceptionInfo *exception) 01318 % 01319 % A description of each parameter follows: 01320 % 01321 % o filename: the font file tag. 01322 % 01323 % o locale: the actual locale. 01324 % 01325 % o exception: return any errors or warnings in this structure. 01326 % 01327 */ 01328 static MagickBooleanType LoadLocaleLists(const char *filename, 01329 const char *locale,ExceptionInfo *exception) 01330 { 01331 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT) 01332 return(LoadLocaleList(LocaleMap,"built-in",locale,0,exception)); 01333 #else 01334 const StringInfo 01335 *option; 01336 01337 LinkedListInfo 01338 *options; 01339 01340 MagickStatusType 01341 status; 01342 01343 status=MagickFalse; 01344 options=GetLocaleOptions(filename,exception); 01345 option=(const StringInfo *) GetNextValueInLinkedList(options); 01346 while (option != (const StringInfo *) NULL) 01347 { 01348 status|=LoadLocaleList((const char *) GetStringInfoDatum(option), 01349 GetStringInfoPath(option),locale,0,exception); 01350 option=(const StringInfo *) GetNextValueInLinkedList(options); 01351 } 01352 options=DestroyLocaleOptions(options); 01353 if ((locale_list == (SplayTreeInfo *) NULL) || 01354 (GetNumberOfNodesInSplayTree(locale_list) == 0)) 01355 { 01356 options=GetLocaleOptions("english.xml",exception); 01357 option=(const StringInfo *) GetNextValueInLinkedList(options); 01358 while (option != (const StringInfo *) NULL) 01359 { 01360 status|=LoadLocaleList((const char *) GetStringInfoDatum(option), 01361 GetStringInfoPath(option),locale,0,exception); 01362 option=(const StringInfo *) GetNextValueInLinkedList(options); 01363 } 01364 options=DestroyLocaleOptions(options); 01365 } 01366 if ((locale_list == (SplayTreeInfo *) NULL) || 01367 (GetNumberOfNodesInSplayTree(locale_list) == 0)) 01368 status|=LoadLocaleList(LocaleMap,"built-in",locale,0,exception); 01369 return(status != 0 ? MagickTrue : MagickFalse); 01370 #endif 01371 } 01372 01373 /* 01374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01375 % % 01376 % % 01377 % % 01378 + L o c a l e C o m p o n e n t G e n e s i s % 01379 % % 01380 % % 01381 % % 01382 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01383 % 01384 % LocaleComponentGenesis() instantiates the locale component. 01385 % 01386 % The format of the LocaleComponentGenesis method is: 01387 % 01388 % MagickBooleanType LocaleComponentGenesis(void) 01389 % 01390 */ 01391 MagickPrivate MagickBooleanType LocaleComponentGenesis(void) 01392 { 01393 AcquireSemaphoreInfo(&locale_semaphore); 01394 return(MagickTrue); 01395 } 01396 01397 /* 01398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01399 % % 01400 % % 01401 % % 01402 + L o c a l e C o m p o n e n t T e r m i n u s % 01403 % % 01404 % % 01405 % % 01406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01407 % 01408 % LocaleComponentTerminus() destroys the locale component. 01409 % 01410 % The format of the LocaleComponentTerminus method is: 01411 % 01412 % LocaleComponentTerminus(void) 01413 % 01414 */ 01415 MagickPrivate void LocaleComponentTerminus(void) 01416 { 01417 if (locale_semaphore == (SemaphoreInfo *) NULL) 01418 AcquireSemaphoreInfo(&locale_semaphore); 01419 LockSemaphoreInfo(locale_semaphore); 01420 #if defined(MAGICKCORE_HAVE_STRTOD_L) 01421 DestroyCLocale(); 01422 #endif 01423 instantiate_locale=MagickFalse; 01424 UnlockSemaphoreInfo(locale_semaphore); 01425 DestroySemaphoreInfo(&locale_semaphore); 01426 }