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/token.h"
55 #include "MagickCore/utility.h"
56 #include "MagickCore/utility-private.h"
57 #include "MagickCore/xml-tree.h"
62 #define ConfigureFilename "configure.xml"
67 typedef struct _ConfigureMapInfo
77 static const ConfigureMapInfo
80 { "NAME", "ImageMagick" }
84 *configure_list = (LinkedListInfo *) NULL;
87 *configure_semaphore = (SemaphoreInfo *) NULL;
89 static volatile MagickBooleanType
90 instantiate_configure = MagickFalse;
95 static MagickBooleanType
96 InitializeConfigureList(ExceptionInfo *),
97 LoadConfigureLists(const char *,ExceptionInfo *);
100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104 + 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 %
108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 % ConfigureComponentGenesis() instantiates the configure component.
112 % The format of the ConfigureComponentGenesis method is:
114 % MagickBooleanType ConfigureComponentGenesis(void)
117 MagickPrivate MagickBooleanType ConfigureComponentGenesis(void)
119 AcquireSemaphoreInfo(&configure_semaphore);
124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 + 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 %
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 % ConfigureComponentTerminus() destroys the configure component.
136 % The format of the ConfigureComponentTerminus method is:
138 % ConfigureComponentTerminus(void)
142 static void *DestroyConfigureElement(void *configure_info)
144 register ConfigureInfo
147 p=(ConfigureInfo *) configure_info;
148 if (p->exempt == MagickFalse)
150 if (p->value != (char *) NULL)
151 p->value=DestroyString(p->value);
152 if (p->name != (char *) NULL)
153 p->name=DestroyString(p->name);
154 if (p->path != (char *) NULL)
155 p->path=DestroyString(p->path);
157 p=(ConfigureInfo *) RelinquishMagickMemory(p);
158 return((void *) NULL);
161 MagickPrivate void ConfigureComponentTerminus(void)
163 if (configure_semaphore == (SemaphoreInfo *) NULL)
164 AcquireSemaphoreInfo(&configure_semaphore);
165 LockSemaphoreInfo(configure_semaphore);
166 if (configure_list != (LinkedListInfo *) NULL)
167 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
168 configure_list=(LinkedListInfo *) NULL;
169 instantiate_configure=MagickFalse;
170 UnlockSemaphoreInfo(configure_semaphore);
171 DestroySemaphoreInfo(&configure_semaphore);
175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179 % D e s t r o y C o n f i g u r e O p t i o n s %
183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 % DestroyConfigureOptions() releases memory associated with an configure
188 % The format of the DestroyProfiles method is:
190 % LinkedListInfo *DestroyConfigureOptions(Image *image)
192 % A description of each parameter follows:
194 % o image: the image.
198 static void *DestroyOptions(void *option)
200 return(DestroyStringInfo((StringInfo *) option));
203 MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
205 assert(options != (LinkedListInfo *) NULL);
206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
207 return(DestroyLinkedList(options,DestroyOptions));
211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
215 + G e t C o n f i g u r e I n f o %
219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
221 % GetConfigureInfo() searches the configure list for the specified name and if
222 % found returns attributes for that element.
224 % The format of the GetConfigureInfo method is:
226 % const ConfigureInfo *GetConfigureInfo(const char *name,
227 % ExceptionInfo *exception)
229 % A description of each parameter follows:
231 % o configure_info: GetConfigureInfo() searches the configure list for the
232 % specified name and if found returns attributes for that element.
234 % o name: the configure name.
236 % o exception: return any errors or warnings in this structure.
239 MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
240 ExceptionInfo *exception)
242 register const ConfigureInfo
245 assert(exception != (ExceptionInfo *) NULL);
246 if ((configure_list == (LinkedListInfo *) NULL) ||
247 (instantiate_configure == MagickFalse))
248 if (InitializeConfigureList(exception) == MagickFalse)
249 return((const ConfigureInfo *) NULL);
250 if ((configure_list == (LinkedListInfo *) NULL) ||
251 (IsLinkedListEmpty(configure_list) != MagickFalse))
252 return((const ConfigureInfo *) NULL);
253 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
254 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
256 Search for configure tag.
258 LockSemaphoreInfo(configure_semaphore);
259 ResetLinkedListIterator(configure_list);
260 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
261 while (p != (const ConfigureInfo *) NULL)
263 if (LocaleCompare(name,p->name) == 0)
265 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
267 if (p != (ConfigureInfo *) NULL)
268 (void) InsertValueInLinkedList(configure_list,0,
269 RemoveElementByValueFromLinkedList(configure_list,p));
270 UnlockSemaphoreInfo(configure_semaphore);
275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279 % G e t C o n f i g u r e I n f o L i s t %
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285 % GetConfigureInfoList() returns any configure options that match the
288 % The format of the GetConfigureInfoList function is:
290 % const ConfigureInfo **GetConfigureInfoList(const char *pattern,
291 % size_t *number_options,ExceptionInfo *exception)
293 % A description of each parameter follows:
295 % o pattern: Specifies a pointer to a text string containing a pattern.
297 % o number_options: This integer returns the number of configure options in
300 % o exception: return any errors or warnings in this structure.
304 #if defined(__cplusplus) || defined(c_plusplus)
308 static int ConfigureInfoCompare(const void *x,const void *y)
314 p=(const ConfigureInfo **) x,
315 q=(const ConfigureInfo **) y;
316 if (LocaleCompare((*p)->path,(*q)->path) == 0)
317 return(LocaleCompare((*p)->name,(*q)->name));
318 return(LocaleCompare((*p)->path,(*q)->path));
321 #if defined(__cplusplus) || defined(c_plusplus)
325 MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
326 size_t *number_options,ExceptionInfo *exception)
331 register const ConfigureInfo
338 Allocate configure list.
340 assert(pattern != (char *) NULL);
341 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
342 assert(number_options != (size_t *) NULL);
344 p=GetConfigureInfo("*",exception);
345 if (p == (const ConfigureInfo *) NULL)
346 return((const ConfigureInfo **) NULL);
347 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
348 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
349 if (options == (const ConfigureInfo **) NULL)
350 return((const ConfigureInfo **) NULL);
352 Generate configure list.
354 LockSemaphoreInfo(configure_semaphore);
355 ResetLinkedListIterator(configure_list);
356 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
357 for (i=0; p != (const ConfigureInfo *) NULL; )
359 if ((p->stealth == MagickFalse) &&
360 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
362 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
364 UnlockSemaphoreInfo(configure_semaphore);
365 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
366 options[i]=(ConfigureInfo *) NULL;
367 *number_options=(size_t) i;
372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 % G e t C o n f i g u r e L i s t %
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382 % GetConfigureList() returns any configure options that match the specified
385 % The format of the GetConfigureList function is:
387 % char **GetConfigureList(const char *pattern,
388 % size_t *number_options,ExceptionInfo *exception)
390 % A description of each parameter follows:
392 % o pattern: Specifies a pointer to a text string containing a pattern.
394 % o number_options: This integer returns the number of options in the list.
396 % o exception: return any errors or warnings in this structure.
400 #if defined(__cplusplus) || defined(c_plusplus)
404 static int ConfigureCompare(const void *x,const void *y)
412 return(LocaleCompare(*p,*q));
415 #if defined(__cplusplus) || defined(c_plusplus)
419 MagickExport char **GetConfigureList(const char *pattern,
420 size_t *number_options,ExceptionInfo *exception)
425 register const ConfigureInfo
432 Allocate configure list.
434 assert(pattern != (char *) NULL);
435 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
436 assert(number_options != (size_t *) NULL);
438 p=GetConfigureInfo("*",exception);
439 if (p == (const ConfigureInfo *) NULL)
440 return((char **) NULL);
441 options=(char **) AcquireQuantumMemory((size_t)
442 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
443 if (options == (char **) NULL)
444 return((char **) NULL);
445 LockSemaphoreInfo(configure_semaphore);
446 ResetLinkedListIterator(configure_list);
447 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
448 for (i=0; p != (const ConfigureInfo *) NULL; )
450 if ((p->stealth == MagickFalse) &&
451 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
452 options[i++]=ConstantString(p->name);
453 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
455 UnlockSemaphoreInfo(configure_semaphore);
456 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
457 options[i]=(char *) NULL;
458 *number_options=(size_t) i;
463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
467 % G e t C o n f i g u r e O p t i o n %
471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 % GetConfigureOption() returns the value associated with the configure option.
475 % The format of the GetConfigureOption method is:
477 % char *GetConfigureOption(const char *option)
479 % A description of each parameter follows:
481 % o configure_info: The configure info.
484 MagickExport char *GetConfigureOption(const char *option)
495 assert(option != (const char *) NULL);
496 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
497 exception=AcquireExceptionInfo();
498 configure_info=GetConfigureInfo(option,exception);
499 exception=DestroyExceptionInfo(exception);
500 if (configure_info == (ConfigureInfo *) NULL)
501 return((char *) NULL);
502 value=GetConfigureValue(configure_info);
503 if ((value == (const char *) NULL) || (*value == '\0'))
504 return((char *) NULL);
505 return(ConstantString(value));
509 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 % G e t C o n f i g u r e O p t i o n s %
517 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519 % GetConfigureOptions() returns any Magick configuration options associated
520 % with the specified filename.
522 % The format of the GetConfigureOptions method is:
524 % LinkedListInfo *GetConfigureOptions(const char *filename,
525 % ExceptionInfo *exception)
527 % A description of each parameter follows:
529 % o filename: the configure file name.
531 % o exception: return any errors or warnings in this structure.
534 MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
535 ExceptionInfo *exception)
550 assert(filename != (const char *) NULL);
551 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
552 assert(exception != (ExceptionInfo *) NULL);
553 (void) CopyMagickString(path,filename,MaxTextExtent);
555 Load XML from configuration files to linked-list.
557 options=NewLinkedList(0);
558 paths=GetConfigurePaths(filename,exception);
559 if (paths != (LinkedListInfo *) NULL)
561 ResetLinkedListIterator(paths);
562 element=(const char *) GetNextValueInLinkedList(paths);
563 while (element != (const char *) NULL)
565 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
566 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
567 "Searching for configure file: \"%s\"",path);
568 xml=ConfigureFileToStringInfo(path);
569 if (xml != (StringInfo *) NULL)
570 (void) AppendValueToLinkedList(options,xml);
571 element=(const char *) GetNextValueInLinkedList(paths);
573 paths=DestroyLinkedList(paths,RelinquishMagickMemory);
575 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
580 blob=(char *) NTResourceToBlob(filename);
581 if (blob != (char *) NULL)
583 xml=StringToStringInfo(blob);
584 SetStringInfoPath(xml,filename);
585 (void) AppendValueToLinkedList(options,xml);
586 blob=DestroyString(blob);
590 if (GetNumberOfElementsInLinkedList(options) == 0)
591 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
592 "UnableToOpenConfigureFile","`%s'",filename);
593 ResetLinkedListIterator(options);
598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602 % G e t C o n f i g u r e P a t h s %
606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
608 % GetConfigurePaths() returns any Magick configuration paths associated
609 % with the specified filename.
611 % The format of the GetConfigurePaths method is:
613 % LinkedListInfo *GetConfigurePaths(const char *filename,
614 % ExceptionInfo *exception)
616 % A description of each parameter follows:
618 % o filename: the configure file name.
620 % o exception: return any errors or warnings in this structure.
623 MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
624 ExceptionInfo *exception)
632 assert(filename != (const char *) NULL);
633 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
634 assert(exception != (ExceptionInfo *) NULL);
635 (void) CopyMagickString(path,filename,MaxTextExtent);
636 paths=NewLinkedList(0);
642 Search $MAGICK_CONFIGURE_PATH.
644 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
645 if (configure_path != (char *) NULL)
651 for (p=configure_path-1; p != (char *) NULL; )
653 (void) CopyMagickString(path,p+1,MaxTextExtent);
654 q=strchr(path,DirectoryListSeparator);
655 if (q != (char *) NULL)
657 q=path+strlen(path)-1;
658 if ((q >= path) && (*q != *DirectorySeparator))
659 (void) ConcatenateMagickString(path,DirectorySeparator,
661 (void) AppendValueToLinkedList(paths,ConstantString(path));
662 p=strchr(p+1,DirectoryListSeparator);
664 configure_path=DestroyString(configure_path);
667 #if defined(MAGICKCORE_INSTALLED_SUPPORT)
668 #if defined(MAGICKCORE_SHARE_PATH)
669 (void) AppendValueToLinkedList(paths,ConstantString(
670 MAGICKCORE_SHARE_PATH));
672 #if defined(MAGICKCORE_CONFIGURE_PATH)
673 (void) AppendValueToLinkedList(paths,ConstantString(
674 MAGICKCORE_CONFIGURE_PATH));
676 #if defined(MAGICKCORE_DOCUMENTATION_PATH)
677 (void) AppendValueToLinkedList(paths,ConstantString(
678 MAGICKCORE_DOCUMENTATION_PATH));
680 #if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
689 Locate file via registry key.
691 registry_key="ConfigurePath";
692 key_value=NTRegistryKeyLookup(registry_key);
693 if (key_value != (unsigned char *) NULL)
695 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
697 (void) AppendValueToLinkedList(paths,ConstantString(path));
698 key_value=(unsigned char *) RelinquishMagickMemory(key_value);
708 Search under MAGICK_HOME.
710 home=GetEnvironmentValue("MAGICK_HOME");
711 if (home != (char *) NULL)
713 #if !defined(MAGICKCORE_POSIX_SUPPORT)
714 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
716 (void) AppendValueToLinkedList(paths,ConstantString(path));
718 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
719 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
720 (void) AppendValueToLinkedList(paths,ConstantString(path));
721 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
722 MAGICKCORE_SHARE_RELATIVE_PATH);
723 (void) AppendValueToLinkedList(paths,ConstantString(path));
725 home=DestroyString(home);
728 if (*GetClientPath() != '\0')
730 #if !defined(MAGICKCORE_POSIX_SUPPORT)
731 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
733 (void) AppendValueToLinkedList(paths,ConstantString(path));
736 prefix[MaxTextExtent];
739 Search based on executable directory if directory is known.
741 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
742 ChopPathComponents(prefix,1);
743 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
744 MAGICKCORE_CONFIGURE_RELATIVE_PATH);
745 (void) AppendValueToLinkedList(paths,ConstantString(path));
746 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
747 MAGICKCORE_SHARE_RELATIVE_PATH);
748 (void) AppendValueToLinkedList(paths,ConstantString(path));
752 Search current directory.
754 (void) AppendValueToLinkedList(paths,ConstantString(""));
760 home=GetEnvironmentValue("HOME");
761 if (home == (char *) NULL)
762 home=GetEnvironmentValue("USERPROFILE");
763 if (home != (char *) NULL)
766 Search $HOME/.magick.
768 (void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
769 DirectorySeparator,DirectorySeparator);
770 (void) AppendValueToLinkedList(paths,ConstantString(path));
771 home=DestroyString(home);
774 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
777 module_path[MaxTextExtent];
779 if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
780 (NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
788 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
790 element=(char *) RemoveElementByValueFromLinkedList(paths,path);
791 if (element != (char *) NULL)
792 element=DestroyString(element);
793 (void) AppendValueToLinkedList(paths,ConstantString(path));
795 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
798 Search PerlMagick module path.
800 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
802 (void) AppendValueToLinkedList(paths,ConstantString(path));
803 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
804 "\\inc\\lib\\auto\\Image\\Magick\\");
805 (void) AppendValueToLinkedList(paths,ConstantString(path));
813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817 % G e t C o n f i g u r e V a l u e %
821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823 % GetConfigureValue() returns the value associated with the configure info.
825 % The format of the GetConfigureValue method is:
827 % const char *GetConfigureValue(const ConfigureInfo *configure_info)
829 % A description of each parameter follows:
831 % o configure_info: The configure info.
834 MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
836 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
837 assert(configure_info != (ConfigureInfo *) NULL);
838 assert(configure_info->signature == MagickSignature);
839 return(configure_info->value);
843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
847 + I n i t i a l i z e C o n f i g u r e L i s t %
851 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
853 % InitializeConfigureList() initializes the configure list.
855 % The format of the InitializeConfigureList method is:
857 % MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
859 % A description of each parameter follows.
861 % o exception: return any errors or warnings in this structure.
864 static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
866 if ((configure_list == (LinkedListInfo *) NULL) &&
867 (instantiate_configure == MagickFalse))
869 if (configure_semaphore == (SemaphoreInfo *) NULL)
870 AcquireSemaphoreInfo(&configure_semaphore);
871 LockSemaphoreInfo(configure_semaphore);
872 if ((configure_list == (LinkedListInfo *) NULL) &&
873 (instantiate_configure == MagickFalse))
875 (void) LoadConfigureLists(ConfigureFilename,exception);
876 instantiate_configure=MagickTrue;
878 UnlockSemaphoreInfo(configure_semaphore);
880 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
888 % L i s t C o n f i g u r e I n f o %
892 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894 % ListConfigureInfo() lists the configure info to a file.
896 % The format of the ListConfigureInfo method is:
898 % MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
900 % A description of each parameter follows.
902 % o file: An pointer to a FILE.
904 % o exception: return any errors or warnings in this structure.
907 MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
908 ExceptionInfo *exception)
927 if (file == (const FILE *) NULL)
929 configure_info=GetConfigureInfoList("*",&number_options,exception);
930 if (configure_info == (const ConfigureInfo **) NULL)
932 path=(const char *) NULL;
933 for (i=0; i < (ssize_t) number_options; i++)
935 if (configure_info[i]->stealth != MagickFalse)
937 if ((path == (const char *) NULL) ||
938 (LocaleCompare(path,configure_info[i]->path) != 0))
940 if (configure_info[i]->path != (char *) NULL)
941 (void) FormatLocaleFile(file,"\nPath: %s\n\n",
942 configure_info[i]->path);
943 (void) FormatLocaleFile(file,"Name Value\n");
944 (void) FormatLocaleFile(file,
945 "-------------------------------------------------"
946 "------------------------------\n");
948 path=configure_info[i]->path;
950 if (configure_info[i]->name != (char *) NULL)
951 name=configure_info[i]->name;
952 (void) FormatLocaleFile(file,"%s",name);
953 for (j=(ssize_t) strlen(name); j <= 12; j++)
954 (void) FormatLocaleFile(file," ");
955 (void) FormatLocaleFile(file," ");
957 if (configure_info[i]->value != (char *) NULL)
958 value=configure_info[i]->value;
959 (void) FormatLocaleFile(file,"%s",value);
960 (void) FormatLocaleFile(file,"\n");
963 configure_info=(const ConfigureInfo **)
964 RelinquishMagickMemory((void *) configure_info);
969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973 + L o a d C o n f i g u r e L i s t %
977 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979 % LoadConfigureList() loads the configure configuration file which provides a
980 % mapping between configure attributes and a configure name.
982 % The format of the LoadConfigureList method is:
984 % MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
985 % const size_t depth,ExceptionInfo *exception)
987 % A description of each parameter follows:
989 % o xml: The configure list in XML format.
991 % o filename: The configure list filename.
993 % o depth: depth of <include /> statements.
995 % o exception: return any errors or warnings in this structure.
998 static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
999 const size_t depth,ExceptionInfo *exception)
1002 keyword[MaxTextExtent],
1015 Load the configure map file.
1017 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1018 "Loading configure file \"%s\" ...",filename);
1019 if (configure_list == (LinkedListInfo *) NULL)
1021 configure_list=NewLinkedList(0);
1022 if (configure_list == (LinkedListInfo *) NULL)
1024 ThrowFileException(exception,ResourceLimitError,
1025 "MemoryAllocationFailed",filename);
1026 return(MagickFalse);
1030 configure_info=(ConfigureInfo *) NULL;
1031 token=AcquireString((char *) xml);
1032 for (q=(char *) xml; *q != '\0'; )
1037 GetMagickToken(q,&q,token);
1040 (void) CopyMagickString(keyword,token,MaxTextExtent);
1041 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1046 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1047 GetMagickToken(q,&q,token);
1050 if (LocaleNCompare(keyword,"<!--",4) == 0)
1055 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1056 GetMagickToken(q,&q,token);
1059 if (LocaleCompare(keyword,"<include") == 0)
1064 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1066 (void) CopyMagickString(keyword,token,MaxTextExtent);
1067 GetMagickToken(q,&q,token);
1070 GetMagickToken(q,&q,token);
1071 if (LocaleCompare(keyword,"file") == 0)
1074 (void) ThrowMagickException(exception,GetMagickModule(),
1075 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
1079 path[MaxTextExtent],
1082 GetPathComponent(filename,HeadPath,path);
1084 (void) ConcatenateMagickString(path,DirectorySeparator,
1086 if (*token == *DirectorySeparator)
1087 (void) CopyMagickString(path,token,MaxTextExtent);
1089 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1090 xml=FileToString(path,~0,exception);
1091 if (xml != (char *) NULL)
1093 status=LoadConfigureList(xml,path,depth+1,exception);
1094 xml=(char *) RelinquishMagickMemory(xml);
1101 if (LocaleCompare(keyword,"<configure") == 0)
1106 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1107 sizeof(*configure_info));
1108 if (configure_info == (ConfigureInfo *) NULL)
1109 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1110 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1111 configure_info->path=ConstantString(filename);
1112 configure_info->exempt=MagickFalse;
1113 configure_info->signature=MagickSignature;
1116 if (configure_info == (ConfigureInfo *) NULL)
1118 if (LocaleCompare(keyword,"/>") == 0)
1120 status=AppendValueToLinkedList(configure_list,configure_info);
1121 if (status == MagickFalse)
1122 (void) ThrowMagickException(exception,GetMagickModule(),
1123 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1124 configure_info->name);
1125 configure_info=(ConfigureInfo *) NULL;
1128 Parse configure element.
1130 GetMagickToken(q,(const char **) NULL,token);
1133 GetMagickToken(q,&q,token);
1134 GetMagickToken(q,&q,token);
1140 if (LocaleCompare((char *) keyword,"name") == 0)
1142 configure_info->name=ConstantString(token);
1150 if (LocaleCompare((char *) keyword,"stealth") == 0)
1152 configure_info->stealth=IsMagickTrue(token);
1160 if (LocaleCompare((char *) keyword,"value") == 0)
1162 configure_info->value=ConstantString(token);
1171 token=(char *) RelinquishMagickMemory(token);
1176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1180 % L o a d C o n f i g u r e L i s t s %
1184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1186 % LoadConfigureList() loads one or more configure configuration files which
1187 % provides a mapping between configure attributes and a configure name.
1189 % The format of the LoadConfigureLists method is:
1191 % MagickBooleanType LoadConfigureLists(const char *filename,
1192 % ExceptionInfo *exception)
1194 % A description of each parameter follows:
1196 % o filename: the font file name.
1198 % o exception: return any errors or warnings in this structure.
1201 static MagickBooleanType LoadConfigureLists(const char *filename,
1202 ExceptionInfo *exception)
1217 Load built-in configure map.
1220 if (configure_list == (LinkedListInfo *) NULL)
1222 configure_list=NewLinkedList(0);
1223 if (configure_list == (LinkedListInfo *) NULL)
1225 ThrowFileException(exception,ResourceLimitError,
1226 "MemoryAllocationFailed",filename);
1227 return(MagickFalse);
1230 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
1235 register const ConfigureMapInfo
1239 configure_info=(ConfigureInfo *) AcquireMagickMemory(
1240 sizeof(*configure_info));
1241 if (configure_info == (ConfigureInfo *) NULL)
1243 (void) ThrowMagickException(exception,GetMagickModule(),
1244 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1245 configure_info->name);
1248 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
1249 configure_info->path=(char *) "[built-in]";
1250 configure_info->name=(char *) p->name;
1251 configure_info->value=(char *) p->value;
1252 configure_info->exempt=MagickTrue;
1253 configure_info->signature=MagickSignature;
1254 status=AppendValueToLinkedList(configure_list,configure_info);
1255 if (status == MagickFalse)
1256 (void) ThrowMagickException(exception,GetMagickModule(),
1257 ResourceLimitError,"MemoryAllocationFailed","`%s'",
1258 configure_info->name);
1261 Load external configure map.
1263 options=GetConfigureOptions(filename,exception);
1264 option=(const StringInfo *) GetNextValueInLinkedList(options);
1265 while (option != (const StringInfo *) NULL)
1267 status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
1268 GetStringInfoPath(option),0,exception);
1269 option=(const StringInfo *) GetNextValueInLinkedList(options);
1271 options=DestroyConfigureOptions(options);
1272 return(status != 0 ? MagickTrue : MagickFalse);