blob: b9b2bee694655e1329afc91550ec9d3c02a6f09b [file] [log] [blame]
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% CCCC OOO N N FFFFF IIIII GGGG U U RRRR EEEEE %
% C O O NN N F I G U U R R E %
% C O O N N N FFF I G GG U U RRRR EEE %
% C O O N NN F I G G U U R R E %
% CCCC OOO N N F IIIII GGG UUU R R EEEEE %
% %
% %
% MagickCore Image Configure Methods %
% %
% Software Design %
% John Cristy %
% July 2003 %
% %
% %
% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
% dedicated to making software imaging solutions freely available. %
% %
% You may not use this file except in compliance with the License. You may %
% obtain a copy of the License at %
% %
% http://www.imagemagick.org/script/license.php %
% %
% Unless required by applicable law or agreed to in writing, software %
% distributed under the License is distributed on an "AS IS" BASIS, %
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
% See the License for the specific language governing permissions and %
% limitations under the License. %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
*/
/*
Include declarations.
*/
#include "MagickCore/studio.h"
#include "MagickCore/blob.h"
#include "MagickCore/client.h"
#include "MagickCore/configure.h"
#include "MagickCore/exception.h"
#include "MagickCore/exception-private.h"
#include "MagickCore/hashmap.h"
#include "MagickCore/log.h"
#include "MagickCore/memory_.h"
#include "MagickCore/semaphore.h"
#include "MagickCore/string_.h"
#include "MagickCore/token.h"
#include "MagickCore/utility.h"
#include "MagickCore/xml-tree.h"
/*
Define declarations.
*/
#define ConfigureFilename "configure.xml"
/*
Typedef declarations.
*/
typedef struct _ConfigureMapInfo
{
const char
*name,
*value;
} ConfigureMapInfo;
/*
Static declarations.
*/
static const ConfigureMapInfo
ConfigureMap[] =
{
{ "NAME", "ImageMagick" }
};
static LinkedListInfo
*configure_list = (LinkedListInfo *) NULL;
static SemaphoreInfo
*configure_semaphore = (SemaphoreInfo *) NULL;
static volatile MagickBooleanType
instantiate_configure = MagickFalse;
/*
Forward declarations.
*/
static MagickBooleanType
InitializeConfigureList(ExceptionInfo *),
LoadConfigureLists(const char *,ExceptionInfo *);
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ 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 %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ConfigureComponentGenesis() instantiates the configure component.
%
% The format of the ConfigureComponentGenesis method is:
%
% MagickBooleanType ConfigureComponentGenesis(void)
%
*/
MagickExport MagickBooleanType ConfigureComponentGenesis(void)
{
AcquireSemaphoreInfo(&configure_semaphore);
return(MagickTrue);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ 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 %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ConfigureComponentTerminus() destroys the configure component.
%
% The format of the ConfigureComponentTerminus method is:
%
% ConfigureComponentTerminus(void)
%
*/
static void *DestroyConfigureElement(void *configure_info)
{
register ConfigureInfo
*p;
p=(ConfigureInfo *) configure_info;
if (p->exempt == MagickFalse)
{
if (p->value != (char *) NULL)
p->value=DestroyString(p->value);
if (p->name != (char *) NULL)
p->name=DestroyString(p->name);
if (p->path != (char *) NULL)
p->path=DestroyString(p->path);
}
p=(ConfigureInfo *) RelinquishMagickMemory(p);
return((void *) NULL);
}
MagickExport void ConfigureComponentTerminus(void)
{
if (configure_semaphore == (SemaphoreInfo *) NULL)
AcquireSemaphoreInfo(&configure_semaphore);
LockSemaphoreInfo(configure_semaphore);
if (configure_list != (LinkedListInfo *) NULL)
configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement);
configure_list=(LinkedListInfo *) NULL;
instantiate_configure=MagickFalse;
UnlockSemaphoreInfo(configure_semaphore);
DestroySemaphoreInfo(&configure_semaphore);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% D e s t r o y C o n f i g u r e O p t i o n s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DestroyConfigureOptions() releases memory associated with an configure
% options.
%
% The format of the DestroyProfiles method is:
%
% LinkedListInfo *DestroyConfigureOptions(Image *image)
%
% A description of each parameter follows:
%
% o image: the image.
%
*/
static void *DestroyOptions(void *option)
{
return(DestroyStringInfo((StringInfo *) option));
}
MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options)
{
assert(options != (LinkedListInfo *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
return(DestroyLinkedList(options,DestroyOptions));
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ G e t C o n f i g u r e I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetConfigureInfo() searches the configure list for the specified name and if
% found returns attributes for that element.
%
% The format of the GetConfigureInfo method is:
%
% const ConfigureInfo *GetConfigureInfo(const char *name,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o configure_info: GetConfigureInfo() searches the configure list for the
% specified name and if found returns attributes for that element.
%
% o name: the configure name.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport const ConfigureInfo *GetConfigureInfo(const char *name,
ExceptionInfo *exception)
{
register const ConfigureInfo
*p;
assert(exception != (ExceptionInfo *) NULL);
if ((configure_list == (LinkedListInfo *) NULL) ||
(instantiate_configure == MagickFalse))
if (InitializeConfigureList(exception) == MagickFalse)
return((const ConfigureInfo *) NULL);
if ((configure_list == (LinkedListInfo *) NULL) ||
(IsLinkedListEmpty(configure_list) != MagickFalse))
return((const ConfigureInfo *) NULL);
if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0));
/*
Search for configure tag.
*/
LockSemaphoreInfo(configure_semaphore);
ResetLinkedListIterator(configure_list);
p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
while (p != (const ConfigureInfo *) NULL)
{
if (LocaleCompare(name,p->name) == 0)
break;
p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
}
if (p != (ConfigureInfo *) NULL)
(void) InsertValueInLinkedList(configure_list,0,
RemoveElementByValueFromLinkedList(configure_list,p));
UnlockSemaphoreInfo(configure_semaphore);
return(p);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t C o n f i g u r e I n f o L i s t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetConfigureInfoList() returns any configure options that match the
% specified pattern.
%
% The format of the GetConfigureInfoList function is:
%
% const ConfigureInfo **GetConfigureInfoList(const char *pattern,
% size_t *number_options,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o pattern: Specifies a pointer to a text string containing a pattern.
%
% o number_options: This integer returns the number of configure options in
% the list.
%
% o exception: return any errors or warnings in this structure.
%
*/
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
static int ConfigureInfoCompare(const void *x,const void *y)
{
const ConfigureInfo
**p,
**q;
p=(const ConfigureInfo **) x,
q=(const ConfigureInfo **) y;
if (LocaleCompare((*p)->path,(*q)->path) == 0)
return(LocaleCompare((*p)->name,(*q)->name));
return(LocaleCompare((*p)->path,(*q)->path));
}
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern,
size_t *number_options,ExceptionInfo *exception)
{
const ConfigureInfo
**options;
register const ConfigureInfo
*p;
register ssize_t
i;
/*
Allocate configure list.
*/
assert(pattern != (char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
assert(number_options != (size_t *) NULL);
*number_options=0;
p=GetConfigureInfo("*",exception);
if (p == (const ConfigureInfo *) NULL)
return((const ConfigureInfo **) NULL);
options=(const ConfigureInfo **) AcquireQuantumMemory((size_t)
GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
if (options == (const ConfigureInfo **) NULL)
return((const ConfigureInfo **) NULL);
/*
Generate configure list.
*/
LockSemaphoreInfo(configure_semaphore);
ResetLinkedListIterator(configure_list);
p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
for (i=0; p != (const ConfigureInfo *) NULL; )
{
if ((p->stealth == MagickFalse) &&
(GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
options[i++]=p;
p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
}
UnlockSemaphoreInfo(configure_semaphore);
qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare);
options[i]=(ConfigureInfo *) NULL;
*number_options=(size_t) i;
return(options);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t C o n f i g u r e L i s t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetConfigureList() returns any configure options that match the specified
% pattern.
%
% The format of the GetConfigureList function is:
%
% char **GetConfigureList(const char *pattern,
% size_t *number_options,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o pattern: Specifies a pointer to a text string containing a pattern.
%
% o number_options: This integer returns the number of options in the list.
%
% o exception: return any errors or warnings in this structure.
%
*/
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
static int ConfigureCompare(const void *x,const void *y)
{
register char
**p,
**q;
p=(char **) x;
q=(char **) y;
return(LocaleCompare(*p,*q));
}
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
MagickExport char **GetConfigureList(const char *pattern,
size_t *number_options,ExceptionInfo *exception)
{
char
**options;
register const ConfigureInfo
*p;
register ssize_t
i;
/*
Allocate configure list.
*/
assert(pattern != (char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
assert(number_options != (size_t *) NULL);
*number_options=0;
p=GetConfigureInfo("*",exception);
if (p == (const ConfigureInfo *) NULL)
return((char **) NULL);
options=(char **) AcquireQuantumMemory((size_t)
GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options));
if (options == (char **) NULL)
return((char **) NULL);
LockSemaphoreInfo(configure_semaphore);
ResetLinkedListIterator(configure_list);
p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
for (i=0; p != (const ConfigureInfo *) NULL; )
{
if ((p->stealth == MagickFalse) &&
(GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
options[i++]=ConstantString(p->name);
p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list);
}
UnlockSemaphoreInfo(configure_semaphore);
qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare);
options[i]=(char *) NULL;
*number_options=(size_t) i;
return(options);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t C o n f i g u r e O p t i o n %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetConfigureOption() returns the value associated with the configure option.
%
% The format of the GetConfigureOption method is:
%
% char *GetConfigureOption(const char *option)
%
% A description of each parameter follows:
%
% o configure_info: The configure info.
%
*/
MagickExport char *GetConfigureOption(const char *option)
{
const char
*value;
const ConfigureInfo
*configure_info;
ExceptionInfo
*exception;
assert(option != (const char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option);
exception=AcquireExceptionInfo();
configure_info=GetConfigureInfo(option,exception);
exception=DestroyExceptionInfo(exception);
if (configure_info == (ConfigureInfo *) NULL)
return((char *) NULL);
value=GetConfigureValue(configure_info);
if ((value == (const char *) NULL) || (*value == '\0'))
return((char *) NULL);
return(ConstantString(value));
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t C o n f i g u r e O p t i o n s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetConfigureOptions() returns any Magick configuration options associated
% with the specified filename.
%
% The format of the GetConfigureOptions method is:
%
% LinkedListInfo *GetConfigureOptions(const char *filename,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o filename: the configure file name.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport LinkedListInfo *GetConfigureOptions(const char *filename,
ExceptionInfo *exception)
{
char
path[MaxTextExtent];
const char
*element;
LinkedListInfo
*options,
*paths;
StringInfo
*xml;
assert(filename != (const char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
assert(exception != (ExceptionInfo *) NULL);
(void) CopyMagickString(path,filename,MaxTextExtent);
/*
Load XML from configuration files to linked-list.
*/
options=NewLinkedList(0);
paths=GetConfigurePaths(filename,exception);
if (paths != (LinkedListInfo *) NULL)
{
ResetLinkedListIterator(paths);
element=(const char *) GetNextValueInLinkedList(paths);
while (element != (const char *) NULL)
{
(void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename);
(void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
"Searching for configure file: \"%s\"",path);
xml=ConfigureFileToStringInfo(path);
if (xml != (StringInfo *) NULL)
(void) AppendValueToLinkedList(options,xml);
element=(const char *) GetNextValueInLinkedList(paths);
}
paths=DestroyLinkedList(paths,RelinquishMagickMemory);
}
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
{
char
*blob;
blob=(char *) NTResourceToBlob(filename);
if (blob != (char *) NULL)
{
xml=StringToStringInfo(blob);
SetStringInfoPath(xml,filename);
(void) AppendValueToLinkedList(options,xml);
blob=DestroyString(blob);
}
}
#endif
if (GetNumberOfElementsInLinkedList(options) == 0)
(void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning,
"UnableToOpenConfigureFile","`%s'",filename);
ResetLinkedListIterator(options);
return(options);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t C o n f i g u r e P a t h s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetConfigurePaths() returns any Magick configuration paths associated
% with the specified filename.
%
% The format of the GetConfigurePaths method is:
%
% LinkedListInfo *GetConfigurePaths(const char *filename,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o filename: the configure file name.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport LinkedListInfo *GetConfigurePaths(const char *filename,
ExceptionInfo *exception)
{
char
path[MaxTextExtent];
LinkedListInfo
*paths;
assert(filename != (const char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
assert(exception != (ExceptionInfo *) NULL);
(void) CopyMagickString(path,filename,MaxTextExtent);
paths=NewLinkedList(0);
{
char
*configure_path;
/*
Search $MAGICK_CONFIGURE_PATH.
*/
configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH");
if (configure_path != (char *) NULL)
{
register char
*p,
*q;
for (p=configure_path-1; p != (char *) NULL; )
{
(void) CopyMagickString(path,p+1,MaxTextExtent);
q=strchr(path,DirectoryListSeparator);
if (q != (char *) NULL)
*q='\0';
q=path+strlen(path)-1;
if ((q >= path) && (*q != *DirectorySeparator))
(void) ConcatenateMagickString(path,DirectorySeparator,
MaxTextExtent);
(void) AppendValueToLinkedList(paths,ConstantString(path));
p=strchr(p+1,DirectoryListSeparator);
}
configure_path=DestroyString(configure_path);
}
}
#if defined(MAGICKCORE_INSTALLED_SUPPORT)
#if defined(MAGICKCORE_SHARE_PATH)
(void) AppendValueToLinkedList(paths,ConstantString(
MAGICKCORE_SHARE_PATH));
#endif
#if defined(MAGICKCORE_CONFIGURE_PATH)
(void) AppendValueToLinkedList(paths,ConstantString(
MAGICKCORE_CONFIGURE_PATH));
#endif
#if defined(MAGICKCORE_DOCUMENTATION_PATH)
(void) AppendValueToLinkedList(paths,ConstantString(
MAGICKCORE_DOCUMENTATION_PATH));
#endif
#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH))
{
char
*registry_key;
unsigned char
*key_value;
/*
Locate file via registry key.
*/
registry_key="ConfigurePath";
key_value=NTRegistryKeyLookup(registry_key);
if (key_value != (unsigned char *) NULL)
{
(void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value,
DirectorySeparator);
(void) AppendValueToLinkedList(paths,ConstantString(path));
key_value=(unsigned char *) RelinquishMagickMemory(key_value);
}
}
#endif
#else
{
char
*home;
/*
Search under MAGICK_HOME.
*/
home=GetEnvironmentValue("MAGICK_HOME");
if (home != (char *) NULL)
{
#if !defined(MAGICKCORE_POSIX_SUPPORT)
(void) FormatLocaleString(path,MaxTextExtent,"%s%s",home,
DirectorySeparator);
(void) AppendValueToLinkedList(paths,ConstantString(path));
#else
(void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home,
MAGICKCORE_CONFIGURE_RELATIVE_PATH);
(void) AppendValueToLinkedList(paths,ConstantString(path));
(void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home,
MAGICKCORE_SHARE_RELATIVE_PATH);
(void) AppendValueToLinkedList(paths,ConstantString(path));
#endif
home=DestroyString(home);
}
}
if (*GetClientPath() != '\0')
{
#if !defined(MAGICKCORE_POSIX_SUPPORT)
(void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(),
DirectorySeparator);
(void) AppendValueToLinkedList(paths,ConstantString(path));
#else
char
prefix[MaxTextExtent];
/*
Search based on executable directory if directory is known.
*/
(void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent);
ChopPathComponents(prefix,1);
(void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix,
MAGICKCORE_CONFIGURE_RELATIVE_PATH);
(void) AppendValueToLinkedList(paths,ConstantString(path));
(void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix,
MAGICKCORE_SHARE_RELATIVE_PATH);
(void) AppendValueToLinkedList(paths,ConstantString(path));
#endif
}
/*
Search current directory.
*/
(void) AppendValueToLinkedList(paths,ConstantString(""));
#endif
{
char
*home;
home=GetEnvironmentValue("HOME");
if (home == (char *) NULL)
home=GetEnvironmentValue("USERPROFILE");
if (home != (char *) NULL)
{
/*
Search $HOME/.magick.
*/
(void) FormatLocaleString(path,MaxTextExtent,"%s%s.magick%s",home,
DirectorySeparator,DirectorySeparator);
(void) AppendValueToLinkedList(paths,ConstantString(path));
home=DestroyString(home);
}
}
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
{
char
module_path[MaxTextExtent];
if ((NTGetModulePath("CORE_RL_magick_.dll",module_path) != MagickFalse) ||
(NTGetModulePath("CORE_DB_magick_.dll",module_path) != MagickFalse))
{
char
*element;
/*
Search module path.
*/
(void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
DirectorySeparator);
element=(char *) RemoveElementByValueFromLinkedList(paths,path);
if (element != (char *) NULL)
element=DestroyString(element);
(void) AppendValueToLinkedList(paths,ConstantString(path));
}
if (NTGetModulePath("Magick.dll",module_path) != MagickFalse)
{
/*
Search PerlMagick module path.
*/
(void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
DirectorySeparator);
(void) AppendValueToLinkedList(paths,ConstantString(path));
(void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path,
"\\inc\\lib\\auto\\Image\\Magick\\");
(void) AppendValueToLinkedList(paths,ConstantString(path));
}
}
#endif
return(paths);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% G e t C o n f i g u r e V a l u e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GetConfigureValue() returns the value associated with the configure info.
%
% The format of the GetConfigureValue method is:
%
% const char *GetConfigureValue(const ConfigureInfo *configure_info)
%
% A description of each parameter follows:
%
% o configure_info: The configure info.
%
*/
MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info)
{
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
assert(configure_info != (ConfigureInfo *) NULL);
assert(configure_info->signature == MagickSignature);
return(configure_info->value);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ I n i t i a l i z e C o n f i g u r e L i s t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% InitializeConfigureList() initializes the configure list.
%
% The format of the InitializeConfigureList method is:
%
% MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
%
% A description of each parameter follows.
%
% o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception)
{
if ((configure_list == (LinkedListInfo *) NULL) &&
(instantiate_configure == MagickFalse))
{
if (configure_semaphore == (SemaphoreInfo *) NULL)
AcquireSemaphoreInfo(&configure_semaphore);
LockSemaphoreInfo(configure_semaphore);
if ((configure_list == (LinkedListInfo *) NULL) &&
(instantiate_configure == MagickFalse))
{
(void) LoadConfigureLists(ConfigureFilename,exception);
instantiate_configure=MagickTrue;
}
UnlockSemaphoreInfo(configure_semaphore);
}
return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% L i s t C o n f i g u r e I n f o %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ListConfigureInfo() lists the configure info to a file.
%
% The format of the ListConfigureInfo method is:
%
% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception)
%
% A description of each parameter follows.
%
% o file: An pointer to a FILE.
%
% o exception: return any errors or warnings in this structure.
%
*/
MagickExport MagickBooleanType ListConfigureInfo(FILE *file,
ExceptionInfo *exception)
{
const char
*name,
*path,
*value;
const ConfigureInfo
**configure_info;
register ssize_t
i;
size_t
number_options;
ssize_t
j;
if (file == (const FILE *) NULL)
file=stdout;
configure_info=GetConfigureInfoList("*",&number_options,exception);
if (configure_info == (const ConfigureInfo **) NULL)
return(MagickFalse);
path=(const char *) NULL;
for (i=0; i < (ssize_t) number_options; i++)
{
if (configure_info[i]->stealth != MagickFalse)
continue;
if ((path == (const char *) NULL) ||
(LocaleCompare(path,configure_info[i]->path) != 0))
{
if (configure_info[i]->path != (char *) NULL)
(void) FormatLocaleFile(file,"\nPath: %s\n\n",
configure_info[i]->path);
(void) FormatLocaleFile(file,"Name Value\n");
(void) FormatLocaleFile(file,
"-------------------------------------------------"
"------------------------------\n");
}
path=configure_info[i]->path;
name="unknown";
if (configure_info[i]->name != (char *) NULL)
name=configure_info[i]->name;
(void) FormatLocaleFile(file,"%s",name);
for (j=(ssize_t) strlen(name); j <= 12; j++)
(void) FormatLocaleFile(file," ");
(void) FormatLocaleFile(file," ");
value="unknown";
if (configure_info[i]->value != (char *) NULL)
value=configure_info[i]->value;
(void) FormatLocaleFile(file,"%s",value);
(void) FormatLocaleFile(file,"\n");
}
(void) fflush(file);
configure_info=(const ConfigureInfo **)
RelinquishMagickMemory((void *) configure_info);
return(MagickTrue);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ L o a d C o n f i g u r e L i s t %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LoadConfigureList() loads the configure configuration file which provides a
% mapping between configure attributes and a configure name.
%
% The format of the LoadConfigureList method is:
%
% MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
% const size_t depth,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o xml: The configure list in XML format.
%
% o filename: The configure list filename.
%
% o depth: depth of <include /> statements.
%
% o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType LoadConfigureList(const char *xml,const char *filename,
const size_t depth,ExceptionInfo *exception)
{
char
keyword[MaxTextExtent],
*token;
ConfigureInfo
*configure_info;
const char
*q;
MagickBooleanType
status;
/*
Load the configure map file.
*/
(void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
"Loading configure file \"%s\" ...",filename);
if (configure_list == (LinkedListInfo *) NULL)
{
configure_list=NewLinkedList(0);
if (configure_list == (LinkedListInfo *) NULL)
{
ThrowFileException(exception,ResourceLimitError,
"MemoryAllocationFailed",filename);
return(MagickFalse);
}
}
status=MagickTrue;
configure_info=(ConfigureInfo *) NULL;
token=AcquireString((char *) xml);
for (q=(char *) xml; *q != '\0'; )
{
/*
Interpret XML.
*/
GetMagickToken(q,&q,token);
if (*token == '\0')
break;
(void) CopyMagickString(keyword,token,MaxTextExtent);
if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
{
/*
Doctype element.
*/
while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
GetMagickToken(q,&q,token);
continue;
}
if (LocaleNCompare(keyword,"<!--",4) == 0)
{
/*
Comment element.
*/
while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
GetMagickToken(q,&q,token);
continue;
}
if (LocaleCompare(keyword,"<include") == 0)
{
/*
Include element.
*/
while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
{
(void) CopyMagickString(keyword,token,MaxTextExtent);
GetMagickToken(q,&q,token);
if (*token != '=')
continue;
GetMagickToken(q,&q,token);
if (LocaleCompare(keyword,"file") == 0)
{
if (depth > 200)
(void) ThrowMagickException(exception,GetMagickModule(),
ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token);
else
{
char
path[MaxTextExtent],
*xml;
GetPathComponent(filename,HeadPath,path);
if (*path != '\0')
(void) ConcatenateMagickString(path,DirectorySeparator,
MaxTextExtent);
if (*token == *DirectorySeparator)
(void) CopyMagickString(path,token,MaxTextExtent);
else
(void) ConcatenateMagickString(path,token,MaxTextExtent);
xml=FileToString(path,~0,exception);
if (xml != (char *) NULL)
{
status=LoadConfigureList(xml,path,depth+1,exception);
xml=(char *) RelinquishMagickMemory(xml);
}
}
}
}
continue;
}
if (LocaleCompare(keyword,"<configure") == 0)
{
/*
Configure element.
*/
configure_info=(ConfigureInfo *) AcquireMagickMemory(
sizeof(*configure_info));
if (configure_info == (ConfigureInfo *) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
(void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
configure_info->path=ConstantString(filename);
configure_info->exempt=MagickFalse;
configure_info->signature=MagickSignature;
continue;
}
if (configure_info == (ConfigureInfo *) NULL)
continue;
if (LocaleCompare(keyword,"/>") == 0)
{
status=AppendValueToLinkedList(configure_list,configure_info);
if (status == MagickFalse)
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
configure_info->name);
configure_info=(ConfigureInfo *) NULL;
}
/*
Parse configure element.
*/
GetMagickToken(q,(const char **) NULL,token);
if (*token != '=')
continue;
GetMagickToken(q,&q,token);
GetMagickToken(q,&q,token);
switch (*keyword)
{
case 'N':
case 'n':
{
if (LocaleCompare((char *) keyword,"name") == 0)
{
configure_info->name=ConstantString(token);
break;
}
break;
}
case 'S':
case 's':
{
if (LocaleCompare((char *) keyword,"stealth") == 0)
{
configure_info->stealth=IsMagickTrue(token);
break;
}
break;
}
case 'V':
case 'v':
{
if (LocaleCompare((char *) keyword,"value") == 0)
{
configure_info->value=ConstantString(token);
break;
}
break;
}
default:
break;
}
}
token=(char *) RelinquishMagickMemory(token);
return(status);
}
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
% L o a d C o n f i g u r e L i s t s %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% LoadConfigureList() loads one or more configure configuration files which
% provides a mapping between configure attributes and a configure name.
%
% The format of the LoadConfigureLists method is:
%
% MagickBooleanType LoadConfigureLists(const char *filename,
% ExceptionInfo *exception)
%
% A description of each parameter follows:
%
% o filename: the font file name.
%
% o exception: return any errors or warnings in this structure.
%
*/
static MagickBooleanType LoadConfigureLists(const char *filename,
ExceptionInfo *exception)
{
const StringInfo
*option;
LinkedListInfo
*options;
MagickStatusType
status;
register ssize_t
i;
/*
Load built-in configure map.
*/
status=MagickFalse;
if (configure_list == (LinkedListInfo *) NULL)
{
configure_list=NewLinkedList(0);
if (configure_list == (LinkedListInfo *) NULL)
{
ThrowFileException(exception,ResourceLimitError,
"MemoryAllocationFailed",filename);
return(MagickFalse);
}
}
for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++)
{
ConfigureInfo
*configure_info;
register const ConfigureMapInfo
*p;
p=ConfigureMap+i;
configure_info=(ConfigureInfo *) AcquireMagickMemory(
sizeof(*configure_info));
if (configure_info == (ConfigureInfo *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
configure_info->name);
continue;
}
(void) ResetMagickMemory(configure_info,0,sizeof(*configure_info));
configure_info->path=(char *) "[built-in]";
configure_info->name=(char *) p->name;
configure_info->value=(char *) p->value;
configure_info->exempt=MagickTrue;
configure_info->signature=MagickSignature;
status=AppendValueToLinkedList(configure_list,configure_info);
if (status == MagickFalse)
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",
configure_info->name);
}
/*
Load external configure map.
*/
options=GetConfigureOptions(filename,exception);
option=(const StringInfo *) GetNextValueInLinkedList(options);
while (option != (const StringInfo *) NULL)
{
status|=LoadConfigureList((const char *) GetStringInfoDatum(option),
GetStringInfoPath(option),0,exception);
option=(const StringInfo *) GetNextValueInLinkedList(options);
}
options=DestroyConfigureOptions(options);
return(status != 0 ? MagickTrue : MagickFalse);
}