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-2010 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 "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/client.h"
45 #include "magick/configure.h"
46 #include "magick/exception.h"
47 #include "magick/exception-private.h"
48 #include "magick/hashmap.h"
49 #include "magick/log.h"
50 #include "magick/memory_.h"
51 #include "magick/semaphore.h"
52 #include "magick/string_.h"
53 #include "magick/token.h"
54 #include "magick/utility.h"
55 #include "magick/xml-tree.h"
60 #define ConfigureFilename "configure.xml"
65 typedef struct _ConfigureMapInfo
75 static const ConfigureMapInfo
78 { "NAME", "ImageMagick" }
82 *configure_list = (LinkedListInfo *) NULL;
85 *configure_semaphore = (SemaphoreInfo *) NULL;
87 static volatile MagickBooleanType
88 instantiate_configure = MagickFalse;
93 static MagickBooleanType
94 InitializeConfigureList(ExceptionInfo *),
95 LoadConfigureLists(const char *,ExceptionInfo *);
98 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 + 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 %
106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 % ConfigureComponentGenesis() instantiates the configure component.
110 % The format of the ConfigureComponentGenesis method is:
112 % MagickBooleanType ConfigureComponentGenesis(void)
115 MagickExport MagickBooleanType ConfigureComponentGenesis(void)
117 AcquireSemaphoreInfo(&configure_semaphore);
122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126 + 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 %
130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132 % ConfigureComponentTerminus() destroys the configure component.
134 % The format of the ConfigureComponentTerminus method is:
136 % ConfigureComponentTerminus(void)
140 static void *DestroyConfigureElement(void *configure_info)
142 register ConfigureInfo
145 p=(ConfigureInfo *) configure_info;
146 if (p->exempt == MagickFalse)
148 if (p->value != (char *) NULL)
149 p->value=DestroyString(p->value);
150 if (p->name != (char *) NULL)
151 p->name=DestroyString(p->name);
152 if (p->path != (char *) NULL)
153 p->path=DestroyString(p->path);
155 p=(ConfigureInfo *) RelinquishMagickMemory(p);
156 return((void *) NULL);
159 MagickExport void ConfigureComponentTerminus(void)
161 if (configure_semaphore == (SemaphoreInfo *) NULL)
162 AcquireSemaphoreInfo(&configure_semaphore);
163 LockSemaphoreInfo(configure_semaphore);
164 if (configure_list != (LinkedListInfo *) NULL)
165 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
166 configure_list=(LinkedListInfo *) NULL;
167 instantiate_configure=MagickFalse;
168 UnlockSemaphoreInfo(configure_semaphore);
169 DestroySemaphoreInfo(&configure_semaphore);
173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
177 % D e s t r o y C o n f i g u r e O p t i o n s %
181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183 % DestroyConfigureOptions() releases memory associated with an configure
186 % The format of the DestroyProfiles method is:
188 % LinkedListInfo *DestroyConfigureOptions(Image *image)
190 % A description of each parameter follows:
192 % o image: the image.
196 static void *DestroyOptions(void *option)
198 return(DestroyStringInfo((StringInfo *) option));
201 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
203 assert(options != (LinkedListInfo *) NULL);
204 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
205 return(DestroyLinkedList(options,DestroyOptions));
209 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
213 + G e t C o n f i g u r e I n f o %
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219 % GetConfigureInfo() searches the configure list for the specified name and if
220 % found returns attributes for that element.
222 % The format of the GetConfigureInfo method is:
224 % const ConfigureInfo *GetConfigureInfo(const char *name,
225 % ExceptionInfo *exception)
227 % A description of each parameter follows:
229 % o configure_info: GetConfigureInfo() searches the configure list for the
230 % specified name and if found returns attributes for that element.
232 % o name: the configure name.
234 % o exception: return any errors or warnings in this structure.
237 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
238 ExceptionInfo *exception)
240 register const ConfigureInfo
243 assert(exception != (ExceptionInfo *) NULL);
244 if ((configure_list == (LinkedListInfo *) NULL) ||
245 (instantiate_configure == MagickFalse))
246 if (InitializeConfigureList(exception) == MagickFalse)
247 return((const ConfigureInfo *) NULL);
248 if ((configure_list == (LinkedListInfo *) NULL) ||
249 (IsLinkedListEmpty(configure_list) != MagickFalse))
250 return((const ConfigureInfo *) NULL);
251 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
252 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
254 Search for configure tag.
256 LockSemaphoreInfo(configure_semaphore);
257 ResetLinkedListIterator(configure_list);
258 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
259 while (p != (const ConfigureInfo *) NULL)
261 if (LocaleCompare(name,p->name) == 0)
263 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
265 if (p != (ConfigureInfo *) NULL)
266 (void) InsertValueInLinkedList(configure_list,0,
267 RemoveElementByValueFromLinkedList(configure_list,p));
268 UnlockSemaphoreInfo(configure_semaphore);
273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277 % G e t C o n f i g u r e I n f o L i s t %
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 % GetConfigureInfoList() returns any configure options that match the
286 % The format of the GetConfigureInfoList function is:
288 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
289 % size_t *number_options,ExceptionInfo *exception)
291 % A description of each parameter follows:
293 % o pattern: Specifies a pointer to a text string containing a pattern.
295 % o number_options: This integer returns the number of configure options in
298 % o exception: return any errors or warnings in this structure.
302 #if defined(__cplusplus) || defined(c_plusplus)
306 static int ConfigureInfoCompare(const void *x,const void *y)
312 p=(const ConfigureInfo **) x,
313 q=(const ConfigureInfo **) y;
314 if (LocaleCompare((*p)->path,(*q)->path) == 0)
315 return(LocaleCompare((*p)->name,(*q)->name));
316 return(LocaleCompare((*p)->path,(*q)->path));
319 #if defined(__cplusplus) || defined(c_plusplus)
323 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
324 size_t *number_options,ExceptionInfo *exception)
329 register const ConfigureInfo
336 Allocate configure list.
338 assert(pattern != (char *) NULL);
339 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
340 assert(number_options != (size_t *) NULL);
342 p=GetConfigureInfo("*",exception);
343 if (p == (const ConfigureInfo *) NULL)
344 return((const ConfigureInfo **) NULL);
345 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
346 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
347 if (options == (const ConfigureInfo **) NULL)
348 return((const ConfigureInfo **) NULL);
350 Generate configure list.
352 LockSemaphoreInfo(configure_semaphore);
353 ResetLinkedListIterator(configure_list);
354 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
355 for (i=0; p != (const ConfigureInfo *) NULL; )
357 if ((p->stealth == MagickFalse) &&
358 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
360 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
362 UnlockSemaphoreInfo(configure_semaphore);
363 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
364 options[i]=(ConfigureInfo *) NULL;
365 *number_options=(size_t) i;
370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374 % G e t C o n f i g u r e L i s t %
378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 % GetConfigureList() returns any configure options that match the specified
383 % The format of the GetConfigureList function is:
385 % char **GetConfigureList(const char *pattern,
386 % size_t *number_options,ExceptionInfo *exception)
388 % A description of each parameter follows:
390 % o pattern: Specifies a pointer to a text string containing a pattern.
392 % o number_options: This integer returns the number of options in the list.
394 % o exception: return any errors or warnings in this structure.
398 #if defined(__cplusplus) || defined(c_plusplus)
402 static int ConfigureCompare(const void *x,const void *y)
410 return(LocaleCompare(*p,*q));
413 #if defined(__cplusplus) || defined(c_plusplus)
417 MagickExport char **GetConfigureList(const char *pattern,
418 size_t *number_options,ExceptionInfo *exception)
423 register const ConfigureInfo
430 Allocate configure list.
432 assert(pattern != (char *) NULL);
433 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
434 assert(number_options != (size_t *) NULL);
436 p=GetConfigureInfo("*",exception);
437 if (p == (const ConfigureInfo *) NULL)
438 return((char **) NULL);
439 options=(char **) AcquireQuantumMemory((size_t)
440 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
441 if (options == (char **) NULL)
442 return((char **) NULL);
443 LockSemaphoreInfo(configure_semaphore);
444 ResetLinkedListIterator(configure_list);
445 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
446 for (i=0; p != (const ConfigureInfo *) NULL; )
448 if ((p->stealth == MagickFalse) &&
449 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
450 options[i++]=ConstantString(p->name);
451 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
453 UnlockSemaphoreInfo(configure_semaphore);
454 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
455 options[i]=(char *) NULL;
456 *number_options=(size_t) i;
461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465 % G e t C o n f i g u r e O p t i o n %
469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
471 % GetConfigureOption() returns the value associated with the configure option.
473 % The format of the GetConfigureOption method is:
475 % char *GetConfigureOption(const char *option)
477 % A description of each parameter follows:
479 % o configure_info: The configure info.
482 MagickExport char *GetConfigureOption(const char *option)
493 assert(option != (const char *) NULL);
494 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
495 exception=AcquireExceptionInfo();
496 configure_info=GetConfigureInfo(option,exception);
497 exception=DestroyExceptionInfo(exception);
498 if (configure_info == (ConfigureInfo *) NULL)
499 return((char *) NULL);
500 value=GetConfigureValue(configure_info);
501 if ((value == (const char *) NULL) || (*value == '\0'))
502 return((char *) NULL);
503 return(ConstantString(value));
507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511 % G e t C o n f i g u r e O p t i o n s %
515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
517 % GetConfigureOptions() returns any Magick configuration options associated
518 % with the specified filename.
520 % The format of the GetConfigureOptions method is:
522 % LinkedListInfo *GetConfigureOptions(const char *filename,
523 % ExceptionInfo *exception)
525 % A description of each parameter follows:
527 % o filename: the configure file name.
529 % o exception: return any errors or warnings in this structure.
532 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
533 ExceptionInfo *exception)
548 assert(filename != (const char *) NULL);
549 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
550 assert(exception != (ExceptionInfo *) NULL);
551 (void) CopyMagickString(path,filename,MaxTextExtent);
553 Load XML from configuration files to linked-list.
555 options=NewLinkedList(0);
556 paths=GetConfigurePaths(filename,exception);
557 if (paths != (LinkedListInfo *) NULL)
559 ResetLinkedListIterator(paths);
560 element=(const char *) GetNextValueInLinkedList(paths);
561 while (element != (const char *) NULL)
563 (void) FormatMagickString(path,MaxTextExtent,"%s%s",element,filename);
564 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
565 "Searching for configure file: \"%s\"",path);
566 xml=ConfigureFileToStringInfo(path);
567 if (xml != (StringInfo *) NULL)
568 (void) AppendValueToLinkedList(options,xml);
569 element=(const char *) GetNextValueInLinkedList(paths);
571 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
573 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
578 blob=(char *) NTResourceToBlob(filename);
579 if (blob != (char *) NULL)
581 xml=StringToStringInfo(blob);
582 SetStringInfoPath(xml,filename);
583 (void) AppendValueToLinkedList(options,xml);
584 blob=DestroyString(blob);
588 if (GetNumberOfElementsInLinkedList(options) == 0)
589 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
590 "UnableToOpenConfigureFile","`%s'",filename);
591 ResetLinkedListIterator(options);
596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
600 % G e t C o n f i g u r e P a t h s %
604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606 % GetConfigurePaths() returns any Magick configuration paths associated
607 % with the specified filename.
609 % The format of the GetConfigurePaths method is:
611 % LinkedListInfo *GetConfigurePaths(const char *filename,
612 % ExceptionInfo *exception)
614 % A description of each parameter follows:
616 % o filename: the configure file name.
618 % o exception: return any errors or warnings in this structure.
621 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
622 ExceptionInfo *exception)
630 assert(filename != (const char *) NULL);
631 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
632 assert(exception != (ExceptionInfo *) NULL);
633 (void) CopyMagickString(path,filename,MaxTextExtent);
634 paths=NewLinkedList(0);
640 Search $MAGICK_CONFIGURE_PATH.
642 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
643 if (configure_path != (char *) NULL)
649 for (p=configure_path-1; p != (char *) NULL; )
651 (void) CopyMagickString(path,p+1,MaxTextExtent);
652 q=strchr(path,DirectoryListSeparator);
653 if (q != (char *) NULL)
655 q=path+strlen(path)-1;
656 if ((q >= path) && (*q != *DirectorySeparator))
657 (void) ConcatenateMagickString(path,DirectorySeparator,
659 (void) AppendValueToLinkedList(paths,ConstantString(path));
660 p=strchr(p+1,DirectoryListSeparator);
662 configure_path=DestroyString(configure_path);
665 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
666 #if defined(MAGICKCORE_SHARE_CONFIGURE_PATH)
667 (void) AppendValueToLinkedList(paths,ConstantString(
668 MAGICKCORE_SHARE_CONFIGURE_PATH));
670 #if defined(MAGICKCORE_CONFIGURE_PATH)
671 (void) AppendValueToLinkedList(paths,ConstantString(
672 MAGICKCORE_CONFIGURE_PATH));
674 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
675 (void) AppendValueToLinkedList(paths,ConstantString(
676 MAGICKCORE_DOCUMENTATION_PATH));
678 #if defined(MAGICKCORE_SHARE_PATH)
679 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH));
681 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_CONFIGURE_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) FormatMagickString(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) FormatMagickString(path,MaxTextExtent,"%s%s",home,
717 (void) AppendValueToLinkedList(paths,ConstantString(path));
719 (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",home,
720 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
721 (void) AppendValueToLinkedList(paths,ConstantString(path));
722 (void) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",home,
723 MAGICKCORE_SHARE_CONFIGURE_RELATIVE_PATH);
724 (void) AppendValueToLinkedList(paths,ConstantString(path));
726 home=DestroyString(home);
729 if (*GetClientPath() != '\0')
731 #if !defined(MAGICKCORE_POSIX_SUPPORT)
732 (void) FormatMagickString(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) FormatMagickString(path,MaxTextExtent,"%s/share/%s/",prefix,
745 MAGICKCORE_SHARE_CONFIGURE_RELATIVE_PATH);
746 (void) AppendValueToLinkedList(paths,ConstantString(path));
747 (void) FormatMagickString(path,MaxTextExtent,"%s/lib/%s/",prefix,
748 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
749 (void) AppendValueToLinkedList(paths,ConstantString(path));
757 home=GetEnvironmentValue("HOME");
758 if (home == (char *) NULL)
759 home=GetEnvironmentValue("USERPROFILE");
760 if (home != (char *) NULL)
763 Search $HOME/.magick.
765 (void) FormatMagickString(path,MaxTextExtent,"%s%s.magick%s",home,
766 DirectorySeparator,DirectorySeparator);
767 (void) AppendValueToLinkedList(paths,ConstantString(path));
768 home=DestroyString(home);
771 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
774 module_path[MaxTextExtent];
776 if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
777 (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
785 (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
787 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
788 if (element != (char *) NULL)
789 element=DestroyString(element);
790 (void) AppendValueToLinkedList(paths,ConstantString(path));
792 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
795 Search PerlMagick module path.
797 (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
799 (void) AppendValueToLinkedList(paths,ConstantString(path));
800 (void) FormatMagickString(path,MaxTextExtent,"%s%s",module_path,
801 "\\inc\\lib\\auto\\Image\\Magick\\");
802 (void) AppendValueToLinkedList(paths,ConstantString(path));
807 Search current directory.
809 (void) AppendValueToLinkedList(paths,ConstantString(""));
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) fprintf(file,"\nPath: %s\n\n",configure_info[i]->path);
943 (void) fprintf(file,"Name Value\n");
944 (void) fprintf(file,"-------------------------------------------------"
945 "------------------------------\n");
947 path=configure_info[i]->path;
949 if (configure_info[i]->name != (char *) NULL)
950 name=configure_info[i]->name;
951 (void) fprintf(file,"%s",name);
952 for (j=(ssize_t) strlen(name); j <= 12; j++)
953 (void) fprintf(file," ");
954 (void) fprintf(file," ");
956 if (configure_info[i]->value != (char *) NULL)
957 value=configure_info[i]->value;
958 (void) fprintf(file,"%s",value);
959 (void) fprintf(file,"\n");
962 configure_info=(const ConfigureInfo **)
963 RelinquishMagickMemory((void *) configure_info);
968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
972 + L o a d C o n f i g u r e L i s t %
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978 % LoadConfigureList() loads the configure configuration file which provides a
979 % mapping between configure attributes and a configure name.
981 % The format of the LoadConfigureList method is:
983 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
984 % const size_t depth,ExceptionInfo *exception)
986 % A description of each parameter follows:
988 % o xml: The configure list in XML format.
990 % o filename: The configure list filename.
992 % o depth: depth of <include /> statements.
994 % o exception: return any errors or warnings in this structure.
997 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
998 const size_t depth,ExceptionInfo *exception)
1001 keyword[MaxTextExtent],
1014 Load the configure map file.
1016 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1017 "Loading configure file \"%s\" ...",filename);
1018 if (configure_list == (LinkedListInfo *) NULL)
1020 configure_list=NewLinkedList(0);
1021 if (configure_list == (LinkedListInfo *) NULL)
1023 ThrowFileException(exception,ResourceLimitError,
1024 "MemoryAllocationFailed",filename);
1025 return(MagickFalse);
1029 configure_info=(ConfigureInfo *) NULL;
1030 token=AcquireString((char *) xml);
1031 for (q=(char *) xml; *q != '\0'; )
1036 GetMagickToken(q,&q,token);
1039 (void) CopyMagickString(keyword,token,MaxTextExtent);
1040 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1045 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1046 GetMagickToken(q,&q,token);
1049 if (LocaleNCompare(keyword,"<!--",4) == 0)
1054 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1055 GetMagickToken(q,&q,token);
1058 if (LocaleCompare(keyword,"<include") == 0)
1063 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1065 (void) CopyMagickString(keyword,token,MaxTextExtent);
1066 GetMagickToken(q,&q,token);
1069 GetMagickToken(q,&q,token);
1070 if (LocaleCompare(keyword,"file") == 0)
1073 (void) ThrowMagickException(exception,GetMagickModule(),
1074 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1078 path[MaxTextExtent],
1081 GetPathComponent(filename,HeadPath,path);
1083 (void) ConcatenateMagickString(path,DirectorySeparator,
1085 if (*token == *DirectorySeparator)
1086 (void) CopyMagickString(path,token,MaxTextExtent);
1088 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1089 xml=FileToString(path,~0,exception);
1090 if (xml != (char *) NULL)
1092 status=LoadConfigureList(xml,path,depth+1,exception);
1093 xml=(char *) RelinquishMagickMemory(xml);
1100 if (LocaleCompare(keyword,"<configure") == 0)
1105 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1106 sizeof(*configure_info));
1107 if (configure_info == (ConfigureInfo *) NULL)
1108 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1109 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1110 configure_info->path=ConstantString(filename);
1111 configure_info->exempt=MagickFalse;
1112 configure_info->signature=MagickSignature;
1115 if (configure_info == (ConfigureInfo *) NULL)
1117 if (LocaleCompare(keyword,"/>") == 0)
1119 status=AppendValueToLinkedList(configure_list,configure_info);
1120 if (status == MagickFalse)
1121 (void) ThrowMagickException(exception,GetMagickModule(),
1122 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1123 configure_info->name);
1124 configure_info=(ConfigureInfo *) NULL;
1127 Parse configure element.
1129 GetMagickToken(q,(const char **) NULL,token);
1132 GetMagickToken(q,&q,token);
1133 GetMagickToken(q,&q,token);
1139 if (LocaleCompare((char *) keyword,"name") == 0)
1141 configure_info->name=ConstantString(token);
1149 if (LocaleCompare((char *) keyword,"stealth") == 0)
1151 configure_info->stealth=IsMagickTrue(token);
1159 if (LocaleCompare((char *) keyword,"value") == 0)
1161 configure_info->value=ConstantString(token);
1170 token=(char *) RelinquishMagickMemory(token);
1175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1179 % L o a d C o n f i g u r e L i s t s %
1183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185 % LoadConfigureList() loads one or more configure configuration files which
1186 % provides a mapping between configure attributes and a configure name.
1188 % The format of the LoadConfigureLists method is:
1190 % MagickBooleanType LoadConfigureLists(const char *filename,
1191 % ExceptionInfo *exception)
1193 % A description of each parameter follows:
1195 % o filename: the font file name.
1197 % o exception: return any errors or warnings in this structure.
1200 static MagickBooleanType LoadConfigureLists(const char *filename,
1201 ExceptionInfo *exception)
1216 Load built-in configure map.
1219 if (configure_list == (LinkedListInfo *) NULL)
1221 configure_list=NewLinkedList(0);
1222 if (configure_list == (LinkedListInfo *) NULL)
1224 ThrowFileException(exception,ResourceLimitError,
1225 "MemoryAllocationFailed",filename);
1226 return(MagickFalse);
1229 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1234 register const ConfigureMapInfo
1238 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1239 sizeof(*configure_info));
1240 if (configure_info == (ConfigureInfo *) NULL)
1242 (void) ThrowMagickException(exception,GetMagickModule(),
1243 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1244 configure_info->name);
1247 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1248 configure_info->path=(char *) "[built-in]";
1249 configure_info->name=(char *) p->name;
1250 configure_info->value=(char *) p->value;
1251 configure_info->exempt=MagickTrue;
1252 configure_info->signature=MagickSignature;
1253 status=AppendValueToLinkedList(configure_list,configure_info);
1254 if (status == MagickFalse)
1255 (void) ThrowMagickException(exception,GetMagickModule(),
1256 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1257 configure_info->name);
1260 Load external configure map.
1262 options=GetConfigureOptions(filename,exception);
1263 option=(const StringInfo *) GetNextValueInLinkedList(options);
1264 while (option != (const StringInfo *) NULL)
1266 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1267 GetStringInfoPath(option),0,exception);
1268 option=(const StringInfo *) GetNextValueInLinkedList(options);
1270 options=DestroyConfigureOptions(options);
1271 return(status != 0 ? MagickTrue : MagickFalse);