configure.c revision 1460f26c740619877283a50656e43db099ebfa1c
1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 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 % 11% % 12% % 13% MagickCore Image Configure Methods % 14% % 15% Software Design % 16% Cristy % 17% July 2003 % 18% % 19% % 20% Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization % 21% dedicated to making software imaging solutions freely available. % 22% % 23% You may not use this file except in compliance with the License. You may % 24% obtain a copy of the License at % 25% % 26% http://www.imagemagick.org/script/license.php % 27% % 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. % 33% % 34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35% 36% 37*/ 38 39/* 40 Include declarations. 41*/ 42#include "MagickCore/studio.h" 43#include "MagickCore/blob.h" 44#include "MagickCore/client.h" 45#include "MagickCore/configure.h" 46#include "MagickCore/configure-private.h" 47#include "MagickCore/exception.h" 48#include "MagickCore/exception-private.h" 49#include "MagickCore/hashmap.h" 50#include "MagickCore/log.h" 51#include "MagickCore/memory_.h" 52#include "MagickCore/semaphore.h" 53#include "MagickCore/string_.h" 54#include "MagickCore/string-private.h" 55#include "MagickCore/token.h" 56#include "MagickCore/utility.h" 57#include "MagickCore/utility-private.h" 58#include "MagickCore/xml-tree.h" 59 60/* 61 Define declarations. 62*/ 63#define ConfigureFilename "configure.xml" 64 65#ifdef _OPENMP 66#define MAGICKCORE_FEATURE_OPENMP_STR "OpenMP " 67#else 68#define MAGICKCORE_FEATURE_OPENMP_STR "" 69#endif 70#ifdef _OPENCL 71#define MAGICKCORE_FEATURE_OPENCL_STR "OpenCL " 72#else 73#define MAGICKCORE_FEATURE_OPENCL_STR "" 74#endif 75#ifdef MAGICKCORE_ZERO_CONFIGURATION_SUPPORT 76#define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR "Zero-Configuration " 77#else 78#define MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR "" 79#endif 80#ifdef HDRI_SUPPORT 81#define MAGICKCORE_FEATURE_HDRI_STR "HDRI" 82#else 83#define MAGICKCORE_FEATURE_HDRI_STR "" 84#endif 85 86#define MAGICKCORE_FEATURES_STR MAGICKCORE_FEATURE_OPENMP_STR MAGICKCORE_FEATURE_OPENCL_STR MAGICKCORE_FEATURE_ZERO_CONFIGURATION_STR MAGICKCORE_FEATURE_HDRI_STR 87 88/* 89 Typedef declarations. 90*/ 91typedef struct _ConfigureMapInfo 92{ 93 const char 94 *name, 95 *value; 96} ConfigureMapInfo; 97 98/* 99 Static declarations. 100*/ 101static const ConfigureMapInfo 102 ConfigureMap[] = 103 { 104 { "NAME", "ImageMagick" }, 105 { "QuantumDepth", MAGICKCORE_STRING_XQUOTE(MAGICKCORE_QUANTUM_DEPTH) } , 106 { "FEATURES", MAGICKCORE_FEATURES_STR } 107 }; 108 109static LinkedListInfo 110 *configure_list = (LinkedListInfo *) NULL; 111 112static SemaphoreInfo 113 *configure_semaphore = (SemaphoreInfo *) NULL; 114 115/* 116 Forward declarations. 117*/ 118static MagickBooleanType 119 InitializeConfigureList(ExceptionInfo *), 120 LoadConfigureLists(const char *,ExceptionInfo *); 121 122/* 123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 124% % 125% % 126% % 127+ 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 % 128% % 129% % 130% % 131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 132% 133% ConfigureComponentGenesis() instantiates the configure component. 134% 135% The format of the ConfigureComponentGenesis method is: 136% 137% MagickBooleanType ConfigureComponentGenesis(void) 138% 139*/ 140MagickPrivate MagickBooleanType ConfigureComponentGenesis(void) 141{ 142 configure_semaphore=AcquireSemaphoreInfo(); 143 return(MagickTrue); 144} 145 146/* 147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 148% % 149% % 150% % 151+ 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 % 152% % 153% % 154% % 155%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 156% 157% ConfigureComponentTerminus() destroys the configure component. 158% 159% The format of the ConfigureComponentTerminus method is: 160% 161% ConfigureComponentTerminus(void) 162% 163*/ 164 165static void *DestroyConfigureElement(void *configure_info) 166{ 167 register ConfigureInfo 168 *p; 169 170 p=(ConfigureInfo *) configure_info; 171 if (p->exempt == MagickFalse) 172 { 173 if (p->value != (char *) NULL) 174 p->value=DestroyString(p->value); 175 if (p->name != (char *) NULL) 176 p->name=DestroyString(p->name); 177 if (p->path != (char *) NULL) 178 p->path=DestroyString(p->path); 179 } 180 p=(ConfigureInfo *) RelinquishMagickMemory(p); 181 return((void *) NULL); 182} 183 184MagickPrivate void ConfigureComponentTerminus(void) 185{ 186 if (configure_semaphore == (SemaphoreInfo *) NULL) 187 ActivateSemaphoreInfo(&configure_semaphore); 188 LockSemaphoreInfo(configure_semaphore); 189 if (configure_list != (LinkedListInfo *) NULL) 190 configure_list=DestroyLinkedList(configure_list,DestroyConfigureElement); 191 configure_list=(LinkedListInfo *) NULL; 192 UnlockSemaphoreInfo(configure_semaphore); 193 RelinquishSemaphoreInfo(&configure_semaphore); 194} 195 196/* 197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 198% % 199% % 200% % 201% D e s t r o y C o n f i g u r e O p t i o n s % 202% % 203% % 204% % 205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 206% 207% DestroyConfigureOptions() releases memory associated with an configure 208% options. 209% 210% The format of the DestroyProfiles method is: 211% 212% LinkedListInfo *DestroyConfigureOptions(Image *image) 213% 214% A description of each parameter follows: 215% 216% o image: the image. 217% 218*/ 219 220static void *DestroyOptions(void *option) 221{ 222 return(DestroyStringInfo((StringInfo *) option)); 223} 224 225MagickExport LinkedListInfo *DestroyConfigureOptions(LinkedListInfo *options) 226{ 227 assert(options != (LinkedListInfo *) NULL); 228 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 229 return(DestroyLinkedList(options,DestroyOptions)); 230} 231 232/* 233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 234% % 235% % 236% % 237+ G e t C o n f i g u r e I n f o % 238% % 239% % 240% % 241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 242% 243% GetConfigureInfo() searches the configure list for the specified name and if 244% found returns attributes for that element. 245% 246% The format of the GetConfigureInfo method is: 247% 248% const ConfigureInfo *GetConfigureInfo(const char *name, 249% ExceptionInfo *exception) 250% 251% A description of each parameter follows: 252% 253% o configure_info: GetConfigureInfo() searches the configure list for the 254% specified name and if found returns attributes for that element. 255% 256% o name: the configure name. 257% 258% o exception: return any errors or warnings in this structure. 259% 260*/ 261MagickExport const ConfigureInfo *GetConfigureInfo(const char *name, 262 ExceptionInfo *exception) 263{ 264 register const ConfigureInfo 265 *p; 266 267 assert(exception != (ExceptionInfo *) NULL); 268 if (configure_list == (LinkedListInfo *) NULL) 269 if (InitializeConfigureList(exception) == MagickFalse) 270 return((const ConfigureInfo *) NULL); 271 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0)) 272 return((const ConfigureInfo *) GetValueFromLinkedList(configure_list,0)); 273 /* 274 Search for configure tag. 275 */ 276 LockSemaphoreInfo(configure_semaphore); 277 ResetLinkedListIterator(configure_list); 278 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 279 while (p != (const ConfigureInfo *) NULL) 280 { 281 if (LocaleCompare(name,p->name) == 0) 282 break; 283 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 284 } 285 if (p != (ConfigureInfo *) NULL) 286 (void) InsertValueInLinkedList(configure_list,0, 287 RemoveElementByValueFromLinkedList(configure_list,p)); 288 UnlockSemaphoreInfo(configure_semaphore); 289 return(p); 290} 291 292/* 293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 294% % 295% % 296% % 297% G e t C o n f i g u r e I n f o L i s t % 298% % 299% % 300% % 301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 302% 303% GetConfigureInfoList() returns any configure options that match the 304% specified pattern. 305% 306% The format of the GetConfigureInfoList function is: 307% 308% const ConfigureInfo **GetConfigureInfoList(const char *pattern, 309% size_t *number_options,ExceptionInfo *exception) 310% 311% A description of each parameter follows: 312% 313% o pattern: Specifies a pointer to a text string containing a pattern. 314% 315% o number_options: This integer returns the number of configure options in 316% the list. 317% 318% o exception: return any errors or warnings in this structure. 319% 320*/ 321 322#if defined(__cplusplus) || defined(c_plusplus) 323extern "C" { 324#endif 325 326static int ConfigureInfoCompare(const void *x,const void *y) 327{ 328 const ConfigureInfo 329 **p, 330 **q; 331 332 p=(const ConfigureInfo **) x, 333 q=(const ConfigureInfo **) y; 334 if (LocaleCompare((*p)->path,(*q)->path) == 0) 335 return(LocaleCompare((*p)->name,(*q)->name)); 336 return(LocaleCompare((*p)->path,(*q)->path)); 337} 338 339#if defined(__cplusplus) || defined(c_plusplus) 340} 341#endif 342 343MagickExport const ConfigureInfo **GetConfigureInfoList(const char *pattern, 344 size_t *number_options,ExceptionInfo *exception) 345{ 346 const ConfigureInfo 347 **options; 348 349 register const ConfigureInfo 350 *p; 351 352 register ssize_t 353 i; 354 355 /* 356 Allocate configure list. 357 */ 358 assert(pattern != (char *) NULL); 359 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 360 assert(number_options != (size_t *) NULL); 361 *number_options=0; 362 p=GetConfigureInfo("*",exception); 363 if (p == (const ConfigureInfo *) NULL) 364 return((const ConfigureInfo **) NULL); 365 options=(const ConfigureInfo **) AcquireQuantumMemory((size_t) 366 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options)); 367 if (options == (const ConfigureInfo **) NULL) 368 return((const ConfigureInfo **) NULL); 369 /* 370 Generate configure list. 371 */ 372 LockSemaphoreInfo(configure_semaphore); 373 ResetLinkedListIterator(configure_list); 374 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 375 for (i=0; p != (const ConfigureInfo *) NULL; ) 376 { 377 if ((p->stealth == MagickFalse) && 378 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 379 options[i++]=p; 380 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 381 } 382 UnlockSemaphoreInfo(configure_semaphore); 383 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureInfoCompare); 384 options[i]=(ConfigureInfo *) NULL; 385 *number_options=(size_t) i; 386 return(options); 387} 388 389/* 390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 391% % 392% % 393% % 394% G e t C o n f i g u r e L i s t % 395% % 396% % 397% % 398%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 399% 400% GetConfigureList() returns any configure options that match the specified 401% pattern. 402% 403% The format of the GetConfigureList function is: 404% 405% char **GetConfigureList(const char *pattern, 406% size_t *number_options,ExceptionInfo *exception) 407% 408% A description of each parameter follows: 409% 410% o pattern: Specifies a pointer to a text string containing a pattern. 411% 412% o number_options: This integer returns the number of options in the list. 413% 414% o exception: return any errors or warnings in this structure. 415% 416*/ 417 418#if defined(__cplusplus) || defined(c_plusplus) 419extern "C" { 420#endif 421 422static int ConfigureCompare(const void *x,const void *y) 423{ 424 register char 425 **p, 426 **q; 427 428 p=(char **) x; 429 q=(char **) y; 430 return(LocaleCompare(*p,*q)); 431} 432 433#if defined(__cplusplus) || defined(c_plusplus) 434} 435#endif 436 437MagickExport char **GetConfigureList(const char *pattern, 438 size_t *number_options,ExceptionInfo *exception) 439{ 440 char 441 **options; 442 443 register const ConfigureInfo 444 *p; 445 446 register ssize_t 447 i; 448 449 /* 450 Allocate configure list. 451 */ 452 assert(pattern != (char *) NULL); 453 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern); 454 assert(number_options != (size_t *) NULL); 455 *number_options=0; 456 p=GetConfigureInfo("*",exception); 457 if (p == (const ConfigureInfo *) NULL) 458 return((char **) NULL); 459 options=(char **) AcquireQuantumMemory((size_t) 460 GetNumberOfElementsInLinkedList(configure_list)+1UL,sizeof(*options)); 461 if (options == (char **) NULL) 462 return((char **) NULL); 463 LockSemaphoreInfo(configure_semaphore); 464 ResetLinkedListIterator(configure_list); 465 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 466 for (i=0; p != (const ConfigureInfo *) NULL; ) 467 { 468 if ((p->stealth == MagickFalse) && 469 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse)) 470 options[i++]=ConstantString(p->name); 471 p=(const ConfigureInfo *) GetNextValueInLinkedList(configure_list); 472 } 473 UnlockSemaphoreInfo(configure_semaphore); 474 qsort((void *) options,(size_t) i,sizeof(*options),ConfigureCompare); 475 options[i]=(char *) NULL; 476 *number_options=(size_t) i; 477 return(options); 478} 479 480/* 481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 482% % 483% % 484% % 485% G e t C o n f i g u r e O p t i o n % 486% % 487% % 488% % 489%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 490% 491% GetConfigureOption() returns the value associated with the configure option. 492% 493% The format of the GetConfigureOption method is: 494% 495% char *GetConfigureOption(const char *option) 496% 497% A description of each parameter follows: 498% 499% o configure_info: The configure info. 500% 501*/ 502MagickExport char *GetConfigureOption(const char *option) 503{ 504 const char 505 *value; 506 507 const ConfigureInfo 508 *configure_info; 509 510 ExceptionInfo 511 *exception; 512 513 assert(option != (const char *) NULL); 514 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",option); 515 exception=AcquireExceptionInfo(); 516 configure_info=GetConfigureInfo(option,exception); 517 exception=DestroyExceptionInfo(exception); 518 if (configure_info == (ConfigureInfo *) NULL) 519 return((char *) NULL); 520 value=GetConfigureValue(configure_info); 521 if ((value == (const char *) NULL) || (*value == '\0')) 522 return((char *) NULL); 523 return(ConstantString(value)); 524} 525 526/* 527%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 528% % 529% % 530% % 531% G e t C o n f i g u r e O p t i o n s % 532% % 533% % 534% % 535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 536% 537% GetConfigureOptions() returns any Magick configuration options associated 538% with the specified filename. 539% 540% The format of the GetConfigureOptions method is: 541% 542% LinkedListInfo *GetConfigureOptions(const char *filename, 543% ExceptionInfo *exception) 544% 545% A description of each parameter follows: 546% 547% o filename: the configure file name. 548% 549% o exception: return any errors or warnings in this structure. 550% 551*/ 552MagickExport LinkedListInfo *GetConfigureOptions(const char *filename, 553 ExceptionInfo *exception) 554{ 555 char 556 path[MaxTextExtent]; 557 558 const char 559 *element; 560 561 LinkedListInfo 562 *options, 563 *paths; 564 565 StringInfo 566 *xml; 567 568 assert(filename != (const char *) NULL); 569 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 570 assert(exception != (ExceptionInfo *) NULL); 571 (void) CopyMagickString(path,filename,MaxTextExtent); 572 /* 573 Load XML from configuration files to linked-list. 574 */ 575 options=NewLinkedList(0); 576 paths=GetConfigurePaths(filename,exception); 577 if (paths != (LinkedListInfo *) NULL) 578 { 579 ResetLinkedListIterator(paths); 580 element=(const char *) GetNextValueInLinkedList(paths); 581 while (element != (const char *) NULL) 582 { 583 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",element,filename); 584 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 585 "Searching for configure file: \"%s\"",path); 586 xml=ConfigureFileToStringInfo(path); 587 if (xml != (StringInfo *) NULL) 588 (void) AppendValueToLinkedList(options,xml); 589 element=(const char *) GetNextValueInLinkedList(paths); 590 } 591 paths=DestroyLinkedList(paths,RelinquishMagickMemory); 592 } 593#if defined(MAGICKCORE_WINDOWS_SUPPORT) 594 if (GetNumberOfElementsInLinkedList(options) == 0) 595 { 596 char 597 *blob; 598 599 blob=(char *) NTResourceToBlob(filename); 600 if (blob != (char *) NULL) 601 { 602 xml=AcquireStringInfo(0); 603 SetStringInfoLength(xml,strlen(blob)+1); 604 SetStringInfoDatum(xml,(unsigned char *) blob); 605 SetStringInfoPath(xml,filename); 606 (void) AppendValueToLinkedList(options,xml); 607 } 608 } 609#endif 610 if (GetNumberOfElementsInLinkedList(options) == 0) 611 (void) ThrowMagickException(exception,GetMagickModule(),ConfigureWarning, 612 "UnableToOpenConfigureFile","`%s'",filename); 613 ResetLinkedListIterator(options); 614 return(options); 615} 616 617/* 618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 619% % 620% % 621% % 622% G e t C o n f i g u r e P a t h s % 623% % 624% % 625% % 626%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 627% 628% GetConfigurePaths() returns any Magick configuration paths associated 629% with the specified filename. 630% 631% The format of the GetConfigurePaths method is: 632% 633% LinkedListInfo *GetConfigurePaths(const char *filename, 634% ExceptionInfo *exception) 635% 636% A description of each parameter follows: 637% 638% o filename: the configure file name. 639% 640% o exception: return any errors or warnings in this structure. 641% 642*/ 643MagickExport LinkedListInfo *GetConfigurePaths(const char *filename, 644 ExceptionInfo *exception) 645{ 646#define RegistryKey "ConfigurePath" 647#define MagickCoreDLL "CORE_RL_MagickCore_.dll" 648#define MagickCoreDebugDLL "CORE_DB_MagickCore_.dll" 649 650 char 651 path[MaxTextExtent]; 652 653 LinkedListInfo 654 *paths; 655 656 assert(filename != (const char *) NULL); 657 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 658 assert(exception != (ExceptionInfo *) NULL); 659 (void) CopyMagickString(path,filename,MaxTextExtent); 660 paths=NewLinkedList(0); 661 { 662 char 663 *configure_path; 664 665 /* 666 Search $MAGICK_CONFIGURE_PATH. 667 */ 668 configure_path=GetEnvironmentValue("MAGICK_CONFIGURE_PATH"); 669 if (configure_path != (char *) NULL) 670 { 671 register char 672 *p, 673 *q; 674 675 for (p=configure_path-1; p != (char *) NULL; ) 676 { 677 (void) CopyMagickString(path,p+1,MaxTextExtent); 678 q=strchr(path,DirectoryListSeparator); 679 if (q != (char *) NULL) 680 *q='\0'; 681 q=path+strlen(path)-1; 682 if ((q >= path) && (*q != *DirectorySeparator)) 683 (void) ConcatenateMagickString(path,DirectorySeparator, 684 MaxTextExtent); 685 (void) AppendValueToLinkedList(paths,ConstantString(path)); 686 p=strchr(p+1,DirectoryListSeparator); 687 } 688 configure_path=DestroyString(configure_path); 689 } 690 } 691#if defined(MAGICKCORE_INSTALLED_SUPPORT) 692#if defined(MAGICKCORE_SHARE_PATH) 693 (void) AppendValueToLinkedList(paths,ConstantString(MAGICKCORE_SHARE_PATH)); 694#endif 695#if defined(MAGICKCORE_SHAREARCH_PATH) 696 (void) AppendValueToLinkedList(paths,ConstantString( 697 MAGICKCORE_SHAREARCH_PATH)); 698#endif 699#if defined(MAGICKCORE_CONFIGURE_PATH) 700 (void) AppendValueToLinkedList(paths,ConstantString( 701 MAGICKCORE_CONFIGURE_PATH)); 702#endif 703#if defined(MAGICKCORE_DOCUMENTATION_PATH) 704 (void) AppendValueToLinkedList(paths,ConstantString( 705 MAGICKCORE_DOCUMENTATION_PATH)); 706#endif 707#if defined(MAGICKCORE_WINDOWS_SUPPORT) && !(defined(MAGICKCORE_CONFIGURE_PATH) || defined(MAGICKCORE_SHARE_PATH)) 708 { 709 unsigned char 710 *key_value; 711 712 /* 713 Locate file via registry key. 714 */ 715 key_value=NTRegistryKeyLookup(RegistryKey); 716 if (key_value != (unsigned char *) NULL) 717 { 718 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",(char *) key_value, 719 DirectorySeparator); 720 (void) AppendValueToLinkedList(paths,ConstantString(path)); 721 key_value=(unsigned char *) RelinquishMagickMemory(key_value); 722 } 723 } 724#endif 725#else 726 { 727 char 728 *home; 729 730 /* 731 Search under MAGICK_HOME. 732 */ 733 home=GetEnvironmentValue("MAGICK_HOME"); 734 if (home != (char *) NULL) 735 { 736#if !defined(MAGICKCORE_POSIX_SUPPORT) 737 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",home, 738 DirectorySeparator); 739 (void) AppendValueToLinkedList(paths,ConstantString(path)); 740#else 741 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",home, 742 MAGICKCORE_CONFIGURE_RELATIVE_PATH); 743 (void) AppendValueToLinkedList(paths,ConstantString(path)); 744 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",home, 745 MAGICKCORE_SHARE_RELATIVE_PATH); 746 (void) AppendValueToLinkedList(paths,ConstantString(path)); 747 (void) FormatLocaleString(path,MaxTextExtent,"%s", 748 MAGICKCORE_SHAREARCH_PATH); 749 (void) AppendValueToLinkedList(paths,ConstantString(path)); 750#endif 751 home=DestroyString(home); 752 } 753 } 754 if (*GetClientPath() != '\0') 755 { 756#if !defined(MAGICKCORE_POSIX_SUPPORT) 757 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",GetClientPath(), 758 DirectorySeparator); 759 (void) AppendValueToLinkedList(paths,ConstantString(path)); 760#else 761 char 762 prefix[MaxTextExtent]; 763 764 /* 765 Search based on executable directory if directory is known. 766 */ 767 (void) CopyMagickString(prefix,GetClientPath(),MaxTextExtent); 768 ChopPathComponents(prefix,1); 769 (void) FormatLocaleString(path,MaxTextExtent,"%s/etc/%s/",prefix, 770 MAGICKCORE_CONFIGURE_RELATIVE_PATH); 771 (void) AppendValueToLinkedList(paths,ConstantString(path)); 772 (void) FormatLocaleString(path,MaxTextExtent,"%s/share/%s/",prefix, 773 MAGICKCORE_SHARE_RELATIVE_PATH); 774 (void) AppendValueToLinkedList(paths,ConstantString(path)); 775 (void) FormatLocaleString(path,MaxTextExtent,"%s", 776 MAGICKCORE_SHAREARCH_PATH); 777 (void) AppendValueToLinkedList(paths,ConstantString(path)); 778#endif 779 } 780 /* 781 Search current directory. 782 */ 783 (void) AppendValueToLinkedList(paths,ConstantString("")); 784#endif 785 { 786 char 787 *home; 788 789 home=GetEnvironmentValue("HOME"); 790 if (home == (char *) NULL) 791 home=GetEnvironmentValue("USERPROFILE"); 792 if (home != (char *) NULL) 793 { 794 /* 795 Search $HOME/.config/ImageMagick. 796 */ 797 (void) FormatLocaleString(path,MaxTextExtent, 798 "%s%s.config%sImageMagick%s",home,DirectorySeparator, 799 DirectorySeparator,DirectorySeparator); 800 (void) AppendValueToLinkedList(paths,ConstantString(path)); 801 home=DestroyString(home); 802 } 803 } 804#if defined(MAGICKCORE_WINDOWS_SUPPORT) 805 { 806 char 807 module_path[MaxTextExtent]; 808 809 if ((NTGetModulePath(MagickCoreDLL,module_path) != MagickFalse) || 810 (NTGetModulePath(MagickCoreDebugDLL,module_path) != MagickFalse)) 811 { 812 unsigned char 813 *key_value; 814 815 /* 816 Search module path. 817 */ 818 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, 819 DirectorySeparator); 820 key_value=NTRegistryKeyLookup(RegistryKey); 821 if (key_value == (unsigned char *) NULL) 822 (void) AppendValueToLinkedList(paths,ConstantString(path)); 823 else 824 key_value=(unsigned char *) RelinquishMagickMemory(key_value); 825 } 826 if (NTGetModulePath("Magick.dll",module_path) != MagickFalse) 827 { 828 /* 829 Search PerlMagick module path. 830 */ 831 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, 832 DirectorySeparator); 833 (void) AppendValueToLinkedList(paths,ConstantString(path)); 834 (void) FormatLocaleString(path,MaxTextExtent,"%s%s",module_path, 835 "\\inc\\lib\\auto\\Image\\Magick\\"); 836 (void) AppendValueToLinkedList(paths,ConstantString(path)); 837 } 838 } 839#endif 840 return(paths); 841} 842 843/* 844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 845% % 846% % 847% % 848% G e t C o n f i g u r e V a l u e % 849% % 850% % 851% % 852%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 853% 854% GetConfigureValue() returns the value associated with the configure info. 855% 856% The format of the GetConfigureValue method is: 857% 858% const char *GetConfigureValue(const ConfigureInfo *configure_info) 859% 860% A description of each parameter follows: 861% 862% o configure_info: The configure info. 863% 864*/ 865MagickExport const char *GetConfigureValue(const ConfigureInfo *configure_info) 866{ 867 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 868 assert(configure_info != (ConfigureInfo *) NULL); 869 assert(configure_info->signature == MagickSignature); 870 return(configure_info->value); 871} 872 873/* 874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 875% % 876% % 877% % 878+ I n i t i a l i z e C o n f i g u r e L i s t % 879% % 880% % 881% % 882%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 883% 884% InitializeConfigureList() initializes the configure list. 885% 886% The format of the InitializeConfigureList method is: 887% 888% MagickBooleanType InitializeConfigureList(ExceptionInfo *exception) 889% 890% A description of each parameter follows. 891% 892% o exception: return any errors or warnings in this structure. 893% 894*/ 895static MagickBooleanType InitializeConfigureList(ExceptionInfo *exception) 896{ 897 if (configure_semaphore == (SemaphoreInfo *) NULL) 898 ActivateSemaphoreInfo(&configure_semaphore); 899 LockSemaphoreInfo(configure_semaphore); 900 if (configure_list == (LinkedListInfo *) NULL) 901 (void) LoadConfigureLists(ConfigureFilename,exception); 902 UnlockSemaphoreInfo(configure_semaphore); 903 return(configure_list != (LinkedListInfo *) NULL ? MagickTrue : MagickFalse); 904} 905 906/* 907%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 908% % 909% % 910% % 911% L i s t C o n f i g u r e I n f o % 912% % 913% % 914% % 915%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 916% 917% ListConfigureInfo() lists the configure info to a file. 918% 919% The format of the ListConfigureInfo method is: 920% 921% MagickBooleanType ListConfigureInfo(FILE *file,ExceptionInfo *exception) 922% 923% A description of each parameter follows. 924% 925% o file: An pointer to a FILE. 926% 927% o exception: return any errors or warnings in this structure. 928% 929*/ 930MagickExport MagickBooleanType ListConfigureInfo(FILE *file, 931 ExceptionInfo *exception) 932{ 933 const char 934 *name, 935 *path, 936 *value; 937 938 const ConfigureInfo 939 **configure_info; 940 941 register ssize_t 942 i; 943 944 size_t 945 number_options; 946 947 ssize_t 948 j; 949 950 if (file == (const FILE *) NULL) 951 file=stdout; 952 configure_info=GetConfigureInfoList("*",&number_options,exception); 953 if (configure_info == (const ConfigureInfo **) NULL) 954 return(MagickFalse); 955 path=(const char *) NULL; 956 for (i=0; i < (ssize_t) number_options; i++) 957 { 958 if (configure_info[i]->stealth != MagickFalse) 959 continue; 960 if ((path == (const char *) NULL) || 961 (LocaleCompare(path,configure_info[i]->path) != 0)) 962 { 963 if (configure_info[i]->path != (char *) NULL) 964 (void) FormatLocaleFile(file,"\nPath: %s\n\n", 965 configure_info[i]->path); 966 (void) FormatLocaleFile(file,"Name Value\n"); 967 (void) FormatLocaleFile(file, 968 "-------------------------------------------------" 969 "------------------------------\n"); 970 } 971 path=configure_info[i]->path; 972 name="unknown"; 973 if (configure_info[i]->name != (char *) NULL) 974 name=configure_info[i]->name; 975 (void) FormatLocaleFile(file,"%s",name); 976 for (j=(ssize_t) strlen(name); j <= 13; j++) 977 (void) FormatLocaleFile(file," "); 978 (void) FormatLocaleFile(file," "); 979 value="unknown"; 980 if (configure_info[i]->value != (char *) NULL) 981 value=configure_info[i]->value; 982 (void) FormatLocaleFile(file,"%s",value); 983 (void) FormatLocaleFile(file,"\n"); 984 } 985 (void) fflush(file); 986 configure_info=(const ConfigureInfo **) 987 RelinquishMagickMemory((void *) configure_info); 988 return(MagickTrue); 989} 990 991/* 992%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 993% % 994% % 995% % 996+ L o a d C o n f i g u r e L i s t % 997% % 998% % 999% % 1000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1001% 1002% LoadConfigureList() loads the configure configuration file which provides a 1003% mapping between configure attributes and a configure name. 1004% 1005% The format of the LoadConfigureList method is: 1006% 1007% MagickBooleanType LoadConfigureList(const char *xml,const char *filename, 1008% const size_t depth,ExceptionInfo *exception) 1009% 1010% A description of each parameter follows: 1011% 1012% o xml: The configure list in XML format. 1013% 1014% o filename: The configure list filename. 1015% 1016% o depth: depth of <include /> statements. 1017% 1018% o exception: return any errors or warnings in this structure. 1019% 1020*/ 1021static MagickBooleanType LoadConfigureList(const char *xml,const char *filename, 1022 const size_t depth,ExceptionInfo *exception) 1023{ 1024 char 1025 keyword[MaxTextExtent], 1026 *token; 1027 1028 ConfigureInfo 1029 *configure_info; 1030 1031 const char 1032 *q; 1033 1034 MagickBooleanType 1035 status; 1036 1037 /* 1038 Load the configure map file. 1039 */ 1040 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), 1041 "Loading configure file \"%s\" ...",filename); 1042 if (configure_list == (LinkedListInfo *) NULL) 1043 { 1044 configure_list=NewLinkedList(0); 1045 if (configure_list == (LinkedListInfo *) NULL) 1046 { 1047 ThrowFileException(exception,ResourceLimitError, 1048 "MemoryAllocationFailed",filename); 1049 return(MagickFalse); 1050 } 1051 } 1052 status=MagickTrue; 1053 configure_info=(ConfigureInfo *) NULL; 1054 token=AcquireString((char *) xml); 1055 for (q=(char *) xml; *q != '\0'; ) 1056 { 1057 /* 1058 Interpret XML. 1059 */ 1060 GetMagickToken(q,&q,token); 1061 if (*token == '\0') 1062 break; 1063 (void) CopyMagickString(keyword,token,MaxTextExtent); 1064 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) 1065 { 1066 /* 1067 Doctype element. 1068 */ 1069 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) 1070 GetMagickToken(q,&q,token); 1071 continue; 1072 } 1073 if (LocaleNCompare(keyword,"<!--",4) == 0) 1074 { 1075 /* 1076 Comment element. 1077 */ 1078 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) 1079 GetMagickToken(q,&q,token); 1080 continue; 1081 } 1082 if (LocaleCompare(keyword,"<include") == 0) 1083 { 1084 /* 1085 Include element. 1086 */ 1087 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) 1088 { 1089 (void) CopyMagickString(keyword,token,MaxTextExtent); 1090 GetMagickToken(q,&q,token); 1091 if (*token != '=') 1092 continue; 1093 GetMagickToken(q,&q,token); 1094 if (LocaleCompare(keyword,"file") == 0) 1095 { 1096 if (depth > 200) 1097 (void) ThrowMagickException(exception,GetMagickModule(), 1098 ConfigureError,"IncludeElementNestedTooDeeply","`%s'",token); 1099 else 1100 { 1101 char 1102 path[MaxTextExtent], 1103 *xml; 1104 1105 GetPathComponent(filename,HeadPath,path); 1106 if (*path != '\0') 1107 (void) ConcatenateMagickString(path,DirectorySeparator, 1108 MaxTextExtent); 1109 if (*token == *DirectorySeparator) 1110 (void) CopyMagickString(path,token,MaxTextExtent); 1111 else 1112 (void) ConcatenateMagickString(path,token,MaxTextExtent); 1113 xml=FileToString(path,~0UL,exception); 1114 if (xml != (char *) NULL) 1115 { 1116 status=LoadConfigureList(xml,path,depth+1,exception); 1117 xml=(char *) RelinquishMagickMemory(xml); 1118 } 1119 } 1120 } 1121 } 1122 continue; 1123 } 1124 if (LocaleCompare(keyword,"<configure") == 0) 1125 { 1126 /* 1127 Configure element. 1128 */ 1129 configure_info=(ConfigureInfo *) AcquireMagickMemory( 1130 sizeof(*configure_info)); 1131 if (configure_info == (ConfigureInfo *) NULL) 1132 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 1133 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info)); 1134 configure_info->path=ConstantString(filename); 1135 configure_info->exempt=MagickFalse; 1136 configure_info->signature=MagickSignature; 1137 continue; 1138 } 1139 if (configure_info == (ConfigureInfo *) NULL) 1140 continue; 1141 if (LocaleCompare(keyword,"/>") == 0) 1142 { 1143 status=AppendValueToLinkedList(configure_list,configure_info); 1144 if (status == MagickFalse) 1145 (void) ThrowMagickException(exception,GetMagickModule(), 1146 ResourceLimitError,"MemoryAllocationFailed","`%s'", 1147 configure_info->name); 1148 configure_info=(ConfigureInfo *) NULL; 1149 continue; 1150 } 1151 /* 1152 Parse configure element. 1153 */ 1154 GetMagickToken(q,(const char **) NULL,token); 1155 if (*token != '=') 1156 continue; 1157 GetMagickToken(q,&q,token); 1158 GetMagickToken(q,&q,token); 1159 switch (*keyword) 1160 { 1161 case 'N': 1162 case 'n': 1163 { 1164 if (LocaleCompare((char *) keyword,"name") == 0) 1165 { 1166 configure_info->name=ConstantString(token); 1167 break; 1168 } 1169 break; 1170 } 1171 case 'S': 1172 case 's': 1173 { 1174 if (LocaleCompare((char *) keyword,"stealth") == 0) 1175 { 1176 configure_info->stealth=IsStringTrue(token); 1177 break; 1178 } 1179 break; 1180 } 1181 case 'V': 1182 case 'v': 1183 { 1184 if (LocaleCompare((char *) keyword,"value") == 0) 1185 { 1186 configure_info->value=ConstantString(token); 1187 break; 1188 } 1189 break; 1190 } 1191 default: 1192 break; 1193 } 1194 } 1195 token=(char *) RelinquishMagickMemory(token); 1196 return(status); 1197} 1198 1199/* 1200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1201% % 1202% % 1203% % 1204% L o a d C o n f i g u r e L i s t s % 1205% % 1206% % 1207% % 1208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1209% 1210% LoadConfigureList() loads one or more configure configuration files which 1211% provides a mapping between configure attributes and a configure name. 1212% 1213% The format of the LoadConfigureLists method is: 1214% 1215% MagickBooleanType LoadConfigureLists(const char *filename, 1216% ExceptionInfo *exception) 1217% 1218% A description of each parameter follows: 1219% 1220% o filename: the font file name. 1221% 1222% o exception: return any errors or warnings in this structure. 1223% 1224*/ 1225static MagickBooleanType LoadConfigureLists(const char *filename, 1226 ExceptionInfo *exception) 1227{ 1228 const StringInfo 1229 *option; 1230 1231 LinkedListInfo 1232 *options; 1233 1234 MagickStatusType 1235 status; 1236 1237 register ssize_t 1238 i; 1239 1240 /* 1241 Load external configure map. 1242 */ 1243 if (configure_list == (LinkedListInfo *) NULL) 1244 { 1245 configure_list=NewLinkedList(0); 1246 if (configure_list == (LinkedListInfo *) NULL) 1247 { 1248 ThrowFileException(exception,ResourceLimitError, 1249 "MemoryAllocationFailed",filename); 1250 return(MagickFalse); 1251 } 1252 } 1253 status=MagickTrue; 1254 options=GetConfigureOptions(filename,exception); 1255 option=(const StringInfo *) GetNextValueInLinkedList(options); 1256 while (option != (const StringInfo *) NULL) 1257 { 1258 status&=LoadConfigureList((const char *) GetStringInfoDatum(option), 1259 GetStringInfoPath(option),0,exception); 1260 option=(const StringInfo *) GetNextValueInLinkedList(options); 1261 } 1262 options=DestroyConfigureOptions(options); 1263 /* 1264 Load built-in configure map. 1265 */ 1266 for (i=0; i < (ssize_t) (sizeof(ConfigureMap)/sizeof(*ConfigureMap)); i++) 1267 { 1268 ConfigureInfo 1269 *configure_info; 1270 1271 register const ConfigureMapInfo 1272 *p; 1273 1274 p=ConfigureMap+i; 1275 configure_info=(ConfigureInfo *) AcquireMagickMemory( 1276 sizeof(*configure_info)); 1277 if (configure_info == (ConfigureInfo *) NULL) 1278 { 1279 (void) ThrowMagickException(exception,GetMagickModule(), 1280 ResourceLimitError,"MemoryAllocationFailed","`%s'",p->name); 1281 continue; 1282 } 1283 (void) ResetMagickMemory(configure_info,0,sizeof(*configure_info)); 1284 configure_info->path=(char *) "[built-in]"; 1285 configure_info->name=(char *) p->name; 1286 configure_info->value=(char *) p->value; 1287 configure_info->exempt=MagickTrue; 1288 configure_info->signature=MagickSignature; 1289 status&=AppendValueToLinkedList(configure_list,configure_info); 1290 if (status == MagickFalse) 1291 (void) ThrowMagickException(exception,GetMagickModule(), 1292 ResourceLimitError,"MemoryAllocationFailed","`%s'", 1293 configure_info->name); 1294 } 1295 return(status != 0 ? MagickTrue : MagickFalse); 1296} 1297