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-2014 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"
66 #define MAGICKCORE_FEATURE_OPENMP_STR "OpenMP "
68 #define MAGICKCORE_FEATURE_OPENMP_STR ""
71 #define MAGICKCORE_FEATURE_OPENCL_STR "OpenCL "
73 #define MAGICKCORE_FEATURE_OPENCL_STR ""
75 #ifdef MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
76 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR "Zero-Configuration "
78 #define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR ""
81 #define MAGICKCORE_FEATURE_HDRI_STR "HDRI"
83 #define MAGICKCORE_FEATURE_HDRI_STR ""
86 #define MAGICKCORE_FEATURES_STR MAGICKCORE_FEATURE_OPENMP_STR MAGICKCORE_FEATURE_OPENCL_STR MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR MAGICKCORE_FEATURE_HDRI_STR
91 typedef struct _ConfigureMapInfo
101 static const ConfigureMapInfo
104 { "NAME", "ImageMagick" },
105 { "QuantumDepth", MAGICKCORE_STRING_XQUOTE(MAGICKCORE_QUANTUM_DEPTH) } ,
106 { "FEATURES", MAGICKCORE_FEATURES_STR }
109 static LinkedListInfo
110 *configure_list = (LinkedListInfo *) NULL;
113 *configure_semaphore = (SemaphoreInfo *) NULL;
115 static volatile MagickBooleanType
116 instantiate_configure = MagickFalse;
119 Forward declarations.
121 static MagickBooleanType
122 InitializeConfigureList(ExceptionInfo *),
123 LoadConfigureLists(const char *,ExceptionInfo *);
126 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 + 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 %
134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 % ConfigureComponentGenesis() instantiates the configure component.
138 % The format of the ConfigureComponentGenesis method is:
140 % MagickBooleanType ConfigureComponentGenesis(void)
143 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
145 AcquireSemaphoreInfo(&configure_semaphore);
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 + 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 %
158 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
160 % ConfigureComponentTerminus() destroys the configure component.
162 % The format of the ConfigureComponentTerminus method is:
164 % ConfigureComponentTerminus(void)
168 static void *DestroyConfigureElement(void *configure_info)
170 register ConfigureInfo
173 p=(ConfigureInfo *) configure_info;
174 if (p->exempt == MagickFalse)
176 if (p->value != (char *) NULL)
177 p->value=DestroyString(p->value);
178 if (p->name != (char *) NULL)
179 p->name=DestroyString(p->name);
180 if (p->path != (char *) NULL)
181 p->path=DestroyString(p->path);
183 p=(ConfigureInfo *) RelinquishMagickMemory(p);
184 return((void *) NULL);
187 MagickPrivate void ConfigureComponentTerminus(void)
189 if (configure_semaphore == (SemaphoreInfo *) NULL)
190 AcquireSemaphoreInfo(&configure_semaphore);
191 LockSemaphoreInfo(configure_semaphore);
192 if (configure_list != (LinkedListInfo *) NULL)
193 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
194 configure_list=(LinkedListInfo *) NULL;
195 instantiate_configure=MagickFalse;
196 UnlockSemaphoreInfo(configure_semaphore);
197 DestroySemaphoreInfo(&configure_semaphore);
201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205 % D e s t r o y C o n f i g u r e O p t i o n s %
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
211 % DestroyConfigureOptions() releases memory associated with an configure
214 % The format of the DestroyProfiles method is:
216 % LinkedListInfo *DestroyConfigureOptions(Image *image)
218 % A description of each parameter follows:
220 % o image: the image.
224 static void *DestroyOptions(void *option)
226 return(DestroyStringInfo((StringInfo *) option));
229 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
231 assert(options != (LinkedListInfo *) NULL);
232 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
233 return(DestroyLinkedList(options,DestroyOptions));
237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241 + G e t C o n f i g u r e I n f o %
245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
247 % GetConfigureInfo() searches the configure list for the specified name and if
248 % found returns attributes for that element.
250 % The format of the GetConfigureInfo method is:
252 % const ConfigureInfo *GetConfigureInfo(const char *name,
253 % ExceptionInfo *exception)
255 % A description of each parameter follows:
257 % o configure_info: GetConfigureInfo() searches the configure list for the
258 % specified name and if found returns attributes for that element.
260 % o name: the configure name.
262 % o exception: return any errors or warnings in this structure.
265 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
266 ExceptionInfo *exception)
268 register const ConfigureInfo
271 assert(exception != (ExceptionInfo *) NULL);
272 if ((configure_list == (LinkedListInfo *) NULL) ||
273 (instantiate_configure == MagickFalse))
274 if (InitializeConfigureList(exception) == MagickFalse)
275 return((const ConfigureInfo *) NULL);
276 if ((configure_list == (LinkedListInfo *) NULL) ||
277 (IsLinkedListEmpty(configure_list) != MagickFalse))
278 return((const ConfigureInfo *) NULL);
279 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
280 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
282 Search for configure tag.
284 LockSemaphoreInfo(configure_semaphore);
285 ResetLinkedListIterator(configure_list);
286 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
287 while (p != (const ConfigureInfo *) NULL)
289 if (LocaleCompare(name,p->name) == 0)
291 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
293 if (p != (ConfigureInfo *) NULL)
294 (void) InsertValueInLinkedList(configure_list,0,
295 RemoveElementByValueFromLinkedList(configure_list,p));
296 UnlockSemaphoreInfo(configure_semaphore);
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305 % G e t C o n f i g u r e I n f o L i s t %
309 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 % GetConfigureInfoList() returns any configure options that match the
314 % The format of the GetConfigureInfoList function is:
316 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
317 % size_t *number_options,ExceptionInfo *exception)
319 % A description of each parameter follows:
321 % o pattern: Specifies a pointer to a text string containing a pattern.
323 % o number_options: This integer returns the number of configure options in
326 % o exception: return any errors or warnings in this structure.
330 #if defined(__cplusplus) || defined(c_plusplus)
334 static int ConfigureInfoCompare(const void *x,const void *y)
340 p=(const ConfigureInfo **) x,
341 q=(const ConfigureInfo **) y;
342 if (LocaleCompare((*p)->path,(*q)->path) == 0)
343 return(LocaleCompare((*p)->name,(*q)->name));
344 return(LocaleCompare((*p)->path,(*q)->path));
347 #if defined(__cplusplus) || defined(c_plusplus)
351 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
352 size_t *number_options,ExceptionInfo *exception)
357 register const ConfigureInfo
364 Allocate configure list.
366 assert(pattern != (char *) NULL);
367 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
368 assert(number_options != (size_t *) NULL);
370 p=GetConfigureInfo("*",exception);
371 if (p == (const ConfigureInfo *) NULL)
372 return((const ConfigureInfo **) NULL);
373 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
374 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
375 if (options == (const ConfigureInfo **) NULL)
376 return((const ConfigureInfo **) NULL);
378 Generate configure list.
380 LockSemaphoreInfo(configure_semaphore);
381 ResetLinkedListIterator(configure_list);
382 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
383 for (i=0; p != (const ConfigureInfo *) NULL; )
385 if ((p->stealth == MagickFalse) &&
386 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
388 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
390 UnlockSemaphoreInfo(configure_semaphore);
391 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
392 options[i]=(ConfigureInfo *) NULL;
393 *number_options=(size_t) i;
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402 % G e t C o n f i g u r e L i s t %
406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 % GetConfigureList() returns any configure options that match the specified
411 % The format of the GetConfigureList function is:
413 % char **GetConfigureList(const char *pattern,
414 % size_t *number_options,ExceptionInfo *exception)
416 % A description of each parameter follows:
418 % o pattern: Specifies a pointer to a text string containing a pattern.
420 % o number_options: This integer returns the number of options in the list.
422 % o exception: return any errors or warnings in this structure.
426 #if defined(__cplusplus) || defined(c_plusplus)
430 static int ConfigureCompare(const void *x,const void *y)
438 return(LocaleCompare(*p,*q));
441 #if defined(__cplusplus) || defined(c_plusplus)
445 MagickExport char **GetConfigureList(const char *pattern,
446 size_t *number_options,ExceptionInfo *exception)
451 register const ConfigureInfo
458 Allocate configure list.
460 assert(pattern != (char *) NULL);
461 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
462 assert(number_options != (size_t *) NULL);
464 p=GetConfigureInfo("*",exception);
465 if (p == (const ConfigureInfo *) NULL)
466 return((char **) NULL);
467 options=(char **) AcquireQuantumMemory((size_t)
468 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
469 if (options == (char **) NULL)
470 return((char **) NULL);
471 LockSemaphoreInfo(configure_semaphore);
472 ResetLinkedListIterator(configure_list);
473 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
474 for (i=0; p != (const ConfigureInfo *) NULL; )
476 if ((p->stealth == MagickFalse) &&
477 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
478 options[i++]=ConstantString(p->name);
479 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
481 UnlockSemaphoreInfo(configure_semaphore);
482 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
483 options[i]=(char *) NULL;
484 *number_options=(size_t) i;
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 % G e t C o n f i g u r e O p t i o n %
497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 % GetConfigureOption() returns the value associated with the configure option.
501 % The format of the GetConfigureOption method is:
503 % char *GetConfigureOption(const char *option)
505 % A description of each parameter follows:
507 % o configure_info: The configure info.
510 MagickExport char *GetConfigureOption(const char *option)
521 assert(option != (const char *) NULL);
522 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
523 exception=AcquireExceptionInfo();
524 configure_info=GetConfigureInfo(option,exception);
525 exception=DestroyExceptionInfo(exception);
526 if (configure_info == (ConfigureInfo *) NULL)
527 return((char *) NULL);
528 value=GetConfigureValue(configure_info);
529 if ((value == (const char *) NULL) || (*value == '\0'))
530 return((char *) NULL);
531 return(ConstantString(value));
535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
539 % G e t C o n f i g u r e O p t i o n s %
543 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545 % GetConfigureOptions() returns any Magick configuration options associated
546 % with the specified filename.
548 % The format of the GetConfigureOptions method is:
550 % LinkedListInfo *GetConfigureOptions(const char *filename,
551 % ExceptionInfo *exception)
553 % A description of each parameter follows:
555 % o filename: the configure file name.
557 % o exception: return any errors or warnings in this structure.
560 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
561 ExceptionInfo *exception)
576 assert(filename != (const char *) NULL);
577 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
578 assert(exception != (ExceptionInfo *) NULL);
579 (void) CopyMagickString(path,filename,MaxTextExtent);
581 Load XML from configuration files to linked-list.
583 options=NewLinkedList(0);
584 paths=GetConfigurePaths(filename,exception);
585 if (paths != (LinkedListInfo *) NULL)
587 ResetLinkedListIterator(paths);
588 element=(const char *) GetNextValueInLinkedList(paths);
589 while (element != (const char *) NULL)
591 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
592 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
593 "Searching for configure file: \"%s\"",path);
594 xml=ConfigureFileToStringInfo(path);
595 if (xml != (StringInfo *) NULL)
596 (void) AppendValueToLinkedList(options,xml);
597 element=(const char *) GetNextValueInLinkedList(paths);
599 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
601 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
602 if (GetNumberOfElementsInLinkedList(options) == 0)
607 blob=(char *) NTResourceToBlob(filename);
608 if (blob != (char *) NULL)
610 xml=AcquireStringInfo(0);
611 SetStringInfoLength(xml,strlen(blob)+1);
612 SetStringInfoDatum(xml,(unsigned char *) blob);
613 SetStringInfoPath(xml,filename);
614 (void) AppendValueToLinkedList(options,xml);
618 if (GetNumberOfElementsInLinkedList(options) == 0)
619 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
620 "UnableToOpenConfigureFile","`%s'",filename);
621 ResetLinkedListIterator(options);
626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630 % G e t C o n f i g u r e P a t h s %
634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636 % GetConfigurePaths() returns any Magick configuration paths associated
637 % with the specified filename.
639 % The format of the GetConfigurePaths method is:
641 % LinkedListInfo *GetConfigurePaths(const char *filename,
642 % ExceptionInfo *exception)
644 % A description of each parameter follows:
646 % o filename: the configure file name.
648 % o exception: return any errors or warnings in this structure.
651 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
652 ExceptionInfo *exception)
654 #define RegistryKey "ConfigurePath"
655 #define MagickCoreDLL "CORE_RL_MagickCore_.dll"
656 #define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll"
664 assert(filename != (const char *) NULL);
665 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
666 assert(exception != (ExceptionInfo *) NULL);
667 (void) CopyMagickString(path,filename,MaxTextExtent);
668 paths=NewLinkedList(0);
674 Search $MAGICK_CONFIGURE_PATH.
676 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
677 if (configure_path != (char *) NULL)
683 for (p=configure_path-1; p != (char *) NULL; )
685 (void) CopyMagickString(path,p+1,MaxTextExtent);
686 q=strchr(path,DirectoryListSeparator);
687 if (q != (char *) NULL)
689 q=path+strlen(path)-1;
690 if ((q >= path) && (*q != *DirectorySeparator))
691 (void) ConcatenateMagickString(path,DirectorySeparator,
693 (void) AppendValueToLinkedList(paths,ConstantString(path));
694 p=strchr(p+1,DirectoryListSeparator);
696 configure_path=DestroyString(configure_path);
699 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
700 #if defined(MAGICKCORE_SHARE_PATH)
701 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
703 #if defined(MAGICKCORE_SHAREARCH_PATH)
704 (void) AppendValueToLinkedList(paths,ConstantString(
705 MAGICKCORE_SHAREARCH_PATH));
707 #if defined(MAGICKCORE_CONFIGURE_PATH)
708 (void) AppendValueToLinkedList(paths,ConstantString(
709 MAGICKCORE_CONFIGURE_PATH));
711 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
712 (void) AppendValueToLinkedList(paths,ConstantString(
713 MAGICKCORE_DOCUMENTATION_PATH));
715 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
721 Locate file via registry key.
723 key_value=NTRegistryKeyLookup(RegistryKey);
724 if (key_value != (unsigned char *) NULL)
726 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
728 (void) AppendValueToLinkedList(paths,ConstantString(path));
729 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
739 Search under MAGICK_HOME.
741 home=GetEnvironmentValue("MAGICK_HOME");
742 if (home != (char *) NULL)
744 #if !defined(MAGICKCORE_POSIX_SUPPORT)
745 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
747 (void) AppendValueToLinkedList(paths,ConstantString(path));
749 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
750 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
751 (void) AppendValueToLinkedList(paths,ConstantString(path));
752 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
753 MAGICKCORE_SHARE_RELATIVE_PATH);
754 (void) AppendValueToLinkedList(paths,ConstantString(path));
755 (void) FormatLocaleString(path,MaxTextExtent,"%s",
756 MAGICKCORE_SHAREARCH_PATH);
757 (void) AppendValueToLinkedList(paths,ConstantString(path));
759 home=DestroyString(home);
762 if (*GetClientPath() != '\0')
764 #if !defined(MAGICKCORE_POSIX_SUPPORT)
765 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
767 (void) AppendValueToLinkedList(paths,ConstantString(path));
770 prefix[MaxTextExtent];
773 Search based on executable directory if directory is known.
775 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
776 ChopPathComponents(prefix,1);
777 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
778 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
779 (void) AppendValueToLinkedList(paths,ConstantString(path));
780 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
781 MAGICKCORE_SHARE_RELATIVE_PATH);
782 (void) AppendValueToLinkedList(paths,ConstantString(path));
783 (void) FormatLocaleString(path,MaxTextExtent,"%s",
784 MAGICKCORE_SHAREARCH_PATH);
785 (void) AppendValueToLinkedList(paths,ConstantString(path));
789 Search current directory.
791 (void) AppendValueToLinkedList(paths,ConstantString(""));
797 home=GetEnvironmentValue("HOME");
798 if (home == (char *) NULL)
799 home=GetEnvironmentValue("USERPROFILE");
800 if (home != (char *) NULL)
803 Search $HOME/.config/ImageMagick.
805 (void) FormatLocaleString(path,MaxTextExtent,
806 "%s%s.config%sImageMagick%s",home,DirectorySeparator,
807 DirectorySeparator,DirectorySeparator);
808 (void) AppendValueToLinkedList(paths,ConstantString(path));
809 home=DestroyString(home);
812 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
815 module_path[MaxTextExtent];
817 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) ||
818 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse))
826 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
828 key_value=NTRegistryKeyLookup(RegistryKey);
829 if (key_value == (unsigned char *) NULL)
830 (void) AppendValueToLinkedList(paths,ConstantString(path));
832 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
834 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
837 Search PerlMagick module path.
839 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
841 (void) AppendValueToLinkedList(paths,ConstantString(path));
842 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
843 "\\inc\\lib\\auto\\Image\\Magick\\");
844 (void) AppendValueToLinkedList(paths,ConstantString(path));
852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 % G e t C o n f i g u r e V a l u e %
860 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
862 % GetConfigureValue() returns the value associated with the configure info.
864 % The format of the GetConfigureValue method is:
866 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
868 % A description of each parameter follows:
870 % o configure_info: The configure info.
873 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
875 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
876 assert(configure_info != (ConfigureInfo *) NULL);
877 assert(configure_info->signature == MagickSignature);
878 return(configure_info->value);
882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886 + I n i t i a l i z e C o n f i g u r e L i s t %
890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892 % InitializeConfigureList() initializes the configure list.
894 % The format of the InitializeConfigureList method is:
896 % MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
898 % A description of each parameter follows.
900 % o exception: return any errors or warnings in this structure.
903 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
905 if ((configure_list == (LinkedListInfo *) NULL) &&
906 (instantiate_configure == MagickFalse))
908 if (configure_semaphore == (SemaphoreInfo *) NULL)
909 AcquireSemaphoreInfo(&configure_semaphore);
910 LockSemaphoreInfo(configure_semaphore);
911 if ((configure_list == (LinkedListInfo *) NULL) &&
912 (instantiate_configure == MagickFalse))
914 (void) LoadConfigureLists(ConfigureFilename,exception);
915 instantiate_configure=MagickTrue;
917 UnlockSemaphoreInfo(configure_semaphore);
919 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
927 % L i s t C o n f i g u r e I n f o %
931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
933 % ListConfigureInfo() lists the configure info to a file.
935 % The format of the ListConfigureInfo method is:
937 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
939 % A description of each parameter follows.
941 % o file: An pointer to a FILE.
943 % o exception: return any errors or warnings in this structure.
946 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
947 ExceptionInfo *exception)
966 if (file == (const FILE *) NULL)
968 configure_info=GetConfigureInfoList("*",&number_options,exception);
969 if (configure_info == (const ConfigureInfo **) NULL)
971 path=(const char *) NULL;
972 for (i=0; i < (ssize_t) number_options; i++)
974 if (configure_info[i]->stealth != MagickFalse)
976 if ((path == (const char *) NULL) ||
977 (LocaleCompare(path,configure_info[i]->path) != 0))
979 if (configure_info[i]->path != (char *) NULL)
980 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
981 configure_info[i]->path);
982 (void) FormatLocaleFile(file,"Name Value\n");
983 (void) FormatLocaleFile(file,
984 "-------------------------------------------------"
985 "------------------------------\n");
987 path=configure_info[i]->path;
989 if (configure_info[i]->name != (char *) NULL)
990 name=configure_info[i]->name;
991 (void) FormatLocaleFile(file,"%s",name);
992 for (j=(ssize_t) strlen(name); j <= 13; j++)
993 (void) FormatLocaleFile(file," ");
994 (void) FormatLocaleFile(file," ");
996 if (configure_info[i]->value != (char *) NULL)
997 value=configure_info[i]->value;
998 (void) FormatLocaleFile(file,"%s",value);
999 (void) FormatLocaleFile(file,"\n");
1001 (void) fflush(file);
1002 configure_info=(const ConfigureInfo **)
1003 RelinquishMagickMemory((void *) configure_info);
1008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1012 + L o a d C o n f i g u r e L i s t %
1016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1018 % LoadConfigureList() loads the configure configuration file which provides a
1019 % mapping between configure attributes and a configure name.
1021 % The format of the LoadConfigureList method is:
1023 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1024 % const size_t depth,ExceptionInfo *exception)
1026 % A description of each parameter follows:
1028 % o xml: The configure list in XML format.
1030 % o filename: The configure list filename.
1032 % o depth: depth of <include /> statements.
1034 % o exception: return any errors or warnings in this structure.
1037 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1038 const size_t depth,ExceptionInfo *exception)
1041 keyword[MaxTextExtent],
1054 Load the configure map file.
1056 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1057 "Loading configure file \"%s\" ...",filename);
1058 if (configure_list == (LinkedListInfo *) NULL)
1060 configure_list=NewLinkedList(0);
1061 if (configure_list == (LinkedListInfo *) NULL)
1063 ThrowFileException(exception,ResourceLimitError,
1064 "MemoryAllocationFailed",filename);
1065 return(MagickFalse);
1069 configure_info=(ConfigureInfo *) NULL;
1070 token=AcquireString((char *) xml);
1071 for (q=(char *) xml; *q != '\0'; )
1076 GetMagickToken(q,&q,token);
1079 (void) CopyMagickString(keyword,token,MaxTextExtent);
1080 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1085 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1086 GetMagickToken(q,&q,token);
1089 if (LocaleNCompare(keyword,"<!--",4) == 0)
1094 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1095 GetMagickToken(q,&q,token);
1098 if (LocaleCompare(keyword,"<include") == 0)
1103 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1105 (void) CopyMagickString(keyword,token,MaxTextExtent);
1106 GetMagickToken(q,&q,token);
1109 GetMagickToken(q,&q,token);
1110 if (LocaleCompare(keyword,"file") == 0)
1113 (void) ThrowMagickException(exception,GetMagickModule(),
1114 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1118 path[MaxTextExtent],
1121 GetPathComponent(filename,HeadPath,path);
1123 (void) ConcatenateMagickString(path,DirectorySeparator,
1125 if (*token == *DirectorySeparator)
1126 (void) CopyMagickString(path,token,MaxTextExtent);
1128 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1129 xml=FileToString(path,~0UL,exception);
1130 if (xml != (char *) NULL)
1132 status=LoadConfigureList(xml,path,depth+1,exception);
1133 xml=(char *) RelinquishMagickMemory(xml);
1140 if (LocaleCompare(keyword,"<configure") == 0)
1145 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1146 sizeof(*configure_info));
1147 if (configure_info == (ConfigureInfo *) NULL)
1148 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1149 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1150 configure_info->path=ConstantString(filename);
1151 configure_info->exempt=MagickFalse;
1152 configure_info->signature=MagickSignature;
1155 if (configure_info == (ConfigureInfo *) NULL)
1157 if (LocaleCompare(keyword,"/>") == 0)
1159 status=AppendValueToLinkedList(configure_list,configure_info);
1160 if (status == MagickFalse)
1161 (void) ThrowMagickException(exception,GetMagickModule(),
1162 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1163 configure_info->name);
1164 configure_info=(ConfigureInfo *) NULL;
1168 Parse configure element.
1170 GetMagickToken(q,(const char **) NULL,token);
1173 GetMagickToken(q,&q,token);
1174 GetMagickToken(q,&q,token);
1180 if (LocaleCompare((char *) keyword,"name") == 0)
1182 configure_info->name=ConstantString(token);
1190 if (LocaleCompare((char *) keyword,"stealth") == 0)
1192 configure_info->stealth=IsStringTrue(token);
1200 if (LocaleCompare((char *) keyword,"value") == 0)
1202 configure_info->value=ConstantString(token);
1211 token=(char *) RelinquishMagickMemory(token);
1216 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220 % L o a d C o n f i g u r e L i s t s %
1224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226 % LoadConfigureList() loads one or more configure configuration files which
1227 % provides a mapping between configure attributes and a configure name.
1229 % The format of the LoadConfigureLists method is:
1231 % MagickBooleanType LoadConfigureLists(const char *filename,
1232 % ExceptionInfo *exception)
1234 % A description of each parameter follows:
1236 % o filename: the font file name.
1238 % o exception: return any errors or warnings in this structure.
1241 static MagickBooleanType LoadConfigureLists(const char *filename,
1242 ExceptionInfo *exception)
1257 Load external configure map.
1259 if (configure_list == (LinkedListInfo *) NULL)
1261 configure_list=NewLinkedList(0);
1262 if (configure_list == (LinkedListInfo *) NULL)
1264 ThrowFileException(exception,ResourceLimitError,
1265 "MemoryAllocationFailed",filename);
1266 return(MagickFalse);
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);
1280 Load built-in configure map.
1282 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1287 register const ConfigureMapInfo
1291 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1292 sizeof(*configure_info));
1293 if (configure_info == (ConfigureInfo *) NULL)
1295 (void) ThrowMagickException(exception,GetMagickModule(),
1296 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name);
1299 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1300 configure_info->path=(char *) "[built-in]";
1301 configure_info->name=(char *) p->name;
1302 configure_info->value=(char *) p->value;
1303 configure_info->exempt=MagickTrue;
1304 configure_info->signature=MagickSignature;
1305 status&=AppendValueToLinkedList(configure_list,configure_info);
1306 if (status == MagickFalse)
1307 (void) ThrowMagickException(exception,GetMagickModule(),
1308 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1309 configure_info->name);
1311 return(status != 0 ? MagickTrue : MagickFalse);