locale.c

Go to the documentation of this file.
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-2009 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 "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   Define declarations.
00061 */
00062 #define LocaleFilename  "locale.xml"
00063 #define MaxRecursionDepth  200
00064 
00065 /*
00066   Static declarations.
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   Forward declarations.
00091 */
00092 static MagickBooleanType
00093   InitializeLocaleList(ExceptionInfo *),
00094   LoadLocaleLists(const char *,const char *,ExceptionInfo *);
00095 
00096 /*
00097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00098 %                                                                             %
00099 %                                                                             %
00100 %                                                                             %
00101 %   D e s t r o y L o c a l e O p t i o n s                                   %
00102 %                                                                             %
00103 %                                                                             %
00104 %                                                                             %
00105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00106 %
00107 %  DestroyLocaleOptions() releases memory associated with an locale
00108 %  messages.
00109 %
00110 %  The format of the DestroyProfiles method is:
00111 %
00112 %      LinkedListInfo *DestroyLocaleOptions(Image *image)
00113 %
00114 %  A description of each parameter follows:
00115 %
00116 %    o image: the image.
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 +   G e t L o c a l e I n f o _                                               %
00138 %                                                                             %
00139 %                                                                             %
00140 %                                                                             %
00141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00142 %
00143 %  GetLocaleInfo_() searches the locale list for the specified tag and if
00144 %  found returns attributes for that element.
00145 %
00146 %  The format of the GetLocaleInfo method is:
00147 %
00148 %      const LocaleInfo *GetLocaleInfo_(const char *tag,
00149 %        ExceptionInfo *exception)
00150 %
00151 %  A description of each parameter follows:
00152 %
00153 %    o tag: the locale tag.
00154 %
00155 %    o exception: return any errors or warnings in this structure.
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 %   G e t L o c a l e I n f o L i s t                                         %
00183 %                                                                             %
00184 %                                                                             %
00185 %                                                                             %
00186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00187 %
00188 %  GetLocaleInfoList() returns any locale messages that match the
00189 %  specified pattern.
00190 %
00191 %  The format of the GetLocaleInfoList function is:
00192 %
00193 %      const LocaleInfo **GetLocaleInfoList(const char *pattern,
00194 %        unsigned long *number_messages,ExceptionInfo *exception)
00195 %
00196 %  A description of each parameter follows:
00197 %
00198 %    o pattern: Specifies a pointer to a text string containing a pattern.
00199 %
00200 %    o number_messages:  This integer returns the number of locale messages in
00201 %    the list.
00202 %
00203 %    o exception: return any errors or warnings in this structure.
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     Allocate locale list.
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     Generate locale list.
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 %   G e t L o c a l e L i s t                                                 %
00280 %                                                                             %
00281 %                                                                             %
00282 %                                                                             %
00283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00284 %
00285 %  GetLocaleList() returns any locale messages that match the specified
00286 %  pattern.
00287 %
00288 %  The format of the GetLocaleList function is:
00289 %
00290 %      char **GetLocaleList(const char *pattern,unsigned long *number_messages,
00291 %        Exceptioninfo *exception)
00292 %
00293 %  A description of each parameter follows:
00294 %
00295 %    o pattern: Specifies a pointer to a text string containing a pattern.
00296 %
00297 %    o number_messages:  This integer returns the number of messages in the
00298 %      list.
00299 %
00300 %    o exception: return any errors or warnings in this structure.
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     Allocate locale list.
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 %   G e t L o c a l e M e s s a g e                                           %
00371 %                                                                             %
00372 %                                                                             %
00373 %                                                                             %
00374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00375 %
00376 %  GetLocaleMessage() returns a message in the current locale that matches the
00377 %  supplied tag.
00378 %
00379 %  The format of the GetLocaleMessage method is:
00380 %
00381 %      const char *GetLocaleMessage(const char *tag)
00382 %
00383 %  A description of each parameter follows:
00384 %
00385 %    o tag: Return a message that matches this tag in the current locale.
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 %  G e t L o c a l e O p t i o n s                                            %
00416 %                                                                             %
00417 %                                                                             %
00418 %                                                                             %
00419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00420 %
00421 %  GetLocaleOptions() returns any Magick configuration messages associated
00422 %  with the specified filename.
00423 %
00424 %  The format of the GetLocaleOptions method is:
00425 %
00426 %      LinkedListInfo *GetLocaleOptions(const char *filename,
00427 %        ExceptionInfo *exception)
00428 %
00429 %  A description of each parameter follows:
00430 %
00431 %    o filename: the locale file tag.
00432 %
00433 %    o exception: return any errors or warnings in this structure.
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     Load XML from configuration files to linked-list.
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 %   G e t L o c a l e V a l u e                                               %
00501 %                                                                             %
00502 %                                                                             %
00503 %                                                                             %
00504 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00505 %
00506 %  GetLocaleValue() returns the message associated with the locale info.
00507 %
00508 %  The format of the GetLocaleValue method is:
00509 %
00510 %      const char *GetLocaleValue(const LocaleInfo *locale_info)
00511 %
00512 %  A description of each parameter follows:
00513 %
00514 %    o locale_info:  The locale info.
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 +   I n i t i a l i z e L o c a l e L i s t                                   %
00531 %                                                                             %
00532 %                                                                             %
00533 %                                                                             %
00534 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00535 %
00536 %  InitializeLocaleList() initializes the locale list.
00537 %
00538 %  The format of the InitializeLocaleList method is:
00539 %
00540 %      MagickBooleanType InitializeLocaleList(ExceptionInfo *exception)
00541 %
00542 %  A description of each parameter follows.
00543 %
00544 %    o exception: return any errors or warnings in this structure.
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 %  L i s t L o c a l e I n f o                                                %
00593 %                                                                             %
00594 %                                                                             %
00595 %                                                                             %
00596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00597 %
00598 %  ListLocaleInfo() lists the locale info to a file.
00599 %
00600 %  The format of the ListLocaleInfo method is:
00601 %
00602 %      MagickBooleanType ListLocaleInfo(FILE *file,ExceptionInfo *exception)
00603 %
00604 %  A description of each parameter follows.
00605 %
00606 %    o file:  An pointer to a FILE.
00607 %
00608 %    o exception: return any errors or warnings in this structure.
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 +   L o a d L o c a l e L i s t                                               %
00664 %                                                                             %
00665 %                                                                             %
00666 %                                                                             %
00667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00668 %
00669 %  LoadLocaleList() loads the locale configuration file which provides a mapping
00670 %  between locale attributes and a locale name.
00671 %
00672 %  The format of the LoadLocaleList method is:
00673 %
00674 %      MagickBooleanType LoadLocaleList(const char *xml,const char *filename,
00675 %        const unsigned long depth,ExceptionInfo *exception)
00676 %
00677 %  A description of each parameter follows:
00678 %
00679 %    o xml:  The locale list in XML format.
00680 %
00681 %    o filename:  The locale list filename.
00682 %
00683 %    o depth: depth of <include /> statements.
00684 %
00685 %    o exception: return any errors or warnings in this structure.
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     Read the locale configure file.
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       Interpret XML.
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           Doctype element.
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           Comment element.
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           Include element.
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           Locale element.
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           Message element.
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           Subpath element.
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 %  L o a d L o c a l e L i s t s                                              %
00964 %                                                                             %
00965 %                                                                             %
00966 %                                                                             %
00967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00968 %
00969 %  LoadLocaleList() loads one or more locale configuration file which
00970 %  provides a mapping between locale attributes and a locale tag.
00971 %
00972 %  The format of the LoadLocaleLists method is:
00973 %
00974 %      MagickBooleanType LoadLocaleLists(const char *filename,
00975 %        ExceptionInfo *exception)
00976 %
00977 %  A description of each parameter follows:
00978 %
00979 %    o filename: the font file tag.
00980 %
00981 %    o locale: the actual locale.
00982 %
00983 %    o exception: return any errors or warnings in this structure.
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 +   L o c a l e C o m p o n e n t G e n e s i s                               %
01037 %                                                                             %
01038 %                                                                             %
01039 %                                                                             %
01040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01041 %
01042 %  LocaleComponentGenesis() instantiates the locale component.
01043 %
01044 %  The format of the LocaleComponentGenesis method is:
01045 %
01046 %      MagickBooleanType LocaleComponentGenesis(void)
01047 %
01048 */
01049 MagickExport MagickBooleanType LocaleComponentGenesis(void)
01050 {
01051   AcquireSemaphoreInfo(&locale_semaphore);
01052   return(MagickTrue);
01053 }
01054 
01055 /*
01056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01057 %                                                                             %
01058 %                                                                             %
01059 %                                                                             %
01060 +   L o c a l e C o m p o n e n t T e r m i n u s                             %
01061 %                                                                             %
01062 %                                                                             %
01063 %                                                                             %
01064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01065 %
01066 %  LocaleComponentTerminus() destroys the locale component.
01067 %
01068 %  The format of the LocaleComponentTerminus method is:
01069 %
01070 %      LocaleComponentTerminus(void)
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 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1