2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % CCCC OOO N N FFFFF IIIII GGGG U U RRRR EEEEE %
7 % C O O NN N F I G U U R R E %
8 % C O O N N N FFF I G GG U U RRRR EEE %
9 % C O O N NN F I G G U U R R E %
10 % CCCC OOO N N F IIIII GGG UUU R R EEEEE %
13 % MagickCore Image Configure Methods %
20 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/client.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/configure-private.h"
47 #include "MagickCore/exception.h"
48 #include "MagickCore/exception-private.h"
49 #include "MagickCore/hashmap.h"
50 #include "MagickCore/log.h"
51 #include "MagickCore/memory_.h"
52 #include "MagickCore/semaphore.h"
53 #include "MagickCore/string_.h"
54 #include "MagickCore/string-private.h"
55 #include "MagickCore/token.h"
56 #include "MagickCore/utility.h"
57 #include "MagickCore/utility-private.h"
58 #include "MagickCore/xml-tree.h"
63 #define ConfigureFilename "configure.xml"
68 typedef struct _ConfigureMapInfo
78 static const ConfigureMapInfo
81 { "NAME", "ImageMagick" }
85 *configure_list = (LinkedListInfo *) NULL;
88 *configure_semaphore = (SemaphoreInfo *) NULL;
90 static volatile MagickBooleanType
91 instantiate_configure = MagickFalse;
96 static MagickBooleanType
97 InitializeConfigureList(ExceptionInfo *),
98 LoadConfigureLists(const char *,ExceptionInfo *);
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
105 + 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 %
109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111 % ConfigureComponentGenesis() instantiates the configure component.
113 % The format of the ConfigureComponentGenesis method is:
115 % MagickBooleanType ConfigureComponentGenesis(void)
118 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
120 AcquireSemaphoreInfo(&configure_semaphore);
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129 + 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 %
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % ConfigureComponentTerminus() destroys the configure component.
137 % The format of the ConfigureComponentTerminus method is:
139 % ConfigureComponentTerminus(void)
143 static void *DestroyConfigureElement(void *configure_info)
145 register ConfigureInfo
148 p=(ConfigureInfo *) configure_info;
149 if (p->exempt == MagickFalse)
151 if (p->value != (char *) NULL)
152 p->value=DestroyString(p->value);
153 if (p->name != (char *) NULL)
154 p->name=DestroyString(p->name);
155 if (p->path != (char *) NULL)
156 p->path=DestroyString(p->path);
158 p=(ConfigureInfo *) RelinquishMagickMemory(p);
159 return((void *) NULL);
162 MagickPrivate void ConfigureComponentTerminus(void)
164 if (configure_semaphore == (SemaphoreInfo *) NULL)
165 AcquireSemaphoreInfo(&configure_semaphore);
166 LockSemaphoreInfo(configure_semaphore);
167 if (configure_list != (LinkedListInfo *) NULL)
168 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
169 configure_list=(LinkedListInfo *) NULL;
170 instantiate_configure=MagickFalse;
171 UnlockSemaphoreInfo(configure_semaphore);
172 DestroySemaphoreInfo(&configure_semaphore);
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 % D e s t r o y C o n f i g u r e O p t i o n s %
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 % DestroyConfigureOptions() releases memory associated with an configure
189 % The format of the DestroyProfiles method is:
191 % LinkedListInfo *DestroyConfigureOptions(Image *image)
193 % A description of each parameter follows:
195 % o image: the image.
199 static void *DestroyOptions(void *option)
201 return(DestroyStringInfo((StringInfo *) option));
204 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
206 assert(options != (LinkedListInfo *) NULL);
207 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
208 return(DestroyLinkedList(options,DestroyOptions));
212 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216 + G e t C o n f i g u r e I n f o %
220 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222 % GetConfigureInfo() searches the configure list for the specified name and if
223 % found returns attributes for that element.
225 % The format of the GetConfigureInfo method is:
227 % const ConfigureInfo *GetConfigureInfo(const char *name,
228 % ExceptionInfo *exception)
230 % A description of each parameter follows:
232 % o configure_info: GetConfigureInfo() searches the configure list for the
233 % specified name and if found returns attributes for that element.
235 % o name: the configure name.
237 % o exception: return any errors or warnings in this structure.
240 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
241 ExceptionInfo *exception)
243 register const ConfigureInfo
246 assert(exception != (ExceptionInfo *) NULL);
247 if ((configure_list == (LinkedListInfo *) NULL) ||
248 (instantiate_configure == MagickFalse))
249 if (InitializeConfigureList(exception) == MagickFalse)
250 return((const ConfigureInfo *) NULL);
251 if ((configure_list == (LinkedListInfo *) NULL) ||
252 (IsLinkedListEmpty(configure_list) != MagickFalse))
253 return((const ConfigureInfo *) NULL);
254 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
255 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
257 Search for configure tag.
259 LockSemaphoreInfo(configure_semaphore);
260 ResetLinkedListIterator(configure_list);
261 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
262 while (p != (const ConfigureInfo *) NULL)
264 if (LocaleCompare(name,p->name) == 0)
266 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
268 if (p != (ConfigureInfo *) NULL)
269 (void) InsertValueInLinkedList(configure_list,0,
270 RemoveElementByValueFromLinkedList(configure_list,p));
271 UnlockSemaphoreInfo(configure_semaphore);
276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280 % G e t C o n f i g u r e I n f o L i s t %
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286 % GetConfigureInfoList() returns any configure options that match the
289 % The format of the GetConfigureInfoList function is:
291 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
292 % size_t *number_options,ExceptionInfo *exception)
294 % A description of each parameter follows:
296 % o pattern: Specifies a pointer to a text string containing a pattern.
298 % o number_options: This integer returns the number of configure options in
301 % o exception: return any errors or warnings in this structure.
305 #if defined(__cplusplus) || defined(c_plusplus)
309 static int ConfigureInfoCompare(const void *x,const void *y)
315 p=(const ConfigureInfo **) x,
316 q=(const ConfigureInfo **) y;
317 if (LocaleCompare((*p)->path,(*q)->path) == 0)
318 return(LocaleCompare((*p)->name,(*q)->name));
319 return(LocaleCompare((*p)->path,(*q)->path));
322 #if defined(__cplusplus) || defined(c_plusplus)
326 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
327 size_t *number_options,ExceptionInfo *exception)
332 register const ConfigureInfo
339 Allocate configure list.
341 assert(pattern != (char *) NULL);
342 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
343 assert(number_options != (size_t *) NULL);
345 p=GetConfigureInfo("*",exception);
346 if (p == (const ConfigureInfo *) NULL)
347 return((const ConfigureInfo **) NULL);
348 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
349 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
350 if (options == (const ConfigureInfo **) NULL)
351 return((const ConfigureInfo **) NULL);
353 Generate configure list.
355 LockSemaphoreInfo(configure_semaphore);
356 ResetLinkedListIterator(configure_list);
357 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
358 for (i=0; p != (const ConfigureInfo *) NULL; )
360 if ((p->stealth == MagickFalse) &&
361 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
363 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
365 UnlockSemaphoreInfo(configure_semaphore);
366 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
367 options[i]=(ConfigureInfo *) NULL;
368 *number_options=(size_t) i;
373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377 % G e t C o n f i g u r e L i s t %
381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383 % GetConfigureList() returns any configure options that match the specified
386 % The format of the GetConfigureList function is:
388 % char **GetConfigureList(const char *pattern,
389 % size_t *number_options,ExceptionInfo *exception)
391 % A description of each parameter follows:
393 % o pattern: Specifies a pointer to a text string containing a pattern.
395 % o number_options: This integer returns the number of options in the list.
397 % o exception: return any errors or warnings in this structure.
401 #if defined(__cplusplus) || defined(c_plusplus)
405 static int ConfigureCompare(const void *x,const void *y)
413 return(LocaleCompare(*p,*q));
416 #if defined(__cplusplus) || defined(c_plusplus)
420 MagickExport char **GetConfigureList(const char *pattern,
421 size_t *number_options,ExceptionInfo *exception)
426 register const ConfigureInfo
433 Allocate configure list.
435 assert(pattern != (char *) NULL);
436 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
437 assert(number_options != (size_t *) NULL);
439 p=GetConfigureInfo("*",exception);
440 if (p == (const ConfigureInfo *) NULL)
441 return((char **) NULL);
442 options=(char **) AcquireQuantumMemory((size_t)
443 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
444 if (options == (char **) NULL)
445 return((char **) NULL);
446 LockSemaphoreInfo(configure_semaphore);
447 ResetLinkedListIterator(configure_list);
448 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
449 for (i=0; p != (const ConfigureInfo *) NULL; )
451 if ((p->stealth == MagickFalse) &&
452 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
453 options[i++]=ConstantString(p->name);
454 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
456 UnlockSemaphoreInfo(configure_semaphore);
457 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
458 options[i]=(char *) NULL;
459 *number_options=(size_t) i;
464 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468 % G e t C o n f i g u r e O p t i o n %
472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474 % GetConfigureOption() returns the value associated with the configure option.
476 % The format of the GetConfigureOption method is:
478 % char *GetConfigureOption(const char *option)
480 % A description of each parameter follows:
482 % o configure_info: The configure info.
485 MagickExport char *GetConfigureOption(const char *option)
496 assert(option != (const char *) NULL);
497 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
498 exception=AcquireExceptionInfo();
499 configure_info=GetConfigureInfo(option,exception);
500 exception=DestroyExceptionInfo(exception);
501 if (configure_info == (ConfigureInfo *) NULL)
502 return((char *) NULL);
503 value=GetConfigureValue(configure_info);
504 if ((value == (const char *) NULL) || (*value == '\0'))
505 return((char *) NULL);
506 return(ConstantString(value));
510 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 % G e t C o n f i g u r e O p t i o n s %
518 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
520 % GetConfigureOptions() returns any Magick configuration options associated
521 % with the specified filename.
523 % The format of the GetConfigureOptions method is:
525 % LinkedListInfo *GetConfigureOptions(const char *filename,
526 % ExceptionInfo *exception)
528 % A description of each parameter follows:
530 % o filename: the configure file name.
532 % o exception: return any errors or warnings in this structure.
535 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
536 ExceptionInfo *exception)
551 assert(filename != (const char *) NULL);
552 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
553 assert(exception != (ExceptionInfo *) NULL);
554 (void) CopyMagickString(path,filename,MaxTextExtent);
556 Load XML from configuration files to linked-list.
558 options=NewLinkedList(0);
559 paths=GetConfigurePaths(filename,exception);
560 if (paths != (LinkedListInfo *) NULL)
562 ResetLinkedListIterator(paths);
563 element=(const char *) GetNextValueInLinkedList(paths);
564 while (element != (const char *) NULL)
566 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
567 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
568 "Searching for configure file: \"%s\"",path);
569 xml=ConfigureFileToStringInfo(path);
570 if (xml != (StringInfo *) NULL)
571 (void) AppendValueToLinkedList(options,xml);
572 element=(const char *) GetNextValueInLinkedList(paths);
574 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
576 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
577 if (GetNumberOfElementsInLinkedList(options) == 0)
582 blob=(char *) NTResourceToBlob(filename);
583 if (blob != (char *) NULL)
585 xml=AcquireStringInfo(0);
586 SetStringInfoLength(xml,strlen(blob)+1);
587 SetStringInfoDatum(xml,blob);
588 SetStringInfoPath(xml,filename);
589 (void) AppendValueToLinkedList(options,xml);
593 if (GetNumberOfElementsInLinkedList(options) == 0)
594 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
595 "UnableToOpenConfigureFile","`%s'",filename);
596 ResetLinkedListIterator(options);
601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
605 % G e t C o n f i g u r e P a t h s %
609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 % GetConfigurePaths() returns any Magick configuration paths associated
612 % with the specified filename.
614 % The format of the GetConfigurePaths method is:
616 % LinkedListInfo *GetConfigurePaths(const char *filename,
617 % ExceptionInfo *exception)
619 % A description of each parameter follows:
621 % o filename: the configure file name.
623 % o exception: return any errors or warnings in this structure.
626 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
627 ExceptionInfo *exception)
629 #define RegistryKey "ConfigurePath"
630 #define MagickCoreDLL "CORE_RL_MagickCore_.dll"
631 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
639 assert(filename != (const char *) NULL);
640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
641 assert(exception != (ExceptionInfo *) NULL);
642 (void) CopyMagickString(path,filename,MaxTextExtent);
643 paths=NewLinkedList(0);
649 Search $MAGICK_CONFIGURE_PATH.
651 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
652 if (configure_path != (char *) NULL)
658 for (p=configure_path-1; p != (char *) NULL; )
660 (void) CopyMagickString(path,p+1,MaxTextExtent);
661 q=strchr(path,DirectoryListSeparator);
662 if (q != (char *) NULL)
664 q=path+strlen(path)-1;
665 if ((q >= path) && (*q != *DirectorySeparator))
666 (void) ConcatenateMagickString(path,DirectorySeparator,
668 (void) AppendValueToLinkedList(paths,ConstantString(path));
669 p=strchr(p+1,DirectoryListSeparator);
671 configure_path=DestroyString(configure_path);
674 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
675 #if defined(MAGICKCORE_SHARE_PATH)
676 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
678 #if defined(MAGICKCORE_SHAREARCH_PATH)
679 (void) AppendValueToLinkedList(paths,ConstantString(
680 MAGICKCORE_SHAREARCH_PATH));
682 #if defined(MAGICKCORE_CONFIGURE_PATH)
683 (void) AppendValueToLinkedList(paths,ConstantString(
684 MAGICKCORE_CONFIGURE_PATH));
686 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
687 (void) AppendValueToLinkedList(paths,ConstantString(
688 MAGICKCORE_DOCUMENTATION_PATH));
690 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
696 Locate file via registry key.
698 key_value=NTRegistryKeyLookup(RegistryKey);
699 if (key_value != (unsigned char *) NULL)
701 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
703 (void) AppendValueToLinkedList(paths,ConstantString(path));
704 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
714 Search under MAGICK_HOME.
716 home=GetEnvironmentValue("MAGICK_HOME");
717 if (home != (char *) NULL)
719 #if !defined(MAGICKCORE_POSIX_SUPPORT)
720 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
722 (void) AppendValueToLinkedList(paths,ConstantString(path));
724 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
725 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
726 (void) AppendValueToLinkedList(paths,ConstantString(path));
727 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
728 MAGICKCORE_SHARE_RELATIVE_PATH);
729 (void) AppendValueToLinkedList(paths,ConstantString(path));
731 home=DestroyString(home);
734 if (*GetClientPath() != '\0')
736 #if !defined(MAGICKCORE_POSIX_SUPPORT)
737 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
739 (void) AppendValueToLinkedList(paths,ConstantString(path));
742 prefix[MaxTextExtent];
745 Search based on executable directory if directory is known.
747 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
748 ChopPathComponents(prefix,1);
749 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
750 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
751 (void) AppendValueToLinkedList(paths,ConstantString(path));
752 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
753 MAGICKCORE_SHARE_RELATIVE_PATH);
754 (void) AppendValueToLinkedList(paths,ConstantString(path));
758 Search current directory.
760 (void) AppendValueToLinkedList(paths,ConstantString(""));
766 home=GetEnvironmentValue("HOME");
767 if (home == (char *) NULL)
768 home=GetEnvironmentValue("USERPROFILE");
769 if (home != (char *) NULL)
772 Search $HOME/.magick.
774 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
775 DirectorySeparator,DirectorySeparator);
776 (void) AppendValueToLinkedList(paths,ConstantString(path));
777 home=DestroyString(home);
780 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
783 module_path[MaxTextExtent];
785 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
786 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
794 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
796 key_value=NTRegistryKeyLookup(RegistryKey);
797 if (key_value == (unsigned char *) NULL)
798 (void) AppendValueToLinkedList(paths,ConstantString(path));
800 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
802 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
805 Search PerlMagick module path.
807 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
809 (void) AppendValueToLinkedList(paths,ConstantString(path));
810 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
811 "\\inc\\lib\\auto\\Image\\Magick\\");
812 (void) AppendValueToLinkedList(paths,ConstantString(path));
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 % G e t C o n f i g u r e V a l u e %
828 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 % GetConfigureValue() returns the value associated with the configure info.
832 % The format of the GetConfigureValue method is:
834 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
836 % A description of each parameter follows:
838 % o configure_info: The configure info.
841 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
843 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
844 assert(configure_info != (ConfigureInfo *) NULL);
845 assert(configure_info->signature == MagickSignature);
846 return(configure_info->value);
850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
854 + I n i t i a l i z e C o n f i g u r e L i s t %
858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860 % InitializeConfigureList() initializes the configure list.
862 % The format of the InitializeConfigureList method is:
864 % MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
866 % A description of each parameter follows.
868 % o exception: return any errors or warnings in this structure.
871 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
873 if ((configure_list == (LinkedListInfo *) NULL) &&
874 (instantiate_configure == MagickFalse))
876 if (configure_semaphore == (SemaphoreInfo *) NULL)
877 AcquireSemaphoreInfo(&configure_semaphore);
878 LockSemaphoreInfo(configure_semaphore);
879 if ((configure_list == (LinkedListInfo *) NULL) &&
880 (instantiate_configure == MagickFalse))
882 (void) LoadConfigureLists(ConfigureFilename,exception);
883 instantiate_configure=MagickTrue;
885 UnlockSemaphoreInfo(configure_semaphore);
887 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895 % L i s t C o n f i g u r e I n f o %
899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901 % ListConfigureInfo() lists the configure info to a file.
903 % The format of the ListConfigureInfo method is:
905 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
907 % A description of each parameter follows.
909 % o file: An pointer to a FILE.
911 % o exception: return any errors or warnings in this structure.
914 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
915 ExceptionInfo *exception)
934 if (file == (const FILE *) NULL)
936 configure_info=GetConfigureInfoList("*",&number_options,exception);
937 if (configure_info == (const ConfigureInfo **) NULL)
939 path=(const char *) NULL;
940 for (i=0; i < (ssize_t) number_options; i++)
942 if (configure_info[i]->stealth != MagickFalse)
944 if ((path == (const char *) NULL) ||
945 (LocaleCompare(path,configure_info[i]->path) != 0))
947 if (configure_info[i]->path != (char *) NULL)
948 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
949 configure_info[i]->path);
950 (void) FormatLocaleFile(file,"Name Value\n");
951 (void) FormatLocaleFile(file,
952 "-------------------------------------------------"
953 "------------------------------\n");
955 path=configure_info[i]->path;
957 if (configure_info[i]->name != (char *) NULL)
958 name=configure_info[i]->name;
959 (void) FormatLocaleFile(file,"%s",name);
960 for (j=(ssize_t) strlen(name); j <= 12; j++)
961 (void) FormatLocaleFile(file," ");
962 (void) FormatLocaleFile(file," ");
964 if (configure_info[i]->value != (char *) NULL)
965 value=configure_info[i]->value;
966 (void) FormatLocaleFile(file,"%s",value);
967 (void) FormatLocaleFile(file,"\n");
970 configure_info=(const ConfigureInfo **)
971 RelinquishMagickMemory((void *) configure_info);
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980 + L o a d C o n f i g u r e L i s t %
984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986 % LoadConfigureList() loads the configure configuration file which provides a
987 % mapping between configure attributes and a configure name.
989 % The format of the LoadConfigureList method is:
991 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
992 % const size_t depth,ExceptionInfo *exception)
994 % A description of each parameter follows:
996 % o xml: The configure list in XML format.
998 % o filename: The configure list filename.
1000 % o depth: depth of <include /> statements.
1002 % o exception: return any errors or warnings in this structure.
1005 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1006 const size_t depth,ExceptionInfo *exception)
1009 keyword[MaxTextExtent],
1022 Load the configure map file.
1024 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1025 "Loading configure file \"%s\" ...",filename);
1026 if (configure_list == (LinkedListInfo *) NULL)
1028 configure_list=NewLinkedList(0);
1029 if (configure_list == (LinkedListInfo *) NULL)
1031 ThrowFileException(exception,ResourceLimitError,
1032 "MemoryAllocationFailed",filename);
1033 return(MagickFalse);
1037 configure_info=(ConfigureInfo *) NULL;
1038 token=AcquireString((char *) xml);
1039 for (q=(char *) xml; *q != '\0'; )
1044 GetMagickToken(q,&q,token);
1047 (void) CopyMagickString(keyword,token,MaxTextExtent);
1048 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1053 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1054 GetMagickToken(q,&q,token);
1057 if (LocaleNCompare(keyword,"<!--",4) == 0)
1062 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1063 GetMagickToken(q,&q,token);
1066 if (LocaleCompare(keyword,"<include") == 0)
1071 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1073 (void) CopyMagickString(keyword,token,MaxTextExtent);
1074 GetMagickToken(q,&q,token);
1077 GetMagickToken(q,&q,token);
1078 if (LocaleCompare(keyword,"file") == 0)
1081 (void) ThrowMagickException(exception,GetMagickModule(),
1082 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1086 path[MaxTextExtent],
1089 GetPathComponent(filename,HeadPath,path);
1091 (void) ConcatenateMagickString(path,DirectorySeparator,
1093 if (*token == *DirectorySeparator)
1094 (void) CopyMagickString(path,token,MaxTextExtent);
1096 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1097 xml=FileToString(path,~0,exception);
1098 if (xml != (char *) NULL)
1100 status=LoadConfigureList(xml,path,depth+1,exception);
1101 xml=(char *) RelinquishMagickMemory(xml);
1108 if (LocaleCompare(keyword,"<configure") == 0)
1113 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1114 sizeof(*configure_info));
1115 if (configure_info == (ConfigureInfo *) NULL)
1116 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1117 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1118 configure_info->path=ConstantString(filename);
1119 configure_info->exempt=MagickFalse;
1120 configure_info->signature=MagickSignature;
1123 if (configure_info == (ConfigureInfo *) NULL)
1125 if (LocaleCompare(keyword,"/>") == 0)
1127 status=AppendValueToLinkedList(configure_list,configure_info);
1128 if (status == MagickFalse)
1129 (void) ThrowMagickException(exception,GetMagickModule(),
1130 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1131 configure_info->name);
1132 configure_info=(ConfigureInfo *) NULL;
1135 Parse configure element.
1137 GetMagickToken(q,(const char **) NULL,token);
1140 GetMagickToken(q,&q,token);
1141 GetMagickToken(q,&q,token);
1147 if (LocaleCompare((char *) keyword,"name") == 0)
1149 configure_info->name=ConstantString(token);
1157 if (LocaleCompare((char *) keyword,"stealth") == 0)
1159 configure_info->stealth=IsMagickTrue(token);
1167 if (LocaleCompare((char *) keyword,"value") == 0)
1169 configure_info->value=ConstantString(token);
1178 token=(char *) RelinquishMagickMemory(token);
1183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1187 % L o a d C o n f i g u r e L i s t s %
1191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 % LoadConfigureList() loads one or more configure configuration files which
1194 % provides a mapping between configure attributes and a configure name.
1196 % The format of the LoadConfigureLists method is:
1198 % MagickBooleanType LoadConfigureLists(const char *filename,
1199 % ExceptionInfo *exception)
1201 % A description of each parameter follows:
1203 % o filename: the font file name.
1205 % o exception: return any errors or warnings in this structure.
1208 static MagickBooleanType LoadConfigureLists(const char *filename,
1209 ExceptionInfo *exception)
1224 Load built-in configure map.
1227 if (configure_list == (LinkedListInfo *) NULL)
1229 configure_list=NewLinkedList(0);
1230 if (configure_list == (LinkedListInfo *) NULL)
1232 ThrowFileException(exception,ResourceLimitError,
1233 "MemoryAllocationFailed",filename);
1234 return(MagickFalse);
1237 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1242 register const ConfigureMapInfo
1246 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1247 sizeof(*configure_info));
1248 if (configure_info == (ConfigureInfo *) NULL)
1250 (void) ThrowMagickException(exception,GetMagickModule(),
1251 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1252 configure_info->name);
1255 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1256 configure_info->path=(char *) "[built-in]";
1257 configure_info->name=(char *) p->name;
1258 configure_info->value=(char *) p->value;
1259 configure_info->exempt=MagickTrue;
1260 configure_info->signature=MagickSignature;
1261 status=AppendValueToLinkedList(configure_list,configure_info);
1262 if (status == MagickFalse)
1263 (void) ThrowMagickException(exception,GetMagickModule(),
1264 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1265 configure_info->name);
1268 Load external configure map.
1270 options=GetConfigureOptions(filename,exception);
1271 option=(const StringInfo *) GetNextValueInLinkedList(options);
1272 while (option != (const StringInfo *) NULL)
1274 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1275 GetStringInfoPath(option),0,exception);
1276 option=(const StringInfo *) GetNextValueInLinkedList(options);
1278 options=DestroyConfigureOptions(options);
1279 return(status != 0 ? MagickTrue : MagickFalse);