00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "magick/studio.h"
00043 #include "magick/blob.h"
00044 #include "magick/client.h"
00045 #include "magick/configure.h"
00046 #include "magick/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/hashmap.h"
00049 #include "magick/locale_.h"
00050 #include "magick/log.h"
00051 #include "magick/memory_.h"
00052 #include "magick/semaphore.h"
00053 #include "magick/splay-tree.h"
00054 #include "magick/string_.h"
00055 #include "magick/token.h"
00056 #include "magick/utility.h"
00057 #include "magick/xml-tree.h"
00058
00059
00060
00061
00062 #define LocaleFilename "locale.xml"
00063 #define MaxRecursionDepth 200
00064
00065
00066
00067
00068 static const char
00069 *LocaleMap =
00070 "<?xml version=\"1.0\"?>"
00071 "<localemap>"
00072 " <locale name=\"C\">"
00073 " <Exception>"
00074 " <Message name=\"\">"
00075 " </Message>"
00076 " </Exception>"
00077 " </locale>"
00078 "</localemap>";
00079
00080 static SemaphoreInfo
00081 *locale_semaphore = (SemaphoreInfo *) NULL;
00082
00083 static SplayTreeInfo
00084 *locale_list = (SplayTreeInfo *) NULL;
00085
00086 static volatile MagickBooleanType
00087 instantiate_locale = MagickFalse;
00088
00089
00090
00091
00092 static MagickBooleanType
00093 InitializeLocaleList(ExceptionInfo *),
00094 LoadLocaleLists(const char *,const char *,ExceptionInfo *);
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 static void *DestroyOptions(void *message)
00121 {
00122 return(DestroyStringInfo((StringInfo *) message));
00123 }
00124
00125 MagickExport LinkedListInfo *DestroyLocaleOptions(LinkedListInfo *messages)
00126 {
00127 assert(messages != (LinkedListInfo *) NULL);
00128 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00129 return(DestroyLinkedList(messages,DestroyOptions));
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158 MagickExport const LocaleInfo *GetLocaleInfo_(const char *tag,
00159 ExceptionInfo *exception)
00160 {
00161 assert(exception != (ExceptionInfo *) NULL);
00162 if ((locale_list == (SplayTreeInfo *) NULL) ||
00163 (instantiate_locale == MagickFalse))
00164 if (InitializeLocaleList(exception) == MagickFalse)
00165 return((const LocaleInfo *) NULL);
00166 if ((locale_list == (SplayTreeInfo *) NULL) ||
00167 (GetNumberOfNodesInSplayTree(locale_list) == 0))
00168 return((const LocaleInfo *) NULL);
00169 if ((tag == (const char *) NULL) || (LocaleCompare(tag,"*") == 0))
00170 {
00171 ResetSplayTreeIterator(locale_list);
00172 return((const LocaleInfo *) GetNextValueInSplayTree(locale_list));
00173 }
00174 return((const LocaleInfo *) GetValueFromSplayTree(locale_list,tag));
00175 }
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 #if defined(__cplusplus) || defined(c_plusplus)
00208 extern "C" {
00209 #endif
00210
00211 static int LocaleInfoCompare(const void *x,const void *y)
00212 {
00213 const LocaleInfo
00214 **p,
00215 **q;
00216
00217 p=(const LocaleInfo **) x,
00218 q=(const LocaleInfo **) y;
00219 if (LocaleCompare((*p)->path,(*q)->path) == 0)
00220 return(LocaleCompare((*p)->tag,(*q)->tag));
00221 return(LocaleCompare((*p)->path,(*q)->path));
00222 }
00223
00224 #if defined(__cplusplus) || defined(c_plusplus)
00225 }
00226 #endif
00227
00228 MagickExport const LocaleInfo **GetLocaleInfoList(const char *pattern,
00229 unsigned long *number_messages,ExceptionInfo *exception)
00230 {
00231 const LocaleInfo
00232 **messages;
00233
00234 register const LocaleInfo
00235 *p;
00236
00237 register long
00238 i;
00239
00240
00241
00242
00243 assert(pattern != (char *) NULL);
00244 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00245 assert(number_messages != (unsigned long *) NULL);
00246 *number_messages=0;
00247 p=GetLocaleInfo_("*",exception);
00248 if (p == (const LocaleInfo *) NULL)
00249 return((const LocaleInfo **) NULL);
00250 messages=(const LocaleInfo **) AcquireQuantumMemory((size_t)
00251 GetNumberOfNodesInSplayTree(locale_list)+1UL,sizeof(*messages));
00252 if (messages == (const LocaleInfo **) NULL)
00253 return((const LocaleInfo **) NULL);
00254
00255
00256
00257 (void) LockSemaphoreInfo(locale_semaphore);
00258 ResetSplayTreeIterator(locale_list);
00259 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list);
00260 for (i=0; p != (const LocaleInfo *) NULL; )
00261 {
00262 if ((p->stealth == MagickFalse) &&
00263 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
00264 messages[i++]=p;
00265 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list);
00266 }
00267 (void) UnlockSemaphoreInfo(locale_semaphore);
00268 qsort((void *) messages,(size_t) i,sizeof(*messages),LocaleInfoCompare);
00269 messages[i]=(LocaleInfo *) NULL;
00270 *number_messages=(unsigned long) i;
00271 return(messages);
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 #if defined(__cplusplus) || defined(c_plusplus)
00305 extern "C" {
00306 #endif
00307
00308 static int LocaleTagCompare(const void *x,const void *y)
00309 {
00310 register char
00311 **p,
00312 **q;
00313
00314 p=(char **) x;
00315 q=(char **) y;
00316 return(LocaleCompare(*p,*q));
00317 }
00318
00319 #if defined(__cplusplus) || defined(c_plusplus)
00320 }
00321 #endif
00322
00323 MagickExport char **GetLocaleList(const char *pattern,
00324 unsigned long *number_messages,ExceptionInfo *exception)
00325 {
00326 char
00327 **messages;
00328
00329 register const LocaleInfo
00330 *p;
00331
00332 register long
00333 i;
00334
00335
00336
00337
00338 assert(pattern != (char *) NULL);
00339 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00340 assert(number_messages != (unsigned long *) NULL);
00341 *number_messages=0;
00342 p=GetLocaleInfo_("*",exception);
00343 if (p == (const LocaleInfo *) NULL)
00344 return((char **) NULL);
00345 messages=(char **) AcquireQuantumMemory((size_t)
00346 GetNumberOfNodesInSplayTree(locale_list)+1UL,sizeof(*messages));
00347 if (messages == (char **) NULL)
00348 return((char **) NULL);
00349 (void) LockSemaphoreInfo(locale_semaphore);
00350 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list);
00351 for (i=0; p != (const LocaleInfo *) NULL; )
00352 {
00353 if ((p->stealth == MagickFalse) &&
00354 (GlobExpression(p->tag,pattern,MagickTrue) != MagickFalse))
00355 messages[i++]=ConstantString(p->tag);
00356 p=(const LocaleInfo *) GetNextValueInSplayTree(locale_list);
00357 }
00358 (void) UnlockSemaphoreInfo(locale_semaphore);
00359 qsort((void *) messages,(size_t) i,sizeof(*messages),LocaleTagCompare);
00360 messages[i]=(char *) NULL;
00361 *number_messages=(unsigned long) i;
00362 return(messages);
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 MagickExport const char *GetLocaleMessage(const char *tag)
00389 {
00390 char
00391 name[MaxTextExtent];
00392
00393 const LocaleInfo
00394 *locale_info;
00395
00396 ExceptionInfo
00397 *exception;
00398
00399 if ((tag == (const char *) NULL) || (*tag == '\0'))
00400 return(tag);
00401 exception=AcquireExceptionInfo();
00402 (void) FormatMagickString(name,MaxTextExtent,"%s/",tag);
00403 locale_info=GetLocaleInfo_(name,exception);
00404 exception=DestroyExceptionInfo(exception);
00405 if (locale_info != (const LocaleInfo *) NULL)
00406 return(locale_info->message);
00407 return(tag);
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 MagickExport LinkedListInfo *GetLocaleOptions(const char *filename,
00437 ExceptionInfo *exception)
00438 {
00439 char
00440 path[MaxTextExtent];
00441
00442 const char
00443 *element;
00444
00445 LinkedListInfo
00446 *messages,
00447 *paths;
00448
00449 StringInfo
00450 *xml;
00451
00452 assert(filename != (const char *) NULL);
00453 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
00454 assert(exception != (ExceptionInfo *) NULL);
00455 (void) CopyMagickString(path,filename,MaxTextExtent);
00456
00457
00458
00459 messages=NewLinkedList(0);
00460 paths=GetConfigurePaths(filename,exception);
00461 if (paths != (LinkedListInfo *) NULL)
00462 {
00463 ResetLinkedListIterator(paths);
00464 element=(const char *) GetNextValueInLinkedList(paths);
00465 while (element != (const char *) NULL)
00466 {
00467 (void) FormatMagickString(path,MaxTextExtent,"%s%s",element,filename);
00468 (void) LogMagickEvent(LocaleEvent,GetMagickModule(),
00469 "Searching for locale file: \"%s\"",path);
00470 xml=ConfigureFileToStringInfo(path);
00471 if (xml != (StringInfo *) NULL)
00472 (void) AppendValueToLinkedList(messages,xml);
00473 element=(const char *) GetNextValueInLinkedList(paths);
00474 }
00475 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
00476 }
00477 #if defined(__WINDOWS__)
00478 {
00479 char
00480 *blob;
00481
00482 blob=(char *) NTResourceToBlob(filename);
00483 if (blob != (char *) NULL)
00484 {
00485 xml=StringToStringInfo(blob);
00486 (void) AppendValueToLinkedList(messages,xml);
00487 blob=DestroyString(blob);
00488 }
00489 }
00490 #endif
00491 ResetLinkedListIterator(messages);
00492 return(messages);
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 MagickExport const char *GetLocaleValue(const LocaleInfo *locale_info)
00518 {
00519 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00520 assert(locale_info != (LocaleInfo *) NULL);
00521 assert(locale_info->signature == MagickSignature);
00522 return(locale_info->message);
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 static MagickBooleanType InitializeLocaleList(ExceptionInfo *exception)
00548 {
00549 if ((locale_list == (SplayTreeInfo *) NULL) &&
00550 (instantiate_locale == MagickFalse))
00551 {
00552 if (locale_semaphore == (SemaphoreInfo *) NULL)
00553 AcquireSemaphoreInfo(&locale_semaphore);
00554 (void) LockSemaphoreInfo(locale_semaphore);
00555 if ((locale_list == (SplayTreeInfo *) NULL) &&
00556 (instantiate_locale == MagickFalse))
00557 {
00558 char
00559 *locale;
00560
00561 register const char
00562 *p;
00563
00564 locale=(char *) NULL;
00565 p=setlocale(LC_CTYPE,(const char *) NULL);
00566 if (p != (const char *) NULL)
00567 locale=ConstantString(p);
00568 if (locale == (char *) NULL)
00569 locale=GetEnvironmentValue("LC_ALL");
00570 if (locale == (char *) NULL)
00571 locale=GetEnvironmentValue("LC_MESSAGES");
00572 if (locale == (char *) NULL)
00573 locale=GetEnvironmentValue("LC_CTYPE");
00574 if (locale == (char *) NULL)
00575 locale=GetEnvironmentValue("LANG");
00576 if (locale == (char *) NULL)
00577 locale=ConstantString("C");
00578 (void) LoadLocaleLists(LocaleFilename,locale,exception);
00579 locale=DestroyString(locale);
00580 instantiate_locale=MagickTrue;
00581 }
00582 (void) UnlockSemaphoreInfo(locale_semaphore);
00583 }
00584 return(locale_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 MagickExport MagickBooleanType ListLocaleInfo(FILE *file,
00612 ExceptionInfo *exception)
00613 {
00614 const char
00615 *path;
00616
00617 const LocaleInfo
00618 **locale_info;
00619
00620 register long
00621 i;
00622
00623 unsigned long
00624 number_messages;
00625
00626 if (file == (const FILE *) NULL)
00627 file=stdout;
00628 number_messages=0;
00629 locale_info=GetLocaleInfoList("*",&number_messages,exception);
00630 if (locale_info == (const LocaleInfo **) NULL)
00631 return(MagickFalse);
00632 path=(const char *) NULL;
00633 for (i=0; i < (long) number_messages; i++)
00634 {
00635 if (locale_info[i]->stealth != MagickFalse)
00636 continue;
00637 if ((path == (const char *) NULL) ||
00638 (LocaleCompare(path,locale_info[i]->path) != 0))
00639 {
00640 if (locale_info[i]->path != (char *) NULL)
00641 (void) fprintf(file,"\nPath: %s\n\n",locale_info[i]->path);
00642 (void) fprintf(file,"Tag/Message\n");
00643 (void) fprintf(file,"-------------------------------------------------"
00644 "------------------------------\n");
00645 }
00646 path=locale_info[i]->path;
00647 (void) fprintf(file,"%s\n",locale_info[i]->tag);
00648 if (locale_info[i]->message != (char *) NULL)
00649 (void) fprintf(file," %s",locale_info[i]->message);
00650 (void) fprintf(file,"\n");
00651 }
00652 (void) fflush(file);
00653 locale_info=(const LocaleInfo **)
00654 RelinquishMagickMemory((void *) locale_info);
00655 return(MagickTrue);
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 static void ChopLocaleComponents(char *path,const unsigned long components)
00690 {
00691 long
00692 count;
00693
00694 register char
00695 *p;
00696
00697 if (*path == '\0')
00698 return;
00699 p=path+strlen(path)-1;
00700 if (*p == '/')
00701 *p='\0';
00702 for (count=0; (count < (long) components) && (p > path); p--)
00703 if (*p == '/')
00704 {
00705 *p='\0';
00706 count++;
00707 }
00708 if (count < (long) components)
00709 *path='\0';
00710 }
00711
00712 static void *DestroyLocaleNode(void *locale_info)
00713 {
00714 register LocaleInfo
00715 *p;
00716
00717 p=(LocaleInfo *) locale_info;
00718 if (p->path != (char *) NULL)
00719 p->path=DestroyString(p->path);
00720 if (p->tag != (char *) NULL)
00721 p->tag=DestroyString(p->tag);
00722 if (p->message != (char *) NULL)
00723 p->message=DestroyString(p->message);
00724 return(RelinquishMagickMemory(p));
00725 }
00726
00727 static MagickBooleanType LoadLocaleList(const char *xml,const char *filename,
00728 const char *locale,const unsigned long depth,ExceptionInfo *exception)
00729 {
00730 char
00731 keyword[MaxTextExtent],
00732 message[MaxTextExtent],
00733 tag[MaxTextExtent],
00734 *token;
00735
00736 const char
00737 *q;
00738
00739 LocaleInfo
00740 *locale_info;
00741
00742 MagickBooleanType
00743 status;
00744
00745 register char
00746 *p;
00747
00748
00749
00750
00751 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00752 "Loading locale configure file \"%s\" ...",filename);
00753 if (xml == (const char *) NULL)
00754 return(MagickFalse);
00755 if (locale_list == (SplayTreeInfo *) NULL)
00756 {
00757 locale_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
00758 DestroyLocaleNode);
00759 if (locale_list == (SplayTreeInfo *) NULL)
00760 {
00761 ThrowFileException(exception,ResourceLimitError,
00762 "MemoryAllocationFailed",filename);
00763 return(MagickFalse);
00764 }
00765 }
00766 status=MagickTrue;
00767 locale_info=(LocaleInfo *) NULL;
00768 *tag='\0';
00769 *message='\0';
00770 *keyword='\0';
00771 token=AcquireString(xml);
00772 for (q=(char *) xml; *q != '\0'; )
00773 {
00774
00775
00776
00777 GetMagickToken(q,&q,token);
00778 if (*token == '\0')
00779 break;
00780 (void) CopyMagickString(keyword,token,MaxTextExtent);
00781 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
00782 {
00783
00784
00785
00786 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
00787 {
00788 GetMagickToken(q,&q,token);
00789 while (isspace((int) ((unsigned char) *q)) != 0)
00790 q++;
00791 }
00792 continue;
00793 }
00794 if (LocaleNCompare(keyword,"<!--",4) == 0)
00795 {
00796
00797
00798
00799 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
00800 {
00801 GetMagickToken(q,&q,token);
00802 while (isspace((int) ((unsigned char) *q)) != 0)
00803 q++;
00804 }
00805 continue;
00806 }
00807 if (LocaleCompare(keyword,"<include") == 0)
00808 {
00809
00810
00811
00812 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
00813 {
00814 (void) CopyMagickString(keyword,token,MaxTextExtent);
00815 GetMagickToken(q,&q,token);
00816 if (*token != '=')
00817 continue;
00818 GetMagickToken(q,&q,token);
00819 if (LocaleCompare(keyword,"locale") == 0)
00820 {
00821 if (LocaleCompare(locale,token) != 0)
00822 break;
00823 continue;
00824 }
00825 if (LocaleCompare(keyword,"file") == 0)
00826 {
00827 if (depth > 200)
00828 (void) ThrowMagickException(exception,GetMagickModule(),
00829 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
00830 else
00831 {
00832 char
00833 path[MaxTextExtent],
00834 *xml;
00835
00836 *path='\0';
00837 GetPathComponent(filename,HeadPath,path);
00838 if (*path != '\0')
00839 (void) ConcatenateMagickString(path,DirectorySeparator,
00840 MaxTextExtent);
00841 if (*token == *DirectorySeparator)
00842 (void) CopyMagickString(path,token,MaxTextExtent);
00843 else
00844 (void) ConcatenateMagickString(path,token,MaxTextExtent);
00845 xml=FileToString(path,~0,exception);
00846 if (xml != (char *) NULL)
00847 {
00848 status=LoadLocaleList(xml,path,locale,depth+1,exception);
00849 xml=(char *) RelinquishMagickMemory(xml);
00850 }
00851 }
00852 }
00853 }
00854 continue;
00855 }
00856 if (LocaleCompare(keyword,"<locale") == 0)
00857 {
00858
00859
00860
00861 while ((*token != '>') && (*q != '\0'))
00862 {
00863 (void) CopyMagickString(keyword,token,MaxTextExtent);
00864 GetMagickToken(q,&q,token);
00865 if (*token != '=')
00866 continue;
00867 GetMagickToken(q,&q,token);
00868 }
00869 continue;
00870 }
00871 if (LocaleCompare(keyword,"</locale>") == 0)
00872 {
00873 ChopLocaleComponents(tag,1);
00874 (void) ConcatenateMagickString(tag,"/",MaxTextExtent);
00875 continue;
00876 }
00877 if (LocaleCompare(keyword,"<localemap>") == 0)
00878 continue;
00879 if (LocaleCompare(keyword,"</localemap>") == 0)
00880 continue;
00881 if (LocaleCompare(keyword,"<message") == 0)
00882 {
00883
00884
00885
00886 while ((*token != '>') && (*q != '\0'))
00887 {
00888 (void) CopyMagickString(keyword,token,MaxTextExtent);
00889 GetMagickToken(q,&q,token);
00890 if (*token != '=')
00891 continue;
00892 GetMagickToken(q,&q,token);
00893 if (LocaleCompare(keyword,"name") == 0)
00894 {
00895 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
00896 (void) ConcatenateMagickString(tag,"/",MaxTextExtent);
00897 }
00898 }
00899 for (p=(char *) q; (*q != '<') && (*q != '\0'); q++) ;
00900 while (isspace((int) ((unsigned char) *p)) != 0)
00901 p++;
00902 q--;
00903 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
00904 q--;
00905 (void) CopyMagickString(message,p,(size_t) (q-p+2));
00906 locale_info=(LocaleInfo *) AcquireMagickMemory(sizeof(*locale_info));
00907 if (locale_info == (LocaleInfo *) NULL)
00908 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00909 (void) ResetMagickMemory(locale_info,0,sizeof(*locale_info));
00910 locale_info->path=ConstantString(filename);
00911 locale_info->tag=ConstantString(tag);
00912 locale_info->message=ConstantString(message);
00913 locale_info->signature=MagickSignature;
00914 status=AddValueToSplayTree(locale_list,locale_info->tag,locale_info);
00915 if (status == MagickFalse)
00916 (void) ThrowMagickException(exception,GetMagickModule(),
00917 ResourceLimitError,"MemoryAllocationFailed","`%s'",
00918 locale_info->tag);
00919 (void) ConcatenateMagickString(tag,message,MaxTextExtent);
00920 (void) ConcatenateMagickString(tag,"\n",MaxTextExtent);
00921 q++;
00922 continue;
00923 }
00924 if (LocaleCompare(keyword,"</message>") == 0)
00925 {
00926 ChopLocaleComponents(tag,2);
00927 (void) ConcatenateMagickString(tag,"/",MaxTextExtent);
00928 continue;
00929 }
00930 if (*keyword == '<')
00931 {
00932
00933
00934
00935 if (*(keyword+1) == '?')
00936 continue;
00937 if (*(keyword+1) == '/')
00938 {
00939 ChopLocaleComponents(tag,1);
00940 if (*tag != '\0')
00941 (void) ConcatenateMagickString(tag,"/",MaxTextExtent);
00942 continue;
00943 }
00944 token[strlen(token)-1]='\0';
00945 (void) CopyMagickString(token,token+1,MaxTextExtent);
00946 (void) ConcatenateMagickString(tag,token,MaxTextExtent);
00947 (void) ConcatenateMagickString(tag,"/",MaxTextExtent);
00948 continue;
00949 }
00950 GetMagickToken(q,(const char **) NULL,token);
00951 if (*token != '=')
00952 continue;
00953 }
00954 token=(char *) RelinquishMagickMemory(token);
00955 return(status);
00956 }
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986 static MagickBooleanType LoadLocaleLists(const char *filename,
00987 const char *locale,ExceptionInfo *exception)
00988 {
00989 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
00990 return(LoadLocaleList(LocaleMap,"built-in",locale,0,exception));
00991 #else
00992 const StringInfo
00993 *option;
00994
00995 LinkedListInfo
00996 *options;
00997
00998 MagickStatusType
00999 status;
01000
01001 status=MagickFalse;
01002 options=GetLocaleOptions(filename,exception);
01003 option=(const StringInfo *) GetNextValueInLinkedList(options);
01004 while (option != (const StringInfo *) NULL)
01005 {
01006 status|=LoadLocaleList((const char *) GetStringInfoDatum(option),
01007 GetStringInfoPath(option),locale,0,exception);
01008 option=(const StringInfo *) GetNextValueInLinkedList(options);
01009 }
01010 options=DestroyLocaleOptions(options);
01011 if ((locale_list == (SplayTreeInfo *) NULL) ||
01012 (GetNumberOfNodesInSplayTree(locale_list) == 0))
01013 {
01014 options=GetLocaleOptions("english.xml",exception);
01015 option=(const StringInfo *) GetNextValueInLinkedList(options);
01016 while (option != (const StringInfo *) NULL)
01017 {
01018 status|=LoadLocaleList((const char *) GetStringInfoDatum(option),
01019 GetStringInfoPath(option),locale,0,exception);
01020 option=(const StringInfo *) GetNextValueInLinkedList(options);
01021 }
01022 options=DestroyLocaleOptions(options);
01023 }
01024 if ((locale_list == (SplayTreeInfo *) NULL) ||
01025 (GetNumberOfNodesInSplayTree(locale_list) == 0))
01026 status|=LoadLocaleList(LocaleMap,"built-in",locale,0,exception);
01027 return(status != 0 ? MagickTrue : MagickFalse);
01028 #endif
01029 }
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 MagickExport MagickBooleanType LocaleComponentGenesis(void)
01050 {
01051 AcquireSemaphoreInfo(&locale_semaphore);
01052 return(MagickTrue);
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 MagickExport void LocaleComponentTerminus(void)
01074 {
01075 if (locale_semaphore == (SemaphoreInfo *) NULL)
01076 AcquireSemaphoreInfo(&locale_semaphore);
01077 (void) LockSemaphoreInfo(locale_semaphore);
01078 if (locale_list != (SplayTreeInfo *) NULL)
01079 locale_list=DestroySplayTree(locale_list);
01080 instantiate_locale=MagickFalse;
01081 (void) UnlockSemaphoreInfo(locale_semaphore);
01082 DestroySemaphoreInfo(&locale_semaphore);
01083 }