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