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