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)
633 assert(filename != (const char *) NULL);
634 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
635 assert(exception != (ExceptionInfo *) NULL);
636 (void) CopyMagickString(path,filename,MaxTextExtent);
637 paths=NewLinkedList(0);
643 Search $MAGICK_CONFIGURE_PATH.
645 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
646 if (configure_path != (char *) NULL)
652 for (p=configure_path-1; p != (char *) NULL; )
654 (void) CopyMagickString(path,p+1,MaxTextExtent);
655 q=strchr(path,DirectoryListSeparator);
656 if (q != (char *) NULL)
658 q=path+strlen(path)-1;
659 if ((q >= path) && (*q != *DirectorySeparator))
660 (void) ConcatenateMagickString(path,DirectorySeparator,
662 (void) AppendValueToLinkedList(paths,ConstantString(path));
663 p=strchr(p+1,DirectoryListSeparator);
665 configure_path=DestroyString(configure_path);
668 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
669 #if defined(MAGICKCORE_SHARE_PATH)
670 (void) AppendValueToLinkedList(paths,ConstantString(
671 MAGICKCORE_SHARE_PATH));
673 #if defined(MAGICKCORE_CONFIGURE_PATH)
674 (void) AppendValueToLinkedList(paths,ConstantString(
675 MAGICKCORE_CONFIGURE_PATH));
677 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
678 (void) AppendValueToLinkedList(paths,ConstantString(
679 MAGICKCORE_DOCUMENTATION_PATH));
681 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
690 Locate file via registry key.
692 registry_key="ConfigurePath";
693 key_value=NTRegistryKeyLookup(registry_key);
694 if (key_value != (unsigned char *) NULL)
696 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
698 (void) AppendValueToLinkedList(paths,ConstantString(path));
699 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
709 Search under MAGICK_HOME.
711 home=GetEnvironmentValue("MAGICK_HOME");
712 if (home != (char *) NULL)
714 #if !defined(MAGICKCORE_POSIX_SUPPORT)
715 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
717 (void) AppendValueToLinkedList(paths,ConstantString(path));
719 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
720 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
721 (void) AppendValueToLinkedList(paths,ConstantString(path));
722 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
723 MAGICKCORE_SHARE_RELATIVE_PATH);
724 (void) AppendValueToLinkedList(paths,ConstantString(path));
726 home=DestroyString(home);
729 if (*GetClientPath() != '\0')
731 #if !defined(MAGICKCORE_POSIX_SUPPORT)
732 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
734 (void) AppendValueToLinkedList(paths,ConstantString(path));
737 prefix[MaxTextExtent];
740 Search based on executable directory if directory is known.
742 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
743 ChopPathComponents(prefix,1);
744 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
745 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
746 (void) AppendValueToLinkedList(paths,ConstantString(path));
747 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
748 MAGICKCORE_SHARE_RELATIVE_PATH);
749 (void) AppendValueToLinkedList(paths,ConstantString(path));
753 Search current directory.
755 (void) AppendValueToLinkedList(paths,ConstantString(""));
761 home=GetEnvironmentValue("HOME");
762 if (home == (char *) NULL)
763 home=GetEnvironmentValue("USERPROFILE");
764 if (home != (char *) NULL)
767 Search $HOME/.magick.
769 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
770 DirectorySeparator,DirectorySeparator);
771 (void) AppendValueToLinkedList(paths,ConstantString(path));
772 home=DestroyString(home);
775 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
778 module_path[MaxTextExtent];
780 if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
781 (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
789 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
791 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
792 if (element != (char *) NULL)
793 element=DestroyString(element);
794 (void) AppendValueToLinkedList(paths,ConstantString(path));
796 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
799 Search PerlMagick module path.
801 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
803 (void) AppendValueToLinkedList(paths,ConstantString(path));
804 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
805 "\\inc\\lib\\auto\\Image\\Magick\\");
806 (void) AppendValueToLinkedList(paths,ConstantString(path));
814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
818 % G e t C o n f i g u r e V a l u e %
822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824 % GetConfigureValue() returns the value associated with the configure info.
826 % The format of the GetConfigureValue method is:
828 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
830 % A description of each parameter follows:
832 % o configure_info: The configure info.
835 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
837 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
838 assert(configure_info != (ConfigureInfo *) NULL);
839 assert(configure_info->signature == MagickSignature);
840 return(configure_info->value);
844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 + I n i t i a l i z e C o n f i g u r e L i s t %
852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
854 % InitializeConfigureList() initializes the configure list.
856 % The format of the InitializeConfigureList method is:
858 % MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
860 % A description of each parameter follows.
862 % o exception: return any errors or warnings in this structure.
865 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
867 if ((configure_list == (LinkedListInfo *) NULL) &&
868 (instantiate_configure == MagickFalse))
870 if (configure_semaphore == (SemaphoreInfo *) NULL)
871 AcquireSemaphoreInfo(&configure_semaphore);
872 LockSemaphoreInfo(configure_semaphore);
873 if ((configure_list == (LinkedListInfo *) NULL) &&
874 (instantiate_configure == MagickFalse))
876 (void) LoadConfigureLists(ConfigureFilename,exception);
877 instantiate_configure=MagickTrue;
879 UnlockSemaphoreInfo(configure_semaphore);
881 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
885 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889 % L i s t C o n f i g u r e I n f o %
893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895 % ListConfigureInfo() lists the configure info to a file.
897 % The format of the ListConfigureInfo method is:
899 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
901 % A description of each parameter follows.
903 % o file: An pointer to a FILE.
905 % o exception: return any errors or warnings in this structure.
908 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
909 ExceptionInfo *exception)
928 if (file == (const FILE *) NULL)
930 configure_info=GetConfigureInfoList("*",&number_options,exception);
931 if (configure_info == (const ConfigureInfo **) NULL)
933 path=(const char *) NULL;
934 for (i=0; i < (ssize_t) number_options; i++)
936 if (configure_info[i]->stealth != MagickFalse)
938 if ((path == (const char *) NULL) ||
939 (LocaleCompare(path,configure_info[i]->path) != 0))
941 if (configure_info[i]->path != (char *) NULL)
942 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
943 configure_info[i]->path);
944 (void) FormatLocaleFile(file,"Name Value\n");
945 (void) FormatLocaleFile(file,
946 "-------------------------------------------------"
947 "------------------------------\n");
949 path=configure_info[i]->path;
951 if (configure_info[i]->name != (char *) NULL)
952 name=configure_info[i]->name;
953 (void) FormatLocaleFile(file,"%s",name);
954 for (j=(ssize_t) strlen(name); j <= 12; j++)
955 (void) FormatLocaleFile(file," ");
956 (void) FormatLocaleFile(file," ");
958 if (configure_info[i]->value != (char *) NULL)
959 value=configure_info[i]->value;
960 (void) FormatLocaleFile(file,"%s",value);
961 (void) FormatLocaleFile(file,"\n");
964 configure_info=(const ConfigureInfo **)
965 RelinquishMagickMemory((void *) configure_info);
970 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
974 + L o a d C o n f i g u r e L i s t %
978 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980 % LoadConfigureList() loads the configure configuration file which provides a
981 % mapping between configure attributes and a configure name.
983 % The format of the LoadConfigureList method is:
985 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
986 % const size_t depth,ExceptionInfo *exception)
988 % A description of each parameter follows:
990 % o xml: The configure list in XML format.
992 % o filename: The configure list filename.
994 % o depth: depth of <include /> statements.
996 % o exception: return any errors or warnings in this structure.
999 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
1000 const size_t depth,ExceptionInfo *exception)
1003 keyword[MaxTextExtent],
1016 Load the configure map file.
1018 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1019 "Loading configure file \"%s\" ...",filename);
1020 if (configure_list == (LinkedListInfo *) NULL)
1022 configure_list=NewLinkedList(0);
1023 if (configure_list == (LinkedListInfo *) NULL)
1025 ThrowFileException(exception,ResourceLimitError,
1026 "MemoryAllocationFailed",filename);
1027 return(MagickFalse);
1031 configure_info=(ConfigureInfo *) NULL;
1032 token=AcquireString((char *) xml);
1033 for (q=(char *) xml; *q != '\0'; )
1038 GetMagickToken(q,&q,token);
1041 (void) CopyMagickString(keyword,token,MaxTextExtent);
1042 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1047 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1048 GetMagickToken(q,&q,token);
1051 if (LocaleNCompare(keyword,"<!--",4) == 0)
1056 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1057 GetMagickToken(q,&q,token);
1060 if (LocaleCompare(keyword,"<include") == 0)
1065 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1067 (void) CopyMagickString(keyword,token,MaxTextExtent);
1068 GetMagickToken(q,&q,token);
1071 GetMagickToken(q,&q,token);
1072 if (LocaleCompare(keyword,"file") == 0)
1075 (void) ThrowMagickException(exception,GetMagickModule(),
1076 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1080 path[MaxTextExtent],
1083 GetPathComponent(filename,HeadPath,path);
1085 (void) ConcatenateMagickString(path,DirectorySeparator,
1087 if (*token == *DirectorySeparator)
1088 (void) CopyMagickString(path,token,MaxTextExtent);
1090 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1091 xml=FileToString(path,~0,exception);
1092 if (xml != (char *) NULL)
1094 status=LoadConfigureList(xml,path,depth+1,exception);
1095 xml=(char *) RelinquishMagickMemory(xml);
1102 if (LocaleCompare(keyword,"<configure") == 0)
1107 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1108 sizeof(*configure_info));
1109 if (configure_info == (ConfigureInfo *) NULL)
1110 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1111 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1112 configure_info->path=ConstantString(filename);
1113 configure_info->exempt=MagickFalse;
1114 configure_info->signature=MagickSignature;
1117 if (configure_info == (ConfigureInfo *) NULL)
1119 if (LocaleCompare(keyword,"/>") == 0)
1121 status=AppendValueToLinkedList(configure_list,configure_info);
1122 if (status == MagickFalse)
1123 (void) ThrowMagickException(exception,GetMagickModule(),
1124 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1125 configure_info->name);
1126 configure_info=(ConfigureInfo *) NULL;
1129 Parse configure element.
1131 GetMagickToken(q,(const char **) NULL,token);
1134 GetMagickToken(q,&q,token);
1135 GetMagickToken(q,&q,token);
1141 if (LocaleCompare((char *) keyword,"name") == 0)
1143 configure_info->name=ConstantString(token);
1151 if (LocaleCompare((char *) keyword,"stealth") == 0)
1153 configure_info->stealth=IsMagickTrue(token);
1161 if (LocaleCompare((char *) keyword,"value") == 0)
1163 configure_info->value=ConstantString(token);
1172 token=(char *) RelinquishMagickMemory(token);
1177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1181 % L o a d C o n f i g u r e L i s t s %
1185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1187 % LoadConfigureList() loads one or more configure configuration files which
1188 % provides a mapping between configure attributes and a configure name.
1190 % The format of the LoadConfigureLists method is:
1192 % MagickBooleanType LoadConfigureLists(const char *filename,
1193 % ExceptionInfo *exception)
1195 % A description of each parameter follows:
1197 % o filename: the font file name.
1199 % o exception: return any errors or warnings in this structure.
1202 static MagickBooleanType LoadConfigureLists(const char *filename,
1203 ExceptionInfo *exception)
1218 Load built-in configure map.
1221 if (configure_list == (LinkedListInfo *) NULL)
1223 configure_list=NewLinkedList(0);
1224 if (configure_list == (LinkedListInfo *) NULL)
1226 ThrowFileException(exception,ResourceLimitError,
1227 "MemoryAllocationFailed",filename);
1228 return(MagickFalse);
1231 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1236 register const ConfigureMapInfo
1240 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1241 sizeof(*configure_info));
1242 if (configure_info == (ConfigureInfo *) NULL)
1244 (void) ThrowMagickException(exception,GetMagickModule(),
1245 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1246 configure_info->name);
1249 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1250 configure_info->path=(char *) "[built-in]";
1251 configure_info->name=(char *) p->name;
1252 configure_info->value=(char *) p->value;
1253 configure_info->exempt=MagickTrue;
1254 configure_info->signature=MagickSignature;
1255 status=AppendValueToLinkedList(configure_list,configure_info);
1256 if (status == MagickFalse)
1257 (void) ThrowMagickException(exception,GetMagickModule(),
1258 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1259 configure_info->name);
1262 Load external configure map.
1264 options=GetConfigureOptions(filename,exception);
1265 option=(const StringInfo *) GetNextValueInLinkedList(options);
1266 while (option != (const StringInfo *) NULL)
1268 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1269 GetStringInfoPath(option),0,exception);
1270 option=(const StringInfo *) GetNextValueInLinkedList(options);
1272 options=DestroyConfigureOptions(options);
1273 return(status != 0 ? MagickTrue : MagickFalse);