MagickCore  6.7.5
configure.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %          CCCC   OOO   N   N  FFFFF  IIIII   GGGG  U   U  RRRR   EEEEE       %
00007 %         C      O   O  NN  N  F        I    G      U   U  R   R  E           %
00008 %         C      O   O  N N N  FFF      I    G GG   U   U  RRRR   EEE         %
00009 %         C      O   O  N  NN  F        I    G   G  U   U  R R    E           %
00010 %          CCCC   OOO   N   N  F      IIIII   GGG    UUU   R  R   EEEEE       %
00011 %                                                                             %
00012 %                                                                             %
00013 %                      MagickCore Image Configure 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/configure-private.h"
00047 #include "MagickCore/exception.h"
00048 #include "MagickCore/exception-private.h"
00049 #include "MagickCore/hashmap.h"
00050 #include "MagickCore/log.h"
00051 #include "MagickCore/memory_.h"
00052 #include "MagickCore/semaphore.h"
00053 #include "MagickCore/string_.h"
00054 #include "MagickCore/string-private.h"
00055 #include "MagickCore/token.h"
00056 #include "MagickCore/utility.h"
00057 #include "MagickCore/utility-private.h"
00058 #include "MagickCore/xml-tree.h"
00059 
00060 /*
00061   Define declarations.
00062 */
00063 #define ConfigureFilename  "configure.xml"
00064 
00065 /*
00066   Typedef declarations.
00067 */
00068 typedef struct _ConfigureMapInfo
00069 {
00070   const char
00071     *name,
00072     *value;
00073 } ConfigureMapInfo;
00074 
00075 /*
00076   Static declarations.
00077 */
00078 static const ConfigureMapInfo
00079   ConfigureMap[] =
00080   {
00081     { "NAME", "ImageMagick" }
00082   };
00083 
00084 static LinkedListInfo
00085   *configure_list = (LinkedListInfo *) NULL;
00086 
00087 static SemaphoreInfo
00088   *configure_semaphore = (SemaphoreInfo *) NULL;
00089 
00090 static volatile MagickBooleanType
00091   instantiate_configure = MagickFalse;
00092 
00093 /*
00094   Forward declarations.
00095 */
00096 static MagickBooleanType
00097   InitializeConfigureList(ExceptionInfo *),
00098   LoadConfigureLists(const char *,ExceptionInfo *);
00099 
00100 /*
00101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00102 %                                                                             %
00103 %                                                                             %
00104 %                                                                             %
00105 +   C o n f i g u r e C o m p o n e n t G e n e s i s                         %
00106 %                                                                             %
00107 %                                                                             %
00108 %                                                                             %
00109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00110 %
00111 %  ConfigureComponentGenesis() instantiates the configure component.
00112 %
00113 %  The format of the ConfigureComponentGenesis method is:
00114 %
00115 %      MagickBooleanType ConfigureComponentGenesis(void)
00116 %
00117 */
00118 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
00119 {
00120   AcquireSemaphoreInfo(&configure_semaphore);
00121   return(MagickTrue);
00122 }
00123 
00124 /*
00125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00126 %                                                                             %
00127 %                                                                             %
00128 %                                                                             %
00129 +   C o n f i g u r e C o m p o n e n t T e r m i n u s                       %
00130 %                                                                             %
00131 %                                                                             %
00132 %                                                                             %
00133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00134 %
00135 %  ConfigureComponentTerminus() destroys the configure component.
00136 %
00137 %  The format of the ConfigureComponentTerminus method is:
00138 %
00139 %      ConfigureComponentTerminus(void)
00140 %
00141 */
00142 
00143 static void *DestroyConfigureElement(void *configure_info)
00144 {
00145   register ConfigureInfo
00146     *p;
00147 
00148   p=(ConfigureInfo *) configure_info;
00149   if (p->exempt == MagickFalse)
00150     {
00151       if (p->value != (char *) NULL)
00152         p->value=DestroyString(p->value);
00153       if (p->name != (char *) NULL)
00154         p->name=DestroyString(p->name);
00155       if (p->path != (char *) NULL)
00156         p->path=DestroyString(p->path);
00157     }
00158   p=(ConfigureInfo *) RelinquishMagickMemory(p);
00159   return((void *) NULL);
00160 }
00161 
00162 MagickPrivate void ConfigureComponentTerminus(void)
00163 {
00164   if (configure_semaphore == (SemaphoreInfo *) NULL)
00165     AcquireSemaphoreInfo(&configure_semaphore);
00166   LockSemaphoreInfo(configure_semaphore);
00167   if (configure_list != (LinkedListInfo *) NULL)
00168     configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
00169   configure_list=(LinkedListInfo *) NULL;
00170   instantiate_configure=MagickFalse;
00171   UnlockSemaphoreInfo(configure_semaphore);
00172   DestroySemaphoreInfo(&configure_semaphore);
00173 }
00174 
00175 /*
00176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00177 %                                                                             %
00178 %                                                                             %
00179 %                                                                             %
00180 %   D e s t r o y C o n f i g u r e O p t i o n s                             %
00181 %                                                                             %
00182 %                                                                             %
00183 %                                                                             %
00184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00185 %
00186 %  DestroyConfigureOptions() releases memory associated with an configure
00187 %  options.
00188 %
00189 %  The format of the DestroyProfiles method is:
00190 %
00191 %      LinkedListInfo *DestroyConfigureOptions(Image *image)
00192 %
00193 %  A description of each parameter follows:
00194 %
00195 %    o image: the image.
00196 %
00197 */
00198 
00199 static void *DestroyOptions(void *option)
00200 {
00201   return(DestroyStringInfo((StringInfo *) option));
00202 }
00203 
00204 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
00205 {
00206   assert(options != (LinkedListInfo *) NULL);
00207   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00208   return(DestroyLinkedList(options,DestroyOptions));
00209 }
00210 
00211 /*
00212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00213 %                                                                             %
00214 %                                                                             %
00215 %                                                                             %
00216 +   G e t C o n f i g u r e I n f o                                           %
00217 %                                                                             %
00218 %                                                                             %
00219 %                                                                             %
00220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00221 %
00222 %  GetConfigureInfo() searches the configure list for the specified name and if
00223 %  found returns attributes for that element.
00224 %
00225 %  The format of the GetConfigureInfo method is:
00226 %
00227 %      const ConfigureInfo *GetConfigureInfo(const char *name,
00228 %        ExceptionInfo *exception)
00229 %
00230 %  A description of each parameter follows:
00231 %
00232 %    o configure_info: GetConfigureInfo() searches the configure list for the
00233 %      specified name and if found returns attributes for that element.
00234 %
00235 %    o name: the configure name.
00236 %
00237 %    o exception: return any errors or warnings in this structure.
00238 %
00239 */
00240 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
00241   ExceptionInfo *exception)
00242 {
00243   register const ConfigureInfo
00244     *p;
00245 
00246   assert(exception != (ExceptionInfo *) NULL);
00247   if ((configure_list == (LinkedListInfo *) NULL) ||
00248       (instantiate_configure == MagickFalse))
00249     if (InitializeConfigureList(exception) == MagickFalse)
00250       return((const ConfigureInfo *) NULL);
00251   if ((configure_list == (LinkedListInfo *) NULL) ||
00252       (IsLinkedListEmpty(configure_list) != MagickFalse))
00253     return((const ConfigureInfo *) NULL);
00254   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
00255     return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
00256   /*
00257     Search for configure tag.
00258   */
00259   LockSemaphoreInfo(configure_semaphore);
00260   ResetLinkedListIterator(configure_list);
00261   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
00262   while (p != (const ConfigureInfo *) NULL)
00263   {
00264     if (LocaleCompare(name,p->name) == 0)
00265       break;
00266     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
00267   }
00268   if (p != (ConfigureInfo *) NULL)
00269     (void) InsertValueInLinkedList(configure_list,0,
00270       RemoveElementByValueFromLinkedList(configure_list,p));
00271   UnlockSemaphoreInfo(configure_semaphore);
00272   return(p);
00273 }
00274 
00275 /*
00276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00277 %                                                                             %
00278 %                                                                             %
00279 %                                                                             %
00280 %   G e t C o n f i g u r e I n f o L i s t                                   %
00281 %                                                                             %
00282 %                                                                             %
00283 %                                                                             %
00284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00285 %
00286 %  GetConfigureInfoList() returns any configure options that match the
00287 %  specified pattern.
00288 %
00289 %  The format of the GetConfigureInfoList function is:
00290 %
00291 %      const ConfigureInfo **GetConfigureInfoList(const char *pattern,
00292 %        size_t *number_options,ExceptionInfo *exception)
00293 %
00294 %  A description of each parameter follows:
00295 %
00296 %    o pattern: Specifies a pointer to a text string containing a pattern.
00297 %
00298 %    o number_options:  This integer returns the number of configure options in
00299 %    the list.
00300 %
00301 %    o exception: return any errors or warnings in this structure.
00302 %
00303 */
00304 
00305 #if defined(__cplusplus) || defined(c_plusplus)
00306 extern "C" {
00307 #endif
00308 
00309 static int ConfigureInfoCompare(const void *x,const void *y)
00310 {
00311   const ConfigureInfo
00312     **p,
00313     **q;
00314 
00315   p=(const ConfigureInfo **) x,
00316   q=(const ConfigureInfo **) y;
00317   if (LocaleCompare((*p)->path,(*q)->path) == 0)
00318     return(LocaleCompare((*p)->name,(*q)->name));
00319   return(LocaleCompare((*p)->path,(*q)->path));
00320 }
00321 
00322 #if defined(__cplusplus) || defined(c_plusplus)
00323 }
00324 #endif
00325 
00326 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
00327   size_t *number_options,ExceptionInfo *exception)
00328 {
00329   const ConfigureInfo
00330     **options;
00331 
00332   register const ConfigureInfo
00333     *p;
00334 
00335   register ssize_t
00336     i;
00337 
00338   /*
00339     Allocate configure list.
00340   */
00341   assert(pattern != (char *) NULL);
00342   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00343   assert(number_options != (size_t *) NULL);
00344   *number_options=0;
00345   p=GetConfigureInfo("*",exception);
00346   if (p == (const ConfigureInfo *) NULL)
00347     return((const ConfigureInfo **) NULL);
00348   options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
00349     GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
00350   if (options == (const ConfigureInfo **) NULL)
00351     return((const ConfigureInfo **) NULL);
00352   /*
00353     Generate configure list.
00354   */
00355   LockSemaphoreInfo(configure_semaphore);
00356   ResetLinkedListIterator(configure_list);
00357   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
00358   for (i=0; p != (const ConfigureInfo *) NULL; )
00359   {
00360     if ((p->stealth == MagickFalse) &&
00361         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00362       options[i++]=p;
00363     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
00364   }
00365   UnlockSemaphoreInfo(configure_semaphore);
00366   qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
00367   options[i]=(ConfigureInfo *) NULL;
00368   *number_options=(size_t) i;
00369   return(options);
00370 }
00371 
00372 /*
00373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00374 %                                                                             %
00375 %                                                                             %
00376 %                                                                             %
00377 %   G e t C o n f i g u r e L i s t                                           %
00378 %                                                                             %
00379 %                                                                             %
00380 %                                                                             %
00381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00382 %
00383 %  GetConfigureList() returns any configure options that match the specified
00384 %  pattern.
00385 %
00386 %  The format of the GetConfigureList function is:
00387 %
00388 %      char **GetConfigureList(const char *pattern,
00389 %        size_t *number_options,ExceptionInfo *exception)
00390 %
00391 %  A description of each parameter follows:
00392 %
00393 %    o pattern: Specifies a pointer to a text string containing a pattern.
00394 %
00395 %    o number_options:  This integer returns the number of options in the list.
00396 %
00397 %    o exception: return any errors or warnings in this structure.
00398 %
00399 */
00400 
00401 #if defined(__cplusplus) || defined(c_plusplus)
00402 extern "C" {
00403 #endif
00404 
00405 static int ConfigureCompare(const void *x,const void *y)
00406 {
00407   register char
00408     **p,
00409     **q;
00410 
00411   p=(char **) x;
00412   q=(char **) y;
00413   return(LocaleCompare(*p,*q));
00414 }
00415 
00416 #if defined(__cplusplus) || defined(c_plusplus)
00417 }
00418 #endif
00419 
00420 MagickExport char **GetConfigureList(const char *pattern,
00421   size_t *number_options,ExceptionInfo *exception)
00422 {
00423   char
00424     **options;
00425 
00426   register const ConfigureInfo
00427     *p;
00428 
00429   register ssize_t
00430     i;
00431 
00432   /*
00433     Allocate configure list.
00434   */
00435   assert(pattern != (char *) NULL);
00436   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00437   assert(number_options != (size_t *) NULL);
00438   *number_options=0;
00439   p=GetConfigureInfo("*",exception);
00440   if (p == (const ConfigureInfo *) NULL)
00441     return((char **) NULL);
00442   options=(char **) AcquireQuantumMemory((size_t)
00443     GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
00444   if (options == (char **) NULL)
00445     return((char **) NULL);
00446   LockSemaphoreInfo(configure_semaphore);
00447   ResetLinkedListIterator(configure_list);
00448   p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
00449   for (i=0; p != (const ConfigureInfo *) NULL; )
00450   {
00451     if ((p->stealth == MagickFalse) &&
00452         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00453       options[i++]=ConstantString(p->name);
00454     p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
00455   }
00456   UnlockSemaphoreInfo(configure_semaphore);
00457   qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
00458   options[i]=(char *) NULL;
00459   *number_options=(size_t) i;
00460   return(options);
00461 }
00462 
00463 /*
00464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00465 %                                                                             %
00466 %                                                                             %
00467 %                                                                             %
00468 %   G e t C o n f i g u r e O p t i o n                                       %
00469 %                                                                             %
00470 %                                                                             %
00471 %                                                                             %
00472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00473 %
00474 %  GetConfigureOption() returns the value associated with the configure option.
00475 %
00476 %  The format of the GetConfigureOption method is:
00477 %
00478 %      char *GetConfigureOption(const char *option)
00479 %
00480 %  A description of each parameter follows:
00481 %
00482 %    o configure_info:  The configure info.
00483 %
00484 */
00485 MagickExport char *GetConfigureOption(const char *option)
00486 {
00487   const char
00488     *value;
00489 
00490   const ConfigureInfo
00491     *configure_info;
00492 
00493   ExceptionInfo
00494     *exception;
00495 
00496   assert(option != (const char *) NULL);
00497   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
00498   exception=AcquireExceptionInfo();
00499   configure_info=GetConfigureInfo(option,exception);
00500   exception=DestroyExceptionInfo(exception);
00501   if (configure_info == (ConfigureInfo *) NULL)
00502     return((char *) NULL);
00503   value=GetConfigureValue(configure_info);
00504   if ((value == (const char *) NULL) || (*value == '\0'))
00505     return((char *) NULL);
00506   return(ConstantString(value));
00507 }
00508 
00509 /*
00510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00511 %                                                                             %
00512 %                                                                             %
00513 %                                                                             %
00514 %  G e t C o n f i g u r e O p t i o n s                                      %
00515 %                                                                             %
00516 %                                                                             %
00517 %                                                                             %
00518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00519 %
00520 %  GetConfigureOptions() returns any Magick configuration options associated
00521 %  with the specified filename.
00522 %
00523 %  The format of the GetConfigureOptions method is:
00524 %
00525 %      LinkedListInfo *GetConfigureOptions(const char *filename,
00526 %        ExceptionInfo *exception)
00527 %
00528 %  A description of each parameter follows:
00529 %
00530 %    o filename: the configure file name.
00531 %
00532 %    o exception: return any errors or warnings in this structure.
00533 %
00534 */
00535 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
00536   ExceptionInfo *exception)
00537 {
00538   char
00539     path[MaxTextExtent];
00540 
00541   const char
00542     *element;
00543 
00544   LinkedListInfo
00545     *options,
00546     *paths;
00547 
00548   StringInfo
00549     *xml;
00550 
00551   assert(filename != (const char *) NULL);
00552   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
00553   assert(exception != (ExceptionInfo *) NULL);
00554   (void) CopyMagickString(path,filename,MaxTextExtent);
00555   /*
00556     Load XML from configuration files to linked-list.
00557   */
00558   options=NewLinkedList(0);
00559   paths=GetConfigurePaths(filename,exception);
00560   if (paths != (LinkedListInfo *) NULL)
00561     {
00562       ResetLinkedListIterator(paths);
00563       element=(const char *) GetNextValueInLinkedList(paths);
00564       while (element != (const char *) NULL)
00565       {
00566         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
00567         (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00568           "Searching for configure file: \"%s\"",path);
00569         xml=ConfigureFileToStringInfo(path);
00570         if (xml != (StringInfo *) NULL)
00571           (void) AppendValueToLinkedList(options,xml);
00572         element=(const char *) GetNextValueInLinkedList(paths);
00573       }
00574       paths=DestroyLinkedList(paths,RelinquishMagickMemory);
00575     }
00576 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
00577   if (GetNumberOfElementsInLinkedList(options) == 0)
00578     {
00579       char
00580         *blob;
00581 
00582       blob=(char *) NTResourceToBlob(filename);
00583       if (blob != (char *) NULL)
00584         {
00585           xml=AcquireStringInfo(0);
00586           SetStringInfoLength(xml,strlen(blob)+1);
00587           SetStringInfoDatum(xml,blob);
00588           SetStringInfoPath(xml,filename);
00589           (void) AppendValueToLinkedList(options,xml);
00590         }
00591     }
00592 #endif
00593   if (GetNumberOfElementsInLinkedList(options) == 0)
00594     (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
00595       "UnableToOpenConfigureFile","`%s'",filename);
00596   ResetLinkedListIterator(options);
00597   return(options);
00598 }
00599 
00600 /*
00601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00602 %                                                                             %
00603 %                                                                             %
00604 %                                                                             %
00605 %  G e t C o n f i g u r e P a t h s                                          %
00606 %                                                                             %
00607 %                                                                             %
00608 %                                                                             %
00609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00610 %
00611 %  GetConfigurePaths() returns any Magick configuration paths associated
00612 %  with the specified filename.
00613 %
00614 %  The format of the GetConfigurePaths method is:
00615 %
00616 %      LinkedListInfo *GetConfigurePaths(const char *filename,
00617 %        ExceptionInfo *exception)
00618 %
00619 %  A description of each parameter follows:
00620 %
00621 %    o filename: the configure file name.
00622 %
00623 %    o exception: return any errors or warnings in this structure.
00624 %
00625 */
00626 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
00627   ExceptionInfo *exception)
00628 {
00629 #define RegistryKey  "ConfigurePath"
00630 #define MagickCoreDLL  "CORE_RL_MagickCore_.dll"
00631 #define MagickCoreDebugDLL  "CORE_DB_MagickCore_.dll"
00632 
00633   char
00634     path[MaxTextExtent];
00635 
00636   LinkedListInfo
00637     *paths;
00638 
00639   assert(filename != (const char *) NULL);
00640   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
00641   assert(exception != (ExceptionInfo *) NULL);
00642   (void) CopyMagickString(path,filename,MaxTextExtent);
00643   paths=NewLinkedList(0);
00644   {
00645     char
00646       *configure_path;
00647 
00648     /*
00649       Search $MAGICK_CONFIGURE_PATH.
00650     */
00651     configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
00652     if (configure_path != (char *) NULL)
00653       {
00654         register char
00655           *p,
00656           *q;
00657 
00658         for (p=configure_path-1; p != (char *) NULL; )
00659         {
00660           (void) CopyMagickString(path,p+1,MaxTextExtent);
00661           q=strchr(path,DirectoryListSeparator);
00662           if (q != (char *) NULL)
00663             *q='\0';
00664           q=path+strlen(path)-1;
00665           if ((q >= path) && (*q != *DirectorySeparator))
00666             (void) ConcatenateMagickString(path,DirectorySeparator,
00667               MaxTextExtent);
00668           (void) AppendValueToLinkedList(paths,ConstantString(path));
00669           p=strchr(p+1,DirectoryListSeparator);
00670         }
00671         configure_path=DestroyString(configure_path);
00672       }
00673   }
00674 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
00675 #if defined(MAGICKCORE_SHARE_PATH)
00676   (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
00677 #endif
00678 #if defined(MAGICKCORE_SHAREARCH_PATH)
00679   (void) AppendValueToLinkedList(paths,ConstantString(
00680     MAGICKCORE_SHAREARCH_PATH));
00681 #endif
00682 #if defined(MAGICKCORE_CONFIGURE_PATH)
00683   (void) AppendValueToLinkedList(paths,ConstantString(
00684     MAGICKCORE_CONFIGURE_PATH));
00685 #endif
00686 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
00687   (void) AppendValueToLinkedList(paths,ConstantString(
00688     MAGICKCORE_DOCUMENTATION_PATH));
00689 #endif
00690 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
00691   {
00692     unsigned char
00693       *key_value;
00694 
00695     /*
00696       Locate file via registry key.
00697     */
00698     key_value=NTRegistryKeyLookup(RegistryKey);
00699     if (key_value != (unsigned char *) NULL)
00700       {
00701         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
00702           DirectorySeparator);
00703         (void) AppendValueToLinkedList(paths,ConstantString(path));
00704         key_value=(unsigned char *) RelinquishMagickMemory(key_value);
00705       }
00706   }
00707 #endif
00708 #else
00709   {
00710     char
00711       *home;
00712 
00713     /*
00714       Search under MAGICK_HOME.
00715     */
00716     home=GetEnvironmentValue("MAGICK_HOME");
00717     if (home != (char *) NULL)
00718       {
00719 #if !defined(MAGICKCORE_POSIX_SUPPORT)
00720         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
00721           DirectorySeparator);
00722         (void) AppendValueToLinkedList(paths,ConstantString(path));
00723 #else
00724         (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
00725           MAGICKCORE_CONFIGURE_RELATIVE_PATH);
00726         (void) AppendValueToLinkedList(paths,ConstantString(path));
00727         (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
00728           MAGICKCORE_SHARE_RELATIVE_PATH);
00729         (void) AppendValueToLinkedList(paths,ConstantString(path));
00730 #endif
00731         home=DestroyString(home);
00732       }
00733     }
00734   if (*GetClientPath() != '\0')
00735     {
00736 #if !defined(MAGICKCORE_POSIX_SUPPORT)
00737       (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
00738         DirectorySeparator);
00739       (void) AppendValueToLinkedList(paths,ConstantString(path));
00740 #else
00741       char
00742         prefix[MaxTextExtent];
00743 
00744       /*
00745         Search based on executable directory if directory is known.
00746       */
00747       (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
00748       ChopPathComponents(prefix,1);
00749       (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
00750         MAGICKCORE_CONFIGURE_RELATIVE_PATH);
00751       (void) AppendValueToLinkedList(paths,ConstantString(path));
00752       (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
00753         MAGICKCORE_SHARE_RELATIVE_PATH);
00754       (void) AppendValueToLinkedList(paths,ConstantString(path));
00755 #endif
00756     }
00757   /*
00758     Search current directory.
00759   */
00760   (void) AppendValueToLinkedList(paths,ConstantString(""));
00761 #endif
00762   {
00763     char
00764       *home;
00765 
00766     home=GetEnvironmentValue("HOME");
00767     if (home == (char *) NULL)
00768       home=GetEnvironmentValue("USERPROFILE");
00769     if (home != (char *) NULL)
00770       {
00771         /*
00772           Search $HOME/.magick.
00773         */
00774         (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
00775           DirectorySeparator,DirectorySeparator);
00776         (void) AppendValueToLinkedList(paths,ConstantString(path));
00777         home=DestroyString(home);
00778       }
00779   }
00780 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
00781   {
00782     char
00783       module_path[MaxTextExtent];
00784 
00785     if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
00786         (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
00787       {
00788         unsigned char
00789           *key_value;
00790 
00791         /*
00792           Search module path.
00793         */
00794         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
00795           DirectorySeparator);
00796         key_value=NTRegistryKeyLookup(RegistryKey);
00797         if (key_value == (unsigned char *) NULL)
00798           (void) AppendValueToLinkedList(paths,ConstantString(path));
00799         else
00800           key_value=(unsigned char *) RelinquishMagickMemory(key_value);
00801       }
00802     if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
00803       {
00804         /*
00805           Search PerlMagick module path.
00806         */
00807         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
00808           DirectorySeparator);
00809         (void) AppendValueToLinkedList(paths,ConstantString(path));
00810         (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
00811           "\\inc\\lib\\auto\\Image\\Magick\\");
00812         (void) AppendValueToLinkedList(paths,ConstantString(path));
00813       }
00814   }
00815 #endif
00816   return(paths);
00817 }
00818 
00819 /*
00820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00821 %                                                                             %
00822 %                                                                             %
00823 %                                                                             %
00824 %   G e t C o n f i g u r e V a l u e                                         %
00825 %                                                                             %
00826 %                                                                             %
00827 %                                                                             %
00828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00829 %
00830 %  GetConfigureValue() returns the value associated with the configure info.
00831 %
00832 %  The format of the GetConfigureValue method is:
00833 %
00834 %      const char *GetConfigureValue(const ConfigureInfo *configure_info)
00835 %
00836 %  A description of each parameter follows:
00837 %
00838 %    o configure_info:  The configure info.
00839 %
00840 */
00841 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
00842 {
00843   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00844   assert(configure_info != (ConfigureInfo *) NULL);
00845   assert(configure_info->signature == MagickSignature);
00846   return(configure_info->value);
00847 }
00848 
00849 /*
00850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00851 %                                                                             %
00852 %                                                                             %
00853 %                                                                             %
00854 +   I n i t i a l i z e C o n f i g u r e L i s t                             %
00855 %                                                                             %
00856 %                                                                             %
00857 %                                                                             %
00858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00859 %
00860 %  InitializeConfigureList() initializes the configure list.
00861 %
00862 %  The format of the InitializeConfigureList method is:
00863 %
00864 %      MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
00865 %
00866 %  A description of each parameter follows.
00867 %
00868 %    o exception: return any errors or warnings in this structure.
00869 %
00870 */
00871 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
00872 {
00873   if ((configure_list == (LinkedListInfo *) NULL) &&
00874       (instantiate_configure == MagickFalse))
00875     {
00876       if (configure_semaphore == (SemaphoreInfo *) NULL)
00877         AcquireSemaphoreInfo(&configure_semaphore);
00878       LockSemaphoreInfo(configure_semaphore);
00879       if ((configure_list == (LinkedListInfo *) NULL) &&
00880           (instantiate_configure == MagickFalse))
00881         {
00882           (void) LoadConfigureLists(ConfigureFilename,exception);
00883           instantiate_configure=MagickTrue;
00884         }
00885       UnlockSemaphoreInfo(configure_semaphore);
00886     }
00887   return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
00888 }
00889 
00890 /*
00891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00892 %                                                                             %
00893 %                                                                             %
00894 %                                                                             %
00895 %  L i s t C o n f i g u r e I n f o                                          %
00896 %                                                                             %
00897 %                                                                             %
00898 %                                                                             %
00899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00900 %
00901 %  ListConfigureInfo() lists the configure info to a file.
00902 %
00903 %  The format of the ListConfigureInfo method is:
00904 %
00905 %      MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
00906 %
00907 %  A description of each parameter follows.
00908 %
00909 %    o file:  An pointer to a FILE.
00910 %
00911 %    o exception: return any errors or warnings in this structure.
00912 %
00913 */
00914 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
00915   ExceptionInfo *exception)
00916 {
00917   const char
00918     *name,
00919     *path,
00920     *value;
00921 
00922   const ConfigureInfo
00923     **configure_info;
00924 
00925   register ssize_t
00926     i;
00927 
00928   size_t
00929     number_options;
00930 
00931   ssize_t
00932     j;
00933 
00934   if (file == (const FILE *) NULL)
00935     file=stdout;
00936   configure_info=GetConfigureInfoList("*",&number_options,exception);
00937   if (configure_info == (const ConfigureInfo **) NULL)
00938     return(MagickFalse);
00939   path=(const char *) NULL;
00940   for (i=0; i < (ssize_t) number_options; i++)
00941   {
00942     if (configure_info[i]->stealth != MagickFalse)
00943       continue;
00944     if ((path == (const char *) NULL) ||
00945         (LocaleCompare(path,configure_info[i]->path) != 0))
00946       {
00947         if (configure_info[i]->path != (char *) NULL)
00948           (void) FormatLocaleFile(file,"\nPath: %s\n\n",
00949             configure_info[i]->path);
00950         (void) FormatLocaleFile(file,"Name          Value\n");
00951         (void) FormatLocaleFile(file,
00952           "-------------------------------------------------"
00953           "------------------------------\n");
00954       }
00955     path=configure_info[i]->path;
00956     name="unknown";
00957     if (configure_info[i]->name != (char *) NULL)
00958       name=configure_info[i]->name;
00959     (void) FormatLocaleFile(file,"%s",name);
00960     for (j=(ssize_t) strlen(name); j <= 12; j++)
00961       (void) FormatLocaleFile(file," ");
00962     (void) FormatLocaleFile(file," ");
00963     value="unknown";
00964     if (configure_info[i]->value != (char *) NULL)
00965       value=configure_info[i]->value;
00966     (void) FormatLocaleFile(file,"%s",value);
00967     (void) FormatLocaleFile(file,"\n");
00968   }
00969   (void) fflush(file);
00970   configure_info=(const ConfigureInfo **)
00971     RelinquishMagickMemory((void *) configure_info);
00972   return(MagickTrue);
00973 }
00974 
00975 /*
00976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00977 %                                                                             %
00978 %                                                                             %
00979 %                                                                             %
00980 +   L o a d C o n f i g u r e L i s t                                         %
00981 %                                                                             %
00982 %                                                                             %
00983 %                                                                             %
00984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00985 %
00986 %  LoadConfigureList() loads the configure configuration file which provides a
00987 %  mapping between configure attributes and a configure name.
00988 %
00989 %  The format of the LoadConfigureList method is:
00990 %
00991 %      MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
00992 %        const size_t depth,ExceptionInfo *exception)
00993 %
00994 %  A description of each parameter follows:
00995 %
00996 %    o xml:  The configure list in XML format.
00997 %
00998 %    o filename:  The configure list filename.
00999 %
01000 %    o depth: depth of <include /> statements.
01001 %
01002 %    o exception: return any errors or warnings in this structure.
01003 %
01004 */
01005 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
01006   const size_t depth,ExceptionInfo *exception)
01007 {
01008   char
01009     keyword[MaxTextExtent],
01010     *token;
01011 
01012   ConfigureInfo
01013     *configure_info;
01014 
01015   const char
01016     *q;
01017 
01018   MagickBooleanType
01019     status;
01020 
01021   /*
01022     Load the configure map file.
01023   */
01024   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
01025     "Loading configure file \"%s\" ...",filename);
01026   if (configure_list == (LinkedListInfo *) NULL)
01027     {
01028       configure_list=NewLinkedList(0);
01029       if (configure_list == (LinkedListInfo *) NULL)
01030         {
01031           ThrowFileException(exception,ResourceLimitError,
01032             "MemoryAllocationFailed",filename);
01033           return(MagickFalse);
01034         }
01035     }
01036   status=MagickTrue;
01037   configure_info=(ConfigureInfo *) NULL;
01038   token=AcquireString((char *) xml);
01039   for (q=(char *) xml; *q != '\0'; )
01040   {
01041     /*
01042       Interpret XML.
01043     */
01044     GetMagickToken(q,&q,token);
01045     if (*token == '\0')
01046       break;
01047     (void) CopyMagickString(keyword,token,MaxTextExtent);
01048     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
01049       {
01050         /*
01051           Doctype element.
01052         */
01053         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
01054           GetMagickToken(q,&q,token);
01055         continue;
01056       }
01057     if (LocaleNCompare(keyword,"<!--",4) == 0)
01058       {
01059         /*
01060           Comment element.
01061         */
01062         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
01063           GetMagickToken(q,&q,token);
01064         continue;
01065       }
01066     if (LocaleCompare(keyword,"<include") == 0)
01067       {
01068         /*
01069           Include element.
01070         */
01071         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
01072         {
01073           (void) CopyMagickString(keyword,token,MaxTextExtent);
01074           GetMagickToken(q,&q,token);
01075           if (*token != '=')
01076             continue;
01077           GetMagickToken(q,&q,token);
01078           if (LocaleCompare(keyword,"file") == 0)
01079             {
01080               if (depth > 200)
01081                 (void) ThrowMagickException(exception,GetMagickModule(),
01082                   ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
01083               else
01084                 {
01085                   char
01086                     path[MaxTextExtent],
01087                     *xml;
01088 
01089                   GetPathComponent(filename,HeadPath,path);
01090                   if (*path != '\0')
01091                     (void) ConcatenateMagickString(path,DirectorySeparator,
01092                       MaxTextExtent);
01093                   if (*token == *DirectorySeparator)
01094                     (void) CopyMagickString(path,token,MaxTextExtent);
01095                   else
01096                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
01097                   xml=FileToString(path,~0,exception);
01098                   if (xml != (char *) NULL)
01099                     {
01100                       status=LoadConfigureList(xml,path,depth+1,exception);
01101                       xml=(char *) RelinquishMagickMemory(xml);
01102                     }
01103                 }
01104             }
01105         }
01106         continue;
01107       }
01108     if (LocaleCompare(keyword,"<configure") == 0)
01109       {
01110         /*
01111           Configure element.
01112         */
01113         configure_info=(ConfigureInfo *) AcquireMagickMemory(
01114           sizeof(*configure_info));
01115         if (configure_info == (ConfigureInfo *) NULL)
01116           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01117         (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
01118         configure_info->path=ConstantString(filename);
01119         configure_info->exempt=MagickFalse;
01120         configure_info->signature=MagickSignature;
01121         continue;
01122       }
01123     if (configure_info == (ConfigureInfo *) NULL)
01124       continue;
01125     if (LocaleCompare(keyword,"/>") == 0)
01126       {
01127         status=AppendValueToLinkedList(configure_list,configure_info);
01128         if (status == MagickFalse)
01129           (void) ThrowMagickException(exception,GetMagickModule(),
01130             ResourceLimitError,"MemoryAllocationFailed","`%s'",
01131             configure_info->name);
01132         configure_info=(ConfigureInfo *) NULL;
01133       }
01134     /*
01135       Parse configure element.
01136     */
01137     GetMagickToken(q,(const char **) NULL,token);
01138     if (*token != '=')
01139       continue;
01140     GetMagickToken(q,&q,token);
01141     GetMagickToken(q,&q,token);
01142     switch (*keyword)
01143     {
01144       case 'N':
01145       case 'n':
01146       {
01147         if (LocaleCompare((char *) keyword,"name") == 0)
01148           {
01149             configure_info->name=ConstantString(token);
01150             break;
01151           }
01152         break;
01153       }
01154       case 'S':
01155       case 's':
01156       {
01157         if (LocaleCompare((char *) keyword,"stealth") == 0)
01158           {
01159             configure_info->stealth=IsMagickTrue(token);
01160             break;
01161           }
01162         break;
01163       }
01164       case 'V':
01165       case 'v':
01166       {
01167         if (LocaleCompare((char *) keyword,"value") == 0)
01168           {
01169             configure_info->value=ConstantString(token);
01170             break;
01171           }
01172         break;
01173       }
01174       default:
01175         break;
01176     }
01177   }
01178   token=(char *) RelinquishMagickMemory(token);
01179   return(status);
01180 }
01181 
01182 /*
01183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01184 %                                                                             %
01185 %                                                                             %
01186 %                                                                             %
01187 %  L o a d C o n f i g u r e L i s t s                                        %
01188 %                                                                             %
01189 %                                                                             %
01190 %                                                                             %
01191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01192 %
01193 %  LoadConfigureList() loads one or more configure configuration files which
01194 %  provides a mapping between configure attributes and a configure name.
01195 %
01196 %  The format of the LoadConfigureLists method is:
01197 %
01198 %      MagickBooleanType LoadConfigureLists(const char *filename,
01199 %        ExceptionInfo *exception)
01200 %
01201 %  A description of each parameter follows:
01202 %
01203 %    o filename: the font file name.
01204 %
01205 %    o exception: return any errors or warnings in this structure.
01206 %
01207 */
01208 static MagickBooleanType LoadConfigureLists(const char *filename,
01209   ExceptionInfo *exception)
01210 {
01211   const StringInfo
01212     *option;
01213 
01214   LinkedListInfo
01215     *options;
01216 
01217   MagickStatusType
01218     status;
01219 
01220   register ssize_t
01221     i;
01222 
01223   /*
01224     Load built-in configure map.
01225   */
01226   status=MagickFalse;
01227   if (configure_list == (LinkedListInfo *) NULL)
01228     {
01229       configure_list=NewLinkedList(0);
01230       if (configure_list == (LinkedListInfo *) NULL)
01231         {
01232           ThrowFileException(exception,ResourceLimitError,
01233             "MemoryAllocationFailed",filename);
01234           return(MagickFalse);
01235         }
01236     }
01237   for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
01238   {
01239     ConfigureInfo
01240       *configure_info;
01241 
01242     register const ConfigureMapInfo
01243       *p;
01244 
01245     p=ConfigureMap+i;
01246     configure_info=(ConfigureInfo *) AcquireMagickMemory(
01247       sizeof(*configure_info));
01248     if (configure_info == (ConfigureInfo *) NULL)
01249       {
01250         (void) ThrowMagickException(exception,GetMagickModule(),
01251           ResourceLimitError,"MemoryAllocationFailed","`%s'",
01252           configure_info->name);
01253         continue;
01254       }
01255     (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
01256     configure_info->path=(char *) "[built-in]";
01257     configure_info->name=(char *) p->name;
01258     configure_info->value=(char *) p->value;
01259     configure_info->exempt=MagickTrue;
01260     configure_info->signature=MagickSignature;
01261     status=AppendValueToLinkedList(configure_list,configure_info);
01262     if (status == MagickFalse)
01263       (void) ThrowMagickException(exception,GetMagickModule(),
01264         ResourceLimitError,"MemoryAllocationFailed","`%s'",
01265         configure_info->name);
01266   }
01267   /*
01268     Load external configure map.
01269   */
01270   options=GetConfigureOptions(filename,exception);
01271   option=(const StringInfo *) GetNextValueInLinkedList(options);
01272   while (option != (const StringInfo *) NULL)
01273   {
01274     status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
01275       GetStringInfoPath(option),0,exception);
01276     option=(const StringInfo *) GetNextValueInLinkedList(options);
01277   }
01278   options=DestroyConfigureOptions(options);
01279   return(status != 0 ? MagickTrue : MagickFalse);
01280 }