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