blob: 070555206dedf910c28ea8421fa5dc20d7338d18 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
cristy670aa3c2011-11-03 00:54:00 +00006% 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 %
cristy3ed852e2009-09-05 21:47:34 +000011% %
12% %
cristy670aa3c2011-11-03 00:54:00 +000013% MagickCore String Methods %
cristy3ed852e2009-09-05 21:47:34 +000014% %
cristy670aa3c2011-11-03 00:54:00 +000015% Software Design %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy670aa3c2011-11-03 00:54:00 +000017% August 2003 %
cristy3ed852e2009-09-05 21:47:34 +000018% %
19% %
cristyb56bb242014-11-25 17:12:48 +000020% Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
cristy670aa3c2011-11-03 00:54:00 +000023% You may not use this file except in compliance with the license. You may %
cristy99bbf2c2011-09-26 18:27:50 +000024% obtain a copy of the license at %
cristy3ed852e2009-09-05 21:47:34 +000025% %
26% http://www.imagemagick.org/script/license.php %
27% %
cristy99bbf2c2011-09-26 18:27:50 +000028% unless required by applicable law or agreed to in writing, software %
29% distributed under the license is distributed on an "as is" basis, %
30% without warranties or conditions of any kind, either express or implied. %
cristy670aa3c2011-11-03 00:54:00 +000031% See the license for the specific language governing permissions and %
cristy99bbf2c2011-09-26 18:27:50 +000032% limitations under the license. %
cristy3ed852e2009-09-05 21:47:34 +000033% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
cristy99bbf2c2011-09-26 18:27:50 +000040 include declarations.
cristy3ed852e2009-09-05 21:47:34 +000041*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/exception.h"
46#include "MagickCore/exception-private.h"
dirk007e9252015-01-15 21:02:57 +000047#include "MagickCore/image-private.h"
cristy4c08aed2011-07-01 19:47:50 +000048#include "MagickCore/list.h"
49#include "MagickCore/locale_.h"
50#include "MagickCore/log.h"
51#include "MagickCore/memory_.h"
cristyd2d11ec2012-03-28 13:53:49 +000052#include "MagickCore/nt-base-private.h"
cristy4c08aed2011-07-01 19:47:50 +000053#include "MagickCore/property.h"
54#include "MagickCore/resource_.h"
55#include "MagickCore/signature-private.h"
56#include "MagickCore/string_.h"
anthonyb1d483a2012-04-14 12:53:56 +000057#include "MagickCore/string-private.h"
cristy18c6c272011-09-23 14:40:37 +000058#include "MagickCore/utility-private.h"
cristy3ed852e2009-09-05 21:47:34 +000059
60/*
cristy99bbf2c2011-09-26 18:27:50 +000061 static declarations.
cristy3ed852e2009-09-05 21:47:34 +000062*/
63#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
64static const unsigned char
cristy8e7a4612013-09-16 22:10:27 +000065 AsciiMap[] =
cristy3ed852e2009-09-05 21:47:34 +000066 {
67 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
68 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
69 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
70 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
71 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
72 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
73 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
74 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
75 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
76 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
77 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
78 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
79 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
80 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
81 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
82 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
83 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
84 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
85 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
86 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
87 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
88 0xfc, 0xfd, 0xfe, 0xff,
89 };
90#endif
91
92/*
93%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94% %
95% %
96% %
97% A c q u i r e S t r i n g %
98% %
99% %
100% %
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102%
anthony104f8932012-05-13 01:54:53 +0000103% AcquireString() returns an new extented string, containing a clone of the
104% given string.
cristy3ed852e2009-09-05 21:47:34 +0000105%
anthony104f8932012-05-13 01:54:53 +0000106% An extended string is the string length, plus an extra MaxTextExtent space
cristy5364f9c2013-12-28 23:29:28 +0000107% to allow for the string to be actively worked on.
anthony104f8932012-05-13 01:54:53 +0000108%
109% The returned string shoud be freed using DestoryString().
anthonyb1d483a2012-04-14 12:53:56 +0000110%
cristy3ed852e2009-09-05 21:47:34 +0000111% The format of the AcquireString method is:
112%
113% char *AcquireString(const char *source)
114%
115% A description of each parameter follows:
116%
117% o source: A character string.
118%
119*/
120MagickExport char *AcquireString(const char *source)
121{
122 char
123 *destination;
124
125 size_t
126 length;
127
128 length=0;
129 if (source != (char *) NULL)
130 length+=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000131 if (~length < MaxTextExtent)
132 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
133 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
134 sizeof(*destination));
cristy3ed852e2009-09-05 21:47:34 +0000135 if (destination == (char *) NULL)
136 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
137 *destination='\0';
138 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000139 (void) memcpy(destination,source,length*sizeof(*destination));
140 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000141 return(destination);
142}
143
144/*
145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146% %
147% %
148% %
149% A c q u i r e S t r i n g I n f o %
150% %
151% %
152% %
153%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154%
155% AcquireStringInfo() allocates the StringInfo structure.
156%
157% The format of the AcquireStringInfo method is:
158%
159% StringInfo *AcquireStringInfo(const size_t length)
160%
161% A description of each parameter follows:
162%
163% o length: the string length.
164%
165*/
166MagickExport StringInfo *AcquireStringInfo(const size_t length)
167{
168 StringInfo
169 *string_info;
170
cristy73bd4a52010-10-05 11:24:23 +0000171 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000172 if (string_info == (StringInfo *) NULL)
173 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
174 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
175 string_info->signature=MagickSignature;
176 string_info->length=length;
cristy8a68c242014-04-07 20:43:37 +0000177 string_info->datum=(unsigned char *) NULL;
178 if (~string_info->length >= (MaxTextExtent-1))
179 string_info->datum=(unsigned char *) AcquireQuantumMemory(
180 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
181 if (string_info->datum == (unsigned char *) NULL)
182 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000183 return(string_info);
184}
185
186/*
187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188% %
189% %
190% %
cristy8723e4b2011-09-01 13:11:19 +0000191% B l o b T o S t r i n g I n f o %
192% %
193% %
194% %
195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196%
anthony104f8932012-05-13 01:54:53 +0000197% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
198% with MaxTextExtent extra space.
cristy8723e4b2011-09-01 13:11:19 +0000199%
200% The format of the BlobToStringInfo method is:
201%
202% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
203%
204% A description of each parameter follows:
205%
206% o blob: the blob.
207%
208% o length: the length of the blob.
209%
210*/
211MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
212{
213 StringInfo
214 *string_info;
215
216 string_info=AcquireStringInfo(0);
cristy5ce7dac2014-05-28 12:22:17 +0000217 if (~length < MaxTextExtent)
218 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristyf8316342011-09-01 13:55:00 +0000219 string_info->length=length;
cristy5ce7dac2014-05-28 12:22:17 +0000220 if (string_info->datum == (unsigned char *) NULL)
221 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
222 MaxTextExtent,sizeof(*string_info->datum));
223 else
224 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
225 length+MaxTextExtent,sizeof(*string_info->datum));
cristy8723e4b2011-09-01 13:11:19 +0000226 if (string_info->datum == (unsigned char *) NULL)
227 {
228 string_info=DestroyStringInfo(string_info);
229 return((StringInfo *) NULL);
230 }
231 if (blob != (const void *) NULL)
232 (void) memcpy(string_info->datum,blob,length);
233 return(string_info);
234}
235
236/*
237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238% %
239% %
240% %
cristy3ed852e2009-09-05 21:47:34 +0000241% C l o n e S t r i n g %
242% %
243% %
244% %
245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246%
anthony104f8932012-05-13 01:54:53 +0000247% CloneString() replaces or frees the destination string to make it
248% a clone of the input string plus MaxTextExtent more space so the string may
249% be worked on on.
cristy3ed852e2009-09-05 21:47:34 +0000250%
anthony104f8932012-05-13 01:54:53 +0000251% If source is a NULL pointer the destination string will be freed and set to
252% a NULL pointer. A pointer to the stored in the destination is also returned.
anthony72feaa62012-01-17 06:46:23 +0000253%
anthony104f8932012-05-13 01:54:53 +0000254% When finished the non-NULL string should be freed using DestoryString()
255% or using CloneString() with a NULL pointed for the source.
anthony06762232012-04-29 11:45:40 +0000256%
cristy3ed852e2009-09-05 21:47:34 +0000257% The format of the CloneString method is:
258%
259% char *CloneString(char **destination,const char *source)
260%
261% A description of each parameter follows:
262%
263% o destination: A pointer to a character string.
264%
265% o source: A character string.
266%
267*/
268MagickExport char *CloneString(char **destination,const char *source)
269{
270 size_t
271 length;
272
cristy3ed852e2009-09-05 21:47:34 +0000273 assert(destination != (char **) NULL);
274 if (source == (const char *) NULL)
275 {
276 if (*destination != (char *) NULL)
277 *destination=DestroyString(*destination);
278 return(*destination);
279 }
280 if (*destination == (char *) NULL)
281 {
282 *destination=AcquireString(source);
283 return(*destination);
284 }
285 length=strlen(source);
286 if (~length < MaxTextExtent)
287 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
288 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000289 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000290 if (*destination == (char *) NULL)
291 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000292 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000293 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000294 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000295 return(*destination);
296}
297
298/*
299%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
300% %
301% %
302% %
303% C l o n e S t r i n g I n f o %
304% %
305% %
306% %
307%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308%
309% CloneStringInfo() clones a copy of the StringInfo structure.
310%
311% The format of the CloneStringInfo method is:
312%
313% StringInfo *CloneStringInfo(const StringInfo *string_info)
314%
315% A description of each parameter follows:
316%
317% o string_info: the string info.
318%
319*/
320MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
321{
322 StringInfo
323 *clone_info;
324
cristy3ed852e2009-09-05 21:47:34 +0000325 assert(string_info != (StringInfo *) NULL);
326 assert(string_info->signature == MagickSignature);
327 clone_info=AcquireStringInfo(string_info->length);
328 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000329 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000330 return(clone_info);
331}
332
333/*
334%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
335% %
336% %
337% %
338% C o m p a r e S t r i n g I n f o %
339% %
340% %
341% %
342%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343%
344% CompareStringInfo() compares the two datums target and source. It returns
345% an integer less than, equal to, or greater than zero if target is found,
346% respectively, to be less than, to match, or be greater than source.
347%
348% The format of the CompareStringInfo method is:
349%
350% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
351%
352% A description of each parameter follows:
353%
354% o target: the target string.
355%
356% o source: the source string.
357%
358*/
359
cristy3ed852e2009-09-05 21:47:34 +0000360MagickExport int CompareStringInfo(const StringInfo *target,
361 const StringInfo *source)
362{
363 int
364 status;
365
cristy3ed852e2009-09-05 21:47:34 +0000366 assert(target != (StringInfo *) NULL);
367 assert(target->signature == MagickSignature);
368 assert(source != (StringInfo *) NULL);
369 assert(source->signature == MagickSignature);
370 status=memcmp(target->datum,source->datum,MagickMin(target->length,
371 source->length));
372 if (status != 0)
373 return(status);
374 if (target->length == source->length)
375 return(0);
376 return(target->length < source->length ? -1 : 1);
377}
378
379/*
380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381% %
382% %
383% %
384% C o n c a t e n a t e M a g i c k S t r i n g %
385% %
386% %
387% %
388%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389%
390% ConcatenateMagickString() concatenates the source string to the destination
391% string. The destination buffer is always null-terminated even if the
392% string must be truncated.
393%
394% The format of the ConcatenateMagickString method is:
395%
396% size_t ConcatenateMagickString(char *destination,const char *source,
397% const size_t length)
398%
399% A description of each parameter follows:
400%
401% o destination: the destination string.
402%
403% o source: the source string.
404%
405% o length: the length of the destination string.
406%
407*/
408MagickExport size_t ConcatenateMagickString(char *destination,
409 const char *source,const size_t length)
410{
411 register char
412 *q;
413
414 register const char
415 *p;
416
417 register size_t
418 i;
419
420 size_t
421 count;
422
423 assert(destination != (char *) NULL);
424 assert(source != (const char *) NULL);
425 assert(length >= 1);
426 p=source;
427 q=destination;
428 i=length;
429 while ((i-- != 0) && (*q != '\0'))
430 q++;
431 count=(size_t) (q-destination);
432 i=length-count;
433 if (i == 0)
434 return(count+strlen(p));
435 while (*p != '\0')
436 {
437 if (i != 1)
438 {
439 *q++=(*p);
440 i--;
441 }
442 p++;
443 }
444 *q='\0';
445 return(count+(p-source));
446}
447
448/*
449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450% %
451% %
452% %
453% C o n c a t e n a t e S t r i n g %
454% %
455% %
456% %
457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458%
459% ConcatenateString() appends a copy of string source, including the
460% terminating null character, to the end of string destination.
461%
462% The format of the ConcatenateString method is:
463%
464% MagickBooleanType ConcatenateString(char **destination,
465% const char *source)
466%
467% A description of each parameter follows:
468%
469% o destination: A pointer to a character string.
470%
471% o source: A character string.
472%
473*/
474MagickExport MagickBooleanType ConcatenateString(char **destination,
475 const char *source)
476{
477 size_t
cristy54aad5e2010-09-03 16:02:04 +0000478 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000479 length,
480 source_length;
481
482 assert(destination != (char **) NULL);
483 if (source == (const char *) NULL)
484 return(MagickTrue);
485 if (*destination == (char *) NULL)
486 {
487 *destination=AcquireString(source);
488 return(MagickTrue);
489 }
cristy54aad5e2010-09-03 16:02:04 +0000490 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000491 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000492 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000493 if (~length < source_length)
494 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
495 length+=source_length;
496 if (~length < MaxTextExtent)
497 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
498 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000499 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000500 if (*destination == (char *) NULL)
501 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000502 if (source_length != 0)
503 (void) memcpy((*destination)+destination_length,source,source_length);
504 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000505 return(MagickTrue);
506}
507
508/*
509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510% %
511% %
512% %
513% C o n c a t e n a t e S t r i n g I n f o %
514% %
515% %
516% %
517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
518%
519% ConcatenateStringInfo() concatenates the source string to the destination
520% string.
521%
522% The format of the ConcatenateStringInfo method is:
523%
524% void ConcatenateStringInfo(StringInfo *string_info,
525% const StringInfo *source)
526%
527% A description of each parameter follows:
528%
529% o string_info: the string info.
530%
531% o source: the source string.
532%
533*/
534MagickExport void ConcatenateStringInfo(StringInfo *string_info,
535 const StringInfo *source)
536{
537 size_t
538 length;
539
cristy3ed852e2009-09-05 21:47:34 +0000540 assert(string_info != (StringInfo *) NULL);
541 assert(string_info->signature == MagickSignature);
542 assert(source != (const StringInfo *) NULL);
543 length=string_info->length;
544 if (~length < source->length)
545 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
546 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000547 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000548}
549
550/*
551%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
552% %
553% %
554% %
555% 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 %
556% %
557% %
558% %
559%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
560%
561% ConfigureFileToStringInfo() returns the contents of a configure file as a
562% string.
563%
564% The format of the ConfigureFileToStringInfo method is:
565%
566% StringInfo *ConfigureFileToStringInfo(const char *filename)
567% ExceptionInfo *exception)
568%
569% A description of each parameter follows:
570%
571% o filename: the filename.
572%
573*/
cristy99bbf2c2011-09-26 18:27:50 +0000574MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +0000575{
576 char
577 *string;
578
579 int
580 file;
581
582 MagickOffsetType
583 offset;
584
585 size_t
586 length;
587
588 StringInfo
589 *string_info;
590
591 void
592 *map;
593
594 assert(filename != (const char *) NULL);
cristy18c6c272011-09-23 14:40:37 +0000595 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
cristy3ed852e2009-09-05 21:47:34 +0000596 if (file == -1)
597 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000598 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000599 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
600 {
601 file=close(file)-1;
602 return((StringInfo *) NULL);
603 }
604 length=(size_t) offset;
605 string=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000606 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000607 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
608 if (string == (char *) NULL)
609 {
610 file=close(file)-1;
611 return((StringInfo *) NULL);
612 }
613 map=MapBlob(file,ReadMode,0,length);
614 if (map != (void *) NULL)
615 {
cristy54aad5e2010-09-03 16:02:04 +0000616 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000617 (void) UnmapBlob(map,length);
618 }
619 else
620 {
621 register size_t
622 i;
623
624 ssize_t
625 count;
626
cristy7f317702011-02-18 20:40:28 +0000627 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000628 for (i=0; i < length; i+=count)
629 {
630 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
631 SSIZE_MAX));
632 if (count <= 0)
633 {
634 count=0;
635 if (errno != EINTR)
636 break;
637 }
638 }
639 if (i < length)
640 {
641 file=close(file)-1;
642 string=DestroyString(string);
643 return((StringInfo *) NULL);
644 }
645 }
646 string[length]='\0';
647 file=close(file)-1;
648 string_info=AcquireStringInfo(0);
dirkcecec522015-04-14 20:17:56 +0000649 string_info->path=ConstantString(filename);
cristy5ce7dac2014-05-28 12:22:17 +0000650 string_info->length=length;
cristy7fb9fc12014-05-28 01:18:24 +0000651 if (string_info->datum != (unsigned char *) NULL)
652 string_info->datum=(unsigned char *) RelinquishMagickMemory(
653 string_info->datum);
cristy3ed852e2009-09-05 21:47:34 +0000654 string_info->datum=(unsigned char *) string;
655 return(string_info);
656}
657
658/*
659%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660% %
661% %
662% %
663% C o n s t a n t S t r i n g %
664% %
665% %
666% %
667%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668%
anthony104f8932012-05-13 01:54:53 +0000669% ConstantString() allocates exactly the needed memory for a string and
670% copies the source string to that memory location. A NULL string pointer
671% will allocate an empty string containing just the NUL character.
cristy3ed852e2009-09-05 21:47:34 +0000672%
anthony104f8932012-05-13 01:54:53 +0000673% When finished the string should be freed using DestoryString()
anthony06762232012-04-29 11:45:40 +0000674%
cristy3ed852e2009-09-05 21:47:34 +0000675% The format of the ConstantString method is:
676%
677% char *ConstantString(const char *source)
678%
679% A description of each parameter follows:
680%
681% o source: A character string.
682%
683*/
684MagickExport char *ConstantString(const char *source)
685{
686 char
687 *destination;
688
689 size_t
690 length;
691
692 length=0;
693 if (source != (char *) NULL)
694 length+=strlen(source);
695 destination=(char *) NULL;
696 if (~length >= 1UL)
697 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
698 if (destination == (char *) NULL)
699 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
700 *destination='\0';
701 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000702 (void) memcpy(destination,source,length*sizeof(*destination));
703 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000704 return(destination);
705}
706
707/*
708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709% %
710% %
711% %
712% C o p y M a g i c k S t r i n g %
713% %
714% %
715% %
716%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
717%
anthony06762232012-04-29 11:45:40 +0000718% CopyMagickString() copies the source string to the destination string, with
719% out exceeding the given pre-declared length.
720%
721% The destination buffer is always null-terminated even if the string must be
722% truncated. The return value is the minimum of the source string length or
723% the length parameter.
cristy3ed852e2009-09-05 21:47:34 +0000724%
725% The format of the CopyMagickString method is:
726%
727% size_t CopyMagickString(const char *destination,char *source,
728% const size_t length)
729%
730% A description of each parameter follows:
731%
732% o destination: the destination string.
733%
734% o source: the source string.
735%
736% o length: the length of the destination string.
737%
738*/
739MagickExport size_t CopyMagickString(char *destination,const char *source,
740 const size_t length)
741{
742 register char
743 *q;
744
745 register const char
746 *p;
747
748 register size_t
749 n;
750
cristy77e3fcc2011-10-11 00:04:41 +0000751 if (source == (const char *) NULL)
752 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000753 p=source;
754 q=destination;
755 for (n=length; n > 4; n-=4)
756 {
757 *q=(*p++);
758 if (*q == '\0')
759 return((size_t) (p-source-1));
760 q++;
761 *q=(*p++);
762 if (*q == '\0')
763 return((size_t) (p-source-1));
764 q++;
765 *q=(*p++);
766 if (*q == '\0')
767 return((size_t) (p-source-1));
768 q++;
769 *q=(*p++);
770 if (*q == '\0')
771 return((size_t) (p-source-1));
772 q++;
773 }
774 if (n != 0)
775 for (n--; n != 0; n--)
776 {
777 *q=(*p++);
778 if (*q == '\0')
779 return((size_t) (p-source-1));
780 q++;
781 }
782 if (length != 0)
783 *q='\0';
784 return((size_t) (p-source-1));
785}
786
787/*
788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789% %
790% %
791% %
792% D e s t r o y S t r i n g %
793% %
794% %
795% %
796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
797%
798% DestroyString() destroys memory associated with a string.
799%
800% The format of the DestroyString method is:
801%
802% char *DestroyString(char *string)
803%
804% A description of each parameter follows:
805%
806% o string: the string.
807%
808*/
809MagickExport char *DestroyString(char *string)
810{
811 return((char *) RelinquishMagickMemory(string));
812}
813
814/*
815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816% %
817% %
818% %
819% D e s t r o y S t r i n g I n f o %
820% %
821% %
822% %
823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824%
825% DestroyStringInfo() destroys memory associated with the StringInfo structure.
826%
827% The format of the DestroyStringInfo method is:
828%
829% StringInfo *DestroyStringInfo(StringInfo *string_info)
830%
831% A description of each parameter follows:
832%
833% o string_info: the string info.
834%
835*/
836MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
837{
cristy3ed852e2009-09-05 21:47:34 +0000838 assert(string_info != (StringInfo *) NULL);
839 assert(string_info->signature == MagickSignature);
840 if (string_info->datum != (unsigned char *) NULL)
841 string_info->datum=(unsigned char *) RelinquishMagickMemory(
842 string_info->datum);
dirkcecec522015-04-14 20:17:56 +0000843 if (string_info->path != (char *) NULL)
dirk1e7a6d02015-04-14 20:20:42 +0000844 string_info->path=DestroyString(string_info->path);
cristy3ed852e2009-09-05 21:47:34 +0000845 string_info->signature=(~MagickSignature);
846 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
847 return(string_info);
848}
849
850/*
851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852% %
853% %
854% %
855% D e s t r o y S t r i n g L i s t %
856% %
857% %
858% %
859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860%
861% DestroyStringList() zeros memory associated with a string list.
862%
863% The format of the DestroyStringList method is:
864%
865% char **DestroyStringList(char **list)
866%
867% A description of each parameter follows:
868%
869% o list: the string list.
870%
871*/
872MagickExport char **DestroyStringList(char **list)
873{
cristybb503372010-05-27 20:51:26 +0000874 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000875 i;
876
877 assert(list != (char **) NULL);
878 for (i=0; list[i] != (char *) NULL; i++)
879 list[i]=DestroyString(list[i]);
880 list=(char **) RelinquishMagickMemory(list);
881 return(list);
882}
883
884/*
885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886% %
887% %
888% %
889% E s c a p e S t r i n g %
890% %
891% %
892% %
893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894%
895% EscapeString() allocates memory for a backslash-escaped version of a
896% source text string, copies the escaped version of the text to that
897% memory location while adding backslash characters, and returns the
898% escaped string.
899%
900% The format of the EscapeString method is:
901%
902% char *EscapeString(const char *source,const char escape)
903%
904% A description of each parameter follows:
905%
906% o allocate_string: Method EscapeString returns the escaped string.
907%
908% o source: A character string.
909%
910% o escape: the quoted string termination character to escape (e.g. '"').
911%
912*/
913MagickExport char *EscapeString(const char *source,const char escape)
914{
915 char
916 *destination;
917
918 register char
919 *q;
920
921 register const char
922 *p;
923
924 size_t
925 length;
926
cristy3ed852e2009-09-05 21:47:34 +0000927 assert(source != (const char *) NULL);
928 length=strlen(source);
929 for (p=source; *p != '\0'; p++)
930 if ((*p == '\\') || (*p == escape))
931 {
932 if (~length < 1)
933 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
934 length++;
935 }
936 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000937 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000938 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
939 sizeof(*destination));
940 if (destination == (char *) NULL)
941 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
942 *destination='\0';
cristy4662a132015-01-19 19:27:00 +0000943 q=destination;
944 for (p=source; *p != '\0'; p++)
945 {
946 if ((*p == '\\') || (*p == escape))
947 *q++='\\';
948 *q++=(*p);
949 }
950 *q='\0';
cristy3ed852e2009-09-05 21:47:34 +0000951 return(destination);
952}
953
954/*
955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956% %
957% %
958% %
959% F i l e T o S t r i n g %
960% %
961% %
962% %
963%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964%
965% FileToString() returns the contents of a file as a string.
966%
967% The format of the FileToString method is:
968%
969% char *FileToString(const char *filename,const size_t extent,
970% ExceptionInfo *exception)
971%
972% A description of each parameter follows:
973%
974% o filename: the filename.
975%
976% o extent: Maximum length of the string.
977%
978% o exception: return any errors or warnings in this structure.
979%
980*/
981MagickExport char *FileToString(const char *filename,const size_t extent,
982 ExceptionInfo *exception)
983{
984 size_t
985 length;
986
987 assert(filename != (const char *) NULL);
988 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
989 assert(exception != (ExceptionInfo *) NULL);
990 return((char *) FileToBlob(filename,extent,&length,exception));
991}
992
993/*
994%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995% %
996% %
997% %
998% F i l e T o S t r i n g I n f o %
999% %
1000% %
1001% %
1002%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003%
1004% FileToStringInfo() returns the contents of a file as a string.
1005%
1006% The format of the FileToStringInfo method is:
1007%
1008% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1009% ExceptionInfo *exception)
1010%
1011% A description of each parameter follows:
1012%
1013% o filename: the filename.
1014%
1015% o extent: Maximum length of the string.
1016%
1017% o exception: return any errors or warnings in this structure.
1018%
1019*/
1020MagickExport StringInfo *FileToStringInfo(const char *filename,
1021 const size_t extent,ExceptionInfo *exception)
1022{
1023 StringInfo
1024 *string_info;
1025
1026 assert(filename != (const char *) NULL);
1027 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1028 assert(exception != (ExceptionInfo *) NULL);
1029 string_info=AcquireStringInfo(0);
dirkcecec522015-04-14 20:17:56 +00001030 string_info->path=ConstantString(filename);
cristy7fb9fc12014-05-28 01:18:24 +00001031 if (string_info->datum != (unsigned char *) NULL)
1032 string_info->datum=(unsigned char *) RelinquishMagickMemory(
1033 string_info->datum);
dirkcecec522015-04-14 20:17:56 +00001034 string_info->datum=(unsigned char *) FileToBlob(filename,extent,
1035 &string_info->length,exception);
cristy3ed852e2009-09-05 21:47:34 +00001036 if (string_info->datum == (unsigned char *) NULL)
1037 {
1038 string_info=DestroyStringInfo(string_info);
1039 return((StringInfo *) NULL);
1040 }
1041 return(string_info);
1042}
1043
1044/*
1045%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046% %
1047% %
1048% %
1049% F o r m a t M a g i c k S i z e %
1050% %
1051% %
1052% %
1053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1054%
1055% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +00001056% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +00001057% 1000.
cristy3ed852e2009-09-05 21:47:34 +00001058%
1059% The format of the FormatMagickSize method is:
1060%
cristy40937042014-12-22 01:44:59 +00001061% ssize_t FormatMagickSize(const MagickSizeType size,const char *suffix,
1062^ char *format)
cristy3ed852e2009-09-05 21:47:34 +00001063%
1064% A description of each parameter follows:
1065%
1066% o size: convert this size to a human readable format.
1067%
cristyb9080c92009-12-01 20:13:26 +00001068% o bi: use power of two rather than power of ten.
1069%
cristy40937042014-12-22 01:44:59 +00001070% o suffix: append suffix, typically B or P.
1071%
cristy3ed852e2009-09-05 21:47:34 +00001072% o format: human readable format.
1073%
1074*/
cristy99bbf2c2011-09-26 18:27:50 +00001075MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristy40937042014-12-22 01:44:59 +00001076 const MagickBooleanType bi,const char *suffix,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001077{
cristyb9080c92009-12-01 20:13:26 +00001078 const char
1079 **units;
1080
cristy3ed852e2009-09-05 21:47:34 +00001081 double
cristyb9080c92009-12-01 20:13:26 +00001082 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001083 length;
1084
cristybb503372010-05-27 20:51:26 +00001085 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001086 i,
1087 j;
1088
cristy9d314ff2011-03-09 01:30:28 +00001089 ssize_t
1090 count;
1091
cristy3ed852e2009-09-05 21:47:34 +00001092 static const char
cristyb9080c92009-12-01 20:13:26 +00001093 *bi_units[] =
1094 {
cristy2ce15c92010-03-12 14:03:41 +00001095 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001096 },
1097 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001098 {
cristy2ce15c92010-03-12 14:03:41 +00001099 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001100 };
cristy3ed852e2009-09-05 21:47:34 +00001101
cristyb9080c92009-12-01 20:13:26 +00001102 bytes=1000.0;
1103 units=traditional_units;
1104 if (bi != MagickFalse)
1105 {
1106 bytes=1024.0;
1107 units=bi_units;
1108 }
cristy3ed852e2009-09-05 21:47:34 +00001109#if defined(_MSC_VER) && (_MSC_VER == 1200)
1110 length=(double) ((MagickOffsetType) size);
1111#else
1112 length=(double) size;
1113#endif
cristyb9080c92009-12-01 20:13:26 +00001114 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1115 length/=bytes;
cristyc3b9b362013-05-25 17:16:34 +00001116 count=0;
cristy9bf9da32009-09-27 16:48:34 +00001117 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001118 {
cristy40937042014-12-22 01:44:59 +00001119 if (suffix == (const char *) NULL)
1120 count=FormatLocaleString(format,MaxTextExtent,"%.*g%s",(int) (i+j),
1121 length,units[i]);
1122 else
1123 count=FormatLocaleString(format,MaxTextExtent,"%.*g%s%s",(int) (i+j),
1124 length,units[i],suffix);
cristy3ed852e2009-09-05 21:47:34 +00001125 if (strchr(format,'+') == (char *) NULL)
1126 break;
1127 }
1128 return(count);
1129}
1130
1131/*
1132%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1133% %
1134% %
1135% %
cristy3ed852e2009-09-05 21:47:34 +00001136% F o r m a t M a g i c k T i m e %
1137% %
1138% %
1139% %
1140%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1141%
1142% FormatMagickTime() returns the specified time in the Internet date/time
1143% format and the length of the timestamp.
1144%
1145% The format of the FormatMagickTime method is:
1146%
cristybb503372010-05-27 20:51:26 +00001147% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001148% char *timestamp)
1149%
1150% A description of each parameter follows.
1151%
1152% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1153% measured in seconds.
1154%
1155% o length: the maximum length of the string.
1156%
1157% o timestamp: Return the Internet date/time here.
1158%
1159*/
cristybb503372010-05-27 20:51:26 +00001160MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001161 char *timestamp)
1162{
cristybb503372010-05-27 20:51:26 +00001163 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001164 count;
1165
1166 struct tm
1167 gm_time,
1168 local_time;
1169
1170 time_t
1171 timezone;
1172
1173 assert(timestamp != (char *) NULL);
1174 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1175 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1176#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1177 (void) localtime_r(&time,&local_time);
1178#else
1179 {
cristybc3392a2009-10-06 03:15:57 +00001180 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001181 *my_time;
1182
1183 my_time=localtime(&time);
1184 if (my_time != (struct tm *) NULL)
1185 (void) memcpy(&local_time,my_time,sizeof(local_time));
1186 }
1187#endif
1188#if defined(MAGICKCORE_HAVE_GMTIME_R)
1189 (void) gmtime_r(&time,&gm_time);
1190#else
1191 {
cristybc3392a2009-10-06 03:15:57 +00001192 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001193 *my_time;
1194
1195 my_time=gmtime(&time);
1196 if (my_time != (struct tm *) NULL)
1197 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1198 }
1199#endif
1200 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1201 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1202 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1203 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001204 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001205 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1206 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001207 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001208 return(count);
1209}
1210
1211/*
1212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1213% %
1214% %
1215% %
1216% G e t E n v i r o n m e n t V a l u e %
1217% %
1218% %
1219% %
1220%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1221%
1222% GetEnvironmentValue() returns the environment string that matches the
1223% specified name.
1224%
1225% The format of the GetEnvironmentValue method is:
1226%
1227% char *GetEnvironmentValue(const char *name)
1228%
1229% A description of each parameter follows:
1230%
1231% o name: the environment name.
1232%
1233*/
cristy99bbf2c2011-09-26 18:27:50 +00001234MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001235{
1236 const char
1237 *environment;
1238
1239 environment=getenv(name);
1240 if (environment == (const char *) NULL)
1241 return((char *) NULL);
1242 return(ConstantString(environment));
1243}
1244
1245/*
1246%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1247% %
1248% %
1249% %
1250% G e t S t r i n g I n f o D a t u m %
1251% %
1252% %
1253% %
1254%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1255%
1256% GetStringInfoDatum() returns the datum associated with the string.
1257%
1258% The format of the GetStringInfoDatum method is:
1259%
1260% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1261%
1262% A description of each parameter follows:
1263%
1264% o string_info: the string info.
1265%
1266*/
1267MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1268{
1269 assert(string_info != (StringInfo *) NULL);
1270 assert(string_info->signature == MagickSignature);
1271 return(string_info->datum);
1272}
1273
1274/*
1275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1276% %
1277% %
1278% %
1279% G e t S t r i n g I n f o L e n g t h %
1280% %
1281% %
1282% %
1283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1284%
1285% GetStringInfoLength() returns the string length.
1286%
1287% The format of the GetStringInfoLength method is:
1288%
1289% size_t GetStringInfoLength(const StringInfo *string_info)
1290%
1291% A description of each parameter follows:
1292%
1293% o string_info: the string info.
1294%
1295*/
1296MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1297{
1298 assert(string_info != (StringInfo *) NULL);
1299 assert(string_info->signature == MagickSignature);
1300 return(string_info->length);
1301}
1302
1303/*
1304%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1305% %
1306% %
1307% %
1308% G e t S t r i n g I n f o P a t h %
1309% %
1310% %
1311% %
1312%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1313%
1314% GetStringInfoPath() returns the path associated with the string.
1315%
1316% The format of the GetStringInfoPath method is:
1317%
1318% const char *GetStringInfoPath(const StringInfo *string_info)
1319%
1320% A description of each parameter follows:
1321%
1322% o string_info: the string info.
1323%
1324*/
1325MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1326{
1327 assert(string_info != (StringInfo *) NULL);
1328 assert(string_info->signature == MagickSignature);
1329 return(string_info->path);
1330}
1331
1332/*
1333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1334% %
1335% %
1336% %
cristydbdd0e32011-11-04 23:29:40 +00001337+ I n t e r p r e t S i P r e f i x V a l u e %
1338% %
1339% %
1340% %
1341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1342%
1343% InterpretSiPrefixValue() converts the initial portion of the string to a
1344% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1345% etc.).
1346%
1347% The format of the InterpretSiPrefixValue method is:
1348%
1349% double InterpretSiPrefixValue(const char *value,char **sentinal)
1350%
1351% A description of each parameter follows:
1352%
1353% o value: the string value.
1354%
1355% o sentinal: if sentinal is not NULL, return a pointer to the character
1356% after the last character used in the conversion.
1357%
1358*/
1359MagickExport double InterpretSiPrefixValue(const char *restrict string,
1360 char **restrict sentinal)
1361{
1362 char
1363 *q;
1364
1365 double
1366 value;
1367
cristydbdd0e32011-11-04 23:29:40 +00001368 value=InterpretLocaleValue(string,&q);
1369 if (q != string)
1370 {
1371 if ((*q >= 'E') && (*q <= 'z'))
1372 {
1373 double
1374 e;
1375
cristy0c2684f2011-11-05 21:39:43 +00001376 switch ((int) ((unsigned char) *q))
1377 {
1378 case 'y': e=(-24.0); break;
1379 case 'z': e=(-21.0); break;
1380 case 'a': e=(-18.0); break;
1381 case 'f': e=(-15.0); break;
1382 case 'p': e=(-12.0); break;
1383 case 'n': e=(-9.0); break;
1384 case 'u': e=(-6.0); break;
1385 case 'm': e=(-3.0); break;
1386 case 'c': e=(-2.0); break;
1387 case 'd': e=(-1.0); break;
1388 case 'h': e=2.0; break;
1389 case 'k': e=3.0; break;
1390 case 'K': e=3.0; break;
1391 case 'M': e=6.0; break;
1392 case 'G': e=9.0; break;
1393 case 'T': e=12.0; break;
1394 case 'P': e=15.0; break;
1395 case 'E': e=18.0; break;
1396 case 'Z': e=21.0; break;
1397 case 'Y': e=24.0; break;
1398 default: e=0.0; break;
1399 }
cristydbdd0e32011-11-04 23:29:40 +00001400 if (e >= MagickEpsilon)
1401 {
1402 if (q[1] == 'i')
1403 {
1404 value*=pow(2.0,e/0.3);
1405 q+=2;
1406 }
1407 else
1408 {
1409 value*=pow(10.0,e);
1410 q++;
1411 }
1412 }
1413 }
cristy40937042014-12-22 01:44:59 +00001414 if ((*q == 'B') || (*q == 'P'))
cristy099a7352011-11-09 14:31:35 +00001415 q++;
cristydbdd0e32011-11-04 23:29:40 +00001416 }
1417 if (sentinal != (char **) NULL)
1418 *sentinal=q;
1419 return(value);
1420}
1421
1422/*
1423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1424% %
1425% %
1426% %
anthony6f201312012-03-30 04:08:15 +00001427% I s S t r i n g T r u e %
1428% %
1429% %
1430% %
1431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1432%
1433% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1434% "1". Any other string or undefined returns MagickFalse.
1435%
1436% Typically this is used to look at strings (options or artifacts) which
1437% has a default value of "false", when not defined.
1438%
1439% The format of the IsStringTrue method is:
1440%
1441% MagickBooleanType IsStringTrue(const char *value)
1442%
1443% A description of each parameter follows:
1444%
1445% o value: Specifies a pointer to a character array.
1446%
1447*/
1448MagickExport MagickBooleanType IsStringTrue(const char *value)
1449{
1450 if (value == (const char *) NULL)
1451 return(MagickFalse);
1452 if (LocaleCompare(value,"true") == 0)
1453 return(MagickTrue);
1454 if (LocaleCompare(value,"on") == 0)
1455 return(MagickTrue);
1456 if (LocaleCompare(value,"yes") == 0)
1457 return(MagickTrue);
1458 if (LocaleCompare(value,"1") == 0)
1459 return(MagickTrue);
1460 return(MagickFalse);
1461}
1462
1463/*
1464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1465% %
1466% %
1467% %
1468% I s S t r i n g N o t F a l s e %
1469% %
1470% %
1471% %
1472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1473%
1474% IsStringNotFalse() returns MagickTrue, unless the string specifically
1475% has a value that makes this false. that is if it has a value of
1476% "false", "off", "no" or "0".
1477%
1478% Typically this is used to look at strings (options or artifacts) which
1479% has a default value of "true", when it has not been defined.
1480%
1481% The format of the IsStringNotFalse method is:
1482%
1483% MagickBooleanType IsStringNotFalse(const char *value)
1484%
1485% A description of each parameter follows:
1486%
1487% o value: Specifies a pointer to a character array.
1488%
1489*/
1490MagickExport MagickBooleanType IsStringNotFalse(const char *value)
1491{
1492 if (value == (const char *) NULL)
1493 return(MagickTrue);
1494 if (LocaleCompare(value,"false") == 0)
1495 return(MagickFalse);
1496 if (LocaleCompare(value,"off") == 0)
1497 return(MagickFalse);
1498 if (LocaleCompare(value,"no") == 0)
1499 return(MagickFalse);
1500 if (LocaleCompare(value,"0") == 0)
1501 return(MagickFalse);
1502 return(MagickTrue);
1503}
1504
1505/*
1506%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1507% %
1508% %
1509% %
cristy3ed852e2009-09-05 21:47:34 +00001510% L o c a l e C o m p a r e %
1511% %
1512% %
1513% %
1514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1515%
1516% LocaleCompare() performs a case-insensitive comparison of two strings
1517% byte-by-byte, according to the ordering of the current locale encoding.
1518% LocaleCompare returns an integer greater than, equal to, or less than 0,
1519% if the string pointed to by p is greater than, equal to, or less than the
1520% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001521% is determined by the sign of the difference between the values of the first
1522% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001523%
1524% The format of the LocaleCompare method is:
1525%
cristyde58b412010-02-18 03:53:40 +00001526% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001527%
1528% A description of each parameter follows:
1529%
1530% o p: A pointer to a character string.
1531%
1532% o q: A pointer to a character string to compare to p.
1533%
1534*/
cristyde58b412010-02-18 03:53:40 +00001535MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001536{
1537 if ((p == (char *) NULL) && (q == (char *) NULL))
1538 return(0);
1539 if (p == (char *) NULL)
1540 return(-1);
1541 if (q == (char *) NULL)
1542 return(1);
1543#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001544 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001545#else
1546 {
cristyde58b412010-02-18 03:53:40 +00001547 register int
cristy3ed852e2009-09-05 21:47:34 +00001548 c,
cristya72c2d12010-02-18 01:20:28 +00001549 d;
cristy3ed852e2009-09-05 21:47:34 +00001550
cristya72c2d12010-02-18 01:20:28 +00001551 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001552 {
cristyde58b412010-02-18 03:53:40 +00001553 c=(int) *((unsigned char *) p);
1554 d=(int) *((unsigned char *) q);
1555 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001556 break;
cristya72c2d12010-02-18 01:20:28 +00001557 p++;
1558 q++;
cristy3ed852e2009-09-05 21:47:34 +00001559 }
cristyde58b412010-02-18 03:53:40 +00001560 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001561 }
1562#endif
1563}
1564
1565/*
1566%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1567% %
1568% %
1569% %
1570% L o c a l e L o w e r %
1571% %
1572% %
1573% %
1574%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1575%
1576% LocaleLower() transforms all of the characters in the supplied
1577% null-terminated string, changing all uppercase letters to lowercase.
1578%
1579% The format of the LocaleLower method is:
1580%
1581% void LocaleLower(char *string)
1582%
1583% A description of each parameter follows:
1584%
1585% o string: A pointer to the string to convert to lower-case Locale.
1586%
1587*/
1588MagickExport void LocaleLower(char *string)
1589{
1590 register char
1591 *q;
1592
1593 assert(string != (char *) NULL);
1594 for (q=string; *q != '\0'; q++)
1595 *q=(char) tolower((int) *q);
1596}
1597
1598/*
1599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1600% %
1601% %
1602% %
1603% L o c a l e N C o m p a r e %
1604% %
1605% %
1606% %
1607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1608%
anthony06762232012-04-29 11:45:40 +00001609% LocaleNCompare() performs a case-insensitive comparison of two strings
1610% byte-by-byte, according to the ordering of the current locale encoding.
1611%
1612% LocaleNCompare returns an integer greater than, equal to, or less than 0,
1613% if the string pointed to by p is greater than, equal to, or less than the
1614% string pointed to by q respectively. The sign of a non-zero return value
1615% is determined by the sign of the difference between the values of the first
1616% pair of bytes that differ in the strings being compared.
1617%
1618% The LocaleNCompare method makes the same comparison as LocaleCompare but
1619% looks at a maximum of n bytes. Bytes following a null byte are not
1620% compared.
cristy3ed852e2009-09-05 21:47:34 +00001621%
1622% The format of the LocaleNCompare method is:
1623%
cristyde58b412010-02-18 03:53:40 +00001624% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001625%
1626% A description of each parameter follows:
1627%
1628% o p: A pointer to a character string.
1629%
1630% o q: A pointer to a character string to compare to p.
1631%
cristy7a40ba82011-01-08 20:31:18 +00001632% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001633%
1634*/
cristyde58b412010-02-18 03:53:40 +00001635MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001636{
cristy78c21692011-10-06 14:57:26 +00001637 if ((p == (char *) NULL) && (q == (char *) NULL))
1638 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001639 if (p == (char *) NULL)
1640 return(-1);
1641 if (q == (char *) NULL)
1642 return(1);
1643#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001644 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001645#else
1646 {
cristyde58b412010-02-18 03:53:40 +00001647 register int
cristy3ed852e2009-09-05 21:47:34 +00001648 c,
1649 d;
1650
cristyb6af4a52009-10-06 13:56:23 +00001651 register size_t
cristyc4cded12010-02-18 14:40:57 +00001652 i;
cristyb6af4a52009-10-06 13:56:23 +00001653
cristyc4cded12010-02-18 14:40:57 +00001654 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001655 {
cristyde58b412010-02-18 03:53:40 +00001656 c=(int) *((unsigned char *) p);
1657 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001658 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001659 return(AsciiMap[c]-(int) AsciiMap[d]);
1660 if (c == 0)
1661 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001662 p++;
1663 q++;
1664 }
cristyde58b412010-02-18 03:53:40 +00001665 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001666 }
1667#endif
1668}
1669
1670/*
1671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1672% %
1673% %
1674% %
1675% L o c a l e U p p e r %
1676% %
1677% %
1678% %
1679%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1680%
1681% LocaleUpper() transforms all of the characters in the supplied
1682% null-terminated string, changing all lowercase letters to uppercase.
1683%
1684% The format of the LocaleUpper method is:
1685%
1686% void LocaleUpper(char *string)
1687%
1688% A description of each parameter follows:
1689%
1690% o string: A pointer to the string to convert to upper-case Locale.
1691%
1692*/
1693MagickExport void LocaleUpper(char *string)
1694{
1695 register char
1696 *q;
1697
1698 assert(string != (char *) NULL);
1699 for (q=string; *q != '\0'; q++)
1700 *q=(char) toupper((int) *q);
1701}
1702
1703/*
1704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1705% %
1706% %
1707% %
1708% P r i n t S t r i n g I n f o %
1709% %
1710% %
1711% %
1712%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1713%
1714% PrintStringInfo() prints the string.
1715%
1716% The format of the PrintStringInfo method is:
1717%
1718% void PrintStringInfo(FILE *file,const char *id,
1719% const StringInfo *string_info)
1720%
1721% A description of each parameter follows:
1722%
1723% o file: the file, typically stdout.
1724%
1725% o id: the string id.
1726%
1727% o string_info: the string info.
1728%
1729*/
1730MagickExport void PrintStringInfo(FILE *file,const char *id,
1731 const StringInfo *string_info)
1732{
1733 register const char
1734 *p;
1735
1736 register size_t
1737 i,
1738 j;
1739
1740 assert(id != (const char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001741 assert(string_info != (StringInfo *) NULL);
1742 assert(string_info->signature == MagickSignature);
1743 p=(char *) string_info->datum;
1744 for (i=0; i < string_info->length; i++)
1745 {
1746 if (((int) ((unsigned char) *p) < 32) &&
1747 (isspace((int) ((unsigned char) *p)) == 0))
1748 break;
1749 p++;
1750 }
cristy2d8723c2013-11-14 16:41:27 +00001751 (void) FormatLocaleFile(file,"%s(%.20g): ",id,(double) string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001752 if (i == string_info->length)
1753 {
cristy53ea28b2012-06-10 22:11:59 +00001754 for (i=0; i < string_info->length; i++)
1755 (void) fputc(string_info->datum[i],file);
cristy3ed852e2009-09-05 21:47:34 +00001756 (void) fputc('\n',file);
1757 return;
1758 }
1759 /*
1760 Convert string to a HEX list.
1761 */
1762 p=(char *) string_info->datum;
1763 for (i=0; i < string_info->length; i+=0x14)
1764 {
cristyb51dff52011-05-19 16:55:47 +00001765 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001766 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1767 {
cristyb51dff52011-05-19 16:55:47 +00001768 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001769 if ((j % 0x04) == 0)
1770 (void) fputc(' ',file);
1771 }
1772 for ( ; j <= 0x14; j++)
1773 {
1774 (void) fputc(' ',file);
1775 (void) fputc(' ',file);
1776 if ((j % 0x04) == 0)
1777 (void) fputc(' ',file);
1778 }
1779 (void) fputc(' ',file);
1780 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1781 {
1782 if (isprint((int) ((unsigned char) *p)) != 0)
1783 (void) fputc(*p,file);
1784 else
1785 (void) fputc('-',file);
1786 p++;
1787 }
1788 (void) fputc('\n',file);
1789 }
1790}
1791
1792/*
1793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1794% %
1795% %
1796% %
1797% R e s e t S t r i n g I n f o %
1798% %
1799% %
1800% %
1801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1802%
1803% ResetStringInfo() reset the string to all null bytes.
1804%
1805% The format of the ResetStringInfo method is:
1806%
1807% void ResetStringInfo(StringInfo *string_info)
1808%
1809% A description of each parameter follows:
1810%
1811% o string_info: the string info.
1812%
1813*/
1814MagickExport void ResetStringInfo(StringInfo *string_info)
1815{
cristy3ed852e2009-09-05 21:47:34 +00001816 assert(string_info != (StringInfo *) NULL);
1817 assert(string_info->signature == MagickSignature);
1818 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1819}
1820
1821/*
1822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1823% %
1824% %
1825% %
1826% S e t S t r i n g I n f o %
1827% %
1828% %
1829% %
1830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1831%
1832% SetStringInfo() copies the source string to the destination string.
1833%
1834% The format of the SetStringInfo method is:
1835%
1836% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1837%
1838% A description of each parameter follows:
1839%
1840% o string_info: the string info.
1841%
1842% o source: the source string.
1843%
1844*/
1845MagickExport void SetStringInfo(StringInfo *string_info,
1846 const StringInfo *source)
1847{
cristy3ed852e2009-09-05 21:47:34 +00001848 assert(string_info != (StringInfo *) NULL);
1849 assert(string_info->signature == MagickSignature);
1850 assert(source != (StringInfo *) NULL);
1851 assert(source->signature == MagickSignature);
1852 if (string_info->length == 0)
1853 return;
1854 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001855 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1856 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001857}
1858
1859/*
1860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1861% %
1862% %
1863% %
1864% S e t S t r i n g I n f o D a t u m %
1865% %
1866% %
1867% %
1868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1869%
1870% SetStringInfoDatum() copies bytes from the source string for the length of
1871% the destination string.
1872%
1873% The format of the SetStringInfoDatum method is:
1874%
1875% void SetStringInfoDatum(StringInfo *string_info,
1876% const unsigned char *source)
1877%
1878% A description of each parameter follows:
1879%
1880% o string_info: the string info.
1881%
1882% o source: the source string.
1883%
1884*/
1885MagickExport void SetStringInfoDatum(StringInfo *string_info,
1886 const unsigned char *source)
1887{
cristy3ed852e2009-09-05 21:47:34 +00001888 assert(string_info != (StringInfo *) NULL);
1889 assert(string_info->signature == MagickSignature);
1890 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001891 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001892}
1893
1894/*
1895%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1896% %
1897% %
1898% %
1899% S e t S t r i n g I n f o L e n g t h %
1900% %
1901% %
1902% %
1903%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1904%
1905% SetStringInfoLength() set the string length to the specified value.
1906%
1907% The format of the SetStringInfoLength method is:
1908%
1909% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1910%
1911% A description of each parameter follows:
1912%
1913% o string_info: the string info.
1914%
1915% o length: the string length.
1916%
1917*/
1918MagickExport void SetStringInfoLength(StringInfo *string_info,
1919 const size_t length)
1920{
cristy3ed852e2009-09-05 21:47:34 +00001921 assert(string_info != (StringInfo *) NULL);
1922 assert(string_info->signature == MagickSignature);
1923 if (~length < MaxTextExtent)
1924 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1925 string_info->length=length;
1926 if (string_info->datum == (unsigned char *) NULL)
1927 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1928 MaxTextExtent,sizeof(*string_info->datum));
1929 else
1930 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1931 length+MaxTextExtent,sizeof(*string_info->datum));
1932 if (string_info->datum == (unsigned char *) NULL)
1933 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1934}
1935
1936/*
1937%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1938% %
1939% %
1940% %
1941% S e t S t r i n g I n f o D a t u m %
1942% %
1943% %
1944% %
1945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1946%
1947% SetStringInfoPath() sets the path associated with the string.
1948%
1949% The format of the SetStringInfoPath method is:
1950%
1951% void SetStringInfoPath(StringInfo *string_info,const char *path)
1952%
1953% A description of each parameter follows:
1954%
1955% o string_info: the string info.
1956%
1957% o path: the path.
1958%
1959*/
1960MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1961{
cristy3ed852e2009-09-05 21:47:34 +00001962 assert(string_info != (StringInfo *) NULL);
1963 assert(string_info->signature == MagickSignature);
1964 assert(path != (const char *) NULL);
dirkcecec522015-04-14 20:17:56 +00001965 string_info->path=ConstantString(path);
cristy3ed852e2009-09-05 21:47:34 +00001966}
1967
1968/*
1969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1970% %
1971% %
1972% %
1973% S p l i t S t r i n g I n f o %
1974% %
1975% %
1976% %
1977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1978%
1979% SplitStringInfo() splits a string into two and returns it.
1980%
1981% The format of the SplitStringInfo method is:
1982%
1983% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1984%
1985% A description of each parameter follows:
1986%
1987% o string_info: the string info.
1988%
1989*/
1990MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1991 const size_t offset)
1992{
1993 StringInfo
1994 *split_info;
1995
cristy3ed852e2009-09-05 21:47:34 +00001996 assert(string_info != (StringInfo *) NULL);
1997 assert(string_info->signature == MagickSignature);
1998 if (offset > string_info->length)
1999 return((StringInfo *) NULL);
2000 split_info=AcquireStringInfo(offset);
2001 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00002002 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00002003 string_info->length-offset+MaxTextExtent);
2004 SetStringInfoLength(string_info,string_info->length-offset);
2005 return(split_info);
2006}
2007
2008/*
2009%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2010% %
2011% %
2012% %
2013% S t r i n g I n f o T o S t r i n g %
2014% %
2015% %
2016% %
2017%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2018%
2019% StringInfoToString() converts a string info string to a C string.
2020%
2021% The format of the StringInfoToString method is:
2022%
2023% char *StringInfoToString(const StringInfo *string_info)
2024%
2025% A description of each parameter follows:
2026%
2027% o string_info: the string.
2028%
2029*/
2030MagickExport char *StringInfoToString(const StringInfo *string_info)
2031{
2032 char
2033 *string;
2034
2035 size_t
2036 length;
2037
2038 string=(char *) NULL;
2039 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00002040 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002041 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002042 if (string == (char *) NULL)
2043 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00002044 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002045 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002046 return(string);
2047}
2048
2049/*
2050%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2051% %
2052% %
2053% %
anthonyb1d483a2012-04-14 12:53:56 +00002054% S t r i n g I n f o T o H e x S t r i n g %
2055% %
2056% %
2057% %
2058%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2059%
2060% StringInfoToHexString() converts a string info string to a C string.
2061%
2062% The format of the StringInfoToHexString method is:
2063%
2064% char *StringInfoToHexString(const StringInfo *string_info)
2065%
2066% A description of each parameter follows:
2067%
2068% o string_info: the string.
2069%
2070*/
2071MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2072{
2073 char
2074 *string;
2075
2076 register const unsigned char
2077 *p;
2078
2079 register ssize_t
2080 i;
2081
2082 register unsigned char
2083 *q;
2084
2085 size_t
2086 length;
2087
2088 unsigned char
2089 hex_digits[16];
2090
2091 length=string_info->length;
2092 if (~length < MaxTextExtent)
2093 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2094 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2095 if (string == (char *) NULL)
2096 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2097 hex_digits[0]='0';
2098 hex_digits[1]='1';
2099 hex_digits[2]='2';
2100 hex_digits[3]='3';
2101 hex_digits[4]='4';
2102 hex_digits[5]='5';
2103 hex_digits[6]='6';
2104 hex_digits[7]='7';
2105 hex_digits[8]='8';
2106 hex_digits[9]='9';
2107 hex_digits[10]='a';
2108 hex_digits[11]='b';
2109 hex_digits[12]='c';
2110 hex_digits[13]='d';
2111 hex_digits[14]='e';
2112 hex_digits[15]='f';
2113 p=string_info->datum;
2114 q=(unsigned char *) string;
2115 for (i=0; i < (ssize_t) string_info->length; i++)
2116 {
2117 *q++=hex_digits[(*p >> 4) & 0x0f];
2118 *q++=hex_digits[*p & 0x0f];
2119 p++;
2120 }
2121 *q='\0';
2122 return(string);
2123}
2124
2125/*
2126%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2127% %
2128% %
2129% %
cristy3ed852e2009-09-05 21:47:34 +00002130% S t r i n g T o A r g v %
2131% %
2132% %
2133% %
2134%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2135%
2136% StringToArgv() converts a text string into command line arguments.
anthony31f1bf72012-01-30 12:37:22 +00002137% The 'argv' array of arguments, is returned while the number of arguments
2138% is returned via the provided integer variable pointer.
2139%
2140% Simple 'word' tokenizer, which allows for each word to be optionally
2141% quoted. However it will not allow use of partial quotes, or escape
2142% characters.
cristy3ed852e2009-09-05 21:47:34 +00002143%
2144% The format of the StringToArgv method is:
2145%
2146% char **StringToArgv(const char *text,int *argc)
2147%
2148% A description of each parameter follows:
2149%
2150% o argv: Method StringToArgv returns the string list unless an error
2151% occurs, otherwise NULL.
2152%
2153% o text: Specifies the string to segment into a list.
2154%
2155% o argc: This integer pointer returns the number of arguments in the
2156% list.
2157%
2158*/
2159MagickExport char **StringToArgv(const char *text,int *argc)
2160{
2161 char
2162 **argv;
2163
2164 register const char
2165 *p,
2166 *q;
2167
cristybb503372010-05-27 20:51:26 +00002168 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002169 i;
2170
2171 *argc=0;
2172 if (text == (char *) NULL)
2173 return((char **) NULL);
2174 /*
2175 Determine the number of arguments.
2176 */
2177 for (p=text; *p != '\0'; )
2178 {
2179 while (isspace((int) ((unsigned char) *p)) != 0)
2180 p++;
cristya20c9042011-05-19 13:22:18 +00002181 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00002182 break;
cristy3ed852e2009-09-05 21:47:34 +00002183 (*argc)++;
2184 if (*p == '"')
2185 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2186 if (*p == '\'')
2187 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2188 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2189 p++;
2190 }
2191 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002192 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002193 if (argv == (char **) NULL)
2194 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2195 /*
2196 Convert string to an ASCII list.
2197 */
2198 argv[0]=AcquireString("magick");
2199 p=text;
cristybb503372010-05-27 20:51:26 +00002200 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002201 {
2202 while (isspace((int) ((unsigned char) *p)) != 0)
2203 p++;
2204 q=p;
2205 if (*q == '"')
2206 {
2207 p++;
2208 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2209 }
2210 else
2211 if (*q == '\'')
2212 {
cristy06b15f42011-01-22 21:36:24 +00002213 p++;
cristy3ed852e2009-09-05 21:47:34 +00002214 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002215 }
2216 else
2217 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2218 q++;
2219 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2220 sizeof(**argv));
2221 if (argv[i] == (char *) NULL)
2222 {
2223 for (i--; i >= 0; i--)
2224 argv[i]=DestroyString(argv[i]);
2225 argv=(char **) RelinquishMagickMemory(argv);
2226 ThrowFatalException(ResourceLimitFatalError,
2227 "UnableToConvertStringToARGV");
2228 }
cristy54aad5e2010-09-03 16:02:04 +00002229 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002230 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002231 p=q;
2232 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2233 p++;
2234 }
2235 argv[i]=(char *) NULL;
2236 return(argv);
2237}
2238
2239/*
2240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2241% %
2242% %
2243% %
anthonyb1d483a2012-04-14 12:53:56 +00002244% S t r i n g T o A r r a y O f D o u b l e s %
cristy3ed852e2009-09-05 21:47:34 +00002245% %
2246% %
2247% %
2248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2249%
glennrp6ab82382013-10-28 13:54:30 +00002250% StringToArrayOfDoubles() converts a string of space or comma separated
anthonyb1d483a2012-04-14 12:53:56 +00002251% numbers into array of floating point numbers (doubles). Any number that
2252% failes to parse properly will produce a syntax error. As will two commas
2253% without a number between them. However a final comma at the end will
2254% not be regarded as an error so as to simplify automatic list generation.
cristy3ed852e2009-09-05 21:47:34 +00002255%
anthonyb1d483a2012-04-14 12:53:56 +00002256% A NULL value is returned on syntax or memory errors.
cristy3ed852e2009-09-05 21:47:34 +00002257%
anthonyb1d483a2012-04-14 12:53:56 +00002258% Use RelinquishMagickMemory() to free returned array when finished.
2259%
2260% The format of the StringToArrayOfDoubles method is:
2261%
cristy66336b02014-04-07 20:48:46 +00002262% double *StringToArrayOfDoubles(const char *string,size_t *count,
2263% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002264%
2265% A description of each parameter follows:
2266%
glennrp6ab82382013-10-28 13:54:30 +00002267% o string: the string containing the comma/space separated values.
anthonyb1d483a2012-04-14 12:53:56 +00002268%
2269% o count: returns number of arguments in returned array
2270%
cristy52085732013-11-09 02:32:27 +00002271% o exception: return any errors or warnings in this structure.
2272%
cristy3ed852e2009-09-05 21:47:34 +00002273*/
cristy52085732013-11-09 02:32:27 +00002274MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2275 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002276{
anthonyb1d483a2012-04-14 12:53:56 +00002277 char
2278 *q;
2279
cristy0a887dc2012-08-15 22:58:36 +00002280 const char
2281 *p;
2282
anthonyb1d483a2012-04-14 12:53:56 +00002283 double
2284 *array;
2285
cristybb503372010-05-27 20:51:26 +00002286 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002287 i;
2288
cristy0a887dc2012-08-15 22:58:36 +00002289 /*
2290 Determine count of values, and check syntax.
2291 */
cristyb0de93f2013-05-03 13:39:25 +00002292 assert(exception != (ExceptionInfo *) NULL);
2293 assert(exception->signature == MagickSignature);
anthonyb1d483a2012-04-14 12:53:56 +00002294 *count=0;
anthonyb1d483a2012-04-14 12:53:56 +00002295 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002296 p=string;
2297 while (*p != '\0')
cristy3ed852e2009-09-05 21:47:34 +00002298 {
cristy0a887dc2012-08-15 22:58:36 +00002299 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2300 if (p == q)
2301 return((double *) NULL); /* no value found */
2302 p=q;
2303 i++; /* increment value count */
2304 while (isspace((int) ((unsigned char) *p)) != 0)
2305 p++; /* skip spaces */
2306 if (*p == ',')
2307 p++; /* skip comma */
2308 while (isspace((int) ((unsigned char) *p)) != 0)
2309 p++; /* and more spaces */
cristy3ed852e2009-09-05 21:47:34 +00002310 }
cristy0a887dc2012-08-15 22:58:36 +00002311 /*
2312 Allocate floating point argument list.
2313 */
anthonyb1d483a2012-04-14 12:53:56 +00002314 *count=i;
cristy0a887dc2012-08-15 22:58:36 +00002315 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2316 if (array == (double *) NULL)
cristy70ca0222013-11-09 02:34:16 +00002317 {
2318 (void) ThrowMagickException(exception,GetMagickModule(),
2319 ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2320 return((double *) NULL);
2321 }
cristy0a887dc2012-08-15 22:58:36 +00002322 /*
2323 Fill in the floating point values.
2324 */
anthonyb1d483a2012-04-14 12:53:56 +00002325 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002326 p=string;
2327 while ((*p != '\0') && (i < *count))
2328 {
anthonyb1d483a2012-04-14 12:53:56 +00002329 array[i++]=StringToDouble(p,&q);
2330 p=q;
cristy0a887dc2012-08-15 22:58:36 +00002331 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2332 p++;
anthonyb1d483a2012-04-14 12:53:56 +00002333 }
anthonyb1d483a2012-04-14 12:53:56 +00002334 return(array);
cristy3ed852e2009-09-05 21:47:34 +00002335}
2336
2337/*
2338%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2339% %
2340% %
2341% %
anthonyb1d483a2012-04-14 12:53:56 +00002342+ S t r i n g T o k e n %
cristy3ed852e2009-09-05 21:47:34 +00002343% %
2344% %
2345% %
2346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2347%
cristy66336b02014-04-07 20:48:46 +00002348% StringToken() looks for any one of given delimiters and splits the string
anthonyb1d483a2012-04-14 12:53:56 +00002349% into two separate strings by replacing the delimiter character found with a
2350% nul character.
2351%
2352% The given string pointer is changed to point to the string following the
2353% delimiter character found, or NULL. A pointer to the start of the
2354% string is returned, representing the token before the delimiter.
2355%
2356% In may ways this is equivent to the strtok() C library function, but with
2357% multiple delimiter characters rather than a delimiter string.
cristy3ed852e2009-09-05 21:47:34 +00002358%
2359% The format of the StringToken method is:
2360%
2361% char *StringToken(const char *delimiters,char **string)
2362%
2363% A description of each parameter follows:
2364%
2365% o delimiters: one or more delimiters.
2366%
2367% o string: return the first token in the string. If none is found, return
2368% NULL.
2369%
2370*/
2371MagickExport char *StringToken(const char *delimiters,char **string)
2372{
2373 char
2374 *q;
2375
2376 register char
2377 *p;
2378
2379 register const char
2380 *r;
2381
2382 register int
2383 c,
2384 d;
2385
2386 p=(*string);
2387 if (p == (char *) NULL)
2388 return((char *) NULL);
anthonyb1d483a2012-04-14 12:53:56 +00002389 q=p;
2390 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00002391 {
2392 c=(*p++);
2393 r=delimiters;
2394 do
2395 {
2396 d=(*r++);
2397 if (c == d)
2398 {
2399 if (c == '\0')
2400 p=(char *) NULL;
2401 else
2402 p[-1]='\0';
2403 *string=p;
2404 return(q);
2405 }
2406 } while (d != '\0');
2407 }
2408}
2409
2410/*
2411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2412% %
2413% %
2414% %
2415% S t r i n g T o L i s t %
2416% %
2417% %
2418% %
2419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2420%
2421% StringToList() converts a text string into a list by segmenting the text
2422% string at each carriage return discovered. The list is converted to HEX
2423% characters if any control characters are discovered within the text string.
2424%
2425% The format of the StringToList method is:
2426%
2427% char **StringToList(const char *text)
2428%
2429% A description of each parameter follows:
2430%
cristy3ed852e2009-09-05 21:47:34 +00002431% o text: Specifies the string to segment into a list.
2432%
2433*/
2434MagickExport char **StringToList(const char *text)
2435{
2436 char
2437 **textlist;
2438
2439 register const char
2440 *p;
2441
cristybb503372010-05-27 20:51:26 +00002442 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002443 i;
2444
cristybb503372010-05-27 20:51:26 +00002445 size_t
cristy3ed852e2009-09-05 21:47:34 +00002446 lines;
2447
2448 if (text == (char *) NULL)
2449 return((char **) NULL);
2450 for (p=text; *p != '\0'; p++)
2451 if (((int) ((unsigned char) *p) < 32) &&
2452 (isspace((int) ((unsigned char) *p)) == 0))
2453 break;
2454 if (*p == '\0')
2455 {
2456 register const char
2457 *q;
2458
2459 /*
2460 Convert string to an ASCII list.
2461 */
2462 lines=1;
2463 for (p=text; *p != '\0'; p++)
2464 if (*p == '\n')
2465 lines++;
2466 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2467 sizeof(*textlist));
2468 if (textlist == (char **) NULL)
2469 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2470 p=text;
cristybb503372010-05-27 20:51:26 +00002471 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002472 {
2473 for (q=p; *q != '\0'; q++)
2474 if ((*q == '\r') || (*q == '\n'))
2475 break;
2476 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002477 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002478 if (textlist[i] == (char *) NULL)
2479 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002480 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002481 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002482 if (*q == '\r')
2483 q++;
2484 p=q+1;
2485 }
2486 }
2487 else
2488 {
2489 char
2490 hex_string[MaxTextExtent];
2491
2492 register char
2493 *q;
2494
cristybb503372010-05-27 20:51:26 +00002495 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002496 j;
2497
2498 /*
2499 Convert string to a HEX list.
2500 */
cristybb503372010-05-27 20:51:26 +00002501 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002502 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2503 sizeof(*textlist));
2504 if (textlist == (char **) NULL)
2505 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2506 p=text;
cristybb503372010-05-27 20:51:26 +00002507 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002508 {
2509 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002510 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002511 if (textlist[i] == (char *) NULL)
2512 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002513 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002514 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002515 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002516 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002517 {
cristyb51dff52011-05-19 16:55:47 +00002518 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002519 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2520 q+=2;
2521 if ((j % 0x04) == 0)
2522 *q++=' ';
2523 }
2524 for ( ; j <= 0x14; j++)
2525 {
2526 *q++=' ';
2527 *q++=' ';
2528 if ((j % 0x04) == 0)
2529 *q++=' ';
2530 }
2531 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002532 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002533 {
2534 if (isprint((int) ((unsigned char) *p)) != 0)
2535 *q++=(*p);
2536 else
2537 *q++='-';
2538 p++;
2539 }
2540 *q='\0';
2541 }
2542 }
2543 textlist[i]=(char *) NULL;
2544 return(textlist);
2545}
2546
2547/*
2548%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2549% %
2550% %
2551% %
2552% S t r i n g T o S t r i n g I n f o %
2553% %
2554% %
2555% %
2556%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2557%
cristybca58f32011-08-21 14:48:50 +00002558% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002559%
2560% The format of the StringToStringInfo method is:
2561%
2562% StringInfo *StringToStringInfo(const char *string)
2563%
2564% A description of each parameter follows:
2565%
2566% o string: The string.
2567%
2568*/
2569MagickExport StringInfo *StringToStringInfo(const char *string)
2570{
2571 StringInfo
2572 *string_info;
2573
cristy3ed852e2009-09-05 21:47:34 +00002574 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002575 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002576 SetStringInfoDatum(string_info,(const unsigned char *) string);
2577 return(string_info);
2578}
2579
2580/*
2581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2582% %
2583% %
2584% %
2585% S t r i p S t r i n g %
2586% %
2587% %
2588% %
2589%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2590%
2591% StripString() strips any whitespace or quotes from the beginning and end of
2592% a string of characters.
2593%
2594% The format of the StripString method is:
2595%
2596% void StripString(char *message)
2597%
2598% A description of each parameter follows:
2599%
2600% o message: Specifies an array of characters.
2601%
2602*/
2603MagickExport void StripString(char *message)
2604{
2605 register char
2606 *p,
2607 *q;
2608
2609 size_t
2610 length;
2611
2612 assert(message != (char *) NULL);
2613 if (*message == '\0')
2614 return;
2615 length=strlen(message);
2616 p=message;
2617 while (isspace((int) ((unsigned char) *p)) != 0)
2618 p++;
2619 if ((*p == '\'') || (*p == '"'))
2620 p++;
2621 q=message+length-1;
2622 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2623 q--;
2624 if (q > p)
2625 if ((*q == '\'') || (*q == '"'))
2626 q--;
cristya63c1ba2011-06-02 20:33:43 +00002627 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002628 message[q-p+1]='\0';
2629 for (p=message; *p != '\0'; p++)
2630 if (*p == '\n')
2631 *p=' ';
2632}
2633
2634/*
2635%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2636% %
2637% %
2638% %
2639% S u b s t i t u t e S t r i n g %
2640% %
2641% %
2642% %
2643%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2644%
cristyf1b72c12009-10-06 13:25:21 +00002645% SubstituteString() performs string substitution on a string, replacing the
2646% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002647% If the string is matched and status, MagickTrue is returned otherwise
2648% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002649%
2650% The format of the SubstituteString method is:
2651%
cristyf1b72c12009-10-06 13:25:21 +00002652% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002653% const char *replace)
2654%
2655% A description of each parameter follows:
2656%
cristyf1b72c12009-10-06 13:25:21 +00002657% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002658% allocation if a replacement is made.
2659%
cristybc3392a2009-10-06 03:15:57 +00002660% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002661%
cristybc3392a2009-10-06 03:15:57 +00002662% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002663%
2664*/
cristyf1b72c12009-10-06 13:25:21 +00002665MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002666 const char *search,const char *replace)
2667{
cristybc3392a2009-10-06 03:15:57 +00002668 MagickBooleanType
2669 status;
cristy3ed852e2009-09-05 21:47:34 +00002670
cristybc3392a2009-10-06 03:15:57 +00002671 register char
2672 *p;
cristy3ed852e2009-09-05 21:47:34 +00002673
cristy3ed852e2009-09-05 21:47:34 +00002674 size_t
cristybc3392a2009-10-06 03:15:57 +00002675 extent,
2676 replace_extent,
2677 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002678
cristyf1b72c12009-10-06 13:25:21 +00002679 ssize_t
2680 offset;
2681
cristybc3392a2009-10-06 03:15:57 +00002682 status=MagickFalse;
2683 search_extent=0,
2684 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002685 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002686 {
cristyf1b72c12009-10-06 13:25:21 +00002687 if (search_extent == 0)
2688 search_extent=strlen(search);
2689 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002690 continue;
cristy3ed852e2009-09-05 21:47:34 +00002691 /*
cristybc3392a2009-10-06 03:15:57 +00002692 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002693 */
cristyf1b72c12009-10-06 13:25:21 +00002694 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002695 if (replace_extent == 0)
2696 replace_extent=strlen(replace);
2697 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002698 {
cristybc3392a2009-10-06 03:15:57 +00002699 /*
2700 Make room for the replacement string.
2701 */
cristyde58b412010-02-18 03:53:40 +00002702 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002703 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002704 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2705 sizeof(*p));
2706 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002707 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002708 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002709 }
cristy3ed852e2009-09-05 21:47:34 +00002710 /*
cristybc3392a2009-10-06 03:15:57 +00002711 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002712 */
cristybc3392a2009-10-06 03:15:57 +00002713 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002714 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2715 strlen(p+search_extent)+1);
2716 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002717 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002718 }
cristybc3392a2009-10-06 03:15:57 +00002719 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002720}