string.c revision 77e3fcc5964bb24d44e3a362a82a80bca4f9d43b
1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% sssss ttttt rrrr iiiii n n gggg % 7% ss t r r i nn n g % 8% sss t rrrr i n n n g ggg % 9% ss t r r i n nn g g % 10% sssss t r r iiiii n n gggg % 11% % 12% % 13% MagickCore string methods % 14% % 15% software design % 16% john cristy % 17% august 2003 % 18% % 19% % 20% copyright 1999-2011 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/blob-private.h" 45#include "MagickCore/exception.h" 46#include "MagickCore/exception-private.h" 47#include "MagickCore/list.h" 48#include "MagickCore/locale_.h" 49#include "MagickCore/log.h" 50#include "MagickCore/memory_.h" 51#include "MagickCore/property.h" 52#include "MagickCore/resource_.h" 53#include "MagickCore/signature-private.h" 54#include "MagickCore/string_.h" 55#include "MagickCore/utility-private.h" 56 57/* 58 static declarations. 59*/ 60#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP) 61static const unsigned char 62 asciimap[] = 63 { 64 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 65 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 66 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 67 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 68 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 69 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 70 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 71 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 72 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 73 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 74 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 75 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 76 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 77 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 78 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 79 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 80 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 81 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 82 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 83 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 84 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 85 0xfc, 0xfd, 0xfe, 0xff, 86 }; 87#endif 88 89/* 90%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 91% % 92% % 93% % 94% A c q u i r e S t r i n g % 95% % 96% % 97% % 98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 99% 100% AcquireString() allocates memory for a string and copies the source string 101% to that memory location (and returns it). 102% 103% The format of the AcquireString method is: 104% 105% char *AcquireString(const char *source) 106% 107% A description of each parameter follows: 108% 109% o source: A character string. 110% 111*/ 112MagickExport char *AcquireString(const char *source) 113{ 114 char 115 *destination; 116 117 size_t 118 length; 119 120 length=0; 121 if (source != (char *) NULL) 122 length+=strlen(source); 123 if (~length < MaxTextExtent) 124 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 125 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent, 126 sizeof(*destination)); 127 if (destination == (char *) NULL) 128 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 129 *destination='\0'; 130 if (source != (char *) NULL) 131 (void) memcpy(destination,source,length*sizeof(*destination)); 132 destination[length]='\0'; 133 return(destination); 134} 135 136/* 137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 138% % 139% % 140% % 141% A c q u i r e S t r i n g I n f o % 142% % 143% % 144% % 145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 146% 147% AcquireStringInfo() allocates the StringInfo structure. 148% 149% The format of the AcquireStringInfo method is: 150% 151% StringInfo *AcquireStringInfo(const size_t length) 152% 153% A description of each parameter follows: 154% 155% o length: the string length. 156% 157*/ 158MagickExport StringInfo *AcquireStringInfo(const size_t length) 159{ 160 StringInfo 161 *string_info; 162 163 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info)); 164 if (string_info == (StringInfo *) NULL) 165 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 166 (void) ResetMagickMemory(string_info,0,sizeof(*string_info)); 167 string_info->signature=MagickSignature; 168 string_info->length=length; 169 if (string_info->length != 0) 170 { 171 string_info->datum=(unsigned char *) NULL; 172 if (~string_info->length >= (MaxTextExtent-1)) 173 string_info->datum=(unsigned char *) AcquireQuantumMemory( 174 string_info->length+MaxTextExtent,sizeof(*string_info->datum)); 175 if (string_info->datum == (unsigned char *) NULL) 176 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 177 } 178 return(string_info); 179} 180 181/* 182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 183% % 184% % 185% % 186% B l o b T o S t r i n g I n f o % 187% % 188% % 189% % 190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 191% 192% BlobToStringInfo() returns the contents of a blob as a string. 193% 194% The format of the BlobToStringInfo method is: 195% 196% StringInfo *BlobToStringInfo(const void *blob,const size_t length) 197% 198% A description of each parameter follows: 199% 200% o blob: the blob. 201% 202% o length: the length of the blob. 203% 204*/ 205MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length) 206{ 207 StringInfo 208 *string_info; 209 210 string_info=AcquireStringInfo(0); 211 string_info->length=length; 212 if (~string_info->length >= (MaxTextExtent-1)) 213 string_info->datum=(unsigned char *) AcquireQuantumMemory( 214 string_info->length+MaxTextExtent,sizeof(*string_info->datum)); 215 if (string_info->datum == (unsigned char *) NULL) 216 { 217 string_info=DestroyStringInfo(string_info); 218 return((StringInfo *) NULL); 219 } 220 if (blob != (const void *) NULL) 221 (void) memcpy(string_info->datum,blob,length); 222 return(string_info); 223} 224 225/* 226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 227% % 228% % 229% % 230% C l o n e S t r i n g % 231% % 232% % 233% % 234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 235% 236% CloneString() allocates memory for the destination string and copies 237% the source string to that memory location. 238% 239% The format of the CloneString method is: 240% 241% char *CloneString(char **destination,const char *source) 242% 243% A description of each parameter follows: 244% 245% o destination: A pointer to a character string. 246% 247% o source: A character string. 248% 249*/ 250MagickExport char *CloneString(char **destination,const char *source) 251{ 252 size_t 253 length; 254 255 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 256 assert(destination != (char **) NULL); 257 if (source == (const char *) NULL) 258 { 259 if (*destination != (char *) NULL) 260 *destination=DestroyString(*destination); 261 return(*destination); 262 } 263 if (*destination == (char *) NULL) 264 { 265 *destination=AcquireString(source); 266 return(*destination); 267 } 268 length=strlen(source); 269 if (~length < MaxTextExtent) 270 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 271 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent, 272 sizeof(**destination)); 273 if (*destination == (char *) NULL) 274 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 275 if (length != 0) 276 (void) memcpy(*destination,source,length*sizeof(**destination)); 277 (*destination)[length]='\0'; 278 return(*destination); 279} 280 281/* 282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 283% % 284% % 285% % 286% C l o n e S t r i n g I n f o % 287% % 288% % 289% % 290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 291% 292% CloneStringInfo() clones a copy of the StringInfo structure. 293% 294% The format of the CloneStringInfo method is: 295% 296% StringInfo *CloneStringInfo(const StringInfo *string_info) 297% 298% A description of each parameter follows: 299% 300% o string_info: the string info. 301% 302*/ 303MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info) 304{ 305 StringInfo 306 *clone_info; 307 308 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 309 assert(string_info != (StringInfo *) NULL); 310 assert(string_info->signature == MagickSignature); 311 clone_info=AcquireStringInfo(string_info->length); 312 if (string_info->length != 0) 313 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1); 314 return(clone_info); 315} 316 317/* 318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 319% % 320% % 321% % 322% C o m p a r e S t r i n g I n f o % 323% % 324% % 325% % 326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 327% 328% CompareStringInfo() compares the two datums target and source. It returns 329% an integer less than, equal to, or greater than zero if target is found, 330% respectively, to be less than, to match, or be greater than source. 331% 332% The format of the CompareStringInfo method is: 333% 334% int CompareStringInfo(const StringInfo *target,const StringInfo *source) 335% 336% A description of each parameter follows: 337% 338% o target: the target string. 339% 340% o source: the source string. 341% 342*/ 343 344static inline size_t MagickMin(const size_t x,const size_t y) 345{ 346 if (x < y) 347 return(x); 348 return(y); 349} 350 351MagickExport int CompareStringInfo(const StringInfo *target, 352 const StringInfo *source) 353{ 354 int 355 status; 356 357 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 358 assert(target != (StringInfo *) NULL); 359 assert(target->signature == MagickSignature); 360 assert(source != (StringInfo *) NULL); 361 assert(source->signature == MagickSignature); 362 status=memcmp(target->datum,source->datum,MagickMin(target->length, 363 source->length)); 364 if (status != 0) 365 return(status); 366 if (target->length == source->length) 367 return(0); 368 return(target->length < source->length ? -1 : 1); 369} 370 371/* 372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 373% % 374% % 375% % 376% C o n c a t e n a t e M a g i c k S t r i n g % 377% % 378% % 379% % 380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 381% 382% ConcatenateMagickString() concatenates the source string to the destination 383% string. The destination buffer is always null-terminated even if the 384% string must be truncated. 385% 386% The format of the ConcatenateMagickString method is: 387% 388% size_t ConcatenateMagickString(char *destination,const char *source, 389% const size_t length) 390% 391% A description of each parameter follows: 392% 393% o destination: the destination string. 394% 395% o source: the source string. 396% 397% o length: the length of the destination string. 398% 399*/ 400MagickExport size_t ConcatenateMagickString(char *destination, 401 const char *source,const size_t length) 402{ 403 register char 404 *q; 405 406 register const char 407 *p; 408 409 register size_t 410 i; 411 412 size_t 413 count; 414 415 assert(destination != (char *) NULL); 416 assert(source != (const char *) NULL); 417 assert(length >= 1); 418 p=source; 419 q=destination; 420 i=length; 421 while ((i-- != 0) && (*q != '\0')) 422 q++; 423 count=(size_t) (q-destination); 424 i=length-count; 425 if (i == 0) 426 return(count+strlen(p)); 427 while (*p != '\0') 428 { 429 if (i != 1) 430 { 431 *q++=(*p); 432 i--; 433 } 434 p++; 435 } 436 *q='\0'; 437 return(count+(p-source)); 438} 439 440/* 441%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 442% % 443% % 444% % 445% C o n c a t e n a t e S t r i n g % 446% % 447% % 448% % 449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 450% 451% ConcatenateString() appends a copy of string source, including the 452% terminating null character, to the end of string destination. 453% 454% The format of the ConcatenateString method is: 455% 456% MagickBooleanType ConcatenateString(char **destination, 457% const char *source) 458% 459% A description of each parameter follows: 460% 461% o destination: A pointer to a character string. 462% 463% o source: A character string. 464% 465*/ 466MagickExport MagickBooleanType ConcatenateString(char **destination, 467 const char *source) 468{ 469 size_t 470 destination_length, 471 length, 472 source_length; 473 474 assert(destination != (char **) NULL); 475 if (source == (const char *) NULL) 476 return(MagickTrue); 477 if (*destination == (char *) NULL) 478 { 479 *destination=AcquireString(source); 480 return(MagickTrue); 481 } 482 destination_length=strlen(*destination); 483 source_length=strlen(source); 484 length=destination_length; 485 if (~length < source_length) 486 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); 487 length+=source_length; 488 if (~length < MaxTextExtent) 489 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); 490 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent, 491 sizeof(**destination)); 492 if (*destination == (char *) NULL) 493 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); 494 if (source_length != 0) 495 (void) memcpy((*destination)+destination_length,source,source_length); 496 (*destination)[length]='\0'; 497 return(MagickTrue); 498} 499 500/* 501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 502% % 503% % 504% % 505% C o n c a t e n a t e S t r i n g I n f o % 506% % 507% % 508% % 509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 510% 511% ConcatenateStringInfo() concatenates the source string to the destination 512% string. 513% 514% The format of the ConcatenateStringInfo method is: 515% 516% void ConcatenateStringInfo(StringInfo *string_info, 517% const StringInfo *source) 518% 519% A description of each parameter follows: 520% 521% o string_info: the string info. 522% 523% o source: the source string. 524% 525*/ 526MagickExport void ConcatenateStringInfo(StringInfo *string_info, 527 const StringInfo *source) 528{ 529 size_t 530 length; 531 532 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 533 assert(string_info != (StringInfo *) NULL); 534 assert(string_info->signature == MagickSignature); 535 assert(source != (const StringInfo *) NULL); 536 length=string_info->length; 537 if (~length < source->length) 538 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString"); 539 SetStringInfoLength(string_info,length+source->length); 540 (void) memcpy(string_info->datum+length,source->datum,source->length); 541} 542 543/* 544%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 545% % 546% % 547% % 548% C o n f i g u r e F i l e T o S t r i n g I n f o % 549% % 550% % 551% % 552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 553% 554% ConfigureFileToStringInfo() returns the contents of a configure file as a 555% string. 556% 557% The format of the ConfigureFileToStringInfo method is: 558% 559% StringInfo *ConfigureFileToStringInfo(const char *filename) 560% ExceptionInfo *exception) 561% 562% A description of each parameter follows: 563% 564% o filename: the filename. 565% 566*/ 567MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename) 568{ 569 char 570 *string; 571 572 int 573 file; 574 575 MagickOffsetType 576 offset; 577 578 size_t 579 length; 580 581 StringInfo 582 *string_info; 583 584 void 585 *map; 586 587 assert(filename != (const char *) NULL); 588 file=open_utf8(filename,O_RDONLY | O_BINARY,0); 589 if (file == -1) 590 return((StringInfo *) NULL); 591 offset=(MagickOffsetType) lseek(file,0,SEEK_END); 592 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset))) 593 { 594 file=close(file)-1; 595 return((StringInfo *) NULL); 596 } 597 length=(size_t) offset; 598 string=(char *) NULL; 599 if (~length >= (MaxTextExtent-1)) 600 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string)); 601 if (string == (char *) NULL) 602 { 603 file=close(file)-1; 604 return((StringInfo *) NULL); 605 } 606 map=MapBlob(file,ReadMode,0,length); 607 if (map != (void *) NULL) 608 { 609 (void) memcpy(string,map,length); 610 (void) UnmapBlob(map,length); 611 } 612 else 613 { 614 register size_t 615 i; 616 617 ssize_t 618 count; 619 620 (void) lseek(file,0,SEEK_SET); 621 for (i=0; i < length; i+=count) 622 { 623 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t) 624 SSIZE_MAX)); 625 if (count <= 0) 626 { 627 count=0; 628 if (errno != EINTR) 629 break; 630 } 631 } 632 if (i < length) 633 { 634 file=close(file)-1; 635 string=DestroyString(string); 636 return((StringInfo *) NULL); 637 } 638 } 639 string[length]='\0'; 640 file=close(file)-1; 641 string_info=AcquireStringInfo(0); 642 (void) CopyMagickString(string_info->path,filename,MaxTextExtent); 643 string_info->length=length; 644 string_info->datum=(unsigned char *) string; 645 return(string_info); 646} 647 648/* 649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 650% % 651% % 652% % 653% C o n s t a n t S t r i n g % 654% % 655% % 656% % 657%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 658% 659% ConstantString() allocates memory for a string and copies the source string 660% to that memory location (and returns it). Use it for strings that you do 661% do not expect to change over its lifetime. 662% 663% The format of the ConstantString method is: 664% 665% char *ConstantString(const char *source) 666% 667% A description of each parameter follows: 668% 669% o source: A character string. 670% 671*/ 672MagickExport char *ConstantString(const char *source) 673{ 674 char 675 *destination; 676 677 size_t 678 length; 679 680 length=0; 681 if (source != (char *) NULL) 682 length+=strlen(source); 683 destination=(char *) NULL; 684 if (~length >= 1UL) 685 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination)); 686 if (destination == (char *) NULL) 687 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 688 *destination='\0'; 689 if (source != (char *) NULL) 690 (void) memcpy(destination,source,length*sizeof(*destination)); 691 destination[length]='\0'; 692 return(destination); 693} 694 695/* 696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 697% % 698% % 699% % 700% C o p y M a g i c k S t r i n g % 701% % 702% % 703% % 704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 705% 706% CopyMagickString() copies the source string to the destination string. The 707% destination buffer is always null-terminated even if the string must be 708% truncated. The return value is the minimum of the source string length 709% or the length parameter. 710% 711% The format of the CopyMagickString method is: 712% 713% size_t CopyMagickString(const char *destination,char *source, 714% const size_t length) 715% 716% A description of each parameter follows: 717% 718% o destination: the destination string. 719% 720% o source: the source string. 721% 722% o length: the length of the destination string. 723% 724*/ 725MagickExport size_t CopyMagickString(char *destination,const char *source, 726 const size_t length) 727{ 728 register char 729 *q; 730 731 register const char 732 *p; 733 734 register size_t 735 n; 736 737 if (source == (const char *) NULL) 738 return(0); 739 p=source; 740 q=destination; 741 for (n=length; n > 4; n-=4) 742 { 743 *q=(*p++); 744 if (*q == '\0') 745 return((size_t) (p-source-1)); 746 q++; 747 *q=(*p++); 748 if (*q == '\0') 749 return((size_t) (p-source-1)); 750 q++; 751 *q=(*p++); 752 if (*q == '\0') 753 return((size_t) (p-source-1)); 754 q++; 755 *q=(*p++); 756 if (*q == '\0') 757 return((size_t) (p-source-1)); 758 q++; 759 } 760 if (n != 0) 761 for (n--; n != 0; n--) 762 { 763 *q=(*p++); 764 if (*q == '\0') 765 return((size_t) (p-source-1)); 766 q++; 767 } 768 if (length != 0) 769 *q='\0'; 770 return((size_t) (p-source-1)); 771} 772 773/* 774%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 775% % 776% % 777% % 778% D e s t r o y S t r i n g % 779% % 780% % 781% % 782%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 783% 784% DestroyString() destroys memory associated with a string. 785% 786% The format of the DestroyString method is: 787% 788% char *DestroyString(char *string) 789% 790% A description of each parameter follows: 791% 792% o string: the string. 793% 794*/ 795MagickExport char *DestroyString(char *string) 796{ 797 return((char *) RelinquishMagickMemory(string)); 798} 799 800/* 801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 802% % 803% % 804% % 805% D e s t r o y S t r i n g I n f o % 806% % 807% % 808% % 809%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 810% 811% DestroyStringInfo() destroys memory associated with the StringInfo structure. 812% 813% The format of the DestroyStringInfo method is: 814% 815% StringInfo *DestroyStringInfo(StringInfo *string_info) 816% 817% A description of each parameter follows: 818% 819% o string_info: the string info. 820% 821*/ 822MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info) 823{ 824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 825 assert(string_info != (StringInfo *) NULL); 826 assert(string_info->signature == MagickSignature); 827 if (string_info->datum != (unsigned char *) NULL) 828 string_info->datum=(unsigned char *) RelinquishMagickMemory( 829 string_info->datum); 830 string_info->signature=(~MagickSignature); 831 string_info=(StringInfo *) RelinquishMagickMemory(string_info); 832 return(string_info); 833} 834 835/* 836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 837% % 838% % 839% % 840% D e s t r o y S t r i n g L i s t % 841% % 842% % 843% % 844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 845% 846% DestroyStringList() zeros memory associated with a string list. 847% 848% The format of the DestroyStringList method is: 849% 850% char **DestroyStringList(char **list) 851% 852% A description of each parameter follows: 853% 854% o list: the string list. 855% 856*/ 857MagickExport char **DestroyStringList(char **list) 858{ 859 register ssize_t 860 i; 861 862 assert(list != (char **) NULL); 863 for (i=0; list[i] != (char *) NULL; i++) 864 list[i]=DestroyString(list[i]); 865 list=(char **) RelinquishMagickMemory(list); 866 return(list); 867} 868 869/* 870%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 871% % 872% % 873% % 874% E s c a p e S t r i n g % 875% % 876% % 877% % 878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 879% 880% EscapeString() allocates memory for a backslash-escaped version of a 881% source text string, copies the escaped version of the text to that 882% memory location while adding backslash characters, and returns the 883% escaped string. 884% 885% The format of the EscapeString method is: 886% 887% char *EscapeString(const char *source,const char escape) 888% 889% A description of each parameter follows: 890% 891% o allocate_string: Method EscapeString returns the escaped string. 892% 893% o source: A character string. 894% 895% o escape: the quoted string termination character to escape (e.g. '"'). 896% 897*/ 898MagickExport char *EscapeString(const char *source,const char escape) 899{ 900 char 901 *destination; 902 903 register char 904 *q; 905 906 register const char 907 *p; 908 909 size_t 910 length; 911 912 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 913 assert(source != (const char *) NULL); 914 length=strlen(source); 915 for (p=source; *p != '\0'; p++) 916 if ((*p == '\\') || (*p == escape)) 917 { 918 if (~length < 1) 919 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString"); 920 length++; 921 } 922 destination=(char *) NULL; 923 if (~length >= (MaxTextExtent-1)) 924 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent, 925 sizeof(*destination)); 926 if (destination == (char *) NULL) 927 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString"); 928 *destination='\0'; 929 if (source != (char *) NULL) 930 { 931 q=destination; 932 for (p=source; *p != '\0'; p++) 933 { 934 if ((*p == '\\') || (*p == escape)) 935 *q++='\\'; 936 *q++=(*p); 937 } 938 *q='\0'; 939 } 940 return(destination); 941} 942 943/* 944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 945% % 946% % 947% % 948% F i l e T o S t r i n g % 949% % 950% % 951% % 952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 953% 954% FileToString() returns the contents of a file as a string. 955% 956% The format of the FileToString method is: 957% 958% char *FileToString(const char *filename,const size_t extent, 959% ExceptionInfo *exception) 960% 961% A description of each parameter follows: 962% 963% o filename: the filename. 964% 965% o extent: Maximum length of the string. 966% 967% o exception: return any errors or warnings in this structure. 968% 969*/ 970MagickExport char *FileToString(const char *filename,const size_t extent, 971 ExceptionInfo *exception) 972{ 973 size_t 974 length; 975 976 assert(filename != (const char *) NULL); 977 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 978 assert(exception != (ExceptionInfo *) NULL); 979 return((char *) FileToBlob(filename,extent,&length,exception)); 980} 981 982/* 983%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 984% % 985% % 986% % 987% F i l e T o S t r i n g I n f o % 988% % 989% % 990% % 991%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 992% 993% FileToStringInfo() returns the contents of a file as a string. 994% 995% The format of the FileToStringInfo method is: 996% 997% StringInfo *FileToStringInfo(const char *filename,const size_t extent, 998% ExceptionInfo *exception) 999% 1000% A description of each parameter follows: 1001% 1002% o filename: the filename. 1003% 1004% o extent: Maximum length of the string. 1005% 1006% o exception: return any errors or warnings in this structure. 1007% 1008*/ 1009MagickExport StringInfo *FileToStringInfo(const char *filename, 1010 const size_t extent,ExceptionInfo *exception) 1011{ 1012 StringInfo 1013 *string_info; 1014 1015 assert(filename != (const char *) NULL); 1016 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 1017 assert(exception != (ExceptionInfo *) NULL); 1018 string_info=AcquireStringInfo(0); 1019 (void) CopyMagickString(string_info->path,filename,MaxTextExtent); 1020 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception); 1021 if (string_info->datum == (unsigned char *) NULL) 1022 { 1023 string_info=DestroyStringInfo(string_info); 1024 return((StringInfo *) NULL); 1025 } 1026 return(string_info); 1027} 1028 1029/* 1030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1031% % 1032% % 1033% % 1034% F o r m a t M a g i c k S i z e % 1035% % 1036% % 1037% % 1038%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1039% 1040% FormatMagickSize() converts a size to a human readable format, for example, 1041% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by 1042% 1000. 1043% 1044% The format of the FormatMagickSize method is: 1045% 1046% ssize_t FormatMagickSize(const MagickSizeType size,char *format) 1047% 1048% A description of each parameter follows: 1049% 1050% o size: convert this size to a human readable format. 1051% 1052% o bi: use power of two rather than power of ten. 1053% 1054% o format: human readable format. 1055% 1056*/ 1057MagickExport ssize_t FormatMagickSize(const MagickSizeType size, 1058 const MagickBooleanType bi,char *format) 1059{ 1060 const char 1061 **units; 1062 1063 double 1064 bytes, 1065 length; 1066 1067 register ssize_t 1068 i, 1069 j; 1070 1071 ssize_t 1072 count; 1073 1074 static const char 1075 *bi_units[] = 1076 { 1077 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL 1078 }, 1079 *traditional_units[] = 1080 { 1081 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL 1082 }; 1083 1084 bytes=1000.0; 1085 units=traditional_units; 1086 if (bi != MagickFalse) 1087 { 1088 bytes=1024.0; 1089 units=bi_units; 1090 } 1091#if defined(_MSC_VER) && (_MSC_VER == 1200) 1092 length=(double) ((MagickOffsetType) size); 1093#else 1094 length=(double) size; 1095#endif 1096 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++) 1097 length/=bytes; 1098 for (j=2; j < 12; j++) 1099 { 1100 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length, 1101 units[i]); 1102 if (strchr(format,'+') == (char *) NULL) 1103 break; 1104 } 1105 return(count); 1106} 1107 1108/* 1109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1110% % 1111% % 1112% % 1113% F o r m a t M a g i c k T i m e % 1114% % 1115% % 1116% % 1117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1118% 1119% FormatMagickTime() returns the specified time in the Internet date/time 1120% format and the length of the timestamp. 1121% 1122% The format of the FormatMagickTime method is: 1123% 1124% ssize_t FormatMagickTime(const time_t time,const size_t length, 1125% char *timestamp) 1126% 1127% A description of each parameter follows. 1128% 1129% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970), 1130% measured in seconds. 1131% 1132% o length: the maximum length of the string. 1133% 1134% o timestamp: Return the Internet date/time here. 1135% 1136*/ 1137MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length, 1138 char *timestamp) 1139{ 1140 ssize_t 1141 count; 1142 1143 struct tm 1144 gm_time, 1145 local_time; 1146 1147 time_t 1148 timezone; 1149 1150 assert(timestamp != (char *) NULL); 1151 (void) ResetMagickMemory(&local_time,0,sizeof(local_time)); 1152 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time)); 1153#if defined(MAGICKCORE_HAVE_LOCALTIME_R) 1154 (void) localtime_r(&time,&local_time); 1155#else 1156 { 1157 struct tm 1158 *my_time; 1159 1160 my_time=localtime(&time); 1161 if (my_time != (struct tm *) NULL) 1162 (void) memcpy(&local_time,my_time,sizeof(local_time)); 1163 } 1164#endif 1165#if defined(MAGICKCORE_HAVE_GMTIME_R) 1166 (void) gmtime_r(&time,&gm_time); 1167#else 1168 { 1169 struct tm 1170 *my_time; 1171 1172 my_time=gmtime(&time); 1173 if (my_time != (struct tm *) NULL) 1174 (void) memcpy(&gm_time,my_time,sizeof(gm_time)); 1175 } 1176#endif 1177 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+ 1178 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year- 1179 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) : 1180 (local_time.tm_yday-gm_time.tm_yday))); 1181 count=FormatLocaleString(timestamp,length, 1182 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900, 1183 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour, 1184 local_time.tm_min,local_time.tm_sec,(long) timezone); 1185 return(count); 1186} 1187 1188/* 1189%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1190% % 1191% % 1192% % 1193% G e t E n v i r o n m e n t V a l u e % 1194% % 1195% % 1196% % 1197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1198% 1199% GetEnvironmentValue() returns the environment string that matches the 1200% specified name. 1201% 1202% The format of the GetEnvironmentValue method is: 1203% 1204% char *GetEnvironmentValue(const char *name) 1205% 1206% A description of each parameter follows: 1207% 1208% o name: the environment name. 1209% 1210*/ 1211MagickExport char *GetEnvironmentValue(const char *name) 1212{ 1213 const char 1214 *environment; 1215 1216 environment=getenv(name); 1217 if (environment == (const char *) NULL) 1218 return((char *) NULL); 1219 return(ConstantString(environment)); 1220} 1221 1222/* 1223%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1224% % 1225% % 1226% % 1227% G e t S t r i n g I n f o D a t u m % 1228% % 1229% % 1230% % 1231%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1232% 1233% GetStringInfoDatum() returns the datum associated with the string. 1234% 1235% The format of the GetStringInfoDatum method is: 1236% 1237% unsigned char *GetStringInfoDatum(const StringInfo *string_info) 1238% 1239% A description of each parameter follows: 1240% 1241% o string_info: the string info. 1242% 1243*/ 1244MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info) 1245{ 1246 assert(string_info != (StringInfo *) NULL); 1247 assert(string_info->signature == MagickSignature); 1248 return(string_info->datum); 1249} 1250 1251/* 1252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1253% % 1254% % 1255% % 1256% G e t S t r i n g I n f o L e n g t h % 1257% % 1258% % 1259% % 1260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1261% 1262% GetStringInfoLength() returns the string length. 1263% 1264% The format of the GetStringInfoLength method is: 1265% 1266% size_t GetStringInfoLength(const StringInfo *string_info) 1267% 1268% A description of each parameter follows: 1269% 1270% o string_info: the string info. 1271% 1272*/ 1273MagickExport size_t GetStringInfoLength(const StringInfo *string_info) 1274{ 1275 assert(string_info != (StringInfo *) NULL); 1276 assert(string_info->signature == MagickSignature); 1277 return(string_info->length); 1278} 1279 1280/* 1281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1282% % 1283% % 1284% % 1285% G e t S t r i n g I n f o P a t h % 1286% % 1287% % 1288% % 1289%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1290% 1291% GetStringInfoPath() returns the path associated with the string. 1292% 1293% The format of the GetStringInfoPath method is: 1294% 1295% const char *GetStringInfoPath(const StringInfo *string_info) 1296% 1297% A description of each parameter follows: 1298% 1299% o string_info: the string info. 1300% 1301*/ 1302MagickExport const char *GetStringInfoPath(const StringInfo *string_info) 1303{ 1304 assert(string_info != (StringInfo *) NULL); 1305 assert(string_info->signature == MagickSignature); 1306 return(string_info->path); 1307} 1308 1309/* 1310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1311% % 1312% % 1313% % 1314% L o c a l e C o m p a r e % 1315% % 1316% % 1317% % 1318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1319% 1320% LocaleCompare() performs a case-insensitive comparison of two strings 1321% byte-by-byte, according to the ordering of the current locale encoding. 1322% LocaleCompare returns an integer greater than, equal to, or less than 0, 1323% if the string pointed to by p is greater than, equal to, or less than the 1324% string pointed to by q respectively. The sign of a non-zero return value 1325% is determined by the sign of the difference between the values of the first 1326% pair of bytes that differ in the strings being compared. 1327% 1328% The format of the LocaleCompare method is: 1329% 1330% int LocaleCompare(const char *p,const char *q) 1331% 1332% A description of each parameter follows: 1333% 1334% o p: A pointer to a character string. 1335% 1336% o q: A pointer to a character string to compare to p. 1337% 1338*/ 1339MagickExport int LocaleCompare(const char *p,const char *q) 1340{ 1341 if ((p == (char *) NULL) && (q == (char *) NULL)) 1342 return(0); 1343 if (p == (char *) NULL) 1344 return(-1); 1345 if (q == (char *) NULL) 1346 return(1); 1347#if defined(MAGICKCORE_HAVE_STRCASECMP) 1348 return(strcasecmp(p,q)); 1349#else 1350 { 1351 register int 1352 c, 1353 d; 1354 1355 for ( ; ; ) 1356 { 1357 c=(int) *((unsigned char *) p); 1358 d=(int) *((unsigned char *) q); 1359 if ((c == 0) || (AsciiMap[c] != AsciiMap[d])) 1360 break; 1361 p++; 1362 q++; 1363 } 1364 return(AsciiMap[c]-(int) AsciiMap[d]); 1365 } 1366#endif 1367} 1368 1369/* 1370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1371% % 1372% % 1373% % 1374% L o c a l e L o w e r % 1375% % 1376% % 1377% % 1378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1379% 1380% LocaleLower() transforms all of the characters in the supplied 1381% null-terminated string, changing all uppercase letters to lowercase. 1382% 1383% The format of the LocaleLower method is: 1384% 1385% void LocaleLower(char *string) 1386% 1387% A description of each parameter follows: 1388% 1389% o string: A pointer to the string to convert to lower-case Locale. 1390% 1391*/ 1392MagickExport void LocaleLower(char *string) 1393{ 1394 register char 1395 *q; 1396 1397 assert(string != (char *) NULL); 1398 for (q=string; *q != '\0'; q++) 1399 *q=(char) tolower((int) *q); 1400} 1401 1402/* 1403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1404% % 1405% % 1406% % 1407% L o c a l e N C o m p a r e % 1408% % 1409% % 1410% % 1411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1412% 1413% LocaleNCompare() performs a case-insensitive comparison of two 1414% strings byte-by-byte, according to the ordering of the current locale 1415% encoding. LocaleNCompare returns an integer greater than, equal to, or 1416% less than 0, if the string pointed to by p is greater than, equal to, or 1417% less than the string pointed to by q respectively. The sign of a non-zero 1418% return value is determined by the sign of the difference between the 1419% values of the first pair of bytes that differ in the strings being 1420% compared. The LocaleNCompare method makes the same comparison as 1421% LocaleCompare but looks at a maximum of n bytes. Bytes following a 1422% null byte are not compared. 1423% 1424% The format of the LocaleNCompare method is: 1425% 1426% int LocaleNCompare(const char *p,const char *q,const size_t n) 1427% 1428% A description of each parameter follows: 1429% 1430% o p: A pointer to a character string. 1431% 1432% o q: A pointer to a character string to compare to p. 1433% 1434% o length: the number of characters to compare in strings p and q. 1435% 1436*/ 1437MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length) 1438{ 1439 if ((p == (char *) NULL) && (q == (char *) NULL)) 1440 return(0); 1441 if (p == (char *) NULL) 1442 return(-1); 1443 if (q == (char *) NULL) 1444 return(1); 1445#if defined(MAGICKCORE_HAVE_STRNCASECMP) 1446 return(strncasecmp(p,q,length)); 1447#else 1448 { 1449 register int 1450 c, 1451 d; 1452 1453 register size_t 1454 i; 1455 1456 for (i=length; i != 0; i--) 1457 { 1458 c=(int) *((unsigned char *) p); 1459 d=(int) *((unsigned char *) q); 1460 if (AsciiMap[c] != AsciiMap[d]) 1461 return(AsciiMap[c]-(int) AsciiMap[d]); 1462 if (c == 0) 1463 return(0); 1464 p++; 1465 q++; 1466 } 1467 return(0); 1468 } 1469#endif 1470} 1471 1472/* 1473%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1474% % 1475% % 1476% % 1477% L o c a l e U p p e r % 1478% % 1479% % 1480% % 1481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1482% 1483% LocaleUpper() transforms all of the characters in the supplied 1484% null-terminated string, changing all lowercase letters to uppercase. 1485% 1486% The format of the LocaleUpper method is: 1487% 1488% void LocaleUpper(char *string) 1489% 1490% A description of each parameter follows: 1491% 1492% o string: A pointer to the string to convert to upper-case Locale. 1493% 1494*/ 1495MagickExport void LocaleUpper(char *string) 1496{ 1497 register char 1498 *q; 1499 1500 assert(string != (char *) NULL); 1501 for (q=string; *q != '\0'; q++) 1502 *q=(char) toupper((int) *q); 1503} 1504 1505/* 1506%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1507% % 1508% % 1509% % 1510% P r i n t S t r i n g I n f o % 1511% % 1512% % 1513% % 1514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1515% 1516% PrintStringInfo() prints the string. 1517% 1518% The format of the PrintStringInfo method is: 1519% 1520% void PrintStringInfo(FILE *file,const char *id, 1521% const StringInfo *string_info) 1522% 1523% A description of each parameter follows: 1524% 1525% o file: the file, typically stdout. 1526% 1527% o id: the string id. 1528% 1529% o string_info: the string info. 1530% 1531*/ 1532MagickExport void PrintStringInfo(FILE *file,const char *id, 1533 const StringInfo *string_info) 1534{ 1535 register const char 1536 *p; 1537 1538 register size_t 1539 i, 1540 j; 1541 1542 assert(id != (const char *) NULL); 1543 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id); 1544 assert(string_info != (StringInfo *) NULL); 1545 assert(string_info->signature == MagickSignature); 1546 p=(char *) string_info->datum; 1547 for (i=0; i < string_info->length; i++) 1548 { 1549 if (((int) ((unsigned char) *p) < 32) && 1550 (isspace((int) ((unsigned char) *p)) == 0)) 1551 break; 1552 p++; 1553 } 1554 if (i == string_info->length) 1555 { 1556 (void) fputs((char *) string_info->datum,file); 1557 (void) fputc('\n',file); 1558 return; 1559 } 1560 /* 1561 Convert string to a HEX list. 1562 */ 1563 p=(char *) string_info->datum; 1564 for (i=0; i < string_info->length; i+=0x14) 1565 { 1566 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i)); 1567 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++) 1568 { 1569 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff); 1570 if ((j % 0x04) == 0) 1571 (void) fputc(' ',file); 1572 } 1573 for ( ; j <= 0x14; j++) 1574 { 1575 (void) fputc(' ',file); 1576 (void) fputc(' ',file); 1577 if ((j % 0x04) == 0) 1578 (void) fputc(' ',file); 1579 } 1580 (void) fputc(' ',file); 1581 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++) 1582 { 1583 if (isprint((int) ((unsigned char) *p)) != 0) 1584 (void) fputc(*p,file); 1585 else 1586 (void) fputc('-',file); 1587 p++; 1588 } 1589 (void) fputc('\n',file); 1590 } 1591} 1592 1593/* 1594%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1595% % 1596% % 1597% % 1598% R e s e t S t r i n g I n f o % 1599% % 1600% % 1601% % 1602%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1603% 1604% ResetStringInfo() reset the string to all null bytes. 1605% 1606% The format of the ResetStringInfo method is: 1607% 1608% void ResetStringInfo(StringInfo *string_info) 1609% 1610% A description of each parameter follows: 1611% 1612% o string_info: the string info. 1613% 1614*/ 1615MagickExport void ResetStringInfo(StringInfo *string_info) 1616{ 1617 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1618 assert(string_info != (StringInfo *) NULL); 1619 assert(string_info->signature == MagickSignature); 1620 (void) ResetMagickMemory(string_info->datum,0,string_info->length); 1621} 1622 1623/* 1624%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1625% % 1626% % 1627% % 1628% S e t S t r i n g I n f o % 1629% % 1630% % 1631% % 1632%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1633% 1634% SetStringInfo() copies the source string to the destination string. 1635% 1636% The format of the SetStringInfo method is: 1637% 1638% void SetStringInfo(StringInfo *string_info,const StringInfo *source) 1639% 1640% A description of each parameter follows: 1641% 1642% o string_info: the string info. 1643% 1644% o source: the source string. 1645% 1646*/ 1647MagickExport void SetStringInfo(StringInfo *string_info, 1648 const StringInfo *source) 1649{ 1650 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1651 assert(string_info != (StringInfo *) NULL); 1652 assert(string_info->signature == MagickSignature); 1653 assert(source != (StringInfo *) NULL); 1654 assert(source->signature == MagickSignature); 1655 if (string_info->length == 0) 1656 return; 1657 (void) ResetMagickMemory(string_info->datum,0,string_info->length); 1658 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length, 1659 source->length)); 1660} 1661 1662/* 1663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1664% % 1665% % 1666% % 1667% S e t S t r i n g I n f o D a t u m % 1668% % 1669% % 1670% % 1671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1672% 1673% SetStringInfoDatum() copies bytes from the source string for the length of 1674% the destination string. 1675% 1676% The format of the SetStringInfoDatum method is: 1677% 1678% void SetStringInfoDatum(StringInfo *string_info, 1679% const unsigned char *source) 1680% 1681% A description of each parameter follows: 1682% 1683% o string_info: the string info. 1684% 1685% o source: the source string. 1686% 1687*/ 1688MagickExport void SetStringInfoDatum(StringInfo *string_info, 1689 const unsigned char *source) 1690{ 1691 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1692 assert(string_info != (StringInfo *) NULL); 1693 assert(string_info->signature == MagickSignature); 1694 if (string_info->length != 0) 1695 (void) memcpy(string_info->datum,source,string_info->length); 1696} 1697 1698/* 1699%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1700% % 1701% % 1702% % 1703% S e t S t r i n g I n f o L e n g t h % 1704% % 1705% % 1706% % 1707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1708% 1709% SetStringInfoLength() set the string length to the specified value. 1710% 1711% The format of the SetStringInfoLength method is: 1712% 1713% void SetStringInfoLength(StringInfo *string_info,const size_t length) 1714% 1715% A description of each parameter follows: 1716% 1717% o string_info: the string info. 1718% 1719% o length: the string length. 1720% 1721*/ 1722MagickExport void SetStringInfoLength(StringInfo *string_info, 1723 const size_t length) 1724{ 1725 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1726 assert(string_info != (StringInfo *) NULL); 1727 assert(string_info->signature == MagickSignature); 1728 if (~length < MaxTextExtent) 1729 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 1730 string_info->length=length; 1731 if (string_info->datum == (unsigned char *) NULL) 1732 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+ 1733 MaxTextExtent,sizeof(*string_info->datum)); 1734 else 1735 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum, 1736 length+MaxTextExtent,sizeof(*string_info->datum)); 1737 if (string_info->datum == (unsigned char *) NULL) 1738 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 1739} 1740 1741/* 1742%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1743% % 1744% % 1745% % 1746% S e t S t r i n g I n f o D a t u m % 1747% % 1748% % 1749% % 1750%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1751% 1752% SetStringInfoPath() sets the path associated with the string. 1753% 1754% The format of the SetStringInfoPath method is: 1755% 1756% void SetStringInfoPath(StringInfo *string_info,const char *path) 1757% 1758% A description of each parameter follows: 1759% 1760% o string_info: the string info. 1761% 1762% o path: the path. 1763% 1764*/ 1765MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path) 1766{ 1767 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1768 assert(string_info != (StringInfo *) NULL); 1769 assert(string_info->signature == MagickSignature); 1770 assert(path != (const char *) NULL); 1771 (void) CopyMagickString(string_info->path,path,MaxTextExtent); 1772} 1773 1774/* 1775%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1776% % 1777% % 1778% % 1779% S p l i t S t r i n g I n f o % 1780% % 1781% % 1782% % 1783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1784% 1785% SplitStringInfo() splits a string into two and returns it. 1786% 1787% The format of the SplitStringInfo method is: 1788% 1789% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset) 1790% 1791% A description of each parameter follows: 1792% 1793% o string_info: the string info. 1794% 1795*/ 1796MagickExport StringInfo *SplitStringInfo(StringInfo *string_info, 1797 const size_t offset) 1798{ 1799 StringInfo 1800 *split_info; 1801 1802 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 1803 assert(string_info != (StringInfo *) NULL); 1804 assert(string_info->signature == MagickSignature); 1805 if (offset > string_info->length) 1806 return((StringInfo *) NULL); 1807 split_info=AcquireStringInfo(offset); 1808 SetStringInfo(split_info,string_info); 1809 (void) memmove(string_info->datum,string_info->datum+offset, 1810 string_info->length-offset+MaxTextExtent); 1811 SetStringInfoLength(string_info,string_info->length-offset); 1812 return(split_info); 1813} 1814 1815/* 1816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1817% % 1818% % 1819% % 1820% S t r i n g I n f o T o S t r i n g % 1821% % 1822% % 1823% % 1824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1825% 1826% StringInfoToString() converts a string info string to a C string. 1827% 1828% The format of the StringInfoToString method is: 1829% 1830% char *StringInfoToString(const StringInfo *string_info) 1831% 1832% A description of each parameter follows: 1833% 1834% o string_info: the string. 1835% 1836*/ 1837MagickExport char *StringInfoToString(const StringInfo *string_info) 1838{ 1839 char 1840 *string; 1841 1842 size_t 1843 length; 1844 1845 string=(char *) NULL; 1846 length=string_info->length; 1847 if (~length >= (MaxTextExtent-1)) 1848 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string)); 1849 if (string == (char *) NULL) 1850 return((char *) NULL); 1851 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string)); 1852 string[length]='\0'; 1853 return(string); 1854} 1855 1856/* 1857%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1858% % 1859% % 1860% % 1861% S t r i n g T o A r g v % 1862% % 1863% % 1864% % 1865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1866% 1867% StringToArgv() converts a text string into command line arguments. 1868% 1869% The format of the StringToArgv method is: 1870% 1871% char **StringToArgv(const char *text,int *argc) 1872% 1873% A description of each parameter follows: 1874% 1875% o argv: Method StringToArgv returns the string list unless an error 1876% occurs, otherwise NULL. 1877% 1878% o text: Specifies the string to segment into a list. 1879% 1880% o argc: This integer pointer returns the number of arguments in the 1881% list. 1882% 1883*/ 1884MagickExport char **StringToArgv(const char *text,int *argc) 1885{ 1886 char 1887 **argv; 1888 1889 register const char 1890 *p, 1891 *q; 1892 1893 register ssize_t 1894 i; 1895 1896 *argc=0; 1897 if (text == (char *) NULL) 1898 return((char **) NULL); 1899 /* 1900 Determine the number of arguments. 1901 */ 1902 for (p=text; *p != '\0'; ) 1903 { 1904 while (isspace((int) ((unsigned char) *p)) != 0) 1905 p++; 1906 if (*p == '\0') 1907 break; 1908 (*argc)++; 1909 if (*p == '"') 1910 for (p++; (*p != '"') && (*p != '\0'); p++) ; 1911 if (*p == '\'') 1912 for (p++; (*p != '\'') && (*p != '\0'); p++) ; 1913 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0')) 1914 p++; 1915 } 1916 (*argc)++; 1917 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv)); 1918 if (argv == (char **) NULL) 1919 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV"); 1920 /* 1921 Convert string to an ASCII list. 1922 */ 1923 argv[0]=AcquireString("magick"); 1924 p=text; 1925 for (i=1; i < (ssize_t) *argc; i++) 1926 { 1927 while (isspace((int) ((unsigned char) *p)) != 0) 1928 p++; 1929 q=p; 1930 if (*q == '"') 1931 { 1932 p++; 1933 for (q++; (*q != '"') && (*q != '\0'); q++) ; 1934 } 1935 else 1936 if (*q == '\'') 1937 { 1938 p++; 1939 for (q++; (*q != '\'') && (*q != '\0'); q++) ; 1940 } 1941 else 1942 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0')) 1943 q++; 1944 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent, 1945 sizeof(**argv)); 1946 if (argv[i] == (char *) NULL) 1947 { 1948 for (i--; i >= 0; i--) 1949 argv[i]=DestroyString(argv[i]); 1950 argv=(char **) RelinquishMagickMemory(argv); 1951 ThrowFatalException(ResourceLimitFatalError, 1952 "UnableToConvertStringToARGV"); 1953 } 1954 (void) memcpy(argv[i],p,(size_t) (q-p)); 1955 argv[i][q-p]='\0'; 1956 p=q; 1957 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0')) 1958 p++; 1959 } 1960 argv[i]=(char *) NULL; 1961 return(argv); 1962} 1963 1964/* 1965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1966% % 1967% % 1968% % 1969% S t r i n g I n f o T o H e x S t r i n g % 1970% % 1971% % 1972% % 1973%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1974% 1975% StringInfoToHexString() converts a string info string to a C string. 1976% 1977% The format of the StringInfoToHexString method is: 1978% 1979% char *StringInfoToHexString(const StringInfo *string_info) 1980% 1981% A description of each parameter follows: 1982% 1983% o string_info: the string. 1984% 1985*/ 1986MagickExport char *StringInfoToHexString(const StringInfo *string_info) 1987{ 1988 char 1989 *string; 1990 1991 register const unsigned char 1992 *p; 1993 1994 register ssize_t 1995 i; 1996 1997 register unsigned char 1998 *q; 1999 2000 size_t 2001 length; 2002 2003 unsigned char 2004 hex_digits[16]; 2005 2006 length=string_info->length; 2007 if (~length < MaxTextExtent) 2008 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 2009 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string)); 2010 if (string == (char *) NULL) 2011 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 2012 hex_digits[0]='0'; 2013 hex_digits[1]='1'; 2014 hex_digits[2]='2'; 2015 hex_digits[3]='3'; 2016 hex_digits[4]='4'; 2017 hex_digits[5]='5'; 2018 hex_digits[6]='6'; 2019 hex_digits[7]='7'; 2020 hex_digits[8]='8'; 2021 hex_digits[9]='9'; 2022 hex_digits[10]='a'; 2023 hex_digits[11]='b'; 2024 hex_digits[12]='c'; 2025 hex_digits[13]='d'; 2026 hex_digits[14]='e'; 2027 hex_digits[15]='f'; 2028 p=string_info->datum; 2029 q=(unsigned char *) string; 2030 for (i=0; i < (ssize_t) string_info->length; i++) 2031 { 2032 *q++=hex_digits[(*p >> 4) & 0x0f]; 2033 *q++=hex_digits[*p & 0x0f]; 2034 p++; 2035 } 2036 *q='\0'; 2037 return(string); 2038} 2039 2040/* 2041%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2042% % 2043% % 2044% % 2045% S t r i n g T o k e n % 2046% % 2047% % 2048% % 2049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2050% 2051% StringToken() extracts a token a from the string. 2052% 2053% The format of the StringToken method is: 2054% 2055% char *StringToken(const char *delimiters,char **string) 2056% 2057% A description of each parameter follows: 2058% 2059% o delimiters: one or more delimiters. 2060% 2061% o string: return the first token in the string. If none is found, return 2062% NULL. 2063% 2064*/ 2065MagickExport char *StringToken(const char *delimiters,char **string) 2066{ 2067 char 2068 *q; 2069 2070 register char 2071 *p; 2072 2073 register const char 2074 *r; 2075 2076 register int 2077 c, 2078 d; 2079 2080 p=(*string); 2081 if (p == (char *) NULL) 2082 return((char *) NULL); 2083 for (q=p; ; ) 2084 { 2085 c=(*p++); 2086 r=delimiters; 2087 do 2088 { 2089 d=(*r++); 2090 if (c == d) 2091 { 2092 if (c == '\0') 2093 p=(char *) NULL; 2094 else 2095 p[-1]='\0'; 2096 *string=p; 2097 return(q); 2098 } 2099 } while (d != '\0'); 2100 } 2101} 2102 2103/* 2104%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2105% % 2106% % 2107% % 2108% S t r i n g T o L i s t % 2109% % 2110% % 2111% % 2112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2113% 2114% StringToList() converts a text string into a list by segmenting the text 2115% string at each carriage return discovered. The list is converted to HEX 2116% characters if any control characters are discovered within the text string. 2117% 2118% The format of the StringToList method is: 2119% 2120% char **StringToList(const char *text) 2121% 2122% A description of each parameter follows: 2123% 2124% o text: Specifies the string to segment into a list. 2125% 2126*/ 2127MagickExport char **StringToList(const char *text) 2128{ 2129 char 2130 **textlist; 2131 2132 register const char 2133 *p; 2134 2135 register ssize_t 2136 i; 2137 2138 size_t 2139 lines; 2140 2141 if (text == (char *) NULL) 2142 return((char **) NULL); 2143 for (p=text; *p != '\0'; p++) 2144 if (((int) ((unsigned char) *p) < 32) && 2145 (isspace((int) ((unsigned char) *p)) == 0)) 2146 break; 2147 if (*p == '\0') 2148 { 2149 register const char 2150 *q; 2151 2152 /* 2153 Convert string to an ASCII list. 2154 */ 2155 lines=1; 2156 for (p=text; *p != '\0'; p++) 2157 if (*p == '\n') 2158 lines++; 2159 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL, 2160 sizeof(*textlist)); 2161 if (textlist == (char **) NULL) 2162 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText"); 2163 p=text; 2164 for (i=0; i < (ssize_t) lines; i++) 2165 { 2166 for (q=p; *q != '\0'; q++) 2167 if ((*q == '\r') || (*q == '\n')) 2168 break; 2169 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent, 2170 sizeof(**textlist)); 2171 if (textlist[i] == (char *) NULL) 2172 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText"); 2173 (void) memcpy(textlist[i],p,(size_t) (q-p)); 2174 textlist[i][q-p]='\0'; 2175 if (*q == '\r') 2176 q++; 2177 p=q+1; 2178 } 2179 } 2180 else 2181 { 2182 char 2183 hex_string[MaxTextExtent]; 2184 2185 register char 2186 *q; 2187 2188 register ssize_t 2189 j; 2190 2191 /* 2192 Convert string to a HEX list. 2193 */ 2194 lines=(size_t) (strlen(text)/0x14)+1; 2195 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL, 2196 sizeof(*textlist)); 2197 if (textlist == (char **) NULL) 2198 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText"); 2199 p=text; 2200 for (i=0; i < (ssize_t) lines; i++) 2201 { 2202 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent, 2203 sizeof(**textlist)); 2204 if (textlist[i] == (char *) NULL) 2205 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText"); 2206 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ", 2207 (long) (0x14*i)); 2208 q=textlist[i]+strlen(textlist[i]); 2209 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++) 2210 { 2211 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j)); 2212 (void) CopyMagickString(q,hex_string,MaxTextExtent); 2213 q+=2; 2214 if ((j % 0x04) == 0) 2215 *q++=' '; 2216 } 2217 for ( ; j <= 0x14; j++) 2218 { 2219 *q++=' '; 2220 *q++=' '; 2221 if ((j % 0x04) == 0) 2222 *q++=' '; 2223 } 2224 *q++=' '; 2225 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++) 2226 { 2227 if (isprint((int) ((unsigned char) *p)) != 0) 2228 *q++=(*p); 2229 else 2230 *q++='-'; 2231 p++; 2232 } 2233 *q='\0'; 2234 } 2235 } 2236 textlist[i]=(char *) NULL; 2237 return(textlist); 2238} 2239 2240/* 2241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2242% % 2243% % 2244% % 2245% S t r i n g T o S t r i n g I n f o % 2246% % 2247% % 2248% % 2249%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2250% 2251% StringToStringInfo() converts a string to a StringInfo type. 2252% 2253% The format of the StringToStringInfo method is: 2254% 2255% StringInfo *StringToStringInfo(const char *string) 2256% 2257% A description of each parameter follows: 2258% 2259% o string: The string. 2260% 2261*/ 2262MagickExport StringInfo *StringToStringInfo(const char *string) 2263{ 2264 StringInfo 2265 *string_info; 2266 2267 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 2268 assert(string != (const char *) NULL); 2269 string_info=AcquireStringInfo(strlen(string)); 2270 SetStringInfoDatum(string_info,(const unsigned char *) string); 2271 return(string_info); 2272} 2273 2274/* 2275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2276% % 2277% % 2278% % 2279% S t r i p S t r i n g % 2280% % 2281% % 2282% % 2283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2284% 2285% StripString() strips any whitespace or quotes from the beginning and end of 2286% a string of characters. 2287% 2288% The format of the StripString method is: 2289% 2290% void StripString(char *message) 2291% 2292% A description of each parameter follows: 2293% 2294% o message: Specifies an array of characters. 2295% 2296*/ 2297MagickExport void StripString(char *message) 2298{ 2299 register char 2300 *p, 2301 *q; 2302 2303 size_t 2304 length; 2305 2306 assert(message != (char *) NULL); 2307 if (*message == '\0') 2308 return; 2309 length=strlen(message); 2310 p=message; 2311 while (isspace((int) ((unsigned char) *p)) != 0) 2312 p++; 2313 if ((*p == '\'') || (*p == '"')) 2314 p++; 2315 q=message+length-1; 2316 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p)) 2317 q--; 2318 if (q > p) 2319 if ((*q == '\'') || (*q == '"')) 2320 q--; 2321 (void) memmove(message,p,(size_t) (q-p+1)); 2322 message[q-p+1]='\0'; 2323 for (p=message; *p != '\0'; p++) 2324 if (*p == '\n') 2325 *p=' '; 2326} 2327 2328/* 2329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2330% % 2331% % 2332% % 2333% S u b s t i t u t e S t r i n g % 2334% % 2335% % 2336% % 2337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2338% 2339% SubstituteString() performs string substitution on a string, replacing the 2340% string with the substituted version. Buffer must be allocated from the heap. 2341% If the string is matched and status, MagickTrue is returned otherwise 2342% MagickFalse. 2343% 2344% The format of the SubstituteString method is: 2345% 2346% MagickBooleanType SubstituteString(char **string,const char *search, 2347% const char *replace) 2348% 2349% A description of each parameter follows: 2350% 2351% o string: the string to perform replacements on; replaced with new 2352% allocation if a replacement is made. 2353% 2354% o search: search for this string. 2355% 2356% o replace: replace any matches with this string. 2357% 2358*/ 2359MagickExport MagickBooleanType SubstituteString(char **string, 2360 const char *search,const char *replace) 2361{ 2362 MagickBooleanType 2363 status; 2364 2365 register char 2366 *p; 2367 2368 size_t 2369 extent, 2370 replace_extent, 2371 search_extent; 2372 2373 ssize_t 2374 offset; 2375 2376 status=MagickFalse; 2377 search_extent=0, 2378 replace_extent=0; 2379 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search)) 2380 { 2381 if (search_extent == 0) 2382 search_extent=strlen(search); 2383 if (strncmp(p,search,search_extent) != 0) 2384 continue; 2385 /* 2386 We found a match. 2387 */ 2388 status=MagickTrue; 2389 if (replace_extent == 0) 2390 replace_extent=strlen(replace); 2391 if (replace_extent > search_extent) 2392 { 2393 /* 2394 Make room for the replacement string. 2395 */ 2396 offset=(ssize_t) (p-(*string)); 2397 extent=strlen(*string)+replace_extent-search_extent+1; 2398 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent, 2399 sizeof(*p)); 2400 if (*string == (char *) NULL) 2401 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString"); 2402 p=(*string)+offset; 2403 } 2404 /* 2405 Replace string. 2406 */ 2407 if (search_extent != replace_extent) 2408 (void) CopyMagickMemory(p+replace_extent,p+search_extent, 2409 strlen(p+search_extent)+1); 2410 (void) CopyMagickMemory(p,replace,replace_extent); 2411 p+=replace_extent-1; 2412 } 2413 return(status); 2414} 2415