blob: 2b39da9063de74972c0ea556ac6b9fc80e90b166 [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*/
Cristy9125cd52015-09-17 20:16:13 -040063#ifdef __VMS
64#define asciimap AsciiMap
65#endif
cristy3ed852e2009-09-05 21:47:34 +000066#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
67static const unsigned char
cristy8e7a4612013-09-16 22:10:27 +000068 AsciiMap[] =
cristy3ed852e2009-09-05 21:47:34 +000069 {
70 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
71 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
72 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
73 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
74 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
75 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
76 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
77 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
78 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
79 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
80 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
81 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
82 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
83 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
84 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
85 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
86 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
87 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
88 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
89 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
90 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
91 0xfc, 0xfd, 0xfe, 0xff,
92 };
93#endif
94
95/*
96%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
97% %
98% %
99% %
100% A c q u i r e S t r i n g %
101% %
102% %
103% %
104%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
105%
anthony104f8932012-05-13 01:54:53 +0000106% AcquireString() returns an new extented string, containing a clone of the
107% given string.
cristy3ed852e2009-09-05 21:47:34 +0000108%
cristy151b66d2015-04-15 10:50:31 +0000109% An extended string is the string length, plus an extra MagickPathExtent space
cristy5364f9c2013-12-28 23:29:28 +0000110% to allow for the string to be actively worked on.
anthony104f8932012-05-13 01:54:53 +0000111%
112% The returned string shoud be freed using DestoryString().
anthonyb1d483a2012-04-14 12:53:56 +0000113%
cristy3ed852e2009-09-05 21:47:34 +0000114% The format of the AcquireString method is:
115%
116% char *AcquireString(const char *source)
117%
118% A description of each parameter follows:
119%
120% o source: A character string.
121%
122*/
123MagickExport char *AcquireString(const char *source)
124{
125 char
126 *destination;
127
128 size_t
129 length;
130
131 length=0;
132 if (source != (char *) NULL)
133 length+=strlen(source);
cristy151b66d2015-04-15 10:50:31 +0000134 if (~length < MagickPathExtent)
cristy54aad5e2010-09-03 16:02:04 +0000135 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy151b66d2015-04-15 10:50:31 +0000136 destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
cristy54aad5e2010-09-03 16:02:04 +0000137 sizeof(*destination));
cristy3ed852e2009-09-05 21:47:34 +0000138 if (destination == (char *) NULL)
139 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
140 *destination='\0';
141 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000142 (void) memcpy(destination,source,length*sizeof(*destination));
143 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000144 return(destination);
145}
146
147/*
148%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149% %
150% %
151% %
152% A c q u i r e S t r i n g I n f o %
153% %
154% %
155% %
156%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157%
158% AcquireStringInfo() allocates the StringInfo structure.
159%
160% The format of the AcquireStringInfo method is:
161%
162% StringInfo *AcquireStringInfo(const size_t length)
163%
164% A description of each parameter follows:
165%
166% o length: the string length.
167%
168*/
169MagickExport StringInfo *AcquireStringInfo(const size_t length)
170{
171 StringInfo
172 *string_info;
173
cristy73bd4a52010-10-05 11:24:23 +0000174 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000175 if (string_info == (StringInfo *) NULL)
176 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
177 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
cristye1c94d92015-06-28 12:16:33 +0000178 string_info->signature=MagickCoreSignature;
cristy3ed852e2009-09-05 21:47:34 +0000179 string_info->length=length;
cristy8a68c242014-04-07 20:43:37 +0000180 string_info->datum=(unsigned char *) NULL;
cristy151b66d2015-04-15 10:50:31 +0000181 if (~string_info->length >= (MagickPathExtent-1))
cristy8a68c242014-04-07 20:43:37 +0000182 string_info->datum=(unsigned char *) AcquireQuantumMemory(
cristy151b66d2015-04-15 10:50:31 +0000183 string_info->length+MagickPathExtent,sizeof(*string_info->datum));
cristy8a68c242014-04-07 20:43:37 +0000184 if (string_info->datum == (unsigned char *) NULL)
185 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000186 return(string_info);
187}
188
189/*
190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191% %
192% %
193% %
cristy8723e4b2011-09-01 13:11:19 +0000194% B l o b T o S t r i n g I n f o %
195% %
196% %
197% %
198%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199%
anthony104f8932012-05-13 01:54:53 +0000200% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
cristy151b66d2015-04-15 10:50:31 +0000201% with MagickPathExtent extra space.
cristy8723e4b2011-09-01 13:11:19 +0000202%
203% The format of the BlobToStringInfo method is:
204%
205% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
206%
207% A description of each parameter follows:
208%
209% o blob: the blob.
210%
211% o length: the length of the blob.
212%
213*/
214MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
215{
216 StringInfo
217 *string_info;
218
219 string_info=AcquireStringInfo(0);
cristy151b66d2015-04-15 10:50:31 +0000220 if (~length < MagickPathExtent)
cristy5ce7dac2014-05-28 12:22:17 +0000221 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristyf8316342011-09-01 13:55:00 +0000222 string_info->length=length;
cristy5ce7dac2014-05-28 12:22:17 +0000223 if (string_info->datum == (unsigned char *) NULL)
224 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
cristy151b66d2015-04-15 10:50:31 +0000225 MagickPathExtent,sizeof(*string_info->datum));
cristy5ce7dac2014-05-28 12:22:17 +0000226 else
227 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
cristy151b66d2015-04-15 10:50:31 +0000228 length+MagickPathExtent,sizeof(*string_info->datum));
cristy8723e4b2011-09-01 13:11:19 +0000229 if (string_info->datum == (unsigned char *) NULL)
230 {
231 string_info=DestroyStringInfo(string_info);
232 return((StringInfo *) NULL);
233 }
234 if (blob != (const void *) NULL)
235 (void) memcpy(string_info->datum,blob,length);
236 return(string_info);
237}
238
239/*
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241% %
242% %
243% %
cristy3ed852e2009-09-05 21:47:34 +0000244% C l o n e S t r i n g %
245% %
246% %
247% %
248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249%
anthony104f8932012-05-13 01:54:53 +0000250% CloneString() replaces or frees the destination string to make it
cristya42df252015-04-15 22:33:45 +0000251% a clone of the input string plus MagickPathExtent more space so the string
252% may be worked on.
cristy3ed852e2009-09-05 21:47:34 +0000253%
anthony104f8932012-05-13 01:54:53 +0000254% If source is a NULL pointer the destination string will be freed and set to
255% a NULL pointer. A pointer to the stored in the destination is also returned.
anthony72feaa62012-01-17 06:46:23 +0000256%
anthony104f8932012-05-13 01:54:53 +0000257% When finished the non-NULL string should be freed using DestoryString()
258% or using CloneString() with a NULL pointed for the source.
anthony06762232012-04-29 11:45:40 +0000259%
cristy3ed852e2009-09-05 21:47:34 +0000260% The format of the CloneString method is:
261%
262% char *CloneString(char **destination,const char *source)
263%
264% A description of each parameter follows:
265%
266% o destination: A pointer to a character string.
267%
268% o source: A character string.
269%
270*/
271MagickExport char *CloneString(char **destination,const char *source)
272{
273 size_t
274 length;
275
cristy3ed852e2009-09-05 21:47:34 +0000276 assert(destination != (char **) NULL);
277 if (source == (const char *) NULL)
278 {
279 if (*destination != (char *) NULL)
280 *destination=DestroyString(*destination);
281 return(*destination);
282 }
283 if (*destination == (char *) NULL)
284 {
285 *destination=AcquireString(source);
286 return(*destination);
287 }
288 length=strlen(source);
cristy151b66d2015-04-15 10:50:31 +0000289 if (~length < MagickPathExtent)
cristy3ed852e2009-09-05 21:47:34 +0000290 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristya42df252015-04-15 22:33:45 +0000291 *destination=(char *) ResizeQuantumMemory(*destination,length+
292 MagickPathExtent,sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000293 if (*destination == (char *) NULL)
294 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000295 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000296 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000297 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000298 return(*destination);
299}
300
301/*
302%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
303% %
304% %
305% %
306% C l o n e S t r i n g I n f o %
307% %
308% %
309% %
310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311%
312% CloneStringInfo() clones a copy of the StringInfo structure.
313%
314% The format of the CloneStringInfo method is:
315%
316% StringInfo *CloneStringInfo(const StringInfo *string_info)
317%
318% A description of each parameter follows:
319%
320% o string_info: the string info.
321%
322*/
323MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
324{
325 StringInfo
326 *clone_info;
327
cristy3ed852e2009-09-05 21:47:34 +0000328 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000329 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000330 clone_info=AcquireStringInfo(string_info->length);
331 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000332 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000333 return(clone_info);
334}
335
336/*
337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338% %
339% %
340% %
341% C o m p a r e S t r i n g I n f o %
342% %
343% %
344% %
345%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346%
347% CompareStringInfo() compares the two datums target and source. It returns
348% an integer less than, equal to, or greater than zero if target is found,
349% respectively, to be less than, to match, or be greater than source.
350%
351% The format of the CompareStringInfo method is:
352%
353% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
354%
355% A description of each parameter follows:
356%
357% o target: the target string.
358%
359% o source: the source string.
360%
361*/
362
cristy3ed852e2009-09-05 21:47:34 +0000363MagickExport int CompareStringInfo(const StringInfo *target,
364 const StringInfo *source)
365{
366 int
367 status;
368
cristy3ed852e2009-09-05 21:47:34 +0000369 assert(target != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000370 assert(target->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000371 assert(source != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000372 assert(source->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000373 status=memcmp(target->datum,source->datum,MagickMin(target->length,
374 source->length));
375 if (status != 0)
376 return(status);
377 if (target->length == source->length)
378 return(0);
379 return(target->length < source->length ? -1 : 1);
380}
381
382/*
383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384% %
385% %
386% %
387% C o n c a t e n a t e M a g i c k S t r i n g %
388% %
389% %
390% %
391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392%
393% ConcatenateMagickString() concatenates the source string to the destination
394% string. The destination buffer is always null-terminated even if the
395% string must be truncated.
396%
397% The format of the ConcatenateMagickString method is:
398%
399% size_t ConcatenateMagickString(char *destination,const char *source,
400% const size_t length)
401%
402% A description of each parameter follows:
403%
404% o destination: the destination string.
405%
406% o source: the source string.
407%
408% o length: the length of the destination string.
409%
410*/
411MagickExport size_t ConcatenateMagickString(char *destination,
412 const char *source,const size_t length)
413{
414 register char
415 *q;
416
417 register const char
418 *p;
419
420 register size_t
421 i;
422
423 size_t
424 count;
425
426 assert(destination != (char *) NULL);
427 assert(source != (const char *) NULL);
428 assert(length >= 1);
429 p=source;
430 q=destination;
431 i=length;
432 while ((i-- != 0) && (*q != '\0'))
433 q++;
434 count=(size_t) (q-destination);
435 i=length-count;
436 if (i == 0)
437 return(count+strlen(p));
438 while (*p != '\0')
439 {
440 if (i != 1)
441 {
442 *q++=(*p);
443 i--;
444 }
445 p++;
446 }
447 *q='\0';
448 return(count+(p-source));
449}
450
451/*
452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453% %
454% %
455% %
456% C o n c a t e n a t e S t r i n g %
457% %
458% %
459% %
460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461%
462% ConcatenateString() appends a copy of string source, including the
463% terminating null character, to the end of string destination.
464%
465% The format of the ConcatenateString method is:
466%
467% MagickBooleanType ConcatenateString(char **destination,
468% const char *source)
469%
470% A description of each parameter follows:
471%
472% o destination: A pointer to a character string.
473%
474% o source: A character string.
475%
476*/
477MagickExport MagickBooleanType ConcatenateString(char **destination,
478 const char *source)
479{
480 size_t
cristy54aad5e2010-09-03 16:02:04 +0000481 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000482 length,
483 source_length;
484
485 assert(destination != (char **) NULL);
486 if (source == (const char *) NULL)
487 return(MagickTrue);
488 if (*destination == (char *) NULL)
489 {
490 *destination=AcquireString(source);
491 return(MagickTrue);
492 }
cristy54aad5e2010-09-03 16:02:04 +0000493 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000494 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000495 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000496 if (~length < source_length)
497 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
498 length+=source_length;
cristy151b66d2015-04-15 10:50:31 +0000499 if (~length < MagickPathExtent)
cristy3ed852e2009-09-05 21:47:34 +0000500 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristya42df252015-04-15 22:33:45 +0000501 *destination=(char *) ResizeQuantumMemory(*destination,length+
502 MagickPathExtent,sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000503 if (*destination == (char *) NULL)
504 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000505 if (source_length != 0)
506 (void) memcpy((*destination)+destination_length,source,source_length);
507 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000508 return(MagickTrue);
509}
510
511/*
512%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513% %
514% %
515% %
516% C o n c a t e n a t e S t r i n g I n f o %
517% %
518% %
519% %
520%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
521%
522% ConcatenateStringInfo() concatenates the source string to the destination
523% string.
524%
525% The format of the ConcatenateStringInfo method is:
526%
527% void ConcatenateStringInfo(StringInfo *string_info,
528% const StringInfo *source)
529%
530% A description of each parameter follows:
531%
532% o string_info: the string info.
533%
534% o source: the source string.
535%
536*/
537MagickExport void ConcatenateStringInfo(StringInfo *string_info,
538 const StringInfo *source)
539{
540 size_t
541 length;
542
cristy3ed852e2009-09-05 21:47:34 +0000543 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000544 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000545 assert(source != (const StringInfo *) NULL);
546 length=string_info->length;
547 if (~length < source->length)
548 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
549 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000550 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000551}
552
553/*
554%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
555% %
556% %
557% %
558% 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 %
559% %
560% %
561% %
562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
563%
564% ConfigureFileToStringInfo() returns the contents of a configure file as a
565% string.
566%
567% The format of the ConfigureFileToStringInfo method is:
568%
569% StringInfo *ConfigureFileToStringInfo(const char *filename)
570% ExceptionInfo *exception)
571%
572% A description of each parameter follows:
573%
574% o filename: the filename.
575%
576*/
cristy99bbf2c2011-09-26 18:27:50 +0000577MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +0000578{
579 char
580 *string;
581
582 int
583 file;
584
585 MagickOffsetType
586 offset;
587
588 size_t
589 length;
590
591 StringInfo
592 *string_info;
593
594 void
595 *map;
596
597 assert(filename != (const char *) NULL);
cristy18c6c272011-09-23 14:40:37 +0000598 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
cristy3ed852e2009-09-05 21:47:34 +0000599 if (file == -1)
600 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000601 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000602 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
603 {
604 file=close(file)-1;
605 return((StringInfo *) NULL);
606 }
607 length=(size_t) offset;
608 string=(char *) NULL;
cristy151b66d2015-04-15 10:50:31 +0000609 if (~length >= (MagickPathExtent-1))
cristya42df252015-04-15 22:33:45 +0000610 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
611 sizeof(*string));
cristy3ed852e2009-09-05 21:47:34 +0000612 if (string == (char *) NULL)
613 {
614 file=close(file)-1;
615 return((StringInfo *) NULL);
616 }
617 map=MapBlob(file,ReadMode,0,length);
618 if (map != (void *) NULL)
619 {
cristy54aad5e2010-09-03 16:02:04 +0000620 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000621 (void) UnmapBlob(map,length);
622 }
623 else
624 {
625 register size_t
626 i;
627
628 ssize_t
629 count;
630
cristy7f317702011-02-18 20:40:28 +0000631 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000632 for (i=0; i < length; i+=count)
633 {
634 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
635 SSIZE_MAX));
636 if (count <= 0)
637 {
638 count=0;
639 if (errno != EINTR)
640 break;
641 }
642 }
643 if (i < length)
644 {
645 file=close(file)-1;
646 string=DestroyString(string);
647 return((StringInfo *) NULL);
648 }
649 }
650 string[length]='\0';
651 file=close(file)-1;
652 string_info=AcquireStringInfo(0);
dirkcecec522015-04-14 20:17:56 +0000653 string_info->path=ConstantString(filename);
cristy5ce7dac2014-05-28 12:22:17 +0000654 string_info->length=length;
cristy7fb9fc12014-05-28 01:18:24 +0000655 if (string_info->datum != (unsigned char *) NULL)
656 string_info->datum=(unsigned char *) RelinquishMagickMemory(
657 string_info->datum);
cristy3ed852e2009-09-05 21:47:34 +0000658 string_info->datum=(unsigned char *) string;
659 return(string_info);
660}
661
662/*
663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664% %
665% %
666% %
667% C o n s t a n t S t r i n g %
668% %
669% %
670% %
671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672%
anthony104f8932012-05-13 01:54:53 +0000673% ConstantString() allocates exactly the needed memory for a string and
674% copies the source string to that memory location. A NULL string pointer
675% will allocate an empty string containing just the NUL character.
cristy3ed852e2009-09-05 21:47:34 +0000676%
anthony104f8932012-05-13 01:54:53 +0000677% When finished the string should be freed using DestoryString()
anthony06762232012-04-29 11:45:40 +0000678%
cristy3ed852e2009-09-05 21:47:34 +0000679% The format of the ConstantString method is:
680%
681% char *ConstantString(const char *source)
682%
683% A description of each parameter follows:
684%
685% o source: A character string.
686%
687*/
688MagickExport char *ConstantString(const char *source)
689{
690 char
691 *destination;
692
693 size_t
694 length;
695
696 length=0;
697 if (source != (char *) NULL)
698 length+=strlen(source);
699 destination=(char *) NULL;
700 if (~length >= 1UL)
701 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
702 if (destination == (char *) NULL)
703 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
704 *destination='\0';
705 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000706 (void) memcpy(destination,source,length*sizeof(*destination));
707 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000708 return(destination);
709}
710
711/*
712%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
713% %
714% %
715% %
716% C o p y M a g i c k S t r i n g %
717% %
718% %
719% %
720%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
721%
anthony06762232012-04-29 11:45:40 +0000722% CopyMagickString() copies the source string to the destination string, with
723% out exceeding the given pre-declared length.
724%
725% The destination buffer is always null-terminated even if the string must be
726% truncated. The return value is the minimum of the source string length or
727% the length parameter.
cristy3ed852e2009-09-05 21:47:34 +0000728%
729% The format of the CopyMagickString method is:
730%
731% size_t CopyMagickString(const char *destination,char *source,
732% const size_t length)
733%
734% A description of each parameter follows:
735%
736% o destination: the destination string.
737%
738% o source: the source string.
739%
740% o length: the length of the destination string.
741%
742*/
743MagickExport size_t CopyMagickString(char *destination,const char *source,
744 const size_t length)
745{
746 register char
747 *q;
748
749 register const char
750 *p;
751
752 register size_t
753 n;
754
cristy77e3fcc2011-10-11 00:04:41 +0000755 if (source == (const char *) NULL)
756 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000757 p=source;
758 q=destination;
759 for (n=length; n > 4; n-=4)
760 {
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 *q=(*p++);
774 if (*q == '\0')
775 return((size_t) (p-source-1));
776 q++;
777 }
778 if (n != 0)
779 for (n--; n != 0; n--)
780 {
781 *q=(*p++);
782 if (*q == '\0')
783 return((size_t) (p-source-1));
784 q++;
785 }
786 if (length != 0)
787 *q='\0';
788 return((size_t) (p-source-1));
789}
790
791/*
792%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793% %
794% %
795% %
796% D e s t r o y S t r i n g %
797% %
798% %
799% %
800%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801%
802% DestroyString() destroys memory associated with a string.
803%
804% The format of the DestroyString method is:
805%
806% char *DestroyString(char *string)
807%
808% A description of each parameter follows:
809%
810% o string: the string.
811%
812*/
813MagickExport char *DestroyString(char *string)
814{
815 return((char *) RelinquishMagickMemory(string));
816}
817
818/*
819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820% %
821% %
822% %
823% D e s t r o y S t r i n g I n f o %
824% %
825% %
826% %
827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828%
829% DestroyStringInfo() destroys memory associated with the StringInfo structure.
830%
831% The format of the DestroyStringInfo method is:
832%
833% StringInfo *DestroyStringInfo(StringInfo *string_info)
834%
835% A description of each parameter follows:
836%
837% o string_info: the string info.
838%
839*/
840MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
841{
cristy3ed852e2009-09-05 21:47:34 +0000842 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000843 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000844 if (string_info->datum != (unsigned char *) NULL)
845 string_info->datum=(unsigned char *) RelinquishMagickMemory(
846 string_info->datum);
dirkcecec522015-04-14 20:17:56 +0000847 if (string_info->path != (char *) NULL)
dirk1e7a6d02015-04-14 20:20:42 +0000848 string_info->path=DestroyString(string_info->path);
cristye1c94d92015-06-28 12:16:33 +0000849 string_info->signature=(~MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000850 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
851 return(string_info);
852}
853
854/*
855%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856% %
857% %
858% %
859% D e s t r o y S t r i n g L i s t %
860% %
861% %
862% %
863%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
864%
865% DestroyStringList() zeros memory associated with a string list.
866%
867% The format of the DestroyStringList method is:
868%
869% char **DestroyStringList(char **list)
870%
871% A description of each parameter follows:
872%
873% o list: the string list.
874%
875*/
876MagickExport char **DestroyStringList(char **list)
877{
cristybb503372010-05-27 20:51:26 +0000878 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000879 i;
880
881 assert(list != (char **) NULL);
882 for (i=0; list[i] != (char *) NULL; i++)
883 list[i]=DestroyString(list[i]);
884 list=(char **) RelinquishMagickMemory(list);
885 return(list);
886}
887
888/*
889%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
890% %
891% %
892% %
893% E s c a p e S t r i n g %
894% %
895% %
896% %
897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898%
899% EscapeString() allocates memory for a backslash-escaped version of a
900% source text string, copies the escaped version of the text to that
901% memory location while adding backslash characters, and returns the
902% escaped string.
903%
904% The format of the EscapeString method is:
905%
906% char *EscapeString(const char *source,const char escape)
907%
908% A description of each parameter follows:
909%
910% o allocate_string: Method EscapeString returns the escaped string.
911%
912% o source: A character string.
913%
914% o escape: the quoted string termination character to escape (e.g. '"').
915%
916*/
917MagickExport char *EscapeString(const char *source,const char escape)
918{
919 char
920 *destination;
921
922 register char
923 *q;
924
925 register const char
926 *p;
927
928 size_t
929 length;
930
cristy3ed852e2009-09-05 21:47:34 +0000931 assert(source != (const char *) NULL);
932 length=strlen(source);
933 for (p=source; *p != '\0'; p++)
934 if ((*p == '\\') || (*p == escape))
935 {
936 if (~length < 1)
937 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
938 length++;
939 }
940 destination=(char *) NULL;
cristy151b66d2015-04-15 10:50:31 +0000941 if (~length >= (MagickPathExtent-1))
942 destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +0000943 sizeof(*destination));
944 if (destination == (char *) NULL)
945 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
946 *destination='\0';
cristy4662a132015-01-19 19:27:00 +0000947 q=destination;
948 for (p=source; *p != '\0'; p++)
949 {
950 if ((*p == '\\') || (*p == escape))
951 *q++='\\';
952 *q++=(*p);
953 }
954 *q='\0';
cristy3ed852e2009-09-05 21:47:34 +0000955 return(destination);
956}
957
958/*
959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
960% %
961% %
962% %
963% F i l e T o S t r i n g %
964% %
965% %
966% %
967%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968%
969% FileToString() returns the contents of a file as a string.
970%
971% The format of the FileToString method is:
972%
973% char *FileToString(const char *filename,const size_t extent,
974% ExceptionInfo *exception)
975%
976% A description of each parameter follows:
977%
978% o filename: the filename.
979%
980% o extent: Maximum length of the string.
981%
982% o exception: return any errors or warnings in this structure.
983%
984*/
985MagickExport char *FileToString(const char *filename,const size_t extent,
986 ExceptionInfo *exception)
987{
988 size_t
989 length;
990
991 assert(filename != (const char *) NULL);
992 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
993 assert(exception != (ExceptionInfo *) NULL);
994 return((char *) FileToBlob(filename,extent,&length,exception));
995}
996
997/*
998%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
999% %
1000% %
1001% %
1002% F i l e T o S t r i n g I n f o %
1003% %
1004% %
1005% %
1006%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1007%
1008% FileToStringInfo() returns the contents of a file as a string.
1009%
1010% The format of the FileToStringInfo method is:
1011%
1012% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1013% ExceptionInfo *exception)
1014%
1015% A description of each parameter follows:
1016%
1017% o filename: the filename.
1018%
1019% o extent: Maximum length of the string.
1020%
1021% o exception: return any errors or warnings in this structure.
1022%
1023*/
1024MagickExport StringInfo *FileToStringInfo(const char *filename,
1025 const size_t extent,ExceptionInfo *exception)
1026{
1027 StringInfo
1028 *string_info;
1029
1030 assert(filename != (const char *) NULL);
1031 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1032 assert(exception != (ExceptionInfo *) NULL);
1033 string_info=AcquireStringInfo(0);
dirkcecec522015-04-14 20:17:56 +00001034 string_info->path=ConstantString(filename);
cristy7fb9fc12014-05-28 01:18:24 +00001035 if (string_info->datum != (unsigned char *) NULL)
1036 string_info->datum=(unsigned char *) RelinquishMagickMemory(
1037 string_info->datum);
dirkcecec522015-04-14 20:17:56 +00001038 string_info->datum=(unsigned char *) FileToBlob(filename,extent,
1039 &string_info->length,exception);
cristy3ed852e2009-09-05 21:47:34 +00001040 if (string_info->datum == (unsigned char *) NULL)
1041 {
1042 string_info=DestroyStringInfo(string_info);
1043 return((StringInfo *) NULL);
1044 }
1045 return(string_info);
1046}
1047
1048/*
1049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050% %
1051% %
1052% %
1053% F o r m a t M a g i c k S i z e %
1054% %
1055% %
1056% %
1057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1058%
1059% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +00001060% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +00001061% 1000.
cristy3ed852e2009-09-05 21:47:34 +00001062%
1063% The format of the FormatMagickSize method is:
1064%
cristy40937042014-12-22 01:44:59 +00001065% ssize_t FormatMagickSize(const MagickSizeType size,const char *suffix,
cristyd4618c02015-04-14 23:54:43 +00001066% const size_t length,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001067%
1068% A description of each parameter follows:
1069%
1070% o size: convert this size to a human readable format.
1071%
cristyb9080c92009-12-01 20:13:26 +00001072% o bi: use power of two rather than power of ten.
1073%
cristy40937042014-12-22 01:44:59 +00001074% o suffix: append suffix, typically B or P.
1075%
cristyd4618c02015-04-14 23:54:43 +00001076% o length: the maximum length of the string.
1077%
cristy3ed852e2009-09-05 21:47:34 +00001078% o format: human readable format.
1079%
1080*/
cristy99bbf2c2011-09-26 18:27:50 +00001081MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyd4618c02015-04-14 23:54:43 +00001082 const MagickBooleanType bi,const char *suffix,const size_t length,
1083 char *format)
cristy3ed852e2009-09-05 21:47:34 +00001084{
cristyb9080c92009-12-01 20:13:26 +00001085 const char
1086 **units;
1087
cristy3ed852e2009-09-05 21:47:34 +00001088 double
cristyb9080c92009-12-01 20:13:26 +00001089 bytes,
cristyd4618c02015-04-14 23:54:43 +00001090 extent;
cristy3ed852e2009-09-05 21:47:34 +00001091
cristybb503372010-05-27 20:51:26 +00001092 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001093 i,
1094 j;
1095
cristy9d314ff2011-03-09 01:30:28 +00001096 ssize_t
1097 count;
1098
cristy3ed852e2009-09-05 21:47:34 +00001099 static const char
cristyb9080c92009-12-01 20:13:26 +00001100 *bi_units[] =
1101 {
cristy2ce15c92010-03-12 14:03:41 +00001102 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001103 },
1104 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001105 {
cristy2ce15c92010-03-12 14:03:41 +00001106 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001107 };
cristy3ed852e2009-09-05 21:47:34 +00001108
cristyb9080c92009-12-01 20:13:26 +00001109 bytes=1000.0;
1110 units=traditional_units;
1111 if (bi != MagickFalse)
1112 {
1113 bytes=1024.0;
1114 units=bi_units;
1115 }
cristy3ed852e2009-09-05 21:47:34 +00001116#if defined(_MSC_VER) && (_MSC_VER == 1200)
cristyd4618c02015-04-14 23:54:43 +00001117 extent=(double) ((MagickOffsetType) size);
cristy3ed852e2009-09-05 21:47:34 +00001118#else
cristyd4618c02015-04-14 23:54:43 +00001119 extent=(double) size;
cristy3ed852e2009-09-05 21:47:34 +00001120#endif
cristyd4618c02015-04-14 23:54:43 +00001121 for (i=0; (extent >= bytes) && (units[i+1] != (const char *) NULL); i++)
1122 extent/=bytes;
cristyc3b9b362013-05-25 17:16:34 +00001123 count=0;
cristy9bf9da32009-09-27 16:48:34 +00001124 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001125 {
cristy40937042014-12-22 01:44:59 +00001126 if (suffix == (const char *) NULL)
cristyd4618c02015-04-14 23:54:43 +00001127 count=FormatLocaleString(format,length,"%.*g%s",(int) (i+j),extent,
1128 units[i]);
cristy40937042014-12-22 01:44:59 +00001129 else
cristyd4618c02015-04-14 23:54:43 +00001130 count=FormatLocaleString(format,length,"%.*g%s%s",(int) (i+j),extent,
1131 units[i],suffix);
cristy3ed852e2009-09-05 21:47:34 +00001132 if (strchr(format,'+') == (char *) NULL)
1133 break;
1134 }
1135 return(count);
1136}
1137
1138/*
1139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1140% %
1141% %
1142% %
cristy3ed852e2009-09-05 21:47:34 +00001143% F o r m a t M a g i c k T i m e %
1144% %
1145% %
1146% %
1147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1148%
1149% FormatMagickTime() returns the specified time in the Internet date/time
1150% format and the length of the timestamp.
1151%
1152% The format of the FormatMagickTime method is:
1153%
cristybb503372010-05-27 20:51:26 +00001154% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001155% char *timestamp)
1156%
1157% A description of each parameter follows.
1158%
cristyd4618c02015-04-14 23:54:43 +00001159% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1160% measured in seconds.
cristy3ed852e2009-09-05 21:47:34 +00001161%
cristyd4618c02015-04-14 23:54:43 +00001162% o length: the maximum length of the string.
cristy3ed852e2009-09-05 21:47:34 +00001163%
cristyd4618c02015-04-14 23:54:43 +00001164% o timestamp: Return the Internet date/time here.
cristy3ed852e2009-09-05 21:47:34 +00001165%
1166*/
cristybb503372010-05-27 20:51:26 +00001167MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001168 char *timestamp)
1169{
cristybb503372010-05-27 20:51:26 +00001170 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001171 count;
1172
1173 struct tm
1174 gm_time,
1175 local_time;
1176
1177 time_t
1178 timezone;
1179
1180 assert(timestamp != (char *) NULL);
1181 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1182 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1183#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1184 (void) localtime_r(&time,&local_time);
1185#else
1186 {
cristybc3392a2009-10-06 03:15:57 +00001187 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001188 *my_time;
1189
1190 my_time=localtime(&time);
1191 if (my_time != (struct tm *) NULL)
1192 (void) memcpy(&local_time,my_time,sizeof(local_time));
1193 }
1194#endif
1195#if defined(MAGICKCORE_HAVE_GMTIME_R)
1196 (void) gmtime_r(&time,&gm_time);
1197#else
1198 {
cristybc3392a2009-10-06 03:15:57 +00001199 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001200 *my_time;
1201
1202 my_time=gmtime(&time);
1203 if (my_time != (struct tm *) NULL)
1204 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1205 }
1206#endif
1207 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1208 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1209 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1210 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001211 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001212 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1213 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001214 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001215 return(count);
1216}
1217
1218/*
1219%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220% %
1221% %
1222% %
1223% G e t E n v i r o n m e n t V a l u e %
1224% %
1225% %
1226% %
1227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1228%
1229% GetEnvironmentValue() returns the environment string that matches the
1230% specified name.
1231%
1232% The format of the GetEnvironmentValue method is:
1233%
1234% char *GetEnvironmentValue(const char *name)
1235%
1236% A description of each parameter follows:
1237%
1238% o name: the environment name.
1239%
1240*/
cristy99bbf2c2011-09-26 18:27:50 +00001241MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001242{
1243 const char
1244 *environment;
1245
1246 environment=getenv(name);
1247 if (environment == (const char *) NULL)
1248 return((char *) NULL);
1249 return(ConstantString(environment));
1250}
1251
1252/*
1253%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1254% %
1255% %
1256% %
1257% G e t S t r i n g I n f o D a t u m %
1258% %
1259% %
1260% %
1261%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262%
1263% GetStringInfoDatum() returns the datum associated with the string.
1264%
1265% The format of the GetStringInfoDatum method is:
1266%
1267% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1268%
1269% A description of each parameter follows:
1270%
1271% o string_info: the string info.
1272%
1273*/
1274MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1275{
1276 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001277 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001278 return(string_info->datum);
1279}
1280
1281/*
1282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1283% %
1284% %
1285% %
1286% G e t S t r i n g I n f o L e n g t h %
1287% %
1288% %
1289% %
1290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1291%
1292% GetStringInfoLength() returns the string length.
1293%
1294% The format of the GetStringInfoLength method is:
1295%
1296% size_t GetStringInfoLength(const StringInfo *string_info)
1297%
1298% A description of each parameter follows:
1299%
1300% o string_info: the string info.
1301%
1302*/
1303MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1304{
1305 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001306 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001307 return(string_info->length);
1308}
1309
1310/*
1311%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1312% %
1313% %
1314% %
1315% G e t S t r i n g I n f o P a t h %
1316% %
1317% %
1318% %
1319%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1320%
1321% GetStringInfoPath() returns the path associated with the string.
1322%
1323% The format of the GetStringInfoPath method is:
1324%
1325% const char *GetStringInfoPath(const StringInfo *string_info)
1326%
1327% A description of each parameter follows:
1328%
1329% o string_info: the string info.
1330%
1331*/
1332MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1333{
1334 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001335 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001336 return(string_info->path);
1337}
1338
1339/*
1340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1341% %
1342% %
1343% %
cristydbdd0e32011-11-04 23:29:40 +00001344+ I n t e r p r e t S i P r e f i x V a l u e %
1345% %
1346% %
1347% %
1348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1349%
1350% InterpretSiPrefixValue() converts the initial portion of the string to a
1351% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1352% etc.).
1353%
1354% The format of the InterpretSiPrefixValue method is:
1355%
1356% double InterpretSiPrefixValue(const char *value,char **sentinal)
1357%
1358% A description of each parameter follows:
1359%
1360% o value: the string value.
1361%
1362% o sentinal: if sentinal is not NULL, return a pointer to the character
1363% after the last character used in the conversion.
1364%
1365*/
1366MagickExport double InterpretSiPrefixValue(const char *restrict string,
1367 char **restrict sentinal)
1368{
1369 char
1370 *q;
1371
1372 double
1373 value;
1374
cristydbdd0e32011-11-04 23:29:40 +00001375 value=InterpretLocaleValue(string,&q);
1376 if (q != string)
1377 {
1378 if ((*q >= 'E') && (*q <= 'z'))
1379 {
1380 double
1381 e;
1382
cristy0c2684f2011-11-05 21:39:43 +00001383 switch ((int) ((unsigned char) *q))
1384 {
1385 case 'y': e=(-24.0); break;
1386 case 'z': e=(-21.0); break;
1387 case 'a': e=(-18.0); break;
1388 case 'f': e=(-15.0); break;
1389 case 'p': e=(-12.0); break;
1390 case 'n': e=(-9.0); break;
1391 case 'u': e=(-6.0); break;
1392 case 'm': e=(-3.0); break;
1393 case 'c': e=(-2.0); break;
1394 case 'd': e=(-1.0); break;
1395 case 'h': e=2.0; break;
1396 case 'k': e=3.0; break;
1397 case 'K': e=3.0; break;
1398 case 'M': e=6.0; break;
1399 case 'G': e=9.0; break;
1400 case 'T': e=12.0; break;
1401 case 'P': e=15.0; break;
1402 case 'E': e=18.0; break;
1403 case 'Z': e=21.0; break;
1404 case 'Y': e=24.0; break;
1405 default: e=0.0; break;
1406 }
cristydbdd0e32011-11-04 23:29:40 +00001407 if (e >= MagickEpsilon)
1408 {
1409 if (q[1] == 'i')
1410 {
1411 value*=pow(2.0,e/0.3);
1412 q+=2;
1413 }
1414 else
1415 {
1416 value*=pow(10.0,e);
1417 q++;
1418 }
1419 }
1420 }
cristy40937042014-12-22 01:44:59 +00001421 if ((*q == 'B') || (*q == 'P'))
cristy099a7352011-11-09 14:31:35 +00001422 q++;
cristydbdd0e32011-11-04 23:29:40 +00001423 }
1424 if (sentinal != (char **) NULL)
1425 *sentinal=q;
1426 return(value);
1427}
1428
1429/*
1430%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1431% %
1432% %
1433% %
anthony6f201312012-03-30 04:08:15 +00001434% I s S t r i n g T r u e %
1435% %
1436% %
1437% %
1438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1439%
1440% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1441% "1". Any other string or undefined returns MagickFalse.
1442%
1443% Typically this is used to look at strings (options or artifacts) which
1444% has a default value of "false", when not defined.
1445%
1446% The format of the IsStringTrue method is:
1447%
1448% MagickBooleanType IsStringTrue(const char *value)
1449%
1450% A description of each parameter follows:
1451%
1452% o value: Specifies a pointer to a character array.
1453%
1454*/
1455MagickExport MagickBooleanType IsStringTrue(const char *value)
1456{
1457 if (value == (const char *) NULL)
1458 return(MagickFalse);
1459 if (LocaleCompare(value,"true") == 0)
1460 return(MagickTrue);
1461 if (LocaleCompare(value,"on") == 0)
1462 return(MagickTrue);
1463 if (LocaleCompare(value,"yes") == 0)
1464 return(MagickTrue);
1465 if (LocaleCompare(value,"1") == 0)
1466 return(MagickTrue);
1467 return(MagickFalse);
1468}
1469
1470/*
1471%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1472% %
1473% %
1474% %
dirk9a846de2015-07-25 16:51:01 +00001475% I s S t r i n g F a l s e %
anthony6f201312012-03-30 04:08:15 +00001476% %
1477% %
1478% %
1479%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1480%
dirk9a846de2015-07-25 16:51:01 +00001481% IsStringFalse() returns MagickTrue if the value is "false", "off", "no" or
1482% "0". Any other string or undefined returns MagickFalse.
anthony6f201312012-03-30 04:08:15 +00001483%
1484% Typically this is used to look at strings (options or artifacts) which
1485% has a default value of "true", when it has not been defined.
1486%
dirk9a846de2015-07-25 16:51:01 +00001487% The format of the IsStringFalse method is:
anthony6f201312012-03-30 04:08:15 +00001488%
dirk9a846de2015-07-25 16:51:01 +00001489% MagickBooleanType IsStringFalse(const char *value)
anthony6f201312012-03-30 04:08:15 +00001490%
1491% A description of each parameter follows:
1492%
1493% o value: Specifies a pointer to a character array.
1494%
1495*/
dirk9a846de2015-07-25 16:51:01 +00001496MagickExport MagickBooleanType IsStringFalse(const char *value)
anthony6f201312012-03-30 04:08:15 +00001497{
1498 if (value == (const char *) NULL)
dirk9a846de2015-07-25 16:51:01 +00001499 return(MagickFalse);
anthony6f201312012-03-30 04:08:15 +00001500 if (LocaleCompare(value,"false") == 0)
dirk9a846de2015-07-25 16:51:01 +00001501 return(MagickTrue);
anthony6f201312012-03-30 04:08:15 +00001502 if (LocaleCompare(value,"off") == 0)
dirk9a846de2015-07-25 16:51:01 +00001503 return(MagickTrue);
anthony6f201312012-03-30 04:08:15 +00001504 if (LocaleCompare(value,"no") == 0)
dirk9a846de2015-07-25 16:51:01 +00001505 return(MagickTrue);
anthony6f201312012-03-30 04:08:15 +00001506 if (LocaleCompare(value,"0") == 0)
dirk9a846de2015-07-25 16:51:01 +00001507 return(MagickTrue);
1508 return(MagickFalse);
anthony6f201312012-03-30 04:08:15 +00001509}
1510
1511/*
1512%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1513% %
1514% %
1515% %
cristy3ed852e2009-09-05 21:47:34 +00001516% P r i n t S t r i n g I n f o %
1517% %
1518% %
1519% %
1520%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1521%
1522% PrintStringInfo() prints the string.
1523%
1524% The format of the PrintStringInfo method is:
1525%
1526% void PrintStringInfo(FILE *file,const char *id,
1527% const StringInfo *string_info)
1528%
1529% A description of each parameter follows:
1530%
1531% o file: the file, typically stdout.
1532%
1533% o id: the string id.
1534%
1535% o string_info: the string info.
1536%
1537*/
1538MagickExport void PrintStringInfo(FILE *file,const char *id,
1539 const StringInfo *string_info)
1540{
1541 register const char
1542 *p;
1543
1544 register size_t
1545 i,
1546 j;
1547
1548 assert(id != (const char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001549 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001550 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001551 p=(char *) string_info->datum;
1552 for (i=0; i < string_info->length; i++)
1553 {
1554 if (((int) ((unsigned char) *p) < 32) &&
1555 (isspace((int) ((unsigned char) *p)) == 0))
1556 break;
1557 p++;
1558 }
cristy2d8723c2013-11-14 16:41:27 +00001559 (void) FormatLocaleFile(file,"%s(%.20g): ",id,(double) string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001560 if (i == string_info->length)
1561 {
cristy53ea28b2012-06-10 22:11:59 +00001562 for (i=0; i < string_info->length; i++)
1563 (void) fputc(string_info->datum[i],file);
cristy3ed852e2009-09-05 21:47:34 +00001564 (void) fputc('\n',file);
1565 return;
1566 }
1567 /*
1568 Convert string to a HEX list.
1569 */
1570 p=(char *) string_info->datum;
1571 for (i=0; i < string_info->length; i+=0x14)
1572 {
cristyb51dff52011-05-19 16:55:47 +00001573 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001574 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1575 {
cristyb51dff52011-05-19 16:55:47 +00001576 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001577 if ((j % 0x04) == 0)
1578 (void) fputc(' ',file);
1579 }
1580 for ( ; j <= 0x14; j++)
1581 {
1582 (void) fputc(' ',file);
1583 (void) fputc(' ',file);
1584 if ((j % 0x04) == 0)
1585 (void) fputc(' ',file);
1586 }
1587 (void) fputc(' ',file);
1588 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1589 {
1590 if (isprint((int) ((unsigned char) *p)) != 0)
1591 (void) fputc(*p,file);
1592 else
1593 (void) fputc('-',file);
1594 p++;
1595 }
1596 (void) fputc('\n',file);
1597 }
1598}
1599
1600/*
1601%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1602% %
1603% %
1604% %
1605% R e s e t S t r i n g I n f o %
1606% %
1607% %
1608% %
1609%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1610%
1611% ResetStringInfo() reset the string to all null bytes.
1612%
1613% The format of the ResetStringInfo method is:
1614%
1615% void ResetStringInfo(StringInfo *string_info)
1616%
1617% A description of each parameter follows:
1618%
1619% o string_info: the string info.
1620%
1621*/
1622MagickExport void ResetStringInfo(StringInfo *string_info)
1623{
cristy3ed852e2009-09-05 21:47:34 +00001624 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001625 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001626 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1627}
1628
1629/*
1630%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1631% %
1632% %
1633% %
1634% S e t S t r i n g I n f o %
1635% %
1636% %
1637% %
1638%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1639%
1640% SetStringInfo() copies the source string to the destination string.
1641%
1642% The format of the SetStringInfo method is:
1643%
1644% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1645%
1646% A description of each parameter follows:
1647%
1648% o string_info: the string info.
1649%
1650% o source: the source string.
1651%
1652*/
1653MagickExport void SetStringInfo(StringInfo *string_info,
1654 const StringInfo *source)
1655{
cristy3ed852e2009-09-05 21:47:34 +00001656 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001657 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001658 assert(source != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001659 assert(source->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001660 if (string_info->length == 0)
1661 return;
1662 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001663 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1664 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001665}
1666
1667/*
1668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1669% %
1670% %
1671% %
1672% S e t S t r i n g I n f o D a t u m %
1673% %
1674% %
1675% %
1676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1677%
1678% SetStringInfoDatum() copies bytes from the source string for the length of
1679% the destination string.
1680%
1681% The format of the SetStringInfoDatum method is:
1682%
1683% void SetStringInfoDatum(StringInfo *string_info,
1684% const unsigned char *source)
1685%
1686% A description of each parameter follows:
1687%
1688% o string_info: the string info.
1689%
1690% o source: the source string.
1691%
1692*/
1693MagickExport void SetStringInfoDatum(StringInfo *string_info,
1694 const unsigned char *source)
1695{
cristy3ed852e2009-09-05 21:47:34 +00001696 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001697 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001698 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001699 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001700}
1701
1702/*
1703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1704% %
1705% %
1706% %
1707% S e t S t r i n g I n f o L e n g t h %
1708% %
1709% %
1710% %
1711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1712%
1713% SetStringInfoLength() set the string length to the specified value.
1714%
1715% The format of the SetStringInfoLength method is:
1716%
1717% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1718%
1719% A description of each parameter follows:
1720%
1721% o string_info: the string info.
1722%
1723% o length: the string length.
1724%
1725*/
1726MagickExport void SetStringInfoLength(StringInfo *string_info,
1727 const size_t length)
1728{
cristy3ed852e2009-09-05 21:47:34 +00001729 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001730 assert(string_info->signature == MagickCoreSignature);
cristy151b66d2015-04-15 10:50:31 +00001731 if (~length < MagickPathExtent)
cristy3ed852e2009-09-05 21:47:34 +00001732 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1733 string_info->length=length;
1734 if (string_info->datum == (unsigned char *) NULL)
1735 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
cristy151b66d2015-04-15 10:50:31 +00001736 MagickPathExtent,sizeof(*string_info->datum));
cristy3ed852e2009-09-05 21:47:34 +00001737 else
1738 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
cristy151b66d2015-04-15 10:50:31 +00001739 length+MagickPathExtent,sizeof(*string_info->datum));
cristy3ed852e2009-09-05 21:47:34 +00001740 if (string_info->datum == (unsigned char *) NULL)
1741 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1742}
1743
1744/*
1745%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1746% %
1747% %
1748% %
1749% S e t S t r i n g I n f o D a t u m %
1750% %
1751% %
1752% %
1753%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1754%
1755% SetStringInfoPath() sets the path associated with the string.
1756%
1757% The format of the SetStringInfoPath method is:
1758%
1759% void SetStringInfoPath(StringInfo *string_info,const char *path)
1760%
1761% A description of each parameter follows:
1762%
1763% o string_info: the string info.
1764%
1765% o path: the path.
1766%
1767*/
1768MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1769{
cristy3ed852e2009-09-05 21:47:34 +00001770 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001771 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001772 assert(path != (const char *) NULL);
dirkcecec522015-04-14 20:17:56 +00001773 string_info->path=ConstantString(path);
cristy3ed852e2009-09-05 21:47:34 +00001774}
1775
1776/*
1777%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1778% %
1779% %
1780% %
1781% S p l i t S t r i n g I n f o %
1782% %
1783% %
1784% %
1785%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1786%
1787% SplitStringInfo() splits a string into two and returns it.
1788%
1789% The format of the SplitStringInfo method is:
1790%
1791% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1792%
1793% A description of each parameter follows:
1794%
1795% o string_info: the string info.
1796%
1797*/
1798MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1799 const size_t offset)
1800{
1801 StringInfo
1802 *split_info;
1803
cristy3ed852e2009-09-05 21:47:34 +00001804 assert(string_info != (StringInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001805 assert(string_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +00001806 if (offset > string_info->length)
1807 return((StringInfo *) NULL);
1808 split_info=AcquireStringInfo(offset);
1809 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00001810 (void) memmove(string_info->datum,string_info->datum+offset,
cristy151b66d2015-04-15 10:50:31 +00001811 string_info->length-offset+MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00001812 SetStringInfoLength(string_info,string_info->length-offset);
1813 return(split_info);
1814}
1815
1816/*
1817%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1818% %
1819% %
1820% %
1821% S t r i n g I n f o T o S t r i n g %
1822% %
1823% %
1824% %
1825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1826%
1827% StringInfoToString() converts a string info string to a C string.
1828%
1829% The format of the StringInfoToString method is:
1830%
1831% char *StringInfoToString(const StringInfo *string_info)
1832%
1833% A description of each parameter follows:
1834%
1835% o string_info: the string.
1836%
1837*/
1838MagickExport char *StringInfoToString(const StringInfo *string_info)
1839{
1840 char
1841 *string;
1842
1843 size_t
1844 length;
1845
1846 string=(char *) NULL;
1847 length=string_info->length;
cristy151b66d2015-04-15 10:50:31 +00001848 if (~length >= (MagickPathExtent-1))
cristya42df252015-04-15 22:33:45 +00001849 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
1850 sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001851 if (string == (char *) NULL)
1852 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00001853 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001854 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001855 return(string);
1856}
1857
1858/*
1859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1860% %
1861% %
1862% %
anthonyb1d483a2012-04-14 12:53:56 +00001863% S t r i n g I n f o T o H e x S t r i n g %
1864% %
1865% %
1866% %
1867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1868%
1869% StringInfoToHexString() converts a string info string to a C string.
1870%
1871% The format of the StringInfoToHexString method is:
1872%
1873% char *StringInfoToHexString(const StringInfo *string_info)
1874%
1875% A description of each parameter follows:
1876%
1877% o string_info: the string.
1878%
1879*/
1880MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1881{
1882 char
1883 *string;
1884
1885 register const unsigned char
1886 *p;
1887
1888 register ssize_t
1889 i;
1890
1891 register unsigned char
1892 *q;
1893
1894 size_t
1895 length;
1896
1897 unsigned char
1898 hex_digits[16];
1899
1900 length=string_info->length;
cristy151b66d2015-04-15 10:50:31 +00001901 if (~length < MagickPathExtent)
anthonyb1d483a2012-04-14 12:53:56 +00001902 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristya42df252015-04-15 22:33:45 +00001903 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,2*
1904 sizeof(*string));
anthonyb1d483a2012-04-14 12:53:56 +00001905 if (string == (char *) NULL)
1906 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1907 hex_digits[0]='0';
1908 hex_digits[1]='1';
1909 hex_digits[2]='2';
1910 hex_digits[3]='3';
1911 hex_digits[4]='4';
1912 hex_digits[5]='5';
1913 hex_digits[6]='6';
1914 hex_digits[7]='7';
1915 hex_digits[8]='8';
1916 hex_digits[9]='9';
1917 hex_digits[10]='a';
1918 hex_digits[11]='b';
1919 hex_digits[12]='c';
1920 hex_digits[13]='d';
1921 hex_digits[14]='e';
1922 hex_digits[15]='f';
1923 p=string_info->datum;
1924 q=(unsigned char *) string;
1925 for (i=0; i < (ssize_t) string_info->length; i++)
1926 {
1927 *q++=hex_digits[(*p >> 4) & 0x0f];
1928 *q++=hex_digits[*p & 0x0f];
1929 p++;
1930 }
1931 *q='\0';
1932 return(string);
1933}
1934
1935/*
1936%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1937% %
1938% %
1939% %
cristy3ed852e2009-09-05 21:47:34 +00001940% S t r i n g T o A r g v %
1941% %
1942% %
1943% %
1944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1945%
1946% StringToArgv() converts a text string into command line arguments.
anthony31f1bf72012-01-30 12:37:22 +00001947% The 'argv' array of arguments, is returned while the number of arguments
1948% is returned via the provided integer variable pointer.
1949%
1950% Simple 'word' tokenizer, which allows for each word to be optionally
1951% quoted. However it will not allow use of partial quotes, or escape
1952% characters.
cristy3ed852e2009-09-05 21:47:34 +00001953%
1954% The format of the StringToArgv method is:
1955%
1956% char **StringToArgv(const char *text,int *argc)
1957%
1958% A description of each parameter follows:
1959%
1960% o argv: Method StringToArgv returns the string list unless an error
1961% occurs, otherwise NULL.
1962%
1963% o text: Specifies the string to segment into a list.
1964%
1965% o argc: This integer pointer returns the number of arguments in the
1966% list.
1967%
1968*/
1969MagickExport char **StringToArgv(const char *text,int *argc)
1970{
1971 char
1972 **argv;
1973
1974 register const char
1975 *p,
1976 *q;
1977
cristybb503372010-05-27 20:51:26 +00001978 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001979 i;
1980
1981 *argc=0;
1982 if (text == (char *) NULL)
1983 return((char **) NULL);
1984 /*
1985 Determine the number of arguments.
1986 */
1987 for (p=text; *p != '\0'; )
1988 {
1989 while (isspace((int) ((unsigned char) *p)) != 0)
1990 p++;
cristya20c9042011-05-19 13:22:18 +00001991 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00001992 break;
cristy3ed852e2009-09-05 21:47:34 +00001993 (*argc)++;
1994 if (*p == '"')
1995 for (p++; (*p != '"') && (*p != '\0'); p++) ;
1996 if (*p == '\'')
1997 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
1998 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1999 p++;
2000 }
2001 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002002 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002003 if (argv == (char **) NULL)
2004 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2005 /*
2006 Convert string to an ASCII list.
2007 */
2008 argv[0]=AcquireString("magick");
2009 p=text;
cristybb503372010-05-27 20:51:26 +00002010 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002011 {
2012 while (isspace((int) ((unsigned char) *p)) != 0)
2013 p++;
2014 q=p;
2015 if (*q == '"')
2016 {
2017 p++;
2018 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2019 }
2020 else
2021 if (*q == '\'')
2022 {
cristy06b15f42011-01-22 21:36:24 +00002023 p++;
cristy3ed852e2009-09-05 21:47:34 +00002024 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002025 }
2026 else
2027 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2028 q++;
cristy151b66d2015-04-15 10:50:31 +00002029 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MagickPathExtent,
cristy3ed852e2009-09-05 21:47:34 +00002030 sizeof(**argv));
2031 if (argv[i] == (char *) NULL)
2032 {
2033 for (i--; i >= 0; i--)
2034 argv[i]=DestroyString(argv[i]);
2035 argv=(char **) RelinquishMagickMemory(argv);
2036 ThrowFatalException(ResourceLimitFatalError,
2037 "UnableToConvertStringToARGV");
2038 }
cristy54aad5e2010-09-03 16:02:04 +00002039 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002040 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002041 p=q;
2042 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2043 p++;
2044 }
2045 argv[i]=(char *) NULL;
2046 return(argv);
2047}
2048
2049/*
2050%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2051% %
2052% %
2053% %
anthonyb1d483a2012-04-14 12:53:56 +00002054% 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 +00002055% %
2056% %
2057% %
2058%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2059%
glennrp6ab82382013-10-28 13:54:30 +00002060% StringToArrayOfDoubles() converts a string of space or comma separated
anthonyb1d483a2012-04-14 12:53:56 +00002061% numbers into array of floating point numbers (doubles). Any number that
2062% failes to parse properly will produce a syntax error. As will two commas
2063% without a number between them. However a final comma at the end will
2064% not be regarded as an error so as to simplify automatic list generation.
cristy3ed852e2009-09-05 21:47:34 +00002065%
anthonyb1d483a2012-04-14 12:53:56 +00002066% A NULL value is returned on syntax or memory errors.
cristy3ed852e2009-09-05 21:47:34 +00002067%
anthonyb1d483a2012-04-14 12:53:56 +00002068% Use RelinquishMagickMemory() to free returned array when finished.
2069%
2070% The format of the StringToArrayOfDoubles method is:
2071%
cristy66336b02014-04-07 20:48:46 +00002072% double *StringToArrayOfDoubles(const char *string,size_t *count,
2073% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002074%
2075% A description of each parameter follows:
2076%
glennrp6ab82382013-10-28 13:54:30 +00002077% o string: the string containing the comma/space separated values.
anthonyb1d483a2012-04-14 12:53:56 +00002078%
2079% o count: returns number of arguments in returned array
2080%
cristy52085732013-11-09 02:32:27 +00002081% o exception: return any errors or warnings in this structure.
2082%
cristy3ed852e2009-09-05 21:47:34 +00002083*/
cristy52085732013-11-09 02:32:27 +00002084MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2085 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002086{
anthonyb1d483a2012-04-14 12:53:56 +00002087 char
2088 *q;
2089
cristy0a887dc2012-08-15 22:58:36 +00002090 const char
2091 *p;
2092
anthonyb1d483a2012-04-14 12:53:56 +00002093 double
2094 *array;
2095
cristybb503372010-05-27 20:51:26 +00002096 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002097 i;
2098
cristy0a887dc2012-08-15 22:58:36 +00002099 /*
2100 Determine count of values, and check syntax.
2101 */
cristyb0de93f2013-05-03 13:39:25 +00002102 assert(exception != (ExceptionInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +00002103 assert(exception->signature == MagickCoreSignature);
anthonyb1d483a2012-04-14 12:53:56 +00002104 *count=0;
anthonyb1d483a2012-04-14 12:53:56 +00002105 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002106 p=string;
2107 while (*p != '\0')
cristy3ed852e2009-09-05 21:47:34 +00002108 {
cristy0a887dc2012-08-15 22:58:36 +00002109 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2110 if (p == q)
2111 return((double *) NULL); /* no value found */
2112 p=q;
2113 i++; /* increment value count */
2114 while (isspace((int) ((unsigned char) *p)) != 0)
2115 p++; /* skip spaces */
2116 if (*p == ',')
2117 p++; /* skip comma */
2118 while (isspace((int) ((unsigned char) *p)) != 0)
2119 p++; /* and more spaces */
cristy3ed852e2009-09-05 21:47:34 +00002120 }
cristy0a887dc2012-08-15 22:58:36 +00002121 /*
2122 Allocate floating point argument list.
2123 */
anthonyb1d483a2012-04-14 12:53:56 +00002124 *count=i;
cristy0a887dc2012-08-15 22:58:36 +00002125 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2126 if (array == (double *) NULL)
cristy70ca0222013-11-09 02:34:16 +00002127 {
2128 (void) ThrowMagickException(exception,GetMagickModule(),
2129 ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2130 return((double *) NULL);
2131 }
cristy0a887dc2012-08-15 22:58:36 +00002132 /*
2133 Fill in the floating point values.
2134 */
anthonyb1d483a2012-04-14 12:53:56 +00002135 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002136 p=string;
2137 while ((*p != '\0') && (i < *count))
2138 {
anthonyb1d483a2012-04-14 12:53:56 +00002139 array[i++]=StringToDouble(p,&q);
2140 p=q;
cristy0a887dc2012-08-15 22:58:36 +00002141 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2142 p++;
anthonyb1d483a2012-04-14 12:53:56 +00002143 }
anthonyb1d483a2012-04-14 12:53:56 +00002144 return(array);
cristy3ed852e2009-09-05 21:47:34 +00002145}
2146
2147/*
2148%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2149% %
2150% %
2151% %
anthonyb1d483a2012-04-14 12:53:56 +00002152+ S t r i n g T o k e n %
cristy3ed852e2009-09-05 21:47:34 +00002153% %
2154% %
2155% %
2156%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2157%
cristy66336b02014-04-07 20:48:46 +00002158% StringToken() looks for any one of given delimiters and splits the string
anthonyb1d483a2012-04-14 12:53:56 +00002159% into two separate strings by replacing the delimiter character found with a
2160% nul character.
2161%
2162% The given string pointer is changed to point to the string following the
2163% delimiter character found, or NULL. A pointer to the start of the
2164% string is returned, representing the token before the delimiter.
2165%
2166% In may ways this is equivent to the strtok() C library function, but with
2167% multiple delimiter characters rather than a delimiter string.
cristy3ed852e2009-09-05 21:47:34 +00002168%
2169% The format of the StringToken method is:
2170%
2171% char *StringToken(const char *delimiters,char **string)
2172%
2173% A description of each parameter follows:
2174%
2175% o delimiters: one or more delimiters.
2176%
2177% o string: return the first token in the string. If none is found, return
2178% NULL.
2179%
2180*/
2181MagickExport char *StringToken(const char *delimiters,char **string)
2182{
2183 char
2184 *q;
2185
2186 register char
2187 *p;
2188
2189 register const char
2190 *r;
2191
2192 register int
2193 c,
2194 d;
2195
2196 p=(*string);
2197 if (p == (char *) NULL)
2198 return((char *) NULL);
anthonyb1d483a2012-04-14 12:53:56 +00002199 q=p;
2200 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00002201 {
2202 c=(*p++);
2203 r=delimiters;
2204 do
2205 {
2206 d=(*r++);
2207 if (c == d)
2208 {
2209 if (c == '\0')
2210 p=(char *) NULL;
2211 else
2212 p[-1]='\0';
2213 *string=p;
2214 return(q);
2215 }
2216 } while (d != '\0');
2217 }
2218}
2219
2220/*
2221%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2222% %
2223% %
2224% %
2225% S t r i n g T o L i s t %
2226% %
2227% %
2228% %
2229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2230%
2231% StringToList() converts a text string into a list by segmenting the text
2232% string at each carriage return discovered. The list is converted to HEX
2233% characters if any control characters are discovered within the text string.
2234%
2235% The format of the StringToList method is:
2236%
2237% char **StringToList(const char *text)
2238%
2239% A description of each parameter follows:
2240%
cristy3ed852e2009-09-05 21:47:34 +00002241% o text: Specifies the string to segment into a list.
2242%
2243*/
2244MagickExport char **StringToList(const char *text)
2245{
2246 char
2247 **textlist;
2248
2249 register const char
2250 *p;
2251
cristybb503372010-05-27 20:51:26 +00002252 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002253 i;
2254
cristybb503372010-05-27 20:51:26 +00002255 size_t
cristy3ed852e2009-09-05 21:47:34 +00002256 lines;
2257
2258 if (text == (char *) NULL)
2259 return((char **) NULL);
2260 for (p=text; *p != '\0'; p++)
2261 if (((int) ((unsigned char) *p) < 32) &&
2262 (isspace((int) ((unsigned char) *p)) == 0))
2263 break;
2264 if (*p == '\0')
2265 {
2266 register const char
2267 *q;
2268
2269 /*
2270 Convert string to an ASCII list.
2271 */
2272 lines=1;
2273 for (p=text; *p != '\0'; p++)
2274 if (*p == '\n')
2275 lines++;
2276 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2277 sizeof(*textlist));
2278 if (textlist == (char **) NULL)
2279 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2280 p=text;
cristybb503372010-05-27 20:51:26 +00002281 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002282 {
2283 for (q=p; *q != '\0'; q++)
2284 if ((*q == '\r') || (*q == '\n'))
2285 break;
cristya42df252015-04-15 22:33:45 +00002286 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+
2287 MagickPathExtent,sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002288 if (textlist[i] == (char *) NULL)
2289 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002290 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002291 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002292 if (*q == '\r')
2293 q++;
2294 p=q+1;
2295 }
2296 }
2297 else
2298 {
2299 char
cristy151b66d2015-04-15 10:50:31 +00002300 hex_string[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +00002301
2302 register char
2303 *q;
2304
cristybb503372010-05-27 20:51:26 +00002305 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002306 j;
2307
2308 /*
2309 Convert string to a HEX list.
2310 */
cristybb503372010-05-27 20:51:26 +00002311 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002312 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2313 sizeof(*textlist));
2314 if (textlist == (char **) NULL)
2315 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2316 p=text;
cristybb503372010-05-27 20:51:26 +00002317 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002318 {
cristy151b66d2015-04-15 10:50:31 +00002319 textlist[i]=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
cristy2e25ee62011-03-25 15:43:12 +00002320 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002321 if (textlist[i] == (char *) NULL)
2322 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy151b66d2015-04-15 10:50:31 +00002323 (void) FormatLocaleString(textlist[i],MagickPathExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002324 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002325 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002326 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002327 {
cristy151b66d2015-04-15 10:50:31 +00002328 (void) FormatLocaleString(hex_string,MagickPathExtent,"%02x",*(p+j));
2329 (void) CopyMagickString(q,hex_string,MagickPathExtent);
cristy3ed852e2009-09-05 21:47:34 +00002330 q+=2;
2331 if ((j % 0x04) == 0)
2332 *q++=' ';
2333 }
2334 for ( ; j <= 0x14; j++)
2335 {
2336 *q++=' ';
2337 *q++=' ';
2338 if ((j % 0x04) == 0)
2339 *q++=' ';
2340 }
2341 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002342 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002343 {
2344 if (isprint((int) ((unsigned char) *p)) != 0)
2345 *q++=(*p);
2346 else
2347 *q++='-';
2348 p++;
2349 }
2350 *q='\0';
2351 }
2352 }
2353 textlist[i]=(char *) NULL;
2354 return(textlist);
2355}
2356
2357/*
2358%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2359% %
2360% %
2361% %
2362% S t r i n g T o S t r i n g I n f o %
2363% %
2364% %
2365% %
2366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2367%
cristybca58f32011-08-21 14:48:50 +00002368% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002369%
2370% The format of the StringToStringInfo method is:
2371%
2372% StringInfo *StringToStringInfo(const char *string)
2373%
2374% A description of each parameter follows:
2375%
2376% o string: The string.
2377%
2378*/
2379MagickExport StringInfo *StringToStringInfo(const char *string)
2380{
2381 StringInfo
2382 *string_info;
2383
cristy3ed852e2009-09-05 21:47:34 +00002384 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002385 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002386 SetStringInfoDatum(string_info,(const unsigned char *) string);
2387 return(string_info);
2388}
2389
2390/*
2391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2392% %
2393% %
2394% %
2395% S t r i p S t r i n g %
2396% %
2397% %
2398% %
2399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2400%
2401% StripString() strips any whitespace or quotes from the beginning and end of
2402% a string of characters.
2403%
2404% The format of the StripString method is:
2405%
2406% void StripString(char *message)
2407%
2408% A description of each parameter follows:
2409%
2410% o message: Specifies an array of characters.
2411%
2412*/
2413MagickExport void StripString(char *message)
2414{
2415 register char
2416 *p,
2417 *q;
2418
2419 size_t
2420 length;
2421
2422 assert(message != (char *) NULL);
2423 if (*message == '\0')
2424 return;
2425 length=strlen(message);
2426 p=message;
2427 while (isspace((int) ((unsigned char) *p)) != 0)
2428 p++;
2429 if ((*p == '\'') || (*p == '"'))
2430 p++;
2431 q=message+length-1;
2432 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2433 q--;
2434 if (q > p)
2435 if ((*q == '\'') || (*q == '"'))
2436 q--;
cristya63c1ba2011-06-02 20:33:43 +00002437 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002438 message[q-p+1]='\0';
2439 for (p=message; *p != '\0'; p++)
2440 if (*p == '\n')
2441 *p=' ';
2442}
2443
2444/*
2445%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2446% %
2447% %
2448% %
2449% S u b s t i t u t e S t r i n g %
2450% %
2451% %
2452% %
2453%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2454%
cristyf1b72c12009-10-06 13:25:21 +00002455% SubstituteString() performs string substitution on a string, replacing the
2456% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002457% If the string is matched and status, MagickTrue is returned otherwise
2458% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002459%
2460% The format of the SubstituteString method is:
2461%
cristyf1b72c12009-10-06 13:25:21 +00002462% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002463% const char *replace)
2464%
2465% A description of each parameter follows:
2466%
cristyf1b72c12009-10-06 13:25:21 +00002467% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002468% allocation if a replacement is made.
2469%
cristybc3392a2009-10-06 03:15:57 +00002470% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002471%
cristybc3392a2009-10-06 03:15:57 +00002472% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002473%
2474*/
cristyf1b72c12009-10-06 13:25:21 +00002475MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002476 const char *search,const char *replace)
2477{
cristybc3392a2009-10-06 03:15:57 +00002478 MagickBooleanType
2479 status;
cristy3ed852e2009-09-05 21:47:34 +00002480
cristybc3392a2009-10-06 03:15:57 +00002481 register char
2482 *p;
cristy3ed852e2009-09-05 21:47:34 +00002483
cristy3ed852e2009-09-05 21:47:34 +00002484 size_t
cristybc3392a2009-10-06 03:15:57 +00002485 extent,
2486 replace_extent,
2487 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002488
cristyf1b72c12009-10-06 13:25:21 +00002489 ssize_t
2490 offset;
2491
cristybc3392a2009-10-06 03:15:57 +00002492 status=MagickFalse;
2493 search_extent=0,
2494 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002495 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002496 {
cristyf1b72c12009-10-06 13:25:21 +00002497 if (search_extent == 0)
2498 search_extent=strlen(search);
2499 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002500 continue;
cristy3ed852e2009-09-05 21:47:34 +00002501 /*
cristybc3392a2009-10-06 03:15:57 +00002502 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002503 */
cristyf1b72c12009-10-06 13:25:21 +00002504 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002505 if (replace_extent == 0)
2506 replace_extent=strlen(replace);
2507 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002508 {
cristybc3392a2009-10-06 03:15:57 +00002509 /*
2510 Make room for the replacement string.
2511 */
cristyde58b412010-02-18 03:53:40 +00002512 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002513 extent=strlen(*string)+replace_extent-search_extent+1;
cristy151b66d2015-04-15 10:50:31 +00002514 *string=(char *) ResizeQuantumMemory(*string,extent+MagickPathExtent,
cristyf1b72c12009-10-06 13:25:21 +00002515 sizeof(*p));
2516 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002517 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002518 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002519 }
cristy3ed852e2009-09-05 21:47:34 +00002520 /*
cristybc3392a2009-10-06 03:15:57 +00002521 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002522 */
cristybc3392a2009-10-06 03:15:57 +00002523 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002524 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2525 strlen(p+search_extent)+1);
2526 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002527 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002528 }
cristybc3392a2009-10-06 03:15:57 +00002529 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002530}