MagickCore 7.1.2-26
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=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
629 MagickMaxBufferExtent));
630 if (count <= 0)
631 {
632 count=0;
633 if (errno != EINTR)
634 break;
635 }
636 }
637 if (i < length)
638 {
639 file=close_utf8(file)-1;
640 string=DestroyString(string);
641 return((StringInfo *) NULL);
642 }
643 }
644 string[length]='\0';
645 file=close_utf8(file)-1;
646 string_info=AcquireStringInfoContainer();
647 string_info->path=ConstantString(filename);
648 string_info->length=length;
649 string_info->datum=(unsigned char *) string;
650 return(string_info);
651}
652
653/*
654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655% %
656% %
657% %
658% C o n s t a n t S t r i n g %
659% %
660% %
661% %
662%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
663%
664% ConstantString() allocates exactly the needed memory for a string and
665% copies the source string to that memory location. A NULL string pointer
666% will allocate an empty string containing just the NUL character.
667%
668% When finished the string should be freed using DestroyString()
669%
670% The format of the ConstantString method is:
671%
672% char *ConstantString(const char *source)
673%
674% A description of each parameter follows:
675%
676% o source: A character string.
677%
678*/
679MagickExport char *ConstantString(const char *source)
680{
681 char
682 *destination;
683
684 size_t
685 length;
686
687 length=0;
688 if (source != (char *) NULL)
689 length+=strlen(source);
690 destination=(char *) NULL;
691 if (~length >= 1UL)
692 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
693 if (destination == (char *) NULL)
694 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
695 if (source != (char *) NULL)
696 (void) memcpy(destination,source,length*sizeof(*destination));
697 destination[length]='\0';
698 return(destination);
699}
700
701/*
702%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
703% %
704% %
705% %
706% C o p y M a g i c k S t r i n g %
707% %
708% %
709% %
710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
711%
712% CopyMagickString() copies the source string to the destination string, with
713% out exceeding the given pre-declared length.
714%
715% The destination buffer is always null-terminated even if the string must be
716% truncated. The return value is the length of the string.
717%
718% The format of the CopyMagickString method is:
719%
720% size_t CopyMagickString(const char *magick_restrict destination,
721% char *magick_restrict source,const size_t length)
722%
723% A description of each parameter follows:
724%
725% o destination: the destination string.
726%
727% o source: the source string.
728%
729% o length: the length of the destination string.
730%
731*/
732MagickExport size_t CopyMagickString(char *magick_restrict destination,
733 const char *magick_restrict source,const size_t length)
734{
735 char
736 *magick_restrict q;
737
738 const char
739 *magick_restrict p;
740
741 size_t
742 n;
743
744 p=source;
745 q=destination;
746 for (n=length; n > 4; n-=4)
747 {
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 if (((*q++)=(*p++)) == '\0')
753 return((size_t) (p-source-1));
754 if (((*q++)=(*p++)) == '\0')
755 return((size_t) (p-source-1));
756 }
757 if (length != 0)
758 {
759 while (--n != 0)
760 if (((*q++)=(*p++)) == '\0')
761 return((size_t) (p-source-1));
762 *q='\0';
763 }
764 return((size_t) (p-source));
765}
766
767/*
768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769% %
770% %
771% %
772% D e s t r o y S t r i n g %
773% %
774% %
775% %
776%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777%
778% DestroyString() destroys memory associated with a string.
779%
780% The format of the DestroyString method is:
781%
782% char *DestroyString(char *string)
783%
784% A description of each parameter follows:
785%
786% o string: the string.
787%
788*/
789MagickExport char *DestroyString(char *string)
790{
791 return((char *) RelinquishMagickMemory(string));
792}
793
794/*
795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796% %
797% %
798% %
799% D e s t r o y S t r i n g I n f o %
800% %
801% %
802% %
803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804%
805% DestroyStringInfo() destroys memory associated with the StringInfo structure.
806%
807% The format of the DestroyStringInfo method is:
808%
809% StringInfo *DestroyStringInfo(StringInfo *string_info)
810%
811% A description of each parameter follows:
812%
813% o string_info: the string info.
814%
815*/
816MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
817{
818 assert(string_info != (StringInfo *) NULL);
819 assert(string_info->signature == MagickCoreSignature);
820 if (string_info->datum != (unsigned char *) NULL)
821 string_info->datum=(unsigned char *) RelinquishMagickMemory(
822 string_info->datum);
823 if (string_info->name != (char *) NULL)
824 string_info->name=DestroyString(string_info->name);
825 if (string_info->path != (char *) NULL)
826 string_info->path=DestroyString(string_info->path);
827 string_info->signature=(~MagickCoreSignature);
828 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
829 return(string_info);
830}
831
832/*
833%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834% %
835% %
836% %
837% D e s t r o y S t r i n g L i s t %
838% %
839% %
840% %
841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842%
843% DestroyStringList() zeros memory associated with a string list.
844%
845% The format of the DestroyStringList method is:
846%
847% char **DestroyStringList(char **list)
848%
849% A description of each parameter follows:
850%
851% o list: the string list.
852%
853*/
854MagickExport char **DestroyStringList(char **list)
855{
856 ssize_t
857 i;
858
859 assert(list != (char **) NULL);
860 for (i=0; list[i] != (char *) NULL; i++)
861 list[i]=DestroyString(list[i]);
862 list=(char **) RelinquishMagickMemory(list);
863 return(list);
864}
865
866/*
867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868% %
869% %
870% %
871% E s c a p e S t r i n g %
872% %
873% %
874% %
875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876%
877% EscapeString() allocates memory for a backslash-escaped version of a
878% source text string, copies the escaped version of the text to that
879% memory location while adding backslash characters, and returns the
880% escaped string.
881%
882% The format of the EscapeString method is:
883%
884% char *EscapeString(const char *source,const char escape)
885%
886% A description of each parameter follows:
887%
888% o allocate_string: Method EscapeString returns the escaped string.
889%
890% o source: A character string.
891%
892% o escape: the quoted string termination character to escape (e.g. '"').
893%
894*/
895MagickExport char *EscapeString(const char *source,const char escape)
896{
897 char
898 *destination;
899
900 char
901 *q;
902
903 const char
904 *p;
905
906 size_t
907 length;
908
909 assert(source != (const char *) NULL);
910 length=0;
911 for (p=source; *p != '\0'; p++)
912 {
913 if ((*p == '\\') || (*p == escape))
914 {
915 if (~length < 1)
916 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
917 length++;
918 }
919 length++;
920 }
921 destination=(char *) NULL;
922 if (~length >= (MagickPathExtent-1))
923 destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
924 sizeof(*destination));
925 if (destination == (char *) NULL)
926 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
927 *destination='\0';
928 q=destination;
929 for (p=source; *p != '\0'; p++)
930 {
931 if ((*p == '\\') || (*p == escape))
932 *q++='\\';
933 *q++=(*p);
934 }
935 *q='\0';
936 return(destination);
937}
938
939/*
940%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941% %
942% %
943% %
944% F i l e T o S t r i n g %
945% %
946% %
947% %
948%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949%
950% FileToString() returns the contents of a file as a string.
951%
952% The format of the FileToString method is:
953%
954% char *FileToString(const char *filename,const size_t extent,
955% ExceptionInfo *exception)
956%
957% A description of each parameter follows:
958%
959% o filename: the filename.
960%
961% o extent: Maximum length of the string.
962%
963% o exception: return any errors or warnings in this structure.
964%
965*/
966MagickExport char *FileToString(const char *filename,const size_t extent,
967 ExceptionInfo *exception)
968{
969 const char
970 *p;
971
972 size_t
973 length;
974
975 assert(filename != (const char *) NULL);
976 assert(exception != (ExceptionInfo *) NULL);
977 if (IsEventLogging() != MagickFalse)
978 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
979 p=filename;
980 if ((*filename == '@') && (strlen(filename) > 1))
981 {
982 MagickBooleanType
983 status;
984
985 status=IsRightsAuthorized(PathPolicyDomain,ReadPolicyRights,filename);
986 if (status == MagickFalse)
987 ThrowPolicyException(filename,(char *) NULL);
988 p=filename+1;
989 }
990 return((char *) FileToBlob(p,extent,&length,exception));
991}
992
993/*
994%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995% %
996% %
997% %
998% F i l e T o S t r i n g I n f o %
999% %
1000% %
1001% %
1002%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003%
1004% FileToStringInfo() returns the contents of a file as a string.
1005%
1006% The format of the FileToStringInfo method is:
1007%
1008% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1009% ExceptionInfo *exception)
1010%
1011% A description of each parameter follows:
1012%
1013% o filename: the filename.
1014%
1015% o extent: Maximum length of the string.
1016%
1017% o exception: return any errors or warnings in this structure.
1018%
1019*/
1020MagickExport StringInfo *FileToStringInfo(const char *filename,
1021 const size_t extent,ExceptionInfo *exception)
1022{
1023 StringInfo
1024 *string_info;
1025
1026 assert(filename != (const char *) NULL);
1027 assert(exception != (ExceptionInfo *) NULL);
1028 if (IsEventLogging() != MagickFalse)
1029 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1030 string_info=AcquireStringInfoContainer();
1031 string_info->path=ConstantString(filename);
1032 string_info->datum=(unsigned char *) FileToBlob(filename,extent,
1033 &string_info->length,exception);
1034 if (string_info->datum == (unsigned char *) NULL)
1035 {
1036 string_info=DestroyStringInfo(string_info);
1037 return((StringInfo *) NULL);
1038 }
1039 return(string_info);
1040}
1041
1042/*
1043%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1044% %
1045% %
1046% %
1047% F o r m a t M a g i c k S i z e %
1048% %
1049% %
1050% %
1051%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052%
1053% FormatMagickSize() converts a size to a human readable format, for example,
1054% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
1055% 1000.
1056%
1057% The format of the FormatMagickSize method is:
1058%
1059% ssize_t FormatMagickSize(const MagickSizeType size,const char *suffix,
1060% const size_t length,char *format)
1061%
1062% A description of each parameter follows:
1063%
1064% o size: convert this size to a human readable format.
1065%
1066% o bi: use power of two rather than power of ten.
1067%
1068% o suffix: append suffix, typically B or P.
1069%
1070% o length: the maximum length of the string.
1071%
1072% o format: human readable format.
1073%
1074*/
1075MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
1076 const MagickBooleanType bi,const char *suffix,const size_t length,
1077 char *format)
1078{
1079 const char
1080 **units;
1081
1082 double
1083 bytes,
1084 extent;
1085
1086 ssize_t
1087 i;
1088
1089 ssize_t
1090 count;
1091
1092 static const char
1093 *bi_units[] =
1094 {
1095 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", "Ri", "Qi", (char *) NULL
1096 },
1097 *traditional_units[] =
1098 {
1099 "", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q", (char *) NULL
1100 };
1101
1102 bytes=1000.0;
1103 units=traditional_units;
1104 if (bi != MagickFalse)
1105 {
1106 bytes=1024.0;
1107 units=bi_units;
1108 }
1109 extent=(double) size;
1110 (void) FormatLocaleString(format,MagickFormatExtent,"%.*g",
1111 GetMagickPrecision(),extent);
1112 if (strstr(format,"e+") == (char *) NULL)
1113 {
1114 if (suffix == (const char *) NULL)
1115 count=FormatLocaleString(format,length,"%.20g%s",extent,units[0]);
1116 else
1117 count=FormatLocaleString(format,length,"%.20g%s%s",extent,units[0],
1118 suffix);
1119 return(count);
1120 }
1121 for (i=0; (extent >= bytes) && (units[i+1] != (const char *) NULL); i++)
1122 extent/=bytes;
1123 if (suffix == (const char *) NULL)
1124 count=FormatLocaleString(format,length,"%.*g%s",GetMagickPrecision(),
1125 extent,units[i]);
1126 else
1127 count=FormatLocaleString(format,length,"%.*g%s%s",GetMagickPrecision(),
1128 extent,units[i],suffix);
1129 return(count);
1130}
1131
1132/*
1133%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1134% %
1135% %
1136% %
1137% G e t E n v i r o n m e n t V a l u e %
1138% %
1139% %
1140% %
1141%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1142%
1143% GetEnvironmentValue() returns the environment string that matches the
1144% specified name.
1145%
1146% The format of the GetEnvironmentValue method is:
1147%
1148% char *GetEnvironmentValue(const char *name)
1149%
1150% A description of each parameter follows:
1151%
1152% o name: the environment name.
1153%
1154*/
1155MagickExport char *GetEnvironmentValue(const char *name)
1156{
1157#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1158 return(NTGetEnvironmentValue(name));
1159#else
1160 const char
1161 *environment;
1162
1163 environment=getenv(name);
1164 if (environment == (const char *) NULL)
1165 return((char *) NULL);
1166 return(ConstantString(environment));
1167#endif
1168}
1169
1170/*
1171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1172% %
1173% %
1174% %
1175% G e t S t r i n g I n f o D a t u m %
1176% %
1177% %
1178% %
1179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1180%
1181% GetStringInfoDatum() returns the datum associated with the string.
1182%
1183% The format of the GetStringInfoDatum method is:
1184%
1185% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1186%
1187% A description of each parameter follows:
1188%
1189% o string_info: the string info.
1190%
1191*/
1192MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1193{
1194 assert(string_info != (StringInfo *) NULL);
1195 assert(string_info->signature == MagickCoreSignature);
1196 return(string_info->datum);
1197}
1198
1199/*
1200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1201% %
1202% %
1203% %
1204% G e t S t r i n g I n f o L e n g t h %
1205% %
1206% %
1207% %
1208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1209%
1210% GetStringInfoLength() returns the string length.
1211%
1212% The format of the GetStringInfoLength method is:
1213%
1214% size_t GetStringInfoLength(const StringInfo *string_info)
1215%
1216% A description of each parameter follows:
1217%
1218% o string_info: the string info.
1219%
1220*/
1221MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1222{
1223 assert(string_info != (StringInfo *) NULL);
1224 assert(string_info->signature == MagickCoreSignature);
1225 return(string_info->length);
1226}
1227
1228/*
1229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1230% %
1231% %
1232% %
1233% G e t S t r i n g I n f o N a m e %
1234% %
1235% %
1236% %
1237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1238%
1239% GetStringInfoName() returns the name associated with the string.
1240%
1241% The format of the GetStringInfoName method is:
1242%
1243% const char *GetStringInfoName(const StringInfo *string_info)
1244%
1245% A description of each parameter follows:
1246%
1247% o string_info: the string info.
1248%
1249*/
1250MagickExport const char *GetStringInfoName(const StringInfo *string_info)
1251{
1252 assert(string_info != (StringInfo *) NULL);
1253 assert(string_info->signature == MagickCoreSignature);
1254 return(string_info->name);
1255}
1256
1257/*
1258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259% %
1260% %
1261% %
1262% G e t S t r i n g I n f o P a t h %
1263% %
1264% %
1265% %
1266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267%
1268% GetStringInfoPath() returns the path associated with the string.
1269%
1270% The format of the GetStringInfoPath method is:
1271%
1272% const char *GetStringInfoPath(const StringInfo *string_info)
1273%
1274% A description of each parameter follows:
1275%
1276% o string_info: the string info.
1277%
1278*/
1279MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1280{
1281 assert(string_info != (StringInfo *) NULL);
1282 assert(string_info->signature == MagickCoreSignature);
1283 return(string_info->path);
1284}
1285
1286/*
1287%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288% %
1289% %
1290% %
1291+ I n t e r p r e t S i P r e f i x V a l u e %
1292% %
1293% %
1294% %
1295%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296%
1297% InterpretSiPrefixValue() converts the initial portion of the string to a
1298% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1299% etc.).
1300%
1301% The format of the InterpretSiPrefixValue method is:
1302%
1303% double InterpretSiPrefixValue(const char *value,char **sentinel)
1304%
1305% A description of each parameter follows:
1306%
1307% o value: the string value.
1308%
1309% o sentinel: if sentinel is not NULL, return a pointer to the character
1310% after the last character used in the conversion.
1311%
1312*/
1313MagickExport double InterpretSiPrefixValue(const char *magick_restrict string,
1314 char **magick_restrict sentinel)
1315{
1316 char
1317 *q;
1318
1319 double
1320 value;
1321
1322 value=InterpretLocaleValue(string,&q);
1323 if (q != string)
1324 {
1325 if ((*q >= 'E') && (*q <= 'z'))
1326 {
1327 double
1328 e;
1329
1330 switch ((int) ((unsigned char) *q))
1331 {
1332 case 'q': e=(-30.0); break;
1333 case 'r': e=(-27.0); break;
1334 case 'y': e=(-24.0); break;
1335 case 'z': e=(-21.0); break;
1336 case 'a': e=(-18.0); break;
1337 case 'f': e=(-15.0); break;
1338 case 'p': e=(-12.0); break;
1339 case 'n': e=(-9.0); break;
1340 case 'u': e=(-6.0); break;
1341 case 'm': e=(-3.0); break;
1342 case 'c': e=(-2.0); break;
1343 case 'd': e=(-1.0); break;
1344 case 'h': e=2.0; break;
1345 case 'k': e=3.0; break;
1346 case 'K': e=3.0; break;
1347 case 'M': e=6.0; break;
1348 case 'G': e=9.0; break;
1349 case 'T': e=12.0; break;
1350 case 'P': e=15.0; break;
1351 case 'E': e=18.0; break;
1352 case 'Z': e=21.0; break;
1353 case 'Y': e=24.0; break;
1354 case 'R': e=27.0; break;
1355 case 'Q': e=30.0; break;
1356 default: e=0.0; break;
1357 }
1358 if (e >= MagickEpsilon)
1359 {
1360 if (q[1] == 'i')
1361 {
1362 value*=pow(2.0,e/0.3);
1363 q+=(ptrdiff_t) 2;
1364 }
1365 else
1366 {
1367 value*=pow(10.0,e);
1368 q++;
1369 }
1370 }
1371 }
1372 if ((*q == 'B') || (*q == 'P'))
1373 q++;
1374 }
1375 if (sentinel != (char **) NULL)
1376 *sentinel=q;
1377 return(value);
1378}
1379
1380/*
1381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1382% %
1383% %
1384% %
1385% I s S t r i n g T r u e %
1386% %
1387% %
1388% %
1389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1390%
1391% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1392% "1". Any other string or undefined returns MagickFalse.
1393%
1394% Typically this is used to look at strings (options or artifacts) which
1395% has a default value of "false", when not defined.
1396%
1397% The format of the IsStringTrue method is:
1398%
1399% MagickBooleanType IsStringTrue(const char *value)
1400%
1401% A description of each parameter follows:
1402%
1403% o value: Specifies a pointer to a character array.
1404%
1405*/
1406MagickExport MagickBooleanType IsStringTrue(const char *value)
1407{
1408 if (value == (const char *) NULL)
1409 return(MagickFalse);
1410 if (LocaleCompare(value,"true") == 0)
1411 return(MagickTrue);
1412 if (LocaleCompare(value,"on") == 0)
1413 return(MagickTrue);
1414 if (LocaleCompare(value,"yes") == 0)
1415 return(MagickTrue);
1416 if (LocaleCompare(value,"1") == 0)
1417 return(MagickTrue);
1418 return(MagickFalse);
1419}
1420
1421/*
1422%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1423% %
1424% %
1425% %
1426% I s S t r i n g F a l s e %
1427% %
1428% %
1429% %
1430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1431%
1432% IsStringFalse() returns MagickTrue if the value is "false", "off", "no" or
1433% "0". Any other string or undefined returns MagickFalse.
1434%
1435% Typically this is used to look at strings (options or artifacts) which
1436% has a default value of "true", when it has not been defined.
1437%
1438% The format of the IsStringFalse method is:
1439%
1440% MagickBooleanType IsStringFalse(const char *value)
1441%
1442% A description of each parameter follows:
1443%
1444% o value: Specifies a pointer to a character array.
1445%
1446*/
1447MagickExport MagickBooleanType IsStringFalse(const char *value)
1448{
1449 if (value == (const char *) NULL)
1450 return(MagickFalse);
1451 if (LocaleCompare(value,"false") == 0)
1452 return(MagickTrue);
1453 if (LocaleCompare(value,"off") == 0)
1454 return(MagickTrue);
1455 if (LocaleCompare(value,"no") == 0)
1456 return(MagickTrue);
1457 if (LocaleCompare(value,"0") == 0)
1458 return(MagickTrue);
1459 return(MagickFalse);
1460}
1461
1462/*
1463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1464% %
1465% %
1466% %
1467% P r i n t S t r i n g I n f o %
1468% %
1469% %
1470% %
1471%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1472%
1473% PrintStringInfo() prints the string.
1474%
1475% The format of the PrintStringInfo method is:
1476%
1477% void PrintStringInfo(FILE *file,const char *id,
1478% const StringInfo *string_info)
1479%
1480% A description of each parameter follows:
1481%
1482% o file: the file, typically stdout.
1483%
1484% o id: the string id.
1485%
1486% o string_info: the string info.
1487%
1488*/
1489MagickExport void PrintStringInfo(FILE *file,const char *id,
1490 const StringInfo *string_info)
1491{
1492 const unsigned char
1493 *p;
1494
1495 size_t
1496 i,
1497 j;
1498
1499 /*
1500 Check if string is printable.
1501 */
1502 assert(id != (const char *) NULL);
1503 assert(string_info != (StringInfo *) NULL);
1504 assert(string_info->signature == MagickCoreSignature);
1505 p=(const unsigned char *) string_info->datum;
1506 for (i=0; i < string_info->length; i++)
1507 if ((p[i] < 32) && (isspace((int)p[i]) == 0))
1508 break;
1509 (void) FormatLocaleFile(file,"%s(%.20g):\n",id,(double) string_info->length);
1510 if (i == string_info->length)
1511 {
1512 for (i = 0; i < string_info->length; i++)
1513 (void) fputc(p[i],file);
1514 (void) fputc('\n',file);
1515 return;
1516 }
1517 /*
1518 Convert string to a HEX list.
1519 */
1520 for (i=0; i < string_info->length; i+=CharsPerLine)
1521 {
1522 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) i);
1523 for (j = 0; j < MagickMin(string_info->length-i, CharsPerLine); j++)
1524 {
1525 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (p[i+j]) & 0xff);
1526 if (((j+1) % 0x04) == 0)
1527 (void) fputc(' ',file);
1528 }
1529 /*
1530 Padding.
1531 */
1532 for ( ; j < CharsPerLine; j++)
1533 {
1534 (void) fputc(' ',file);
1535 (void) fputc(' ',file);
1536 if (((j+1) % 0x04) == 0)
1537 (void) fputc(' ',file);
1538 }
1539 (void) fputc(' ',file);
1540 /*
1541 ASCII section.
1542 */
1543 for (j=0; j < MagickMin(string_info->length-i,CharsPerLine); j++)
1544 {
1545 unsigned char c = p[i+j];
1546 if (isprint((int) c) != 0)
1547 (void) fputc(c,file);
1548 else
1549 (void) fputc('-',file);
1550 }
1551 (void) fputc('\n',file);
1552 }
1553}
1554
1555/*
1556%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1557% %
1558% %
1559% %
1560% R e s e t S t r i n g I n f o %
1561% %
1562% %
1563% %
1564%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565%
1566% ResetStringInfo() reset the string to all null bytes.
1567%
1568% The format of the ResetStringInfo method is:
1569%
1570% void ResetStringInfo(StringInfo *string_info)
1571%
1572% A description of each parameter follows:
1573%
1574% o string_info: the string info.
1575%
1576*/
1577MagickExport void ResetStringInfo(StringInfo *string_info)
1578{
1579 assert(string_info != (StringInfo *) NULL);
1580 assert(string_info->signature == MagickCoreSignature);
1581 (void) memset(string_info->datum,0,string_info->length);
1582}
1583
1584/*
1585%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1586% %
1587% %
1588% %
1589% S a n t i z e S t r i n g %
1590% %
1591% %
1592% %
1593%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1594%
1595% SanitizeString() returns a new string with all characters removed except
1596% letters, digits and !#$%&'*+-=?^_`{|}~@.[].
1597%
1598% Free the sanitized string with DestroyString().
1599%
1600% The format of the SanitizeString method is:
1601%
1602% char *SanitizeString(const char *source)
1603%
1604% A description of each parameter follows:
1605%
1606% o source: A character string.
1607%
1608*/
1609MagickExport char *SanitizeString(const char *source)
1610{
1611 char
1612 *sanitize_source;
1613
1614 const char
1615 *q;
1616
1617 char
1618 *p;
1619
1620 static char
1621 allowlist[] =
1622 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "
1623 "$-_.+!*'(),{}|\\^~[]`\"><#%;/?:@&=";
1624
1625 sanitize_source=AcquireString(source);
1626 p=sanitize_source;
1627 q=sanitize_source+strlen(sanitize_source);
1628 for (p+=strspn(p,allowlist); p != q; p+=(ptrdiff_t) strspn(p,allowlist))
1629 *p='_';
1630 return(sanitize_source);
1631}
1632
1633/*
1634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1635% %
1636% %
1637% %
1638% S e t S t r i n g I n f o %
1639% %
1640% %
1641% %
1642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1643%
1644% SetStringInfo() copies the source string to the destination string.
1645%
1646% The format of the SetStringInfo method is:
1647%
1648% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1649%
1650% A description of each parameter follows:
1651%
1652% o string_info: the string info.
1653%
1654% o source: the source string.
1655%
1656*/
1657MagickExport void SetStringInfo(StringInfo *string_info,
1658 const StringInfo *source)
1659{
1660 assert(string_info != (StringInfo *) NULL);
1661 assert(string_info->signature == MagickCoreSignature);
1662 assert(source != (StringInfo *) NULL);
1663 assert(source->signature == MagickCoreSignature);
1664 if (string_info->length == 0)
1665 return;
1666 (void) memset(string_info->datum,0,string_info->length);
1667 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1668 source->length));
1669}
1670
1671/*
1672%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1673% %
1674% %
1675% %
1676% S e t S t r i n g I n f o D a t u m %
1677% %
1678% %
1679% %
1680%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1681%
1682% SetStringInfoDatum() copies bytes from the source string for the length of
1683% the destination string.
1684%
1685% The format of the SetStringInfoDatum method is:
1686%
1687% void SetStringInfoDatum(StringInfo *string_info,
1688% const unsigned char *source)
1689%
1690% A description of each parameter follows:
1691%
1692% o string_info: the string info.
1693%
1694% o source: the source string.
1695%
1696*/
1697MagickExport void SetStringInfoDatum(StringInfo *string_info,
1698 const unsigned char *source)
1699{
1700 assert(string_info != (StringInfo *) NULL);
1701 assert(string_info->signature == MagickCoreSignature);
1702 if (string_info->length != 0)
1703 (void) memcpy(string_info->datum,source,string_info->length);
1704}
1705
1706/*
1707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1708% %
1709% %
1710% %
1711% S e t S t r i n g I n f o L e n g t h %
1712% %
1713% %
1714% %
1715%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1716%
1717% SetStringInfoLength() set the string length to the specified value.
1718%
1719% The format of the SetStringInfoLength method is:
1720%
1721% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1722%
1723% A description of each parameter follows:
1724%
1725% o string_info: the string info.
1726%
1727% o length: the string length.
1728%
1729*/
1730MagickExport void SetStringInfoLength(StringInfo *string_info,
1731 const size_t length)
1732{
1733 assert(string_info != (StringInfo *) NULL);
1734 assert(string_info->signature == MagickCoreSignature);
1735 if (string_info->length == length)
1736 return;
1737 if (~length < MagickPathExtent)
1738 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1739 string_info->length=length;
1740 if (string_info->datum == (unsigned char *) NULL)
1741 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1742 MagickPathExtent,sizeof(*string_info->datum));
1743 else
1744 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1745 length+MagickPathExtent,sizeof(*string_info->datum));
1746 if (string_info->datum == (unsigned char *) NULL)
1747 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1748}
1749
1750/*
1751%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1752% %
1753% %
1754% %
1755% S e t S t r i n g I n f o N a m e %
1756% %
1757% %
1758% %
1759%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1760%
1761% SetStringInfoName() sets the name associated with the string.
1762%
1763% The format of the SetStringInfoName method is:
1764%
1765% void SetStringInfoName(StringInfo *string_info,const char *name)
1766%
1767% A description of each parameter follows:
1768%
1769% o string_info: the string info.
1770%
1771% o name: the name.
1772%
1773*/
1774MagickExport void SetStringInfoName(StringInfo *string_info,const char *name)
1775{
1776 assert(string_info != (StringInfo *) NULL);
1777 assert(string_info->signature == MagickCoreSignature);
1778 assert(name != (const char *) NULL);
1779 string_info->name=ConstantString(name);
1780}
1781
1782/*
1783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1784% %
1785% %
1786% %
1787% S e t S t r i n g I n f o P a t h %
1788% %
1789% %
1790% %
1791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1792%
1793% SetStringInfoPath() sets the path associated with the string.
1794%
1795% The format of the SetStringInfoPath method is:
1796%
1797% void SetStringInfoPath(StringInfo *string_info,const char *path)
1798%
1799% A description of each parameter follows:
1800%
1801% o string_info: the string info.
1802%
1803% o path: the path.
1804%
1805*/
1806MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1807{
1808 assert(string_info != (StringInfo *) NULL);
1809 assert(string_info->signature == MagickCoreSignature);
1810 assert(path != (const char *) NULL);
1811 string_info->path=ConstantString(path);
1812}
1813
1814/*
1815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1816% %
1817% %
1818% %
1819% S p l i t S t r i n g I n f o %
1820% %
1821% %
1822% %
1823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1824%
1825% SplitStringInfo() splits a string into two and returns it.
1826%
1827% The format of the SplitStringInfo method is:
1828%
1829% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1830%
1831% A description of each parameter follows:
1832%
1833% o string_info: the string info.
1834%
1835*/
1836MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1837 const size_t offset)
1838{
1839 StringInfo
1840 *split_info;
1841
1842 assert(string_info != (StringInfo *) NULL);
1843 assert(string_info->signature == MagickCoreSignature);
1844 if (offset > string_info->length)
1845 return((StringInfo *) NULL);
1846 split_info=AcquireStringInfo(offset);
1847 SetStringInfo(split_info,string_info);
1848 (void) memmove(string_info->datum,string_info->datum+offset,
1849 string_info->length-offset+MagickPathExtent);
1850 SetStringInfoLength(string_info,string_info->length-offset);
1851 return(split_info);
1852}
1853
1854/*
1855%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1856% %
1857% %
1858% %
1859% S t r i n g I n f o T o D i g e s t %
1860% %
1861% %
1862% %
1863%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1864%
1865% StringInfoToDigest() converts a string info string to a hex digest.
1866%
1867% The format of the StringInfoToString method is:
1868%
1869% char *StringInfoToDigest(const StringInfo *signature)
1870%
1871% A description of each parameter follows:
1872%
1873% o string_info: the string.
1874%
1875*/
1876MagickExport char *StringInfoToDigest(const StringInfo *signature)
1877{
1878 char
1879 *digest;
1880
1881 SignatureInfo
1882 *signature_info;
1883
1884 signature_info=AcquireSignatureInfo();
1885 UpdateSignature(signature_info,signature);
1886 FinalizeSignature(signature_info);
1887 digest=StringInfoToHexString(GetSignatureDigest(signature_info));
1888 signature_info=DestroySignatureInfo(signature_info);
1889 return(digest);
1890}
1891
1892/*
1893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1894% %
1895% %
1896% %
1897% S t r i n g I n f o T o H e x S t r i n g %
1898% %
1899% %
1900% %
1901%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1902%
1903% StringInfoToHexString() converts a string info string to a C string.
1904%
1905% The format of the StringInfoToHexString method is:
1906%
1907% char *StringInfoToHexString(const StringInfo *string_info)
1908%
1909% A description of each parameter follows:
1910%
1911% o string_info: the string.
1912%
1913*/
1914MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1915{
1916 char
1917 *string;
1918
1919 const unsigned char
1920 *p;
1921
1922 ssize_t
1923 i;
1924
1925 unsigned char
1926 *q;
1927
1928 size_t
1929 length;
1930
1931 unsigned char
1932 hex_digits[16];
1933
1934 length=string_info->length;
1935 if (~length < MagickPathExtent)
1936 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1937 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,2*
1938 sizeof(*string));
1939 if (string == (char *) NULL)
1940 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1941 hex_digits[0]='0';
1942 hex_digits[1]='1';
1943 hex_digits[2]='2';
1944 hex_digits[3]='3';
1945 hex_digits[4]='4';
1946 hex_digits[5]='5';
1947 hex_digits[6]='6';
1948 hex_digits[7]='7';
1949 hex_digits[8]='8';
1950 hex_digits[9]='9';
1951 hex_digits[10]='a';
1952 hex_digits[11]='b';
1953 hex_digits[12]='c';
1954 hex_digits[13]='d';
1955 hex_digits[14]='e';
1956 hex_digits[15]='f';
1957 p=string_info->datum;
1958 q=(unsigned char *) string;
1959 for (i=0; i < (ssize_t) string_info->length; i++)
1960 {
1961 *q++=hex_digits[(*p >> 4) & 0x0f];
1962 *q++=hex_digits[*p & 0x0f];
1963 p++;
1964 }
1965 *q='\0';
1966 return(string);
1967}
1968
1969/*
1970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1971% %
1972% %
1973% %
1974% S t r i n g I n f o T o S t r i n g %
1975% %
1976% %
1977% %
1978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1979%
1980% StringInfoToString() converts a string info string to a C string.
1981%
1982% The format of the StringInfoToString method is:
1983%
1984% char *StringInfoToString(const StringInfo *string_info)
1985%
1986% A description of each parameter follows:
1987%
1988% o string_info: the string.
1989%
1990*/
1991MagickExport char *StringInfoToString(const StringInfo *string_info)
1992{
1993 char
1994 *string;
1995
1996 size_t
1997 length;
1998
1999 string=(char *) NULL;
2000 length=string_info->length;
2001 if (~length >= (MagickPathExtent-1))
2002 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
2003 sizeof(*string));
2004 if (string == (char *) NULL)
2005 return((char *) NULL);
2006 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
2007 string[length]='\0';
2008 return(string);
2009}
2010
2011/*
2012%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2013% %
2014% %
2015% %
2016% S t r i n g T o A r g v %
2017% %
2018% %
2019% %
2020%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2021%
2022% StringToArgv() converts a text string into command line arguments.
2023% The 'argv' array of arguments, is returned while the number of arguments
2024% is returned via the provided integer variable pointer.
2025%
2026% Simple 'word' tokenizer, which allows for each word to be optionally
2027% quoted. However it will not allow use of partial quotes, or escape
2028% characters.
2029%
2030% The format of the StringToArgv method is:
2031%
2032% char **StringToArgv(const char *text,int *argc)
2033%
2034% A description of each parameter follows:
2035%
2036% o argv: Method StringToArgv returns the string list unless an error
2037% occurs, otherwise NULL.
2038%
2039% o text: Specifies the string to segment into a list.
2040%
2041% o argc: This integer pointer returns the number of arguments in the
2042% list.
2043%
2044*/
2045MagickExport char **StringToArgv(const char *text,int *argc)
2046{
2047 char
2048 **argv;
2049
2050 const char
2051 *p,
2052 *q;
2053
2054 ssize_t
2055 i;
2056
2057 *argc=0;
2058 if (text == (char *) NULL)
2059 return((char **) NULL);
2060 /*
2061 Determine the number of arguments.
2062 */
2063 for (p=text; *p != '\0'; )
2064 {
2065 while (isspace((int) ((unsigned char) *p)) != 0)
2066 p++;
2067 if (*p == '\0')
2068 break;
2069 (*argc)++;
2070 if (*p == '"')
2071 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2072 if (*p == '\'')
2073 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2074 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2075 p++;
2076 }
2077 (*argc)++;
2078 argv=(char **) AcquireQuantumMemory((size_t) *argc+1UL,sizeof(*argv));
2079 if (argv == (char **) NULL)
2080 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2081 /*
2082 Convert string to an ASCII list.
2083 */
2084 argv[0]=AcquireString("magick");
2085 p=text;
2086 for (i=1; i < (ssize_t) *argc; i++)
2087 {
2088 while (isspace((int) ((unsigned char) *p)) != 0)
2089 p++;
2090 q=p;
2091 if (*q == '"')
2092 {
2093 p++;
2094 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2095 }
2096 else
2097 if (*q == '\'')
2098 {
2099 p++;
2100 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
2101 }
2102 else
2103 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2104 q++;
2105 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MagickPathExtent,
2106 sizeof(**argv));
2107 if (argv[i] == (char *) NULL)
2108 {
2109 for (i--; i >= 0; i--)
2110 argv[i]=DestroyString(argv[i]);
2111 argv=(char **) RelinquishMagickMemory(argv);
2112 ThrowFatalException(ResourceLimitFatalError,
2113 "UnableToConvertStringToARGV");
2114 }
2115 (void) memcpy(argv[i],p,(size_t) (q-p));
2116 argv[i][q-p]='\0';
2117 p=q;
2118 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2119 p++;
2120 }
2121 argv[i]=(char *) NULL;
2122 return(argv);
2123}
2124
2125/*
2126%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2127% %
2128% %
2129% %
2130% S t r i n g T o A r r a y O f D o u b l e s %
2131% %
2132% %
2133% %
2134%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2135%
2136% StringToArrayOfDoubles() converts a string of space or comma separated
2137% numbers into array of floating point numbers (doubles). Any number that
2138% fails to parse properly will produce a syntax error. As will two commas
2139% without a number between them. However a final comma at the end will
2140% not be regarded as an error so as to simplify automatic list generation.
2141%
2142% A NULL value is returned on syntax or memory errors.
2143%
2144% Use RelinquishMagickMemory() to free returned array when finished.
2145%
2146% The format of the StringToArrayOfDoubles method is:
2147%
2148% double *StringToArrayOfDoubles(const char *string,size_t *count,
2149% ExceptionInfo *exception)
2150%
2151% A description of each parameter follows:
2152%
2153% o string: the string containing the comma/space separated values.
2154%
2155% o count: returns number of arguments in returned array
2156%
2157% o exception: return any errors or warnings in this structure.
2158%
2159*/
2160MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2161 ExceptionInfo *exception)
2162{
2163 char
2164 *q;
2165
2166 const char
2167 *p;
2168
2169 double
2170 *array;
2171
2172 ssize_t
2173 i;
2174
2175 /*
2176 Determine count of values, and check syntax.
2177 */
2178 assert(exception != (ExceptionInfo *) NULL);
2179 assert(exception->signature == MagickCoreSignature);
2180 *count=0;
2181 if (string == (char *) NULL)
2182 return((double *) NULL); /* no value found */
2183 i=0;
2184 p=string;
2185 while (*p != '\0')
2186 {
2187 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2188 if (p == q)
2189 return((double *) NULL); /* no value found */
2190 p=q;
2191 i++; /* increment value count */
2192 while (isspace((int) ((unsigned char) *p)) != 0)
2193 p++; /* skip spaces */
2194 if (*p == ',')
2195 p++; /* skip comma */
2196 while (isspace((int) ((unsigned char) *p)) != 0)
2197 p++; /* and more spaces */
2198 }
2199 /*
2200 Allocate floating point argument list.
2201 */
2202 *count=i;
2203 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2204 if (array == (double *) NULL)
2205 {
2206 (void) ThrowMagickException(exception,GetMagickModule(),
2207 ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2208 return((double *) NULL);
2209 }
2210 /*
2211 Fill in the floating point values.
2212 */
2213 i=0;
2214 p=string;
2215 while ((*p != '\0') && (i < *count))
2216 {
2217 array[i++]=StringToDouble(p,&q);
2218 p=q;
2219 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2220 p++;
2221 }
2222 return(array);
2223}
2224
2225/*
2226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2227% %
2228% %
2229% %
2230+ S t r i n g T o k e n %
2231% %
2232% %
2233% %
2234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2235%
2236% StringToken() looks for any one of given delimiters and splits the string
2237% into two separate strings by replacing the delimiter character found with a
2238% null character.
2239%
2240% The given string pointer is changed to point to the string following the
2241% delimiter character found, or NULL. A pointer to the start of the
2242% string is returned, representing the token before the delimiter.
2243%
2244% StringToken() is similar to the strtok() C library method, but with
2245% multiple delimiter characters rather than a delimiter string.
2246%
2247% The format of the StringToken method is:
2248%
2249% char *StringToken(const char *delimiters,char **string)
2250%
2251% A description of each parameter follows:
2252%
2253% o delimiters: one or more delimiters.
2254%
2255% o string: return the first token in the string. If none is found, return
2256% NULL.
2257%
2258*/
2259MagickExport char *StringToken(const char *delimiters,char **string)
2260{
2261 char
2262 *q;
2263
2264 char
2265 *p;
2266
2267 const char
2268 *r;
2269
2270 int
2271 c,
2272 d;
2273
2274 p=(*string);
2275 if (p == (char *) NULL)
2276 return((char *) NULL);
2277 q=p;
2278 for ( ; ; )
2279 {
2280 c=(*p++);
2281 r=delimiters;
2282 do
2283 {
2284 d=(*r++);
2285 if (c == d)
2286 {
2287 if (c == '\0')
2288 p=(char *) NULL;
2289 else
2290 p[-1]='\0';
2291 *string=p;
2292 return(q);
2293 }
2294 } while (d != '\0');
2295 }
2296}
2297
2298/*
2299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2300% %
2301% %
2302% %
2303% S t r i n g T o L i s t %
2304% %
2305% %
2306% %
2307%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2308%
2309% StringToList() converts a text string into a list by segmenting the text
2310% string at each carriage return discovered. The list is converted to HEX
2311% characters if any control characters are discovered within the text string.
2312%
2313% The format of the StringToList method is:
2314%
2315% char **StringToList(const char *text)
2316%
2317% A description of each parameter follows:
2318%
2319% o text: Specifies the string to segment into a list.
2320%
2321*/
2322MagickExport char **StringToList(const char *text)
2323{
2324 return(StringToStrings(text,(size_t *) NULL));
2325}
2326
2327/*
2328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2329% %
2330% %
2331% %
2332% S t r i n g T o S t r i n g s %
2333% %
2334% %
2335% %
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337%
2338% StringToStrings() converts a text string into a list by segmenting the text
2339% string at each carriage return discovered. The list is converted to HEX
2340% characters if any control characters are discovered within the text string.
2341%
2342% The format of the StringToList method is:
2343%
2344% char **StringToList(const char *text,size_t *lines)
2345%
2346% A description of each parameter follows:
2347%
2348% o text: Specifies the string to segment into a list.
2349%
2350% o count: Return value for the number of items in the list.
2351%
2352*/
2353MagickExport char **StringToStrings(const char *text,size_t *count)
2354{
2355 char
2356 **textlist;
2357
2358 const char
2359 *p;
2360
2361 ssize_t
2362 i;
2363
2364 size_t
2365 lines;
2366
2367 if (text == (char *) NULL)
2368 {
2369 if (count != (size_t *) NULL)
2370 *count=0;
2371 return((char **) NULL);
2372 }
2373 for (p=text; *p != '\0'; p++)
2374 if (((int) ((unsigned char) *p) < 32) &&
2375 (isspace((int) ((unsigned char) *p)) == 0))
2376 break;
2377 if (*p == '\0')
2378 {
2379 const char
2380 *q;
2381
2382 /*
2383 Convert string to an ASCII list.
2384 */
2385 lines=1;
2386 for (p=text; *p != '\0'; p++)
2387 if (*p == '\n')
2388 lines++;
2389 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2390 sizeof(*textlist));
2391 if (textlist == (char **) NULL)
2392 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2393 p=text;
2394 for (i=0; i < (ssize_t) lines; i++)
2395 {
2396 for (q=p; *q != '\0'; q++)
2397 if ((*q == '\r') || (*q == '\n'))
2398 break;
2399 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1,
2400 sizeof(**textlist));
2401 if (textlist[i] == (char *) NULL)
2402 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2403 (void) memcpy(textlist[i],p,(size_t) (q-p));
2404 textlist[i][q-p]='\0';
2405 if (*q == '\r')
2406 q++;
2407 p=q+1;
2408 }
2409 }
2410 else
2411 {
2412 char
2413 hex_string[MagickPathExtent];
2414
2415 char
2416 *q;
2417
2418 ssize_t
2419 j;
2420
2421 /*
2422 Convert string to a HEX list.
2423 */
2424 lines=(size_t) (strlen(text)/CharsPerLine)+1;
2425 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2426 sizeof(*textlist));
2427 if (textlist == (char **) NULL)
2428 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2429 p=text;
2430 for (i=0; i < (ssize_t) lines; i++)
2431 {
2432 size_t
2433 length;
2434
2435 textlist[i]=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
2436 sizeof(**textlist));
2437 if (textlist[i] == (char *) NULL)
2438 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2439 (void) FormatLocaleString(textlist[i],MagickPathExtent,"0x%08lx: ",
2440 (long) (CharsPerLine*i));
2441 q=textlist[i]+strlen(textlist[i]);
2442 length=strlen(p);
2443 for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2444 {
2445 (void) FormatLocaleString(hex_string,MagickPathExtent,"%02x",*(p+j));
2446 (void) CopyMagickString(q,hex_string,MagickPathExtent);
2447 q+=(ptrdiff_t) 2;
2448 if ((j % 0x04) == 0)
2449 *q++=' ';
2450 }
2451 for ( ; j <= CharsPerLine; j++)
2452 {
2453 *q++=' ';
2454 *q++=' ';
2455 if ((j % 0x04) == 0)
2456 *q++=' ';
2457 }
2458 *q++=' ';
2459 for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2460 {
2461 if (isprint((int) ((unsigned char) *p)) != 0)
2462 *q++=(*p);
2463 else
2464 *q++='-';
2465 p++;
2466 }
2467 *q='\0';
2468 textlist[i]=(char *) ResizeQuantumMemory(textlist[i],(size_t) (q-
2469 textlist[i]+1),sizeof(**textlist));
2470 if (textlist[i] == (char *) NULL)
2471 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2472 }
2473 }
2474 if (count != (size_t *) NULL)
2475 *count=lines;
2476 textlist[i]=(char *) NULL;
2477 return(textlist);
2478}
2479
2480/*
2481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2482% %
2483% %
2484% %
2485% S t r i n g T o S t r i n g I n f o %
2486% %
2487% %
2488% %
2489%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2490%
2491% StringToStringInfo() converts a string to a StringInfo type.
2492%
2493% The format of the StringToStringInfo method is:
2494%
2495% StringInfo *StringToStringInfo(const char *string)
2496%
2497% A description of each parameter follows:
2498%
2499% o string: The string.
2500%
2501*/
2502MagickExport StringInfo *StringToStringInfo(const char *string)
2503{
2504 StringInfo
2505 *string_info;
2506
2507 assert(string != (const char *) NULL);
2508 string_info=AcquireStringInfo(strlen(string));
2509 SetStringInfoDatum(string_info,(const unsigned char *) string);
2510 return(string_info);
2511}
2512
2513/*
2514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2515% %
2516% %
2517% %
2518% S t r i p M a g i c k S t r i n g %
2519% %
2520% %
2521% %
2522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2523%
2524% StripMagickString() strips any whitespace or quotes from the beginning and
2525% end of a string of characters. It returns the stripped string length.
2526%
2527% The format of the StripMagickString method is:
2528%
2529% size_t StripMagickString(char *message)
2530%
2531% A description of each parameter follows:
2532%
2533% o message: Specifies an array of characters.
2534%
2535*/
2536
2537MagickExport void StripString(char *message)
2538{
2539 (void) StripMagickString(message);
2540}
2541
2542MagickExport size_t StripMagickString(char *message)
2543{
2544 char
2545 *p,
2546 *q;
2547
2548 size_t
2549 length;
2550
2551 assert(message != (char *) NULL);
2552 if (*message == '\0')
2553 return(0);
2554 length=strlen(message);
2555 if (length == 1)
2556 return(1);
2557 p=message;
2558 while (isspace((int) ((unsigned char) *p)) != 0)
2559 p++;
2560 if ((*p == '\'') || (*p == '"'))
2561 p++;
2562 q=message+length-1;
2563 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2564 q--;
2565 if (q > p)
2566 if ((*q == '\'') || (*q == '"'))
2567 q--;
2568 (void) memmove(message,p,(size_t) (q-p+1));
2569 message[q-p+1]='\0';
2570 for (p=message; *p != '\0'; p++)
2571 if (*p == '\n')
2572 *p=' ';
2573 return((size_t) (q-p+1));
2574}
2575
2576/*
2577%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2578% %
2579% %
2580% %
2581% S u b s t i t u t e S t r i n g %
2582% %
2583% %
2584% %
2585%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2586%
2587% SubstituteString() performs string substitution on a string, replacing the
2588% string with the substituted version. Buffer must be allocated from the heap.
2589% If the string is matched and status, MagickTrue is returned otherwise
2590% MagickFalse.
2591%
2592% The format of the SubstituteString method is:
2593%
2594% MagickBooleanType SubstituteString(char **string,const char *search,
2595% const char *replace)
2596%
2597% A description of each parameter follows:
2598%
2599% o string: the string to perform replacements on; replaced with new
2600% allocation if a replacement is made.
2601%
2602% o search: search for this string.
2603%
2604% o replace: replace any matches with this string.
2605%
2606*/
2607MagickExport MagickBooleanType SubstituteString(char **string,
2608 const char *search,const char *replace)
2609{
2610 MagickBooleanType
2611 status;
2612
2613 char
2614 *p;
2615
2616 size_t
2617 extent,
2618 replace_extent,
2619 search_extent;
2620
2621 ssize_t
2622 offset;
2623
2624 status=MagickFalse;
2625 search_extent=0,
2626 replace_extent=0;
2627 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
2628 {
2629 if (search_extent == 0)
2630 search_extent=strlen(search);
2631 if (strncmp(p,search,search_extent) != 0)
2632 continue;
2633 /*
2634 We found a match.
2635 */
2636 status=MagickTrue;
2637 if (replace_extent == 0)
2638 replace_extent=strlen(replace);
2639 if (replace_extent > search_extent)
2640 {
2641 /*
2642 Make room for the replacement string.
2643 */
2644 offset=(ssize_t) (p-(*string));
2645 extent=strlen(*string)+replace_extent-search_extent+1;
2646 *string=(char *) ResizeQuantumMemory(*string,
2647 OverAllocateMemory(extent+MagickPathExtent),sizeof(*p));
2648 if (*string == (char *) NULL)
2649 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2650 p=(*string)+offset;
2651 }
2652 /*
2653 Replace string.
2654 */
2655 if (search_extent != replace_extent)
2656 (void) memmove(p+replace_extent,p+search_extent,
2657 strlen(p+search_extent)+1);
2658 (void) memcpy(p,replace,replace_extent);
2659 p+=(ptrdiff_t) replace_extent-1;
2660 }
2661 return(status);
2662}