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