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