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-2011 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)
581 blob=(char *) NTResourceToBlob(filename);
582 if (blob != (char *) NULL)
584 xml=StringToStringInfo(blob);
585 SetStringInfoPath(xml,filename);
586 (void) AppendValueToLinkedList(options,xml);
587 blob=DestroyString(blob);
591 if (GetNumberOfElementsInLinkedList(options) == 0)
592 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
593 "UnableToOpenConfigureFile","`%s'",filename);
594 ResetLinkedListIterator(options);
599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 % G e t C o n f i g u r e P a t h s %
607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
609 % GetConfigurePaths() returns any Magick configuration paths associated
610 % with the specified filename.
612 % The format of the GetConfigurePaths method is:
614 % LinkedListInfo *GetConfigurePaths(const char *filename,
615 % ExceptionInfo *exception)
617 % A description of each parameter follows:
619 % o filename: the configure file name.
621 % o exception: return any errors or warnings in this structure.
624 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
625 ExceptionInfo *exception)
627 #define MagickCoreDLL "CORE_RL_MagickCore_.dll"
628 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
636 assert(filename != (const char *) NULL);
637 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
638 assert(exception != (ExceptionInfo *) NULL);
639 (void) CopyMagickString(path,filename,MaxTextExtent);
640 paths=NewLinkedList(0);
646 Search $MAGICK_CONFIGURE_PATH.
648 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
649 if (configure_path != (char *) NULL)
655 for (p=configure_path-1; p != (char *) NULL; )
657 (void) CopyMagickString(path,p+1,MaxTextExtent);
658 q=strchr(path,DirectoryListSeparator);
659 if (q != (char *) NULL)
661 q=path+strlen(path)-1;
662 if ((q >= path) && (*q != *DirectorySeparator))
663 (void) ConcatenateMagickString(path,DirectorySeparator,
665 (void) AppendValueToLinkedList(paths,ConstantString(path));
666 p=strchr(p+1,DirectoryListSeparator);
668 configure_path=DestroyString(configure_path);
671 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
672 #if defined(MAGICKCORE_SHARE_PATH)
673 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
675 #if defined(MAGICKCORE_SHAREARCH_PATH)
676 #if !defined(MAGICKCORE_SHARE_PATH)
677 (void) AppendValueToLinkedList(paths,ConstantString(
678 MAGICKCORE_SHAREARCH_PATH));
680 if (LocaleCompare(MAGICKCORE_SHARE_PATH,MAGICKCORE_SHAREARCH_PATH) != 0)
681 (void) AppendValueToLinkedList(paths,ConstantString(
682 MAGICKCORE_SHAREARCH_PATH));
685 #if defined(MAGICKCORE_CONFIGURE_PATH)
686 (void) AppendValueToLinkedList(paths,ConstantString(
687 MAGICKCORE_CONFIGURE_PATH));
689 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
690 (void) AppendValueToLinkedList(paths,ConstantString(
691 MAGICKCORE_DOCUMENTATION_PATH));
693 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
702 Locate file via registry key.
704 registry_key="ConfigurePath";
705 key_value=NTRegistryKeyLookup(registry_key);
706 if (key_value != (unsigned char *) NULL)
708 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
710 (void) AppendValueToLinkedList(paths,ConstantString(path));
711 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
721 Search under MAGICK_HOME.
723 home=GetEnvironmentValue("MAGICK_HOME");
724 if (home != (char *) NULL)
726 #if !defined(MAGICKCORE_POSIX_SUPPORT)
727 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
729 (void) AppendValueToLinkedList(paths,ConstantString(path));
731 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
732 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
733 (void) AppendValueToLinkedList(paths,ConstantString(path));
734 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
735 MAGICKCORE_SHARE_RELATIVE_PATH);
736 (void) AppendValueToLinkedList(paths,ConstantString(path));
738 home=DestroyString(home);
741 if (*GetClientPath() != '\0')
743 #if !defined(MAGICKCORE_POSIX_SUPPORT)
744 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
746 (void) AppendValueToLinkedList(paths,ConstantString(path));
749 prefix[MaxTextExtent];
752 Search based on executable directory if directory is known.
754 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
755 ChopPathComponents(prefix,1);
756 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
757 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
758 (void) AppendValueToLinkedList(paths,ConstantString(path));
759 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
760 MAGICKCORE_SHARE_RELATIVE_PATH);
761 (void) AppendValueToLinkedList(paths,ConstantString(path));
765 Search current directory.
767 (void) AppendValueToLinkedList(paths,ConstantString(""));
773 home=GetEnvironmentValue("HOME");
774 if (home == (char *) NULL)
775 home=GetEnvironmentValue("USERPROFILE");
776 if (home != (char *) NULL)
779 Search $HOME/.magick.
781 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
782 DirectorySeparator,DirectorySeparator);
783 (void) AppendValueToLinkedList(paths,ConstantString(path));
784 home=DestroyString(home);
787 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
790 module_path[MaxTextExtent];
792 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
793 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
801 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
803 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
804 if (element != (char *) NULL)
805 element=DestroyString(element);
806 (void) AppendValueToLinkedList(paths,ConstantString(path));
808 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
811 Search PerlMagick module path.
813 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
815 (void) AppendValueToLinkedList(paths,ConstantString(path));
816 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
817 "\\inc\\lib\\auto\\Image\\Magick\\");
818 (void) AppendValueToLinkedList(paths,ConstantString(path));
826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
830 % G e t C o n f i g u r e V a l u e %
834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836 % GetConfigureValue() returns the value associated with the configure info.
838 % The format of the GetConfigureValue method is:
840 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
842 % A description of each parameter follows:
844 % o configure_info: The configure info.
847 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
849 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
850 assert(configure_info != (ConfigureInfo *) NULL);
851 assert(configure_info->signature == MagickSignature);
852 return(configure_info->value);
856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860 + I n i t i a l i z e C o n f i g u r e L i s t %
864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866 % InitializeConfigureList() initializes the configure list.
868 % The format of the InitializeConfigureList method is:
870 % MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
872 % A description of each parameter follows.
874 % o exception: return any errors or warnings in this structure.
877 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
879 if ((configure_list == (LinkedListInfo *) NULL) &&
880 (instantiate_configure == MagickFalse))
882 if (configure_semaphore == (SemaphoreInfo *) NULL)
883 AcquireSemaphoreInfo(&configure_semaphore);
884 LockSemaphoreInfo(configure_semaphore);
885 if ((configure_list == (LinkedListInfo *) NULL) &&
886 (instantiate_configure == MagickFalse))
888 (void) LoadConfigureLists(ConfigureFilename,exception);
889 instantiate_configure=MagickTrue;
891 UnlockSemaphoreInfo(configure_semaphore);
893 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901 % L i s t C o n f i g u r e I n f o %
905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
907 % ListConfigureInfo() lists the configure info to a file.
909 % The format of the ListConfigureInfo method is:
911 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
913 % A description of each parameter follows.
915 % o file: An pointer to a FILE.
917 % o exception: return any errors or warnings in this structure.
920 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
921 ExceptionInfo *exception)
940 if (file == (const FILE *) NULL)
942 configure_info=GetConfigureInfoList("*",&number_options,exception);
943 if (configure_info == (const ConfigureInfo **) NULL)
945 path=(const char *) NULL;
946 for (i=0; i < (ssize_t) number_options; i++)
948 if (configure_info[i]->stealth != MagickFalse)
950 if ((path == (const char *) NULL) ||
951 (LocaleCompare(path,configure_info[i]->path) != 0))
953 if (configure_info[i]->path != (char *) NULL)
954 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
955 configure_info[i]->path);
956 (void) FormatLocaleFile(file,"Name Value\n");
957 (void) FormatLocaleFile(file,
958 "-------------------------------------------------"
959 "------------------------------\n");
961 path=configure_info[i]->path;
963 if (configure_info[i]->name != (char *) NULL)
964 name=configure_info[i]->name;
965 (void) FormatLocaleFile(file,"%s",name);
966 for (j=(ssize_t) strlen(name); j <= 12; j++)
967 (void) FormatLocaleFile(file," ");
968 (void) FormatLocaleFile(file," ");
970 if (configure_info[i]->value != (char *) NULL)
971 value=configure_info[i]->value;
972 (void) FormatLocaleFile(file,"%s",value);
973 (void) FormatLocaleFile(file,"\n");
976 configure_info=(const ConfigureInfo **)
977 RelinquishMagickMemory((void *) configure_info);
982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986 + L o a d C o n f i g u r e L i s t %
990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992 % LoadConfigureList() loads the configure configuration file which provides a
993 % mapping between configure attributes and a configure name.
995 % The format of the LoadConfigureList method is:
997 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
998 % const size_t depth,ExceptionInfo *exception)
1000 % A description of each parameter follows:
1002 % o xml: The configure list in XML format.
1004 % o filename: The configure list filename.
1006 % o depth: depth of <include /> statements.
1008 % o exception: return any errors or warnings in this structure.
1011 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1012 const size_t depth,ExceptionInfo *exception)
1015 keyword[MaxTextExtent],
1028 Load the configure map file.
1030 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1031 "Loading configure file \"%s\" ...",filename);
1032 if (configure_list == (LinkedListInfo *) NULL)
1034 configure_list=NewLinkedList(0);
1035 if (configure_list == (LinkedListInfo *) NULL)
1037 ThrowFileException(exception,ResourceLimitError,
1038 "MemoryAllocationFailed",filename);
1039 return(MagickFalse);
1043 configure_info=(ConfigureInfo *) NULL;
1044 token=AcquireString((char *) xml);
1045 for (q=(char *) xml; *q != '\0'; )
1050 GetMagickToken(q,&q,token);
1053 (void) CopyMagickString(keyword,token,MaxTextExtent);
1054 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1059 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1060 GetMagickToken(q,&q,token);
1063 if (LocaleNCompare(keyword,"<!--",4) == 0)
1068 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1069 GetMagickToken(q,&q,token);
1072 if (LocaleCompare(keyword,"<include") == 0)
1077 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1079 (void) CopyMagickString(keyword,token,MaxTextExtent);
1080 GetMagickToken(q,&q,token);
1083 GetMagickToken(q,&q,token);
1084 if (LocaleCompare(keyword,"file") == 0)
1087 (void) ThrowMagickException(exception,GetMagickModule(),
1088 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1092 path[MaxTextExtent],
1095 GetPathComponent(filename,HeadPath,path);
1097 (void) ConcatenateMagickString(path,DirectorySeparator,
1099 if (*token == *DirectorySeparator)
1100 (void) CopyMagickString(path,token,MaxTextExtent);
1102 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1103 xml=FileToString(path,~0,exception);
1104 if (xml != (char *) NULL)
1106 status=LoadConfigureList(xml,path,depth+1,exception);
1107 xml=(char *) RelinquishMagickMemory(xml);
1114 if (LocaleCompare(keyword,"<configure") == 0)
1119 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1120 sizeof(*configure_info));
1121 if (configure_info == (ConfigureInfo *) NULL)
1122 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1123 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1124 configure_info->path=ConstantString(filename);
1125 configure_info->exempt=MagickFalse;
1126 configure_info->signature=MagickSignature;
1129 if (configure_info == (ConfigureInfo *) NULL)
1131 if (LocaleCompare(keyword,"/>") == 0)
1133 status=AppendValueToLinkedList(configure_list,configure_info);
1134 if (status == MagickFalse)
1135 (void) ThrowMagickException(exception,GetMagickModule(),
1136 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1137 configure_info->name);
1138 configure_info=(ConfigureInfo *) NULL;
1141 Parse configure element.
1143 GetMagickToken(q,(const char **) NULL,token);
1146 GetMagickToken(q,&q,token);
1147 GetMagickToken(q,&q,token);
1153 if (LocaleCompare((char *) keyword,"name") == 0)
1155 configure_info->name=ConstantString(token);
1163 if (LocaleCompare((char *) keyword,"stealth") == 0)
1165 configure_info->stealth=IsMagickTrue(token);
1173 if (LocaleCompare((char *) keyword,"value") == 0)
1175 configure_info->value=ConstantString(token);
1184 token=(char *) RelinquishMagickMemory(token);
1189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1193 % L o a d C o n f i g u r e L i s t s %
1197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1199 % LoadConfigureList() loads one or more configure configuration files which
1200 % provides a mapping between configure attributes and a configure name.
1202 % The format of the LoadConfigureLists method is:
1204 % MagickBooleanType LoadConfigureLists(const char *filename,
1205 % ExceptionInfo *exception)
1207 % A description of each parameter follows:
1209 % o filename: the font file name.
1211 % o exception: return any errors or warnings in this structure.
1214 static MagickBooleanType LoadConfigureLists(const char *filename,
1215 ExceptionInfo *exception)
1230 Load built-in configure map.
1233 if (configure_list == (LinkedListInfo *) NULL)
1235 configure_list=NewLinkedList(0);
1236 if (configure_list == (LinkedListInfo *) NULL)
1238 ThrowFileException(exception,ResourceLimitError,
1239 "MemoryAllocationFailed",filename);
1240 return(MagickFalse);
1243 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1248 register const ConfigureMapInfo
1252 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1253 sizeof(*configure_info));
1254 if (configure_info == (ConfigureInfo *) NULL)
1256 (void) ThrowMagickException(exception,GetMagickModule(),
1257 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1258 configure_info->name);
1261 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1262 configure_info->path=(char *) "[built-in]";
1263 configure_info->name=(char *) p->name;
1264 configure_info->value=(char *) p->value;
1265 configure_info->exempt=MagickTrue;
1266 configure_info->signature=MagickSignature;
1267 status=AppendValueToLinkedList(configure_list,configure_info);
1268 if (status == MagickFalse)
1269 (void) ThrowMagickException(exception,GetMagickModule(),
1270 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1271 configure_info->name);
1274 Load external configure map.
1276 options=GetConfigureOptions(filename,exception);
1277 option=(const StringInfo *) GetNextValueInLinkedList(options);
1278 while (option != (const StringInfo *) NULL)
1280 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1281 GetStringInfoPath(option),0,exception);
1282 option=(const StringInfo *) GetNextValueInLinkedList(options);
1284 options=DestroyConfigureOptions(options);
1285 return(status != 0 ? MagickTrue : MagickFalse);