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