blob: 1db06c6256f618b88a906491d55d1d165f3dfb61 [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% %
cristyfe676ee2013-11-18 13:03:38 +000020% Copyright 1999-2014 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"
47#include "MagickCore/list.h"
48#include "MagickCore/locale_.h"
49#include "MagickCore/log.h"
50#include "MagickCore/memory_.h"
cristyd2d11ec2012-03-28 13:53:49 +000051#include "MagickCore/nt-base-private.h"
cristy4c08aed2011-07-01 19:47:50 +000052#include "MagickCore/property.h"
53#include "MagickCore/resource_.h"
54#include "MagickCore/signature-private.h"
55#include "MagickCore/string_.h"
anthonyb1d483a2012-04-14 12:53:56 +000056#include "MagickCore/string-private.h"
cristy18c6c272011-09-23 14:40:37 +000057#include "MagickCore/utility-private.h"
cristy3ed852e2009-09-05 21:47:34 +000058
59/*
cristy99bbf2c2011-09-26 18:27:50 +000060 static declarations.
cristy3ed852e2009-09-05 21:47:34 +000061*/
62#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
63static const unsigned char
cristy8e7a4612013-09-16 22:10:27 +000064 AsciiMap[] =
cristy3ed852e2009-09-05 21:47:34 +000065 {
66 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
67 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
68 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
69 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
70 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
71 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
72 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
73 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
74 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
75 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
76 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
77 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
78 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
79 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
80 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
81 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
82 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
83 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
84 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
85 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
86 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
87 0xfc, 0xfd, 0xfe, 0xff,
88 };
89#endif
90
91/*
92%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93% %
94% %
95% %
96% A c q u i r e S t r i n g %
97% %
98% %
99% %
100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101%
anthony104f8932012-05-13 01:54:53 +0000102% AcquireString() returns an new extented string, containing a clone of the
103% given string.
cristy3ed852e2009-09-05 21:47:34 +0000104%
anthony104f8932012-05-13 01:54:53 +0000105% An extended string is the string length, plus an extra MaxTextExtent space
cristy5364f9c2013-12-28 23:29:28 +0000106% to allow for the string to be actively worked on.
anthony104f8932012-05-13 01:54:53 +0000107%
108% The returned string shoud be freed using DestoryString().
anthonyb1d483a2012-04-14 12:53:56 +0000109%
cristy3ed852e2009-09-05 21:47:34 +0000110% The format of the AcquireString method is:
111%
112% char *AcquireString(const char *source)
113%
114% A description of each parameter follows:
115%
116% o source: A character string.
117%
118*/
119MagickExport char *AcquireString(const char *source)
120{
121 char
122 *destination;
123
124 size_t
125 length;
126
127 length=0;
128 if (source != (char *) NULL)
129 length+=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000130 if (~length < MaxTextExtent)
131 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
132 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
133 sizeof(*destination));
cristy3ed852e2009-09-05 21:47:34 +0000134 if (destination == (char *) NULL)
135 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
136 *destination='\0';
137 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000138 (void) memcpy(destination,source,length*sizeof(*destination));
139 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000140 return(destination);
141}
142
143/*
144%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145% %
146% %
147% %
148% A c q u i r e S t r i n g I n f o %
149% %
150% %
151% %
152%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153%
154% AcquireStringInfo() allocates the StringInfo structure.
155%
156% The format of the AcquireStringInfo method is:
157%
158% StringInfo *AcquireStringInfo(const size_t length)
159%
160% A description of each parameter follows:
161%
162% o length: the string length.
163%
164*/
165MagickExport StringInfo *AcquireStringInfo(const size_t length)
166{
167 StringInfo
168 *string_info;
169
cristy73bd4a52010-10-05 11:24:23 +0000170 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000171 if (string_info == (StringInfo *) NULL)
172 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
173 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
174 string_info->signature=MagickSignature;
175 string_info->length=length;
cristy8a68c242014-04-07 20:43:37 +0000176 string_info->datum=(unsigned char *) NULL;
177 if (~string_info->length >= (MaxTextExtent-1))
178 string_info->datum=(unsigned char *) AcquireQuantumMemory(
179 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
180 if (string_info->datum == (unsigned char *) NULL)
181 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy3ed852e2009-09-05 21:47:34 +0000182 return(string_info);
183}
184
185/*
186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187% %
188% %
189% %
cristy8723e4b2011-09-01 13:11:19 +0000190% B l o b T o S t r i n g I n f o %
191% %
192% %
193% %
194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195%
anthony104f8932012-05-13 01:54:53 +0000196% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
197% with MaxTextExtent extra space.
cristy8723e4b2011-09-01 13:11:19 +0000198%
199% The format of the BlobToStringInfo method is:
200%
201% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
202%
203% A description of each parameter follows:
204%
205% o blob: the blob.
206%
207% o length: the length of the blob.
208%
209*/
210MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
211{
212 StringInfo
213 *string_info;
214
215 string_info=AcquireStringInfo(0);
cristyf8316342011-09-01 13:55:00 +0000216 string_info->length=length;
cristya10e0742011-09-01 13:50:43 +0000217 if (~string_info->length >= (MaxTextExtent-1))
cristyf8316342011-09-01 13:55:00 +0000218 string_info->datum=(unsigned char *) AcquireQuantumMemory(
219 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
cristy8723e4b2011-09-01 13:11:19 +0000220 if (string_info->datum == (unsigned char *) NULL)
221 {
222 string_info=DestroyStringInfo(string_info);
223 return((StringInfo *) NULL);
224 }
225 if (blob != (const void *) NULL)
226 (void) memcpy(string_info->datum,blob,length);
227 return(string_info);
228}
229
230/*
231%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232% %
233% %
234% %
cristy3ed852e2009-09-05 21:47:34 +0000235% C l o n e S t r i n g %
236% %
237% %
238% %
239%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240%
anthony104f8932012-05-13 01:54:53 +0000241% CloneString() replaces or frees the destination string to make it
242% a clone of the input string plus MaxTextExtent more space so the string may
243% be worked on on.
cristy3ed852e2009-09-05 21:47:34 +0000244%
anthony104f8932012-05-13 01:54:53 +0000245% If source is a NULL pointer the destination string will be freed and set to
246% a NULL pointer. A pointer to the stored in the destination is also returned.
anthony72feaa62012-01-17 06:46:23 +0000247%
anthony104f8932012-05-13 01:54:53 +0000248% When finished the non-NULL string should be freed using DestoryString()
249% or using CloneString() with a NULL pointed for the source.
anthony06762232012-04-29 11:45:40 +0000250%
cristy3ed852e2009-09-05 21:47:34 +0000251% The format of the CloneString method is:
252%
253% char *CloneString(char **destination,const char *source)
254%
255% A description of each parameter follows:
256%
257% o destination: A pointer to a character string.
258%
259% o source: A character string.
260%
261*/
262MagickExport char *CloneString(char **destination,const char *source)
263{
264 size_t
265 length;
266
cristy3ed852e2009-09-05 21:47:34 +0000267 assert(destination != (char **) NULL);
268 if (source == (const char *) NULL)
269 {
270 if (*destination != (char *) NULL)
271 *destination=DestroyString(*destination);
272 return(*destination);
273 }
274 if (*destination == (char *) NULL)
275 {
276 *destination=AcquireString(source);
277 return(*destination);
278 }
279 length=strlen(source);
280 if (~length < MaxTextExtent)
281 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
282 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000283 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000284 if (*destination == (char *) NULL)
285 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000286 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000287 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000288 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000289 return(*destination);
290}
291
292/*
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294% %
295% %
296% %
297% C l o n e S t r i n g I n f o %
298% %
299% %
300% %
301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302%
303% CloneStringInfo() clones a copy of the StringInfo structure.
304%
305% The format of the CloneStringInfo method is:
306%
307% StringInfo *CloneStringInfo(const StringInfo *string_info)
308%
309% A description of each parameter follows:
310%
311% o string_info: the string info.
312%
313*/
314MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
315{
316 StringInfo
317 *clone_info;
318
cristy3ed852e2009-09-05 21:47:34 +0000319 assert(string_info != (StringInfo *) NULL);
320 assert(string_info->signature == MagickSignature);
321 clone_info=AcquireStringInfo(string_info->length);
322 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000323 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000324 return(clone_info);
325}
326
327/*
328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329% %
330% %
331% %
332% C o m p a r e S t r i n g I n f o %
333% %
334% %
335% %
336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337%
338% CompareStringInfo() compares the two datums target and source. It returns
339% an integer less than, equal to, or greater than zero if target is found,
340% respectively, to be less than, to match, or be greater than source.
341%
342% The format of the CompareStringInfo method is:
343%
344% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
345%
346% A description of each parameter follows:
347%
348% o target: the target string.
349%
350% o source: the source string.
351%
352*/
353
354static inline size_t MagickMin(const size_t x,const size_t y)
355{
356 if (x < y)
357 return(x);
358 return(y);
359}
360
361MagickExport int CompareStringInfo(const StringInfo *target,
362 const StringInfo *source)
363{
364 int
365 status;
366
cristy3ed852e2009-09-05 21:47:34 +0000367 assert(target != (StringInfo *) NULL);
368 assert(target->signature == MagickSignature);
369 assert(source != (StringInfo *) NULL);
370 assert(source->signature == MagickSignature);
371 status=memcmp(target->datum,source->datum,MagickMin(target->length,
372 source->length));
373 if (status != 0)
374 return(status);
375 if (target->length == source->length)
376 return(0);
377 return(target->length < source->length ? -1 : 1);
378}
379
380/*
381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382% %
383% %
384% %
385% C o n c a t e n a t e M a g i c k S t r i n g %
386% %
387% %
388% %
389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390%
391% ConcatenateMagickString() concatenates the source string to the destination
392% string. The destination buffer is always null-terminated even if the
393% string must be truncated.
394%
395% The format of the ConcatenateMagickString method is:
396%
397% size_t ConcatenateMagickString(char *destination,const char *source,
398% const size_t length)
399%
400% A description of each parameter follows:
401%
402% o destination: the destination string.
403%
404% o source: the source string.
405%
406% o length: the length of the destination string.
407%
408*/
409MagickExport size_t ConcatenateMagickString(char *destination,
410 const char *source,const size_t length)
411{
412 register char
413 *q;
414
415 register const char
416 *p;
417
418 register size_t
419 i;
420
421 size_t
422 count;
423
424 assert(destination != (char *) NULL);
425 assert(source != (const char *) NULL);
426 assert(length >= 1);
427 p=source;
428 q=destination;
429 i=length;
430 while ((i-- != 0) && (*q != '\0'))
431 q++;
432 count=(size_t) (q-destination);
433 i=length-count;
434 if (i == 0)
435 return(count+strlen(p));
436 while (*p != '\0')
437 {
438 if (i != 1)
439 {
440 *q++=(*p);
441 i--;
442 }
443 p++;
444 }
445 *q='\0';
446 return(count+(p-source));
447}
448
449/*
450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451% %
452% %
453% %
454% C o n c a t e n a t e S t r i n g %
455% %
456% %
457% %
458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459%
460% ConcatenateString() appends a copy of string source, including the
461% terminating null character, to the end of string destination.
462%
463% The format of the ConcatenateString method is:
464%
465% MagickBooleanType ConcatenateString(char **destination,
466% const char *source)
467%
468% A description of each parameter follows:
469%
470% o destination: A pointer to a character string.
471%
472% o source: A character string.
473%
474*/
475MagickExport MagickBooleanType ConcatenateString(char **destination,
476 const char *source)
477{
478 size_t
cristy54aad5e2010-09-03 16:02:04 +0000479 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000480 length,
481 source_length;
482
483 assert(destination != (char **) NULL);
484 if (source == (const char *) NULL)
485 return(MagickTrue);
486 if (*destination == (char *) NULL)
487 {
488 *destination=AcquireString(source);
489 return(MagickTrue);
490 }
cristy54aad5e2010-09-03 16:02:04 +0000491 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000492 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000493 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000494 if (~length < source_length)
495 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
496 length+=source_length;
497 if (~length < MaxTextExtent)
498 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
499 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000500 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000501 if (*destination == (char *) NULL)
502 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000503 if (source_length != 0)
504 (void) memcpy((*destination)+destination_length,source,source_length);
505 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000506 return(MagickTrue);
507}
508
509/*
510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
511% %
512% %
513% %
514% C o n c a t e n a t e S t r i n g I n f o %
515% %
516% %
517% %
518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519%
520% ConcatenateStringInfo() concatenates the source string to the destination
521% string.
522%
523% The format of the ConcatenateStringInfo method is:
524%
525% void ConcatenateStringInfo(StringInfo *string_info,
526% const StringInfo *source)
527%
528% A description of each parameter follows:
529%
530% o string_info: the string info.
531%
532% o source: the source string.
533%
534*/
535MagickExport void ConcatenateStringInfo(StringInfo *string_info,
536 const StringInfo *source)
537{
538 size_t
539 length;
540
cristy3ed852e2009-09-05 21:47:34 +0000541 assert(string_info != (StringInfo *) NULL);
542 assert(string_info->signature == MagickSignature);
543 assert(source != (const StringInfo *) NULL);
544 length=string_info->length;
545 if (~length < source->length)
546 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
547 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000548 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000549}
550
551/*
552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553% %
554% %
555% %
556% 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 %
557% %
558% %
559% %
560%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561%
562% ConfigureFileToStringInfo() returns the contents of a configure file as a
563% string.
564%
565% The format of the ConfigureFileToStringInfo method is:
566%
567% StringInfo *ConfigureFileToStringInfo(const char *filename)
568% ExceptionInfo *exception)
569%
570% A description of each parameter follows:
571%
572% o filename: the filename.
573%
574*/
cristy99bbf2c2011-09-26 18:27:50 +0000575MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +0000576{
577 char
578 *string;
579
580 int
581 file;
582
583 MagickOffsetType
584 offset;
585
586 size_t
587 length;
588
589 StringInfo
590 *string_info;
591
592 void
593 *map;
594
595 assert(filename != (const char *) NULL);
cristy18c6c272011-09-23 14:40:37 +0000596 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
cristy3ed852e2009-09-05 21:47:34 +0000597 if (file == -1)
598 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000599 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000600 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
601 {
602 file=close(file)-1;
603 return((StringInfo *) NULL);
604 }
605 length=(size_t) offset;
606 string=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000607 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000608 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
609 if (string == (char *) NULL)
610 {
611 file=close(file)-1;
612 return((StringInfo *) NULL);
613 }
614 map=MapBlob(file,ReadMode,0,length);
615 if (map != (void *) NULL)
616 {
cristy54aad5e2010-09-03 16:02:04 +0000617 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000618 (void) UnmapBlob(map,length);
619 }
620 else
621 {
622 register size_t
623 i;
624
625 ssize_t
626 count;
627
cristy7f317702011-02-18 20:40:28 +0000628 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000629 for (i=0; i < length; i+=count)
630 {
631 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
632 SSIZE_MAX));
633 if (count <= 0)
634 {
635 count=0;
636 if (errno != EINTR)
637 break;
638 }
639 }
640 if (i < length)
641 {
642 file=close(file)-1;
643 string=DestroyString(string);
644 return((StringInfo *) NULL);
645 }
646 }
647 string[length]='\0';
648 file=close(file)-1;
649 string_info=AcquireStringInfo(0);
650 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
651 string_info->length=length;
652 string_info->datum=(unsigned char *) string;
653 return(string_info);
654}
655
656/*
657%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
658% %
659% %
660% %
661% C o n s t a n t S t r i n g %
662% %
663% %
664% %
665%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
666%
anthony104f8932012-05-13 01:54:53 +0000667% ConstantString() allocates exactly the needed memory for a string and
668% copies the source string to that memory location. A NULL string pointer
669% will allocate an empty string containing just the NUL character.
cristy3ed852e2009-09-05 21:47:34 +0000670%
anthony104f8932012-05-13 01:54:53 +0000671% When finished the string should be freed using DestoryString()
anthony06762232012-04-29 11:45:40 +0000672%
cristy3ed852e2009-09-05 21:47:34 +0000673% The format of the ConstantString method is:
674%
675% char *ConstantString(const char *source)
676%
677% A description of each parameter follows:
678%
679% o source: A character string.
680%
681*/
682MagickExport char *ConstantString(const char *source)
683{
684 char
685 *destination;
686
687 size_t
688 length;
689
690 length=0;
691 if (source != (char *) NULL)
692 length+=strlen(source);
693 destination=(char *) NULL;
694 if (~length >= 1UL)
695 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
696 if (destination == (char *) NULL)
697 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
698 *destination='\0';
699 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000700 (void) memcpy(destination,source,length*sizeof(*destination));
701 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000702 return(destination);
703}
704
705/*
706%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707% %
708% %
709% %
710% C o p y M a g i c k S t r i n g %
711% %
712% %
713% %
714%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715%
anthony06762232012-04-29 11:45:40 +0000716% CopyMagickString() copies the source string to the destination string, with
717% out exceeding the given pre-declared length.
718%
719% The destination buffer is always null-terminated even if the string must be
720% truncated. The return value is the minimum of the source string length or
721% the length parameter.
cristy3ed852e2009-09-05 21:47:34 +0000722%
723% The format of the CopyMagickString method is:
724%
725% size_t CopyMagickString(const char *destination,char *source,
726% const size_t length)
727%
728% A description of each parameter follows:
729%
730% o destination: the destination string.
731%
732% o source: the source string.
733%
734% o length: the length of the destination string.
735%
736*/
737MagickExport size_t CopyMagickString(char *destination,const char *source,
738 const size_t length)
739{
740 register char
741 *q;
742
743 register const char
744 *p;
745
746 register size_t
747 n;
748
cristy77e3fcc2011-10-11 00:04:41 +0000749 if (source == (const char *) NULL)
750 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000751 p=source;
752 q=destination;
753 for (n=length; n > 4; n-=4)
754 {
755 *q=(*p++);
756 if (*q == '\0')
757 return((size_t) (p-source-1));
758 q++;
759 *q=(*p++);
760 if (*q == '\0')
761 return((size_t) (p-source-1));
762 q++;
763 *q=(*p++);
764 if (*q == '\0')
765 return((size_t) (p-source-1));
766 q++;
767 *q=(*p++);
768 if (*q == '\0')
769 return((size_t) (p-source-1));
770 q++;
771 }
772 if (n != 0)
773 for (n--; n != 0; n--)
774 {
775 *q=(*p++);
776 if (*q == '\0')
777 return((size_t) (p-source-1));
778 q++;
779 }
780 if (length != 0)
781 *q='\0';
782 return((size_t) (p-source-1));
783}
784
785/*
786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787% %
788% %
789% %
790% D e s t r o y S t r i n g %
791% %
792% %
793% %
794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795%
796% DestroyString() destroys memory associated with a string.
797%
798% The format of the DestroyString method is:
799%
800% char *DestroyString(char *string)
801%
802% A description of each parameter follows:
803%
804% o string: the string.
805%
806*/
807MagickExport char *DestroyString(char *string)
808{
809 return((char *) RelinquishMagickMemory(string));
810}
811
812/*
813%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
814% %
815% %
816% %
817% D e s t r o y S t r i n g I n f o %
818% %
819% %
820% %
821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822%
823% DestroyStringInfo() destroys memory associated with the StringInfo structure.
824%
825% The format of the DestroyStringInfo method is:
826%
827% StringInfo *DestroyStringInfo(StringInfo *string_info)
828%
829% A description of each parameter follows:
830%
831% o string_info: the string info.
832%
833*/
834MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
835{
cristy3ed852e2009-09-05 21:47:34 +0000836 assert(string_info != (StringInfo *) NULL);
837 assert(string_info->signature == MagickSignature);
838 if (string_info->datum != (unsigned char *) NULL)
839 string_info->datum=(unsigned char *) RelinquishMagickMemory(
840 string_info->datum);
841 string_info->signature=(~MagickSignature);
842 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
843 return(string_info);
844}
845
846/*
847%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848% %
849% %
850% %
851% D e s t r o y S t r i n g L i s t %
852% %
853% %
854% %
855%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856%
857% DestroyStringList() zeros memory associated with a string list.
858%
859% The format of the DestroyStringList method is:
860%
861% char **DestroyStringList(char **list)
862%
863% A description of each parameter follows:
864%
865% o list: the string list.
866%
867*/
868MagickExport char **DestroyStringList(char **list)
869{
cristybb503372010-05-27 20:51:26 +0000870 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000871 i;
872
873 assert(list != (char **) NULL);
874 for (i=0; list[i] != (char *) NULL; i++)
875 list[i]=DestroyString(list[i]);
876 list=(char **) RelinquishMagickMemory(list);
877 return(list);
878}
879
880/*
881%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
882% %
883% %
884% %
885% E s c a p e S t r i n g %
886% %
887% %
888% %
889%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
890%
891% EscapeString() allocates memory for a backslash-escaped version of a
892% source text string, copies the escaped version of the text to that
893% memory location while adding backslash characters, and returns the
894% escaped string.
895%
896% The format of the EscapeString method is:
897%
898% char *EscapeString(const char *source,const char escape)
899%
900% A description of each parameter follows:
901%
902% o allocate_string: Method EscapeString returns the escaped string.
903%
904% o source: A character string.
905%
906% o escape: the quoted string termination character to escape (e.g. '"').
907%
908*/
909MagickExport char *EscapeString(const char *source,const char escape)
910{
911 char
912 *destination;
913
914 register char
915 *q;
916
917 register const char
918 *p;
919
920 size_t
921 length;
922
cristy3ed852e2009-09-05 21:47:34 +0000923 assert(source != (const char *) NULL);
924 length=strlen(source);
925 for (p=source; *p != '\0'; p++)
926 if ((*p == '\\') || (*p == escape))
927 {
928 if (~length < 1)
929 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
930 length++;
931 }
932 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000933 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000934 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
935 sizeof(*destination));
936 if (destination == (char *) NULL)
937 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
938 *destination='\0';
939 if (source != (char *) NULL)
940 {
941 q=destination;
942 for (p=source; *p != '\0'; p++)
943 {
944 if ((*p == '\\') || (*p == escape))
945 *q++='\\';
946 *q++=(*p);
947 }
948 *q='\0';
949 }
950 return(destination);
951}
952
953/*
954%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
955% %
956% %
957% %
958% F i l e T o S t r i n g %
959% %
960% %
961% %
962%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
963%
964% FileToString() returns the contents of a file as a string.
965%
966% The format of the FileToString method is:
967%
968% char *FileToString(const char *filename,const size_t extent,
969% ExceptionInfo *exception)
970%
971% A description of each parameter follows:
972%
973% o filename: the filename.
974%
975% o extent: Maximum length of the string.
976%
977% o exception: return any errors or warnings in this structure.
978%
979*/
980MagickExport char *FileToString(const char *filename,const size_t extent,
981 ExceptionInfo *exception)
982{
983 size_t
984 length;
985
986 assert(filename != (const char *) NULL);
987 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
988 assert(exception != (ExceptionInfo *) NULL);
989 return((char *) FileToBlob(filename,extent,&length,exception));
990}
991
992/*
993%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
994% %
995% %
996% %
997% F i l e T o S t r i n g I n f o %
998% %
999% %
1000% %
1001%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1002%
1003% FileToStringInfo() returns the contents of a file as a string.
1004%
1005% The format of the FileToStringInfo method is:
1006%
1007% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1008% ExceptionInfo *exception)
1009%
1010% A description of each parameter follows:
1011%
1012% o filename: the filename.
1013%
1014% o extent: Maximum length of the string.
1015%
1016% o exception: return any errors or warnings in this structure.
1017%
1018*/
1019MagickExport StringInfo *FileToStringInfo(const char *filename,
1020 const size_t extent,ExceptionInfo *exception)
1021{
1022 StringInfo
1023 *string_info;
1024
1025 assert(filename != (const char *) NULL);
1026 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1027 assert(exception != (ExceptionInfo *) NULL);
1028 string_info=AcquireStringInfo(0);
1029 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1030 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1031 if (string_info->datum == (unsigned char *) NULL)
1032 {
1033 string_info=DestroyStringInfo(string_info);
1034 return((StringInfo *) NULL);
1035 }
1036 return(string_info);
1037}
1038
1039/*
1040%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041% %
1042% %
1043% %
1044% F o r m a t M a g i c k S i z e %
1045% %
1046% %
1047% %
1048%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049%
1050% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +00001051% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +00001052% 1000.
cristy3ed852e2009-09-05 21:47:34 +00001053%
1054% The format of the FormatMagickSize method is:
1055%
cristybb503372010-05-27 20:51:26 +00001056% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001057%
1058% A description of each parameter follows:
1059%
1060% o size: convert this size to a human readable format.
1061%
cristyb9080c92009-12-01 20:13:26 +00001062% o bi: use power of two rather than power of ten.
1063%
cristy3ed852e2009-09-05 21:47:34 +00001064% o format: human readable format.
1065%
1066*/
cristy99bbf2c2011-09-26 18:27:50 +00001067MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001068 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001069{
cristyb9080c92009-12-01 20:13:26 +00001070 const char
1071 **units;
1072
cristy3ed852e2009-09-05 21:47:34 +00001073 double
cristyb9080c92009-12-01 20:13:26 +00001074 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001075 length;
1076
cristybb503372010-05-27 20:51:26 +00001077 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001078 i,
1079 j;
1080
cristy9d314ff2011-03-09 01:30:28 +00001081 ssize_t
1082 count;
1083
cristy3ed852e2009-09-05 21:47:34 +00001084 static const char
cristyb9080c92009-12-01 20:13:26 +00001085 *bi_units[] =
1086 {
cristy2ce15c92010-03-12 14:03:41 +00001087 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001088 },
1089 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001090 {
cristy2ce15c92010-03-12 14:03:41 +00001091 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001092 };
cristy3ed852e2009-09-05 21:47:34 +00001093
cristyb9080c92009-12-01 20:13:26 +00001094 bytes=1000.0;
1095 units=traditional_units;
1096 if (bi != MagickFalse)
1097 {
1098 bytes=1024.0;
1099 units=bi_units;
1100 }
cristy3ed852e2009-09-05 21:47:34 +00001101#if defined(_MSC_VER) && (_MSC_VER == 1200)
1102 length=(double) ((MagickOffsetType) size);
1103#else
1104 length=(double) size;
1105#endif
cristyb9080c92009-12-01 20:13:26 +00001106 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1107 length/=bytes;
cristyc3b9b362013-05-25 17:16:34 +00001108 count=0;
cristy9bf9da32009-09-27 16:48:34 +00001109 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001110 {
cristyb51dff52011-05-19 16:55:47 +00001111 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001112 units[i]);
1113 if (strchr(format,'+') == (char *) NULL)
1114 break;
1115 }
1116 return(count);
1117}
1118
1119/*
1120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121% %
1122% %
1123% %
cristy3ed852e2009-09-05 21:47:34 +00001124% F o r m a t M a g i c k T i m e %
1125% %
1126% %
1127% %
1128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1129%
1130% FormatMagickTime() returns the specified time in the Internet date/time
1131% format and the length of the timestamp.
1132%
1133% The format of the FormatMagickTime method is:
1134%
cristybb503372010-05-27 20:51:26 +00001135% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001136% char *timestamp)
1137%
1138% A description of each parameter follows.
1139%
1140% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1141% measured in seconds.
1142%
1143% o length: the maximum length of the string.
1144%
1145% o timestamp: Return the Internet date/time here.
1146%
1147*/
cristybb503372010-05-27 20:51:26 +00001148MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001149 char *timestamp)
1150{
cristybb503372010-05-27 20:51:26 +00001151 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001152 count;
1153
1154 struct tm
1155 gm_time,
1156 local_time;
1157
1158 time_t
1159 timezone;
1160
1161 assert(timestamp != (char *) NULL);
1162 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1163 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1164#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1165 (void) localtime_r(&time,&local_time);
1166#else
1167 {
cristybc3392a2009-10-06 03:15:57 +00001168 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001169 *my_time;
1170
1171 my_time=localtime(&time);
1172 if (my_time != (struct tm *) NULL)
1173 (void) memcpy(&local_time,my_time,sizeof(local_time));
1174 }
1175#endif
1176#if defined(MAGICKCORE_HAVE_GMTIME_R)
1177 (void) gmtime_r(&time,&gm_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=gmtime(&time);
1184 if (my_time != (struct tm *) NULL)
1185 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1186 }
1187#endif
1188 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1189 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1190 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1191 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001192 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001193 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1194 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001195 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001196 return(count);
1197}
1198
1199/*
1200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1201% %
1202% %
1203% %
1204% G e t E n v i r o n m e n t V a l u e %
1205% %
1206% %
1207% %
1208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1209%
1210% GetEnvironmentValue() returns the environment string that matches the
1211% specified name.
1212%
1213% The format of the GetEnvironmentValue method is:
1214%
1215% char *GetEnvironmentValue(const char *name)
1216%
1217% A description of each parameter follows:
1218%
1219% o name: the environment name.
1220%
1221*/
cristy99bbf2c2011-09-26 18:27:50 +00001222MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001223{
1224 const char
1225 *environment;
1226
1227 environment=getenv(name);
1228 if (environment == (const char *) NULL)
1229 return((char *) NULL);
1230 return(ConstantString(environment));
1231}
1232
1233/*
1234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1235% %
1236% %
1237% %
1238% G e t S t r i n g I n f o D a t u m %
1239% %
1240% %
1241% %
1242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1243%
1244% GetStringInfoDatum() returns the datum associated with the string.
1245%
1246% The format of the GetStringInfoDatum method is:
1247%
1248% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1249%
1250% A description of each parameter follows:
1251%
1252% o string_info: the string info.
1253%
1254*/
1255MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1256{
1257 assert(string_info != (StringInfo *) NULL);
1258 assert(string_info->signature == MagickSignature);
1259 return(string_info->datum);
1260}
1261
1262/*
1263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264% %
1265% %
1266% %
1267% G e t S t r i n g I n f o L e n g t h %
1268% %
1269% %
1270% %
1271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272%
1273% GetStringInfoLength() returns the string length.
1274%
1275% The format of the GetStringInfoLength method is:
1276%
1277% size_t GetStringInfoLength(const StringInfo *string_info)
1278%
1279% A description of each parameter follows:
1280%
1281% o string_info: the string info.
1282%
1283*/
1284MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1285{
1286 assert(string_info != (StringInfo *) NULL);
1287 assert(string_info->signature == MagickSignature);
1288 return(string_info->length);
1289}
1290
1291/*
1292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293% %
1294% %
1295% %
1296% G e t S t r i n g I n f o P a t h %
1297% %
1298% %
1299% %
1300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301%
1302% GetStringInfoPath() returns the path associated with the string.
1303%
1304% The format of the GetStringInfoPath method is:
1305%
1306% const char *GetStringInfoPath(const StringInfo *string_info)
1307%
1308% A description of each parameter follows:
1309%
1310% o string_info: the string info.
1311%
1312*/
1313MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1314{
1315 assert(string_info != (StringInfo *) NULL);
1316 assert(string_info->signature == MagickSignature);
1317 return(string_info->path);
1318}
1319
1320/*
1321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1322% %
1323% %
1324% %
cristydbdd0e32011-11-04 23:29:40 +00001325+ I n t e r p r e t S i P r e f i x V a l u e %
1326% %
1327% %
1328% %
1329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1330%
1331% InterpretSiPrefixValue() converts the initial portion of the string to a
1332% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1333% etc.).
1334%
1335% The format of the InterpretSiPrefixValue method is:
1336%
1337% double InterpretSiPrefixValue(const char *value,char **sentinal)
1338%
1339% A description of each parameter follows:
1340%
1341% o value: the string value.
1342%
1343% o sentinal: if sentinal is not NULL, return a pointer to the character
1344% after the last character used in the conversion.
1345%
1346*/
1347MagickExport double InterpretSiPrefixValue(const char *restrict string,
1348 char **restrict sentinal)
1349{
1350 char
1351 *q;
1352
1353 double
1354 value;
1355
cristydbdd0e32011-11-04 23:29:40 +00001356 value=InterpretLocaleValue(string,&q);
1357 if (q != string)
1358 {
1359 if ((*q >= 'E') && (*q <= 'z'))
1360 {
1361 double
1362 e;
1363
cristy0c2684f2011-11-05 21:39:43 +00001364 switch ((int) ((unsigned char) *q))
1365 {
1366 case 'y': e=(-24.0); break;
1367 case 'z': e=(-21.0); break;
1368 case 'a': e=(-18.0); break;
1369 case 'f': e=(-15.0); break;
1370 case 'p': e=(-12.0); break;
1371 case 'n': e=(-9.0); break;
1372 case 'u': e=(-6.0); break;
1373 case 'm': e=(-3.0); break;
1374 case 'c': e=(-2.0); break;
1375 case 'd': e=(-1.0); break;
1376 case 'h': e=2.0; break;
1377 case 'k': e=3.0; break;
1378 case 'K': e=3.0; break;
1379 case 'M': e=6.0; break;
1380 case 'G': e=9.0; break;
1381 case 'T': e=12.0; break;
1382 case 'P': e=15.0; break;
1383 case 'E': e=18.0; break;
1384 case 'Z': e=21.0; break;
1385 case 'Y': e=24.0; break;
1386 default: e=0.0; break;
1387 }
cristydbdd0e32011-11-04 23:29:40 +00001388 if (e >= MagickEpsilon)
1389 {
1390 if (q[1] == 'i')
1391 {
1392 value*=pow(2.0,e/0.3);
1393 q+=2;
1394 }
1395 else
1396 {
1397 value*=pow(10.0,e);
1398 q++;
1399 }
1400 }
1401 }
cristyc0f1ed12011-11-09 14:50:15 +00001402 if (*q == 'B')
cristy099a7352011-11-09 14:31:35 +00001403 q++;
cristydbdd0e32011-11-04 23:29:40 +00001404 }
1405 if (sentinal != (char **) NULL)
1406 *sentinal=q;
1407 return(value);
1408}
1409
1410/*
1411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1412% %
1413% %
1414% %
anthony6f201312012-03-30 04:08:15 +00001415% I s S t r i n g T r u e %
1416% %
1417% %
1418% %
1419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1420%
1421% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1422% "1". Any other string or undefined returns MagickFalse.
1423%
1424% Typically this is used to look at strings (options or artifacts) which
1425% has a default value of "false", when not defined.
1426%
1427% The format of the IsStringTrue method is:
1428%
1429% MagickBooleanType IsStringTrue(const char *value)
1430%
1431% A description of each parameter follows:
1432%
1433% o value: Specifies a pointer to a character array.
1434%
1435*/
1436MagickExport MagickBooleanType IsStringTrue(const char *value)
1437{
1438 if (value == (const char *) NULL)
1439 return(MagickFalse);
1440 if (LocaleCompare(value,"true") == 0)
1441 return(MagickTrue);
1442 if (LocaleCompare(value,"on") == 0)
1443 return(MagickTrue);
1444 if (LocaleCompare(value,"yes") == 0)
1445 return(MagickTrue);
1446 if (LocaleCompare(value,"1") == 0)
1447 return(MagickTrue);
1448 return(MagickFalse);
1449}
1450
1451/*
1452%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453% %
1454% %
1455% %
1456% I s S t r i n g N o t F a l s e %
1457% %
1458% %
1459% %
1460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1461%
1462% IsStringNotFalse() returns MagickTrue, unless the string specifically
1463% has a value that makes this false. that is if it has a value of
1464% "false", "off", "no" or "0".
1465%
1466% Typically this is used to look at strings (options or artifacts) which
1467% has a default value of "true", when it has not been defined.
1468%
1469% The format of the IsStringNotFalse method is:
1470%
1471% MagickBooleanType IsStringNotFalse(const char *value)
1472%
1473% A description of each parameter follows:
1474%
1475% o value: Specifies a pointer to a character array.
1476%
1477*/
1478MagickExport MagickBooleanType IsStringNotFalse(const char *value)
1479{
1480 if (value == (const char *) NULL)
1481 return(MagickTrue);
1482 if (LocaleCompare(value,"false") == 0)
1483 return(MagickFalse);
1484 if (LocaleCompare(value,"off") == 0)
1485 return(MagickFalse);
1486 if (LocaleCompare(value,"no") == 0)
1487 return(MagickFalse);
1488 if (LocaleCompare(value,"0") == 0)
1489 return(MagickFalse);
1490 return(MagickTrue);
1491}
1492
1493/*
1494%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1495% %
1496% %
1497% %
cristy3ed852e2009-09-05 21:47:34 +00001498% L o c a l e C o m p a r e %
1499% %
1500% %
1501% %
1502%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1503%
1504% LocaleCompare() performs a case-insensitive comparison of two strings
1505% byte-by-byte, according to the ordering of the current locale encoding.
1506% LocaleCompare returns an integer greater than, equal to, or less than 0,
1507% if the string pointed to by p is greater than, equal to, or less than the
1508% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001509% is determined by the sign of the difference between the values of the first
1510% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001511%
1512% The format of the LocaleCompare method is:
1513%
cristyde58b412010-02-18 03:53:40 +00001514% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001515%
1516% A description of each parameter follows:
1517%
1518% o p: A pointer to a character string.
1519%
1520% o q: A pointer to a character string to compare to p.
1521%
1522*/
cristyde58b412010-02-18 03:53:40 +00001523MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001524{
1525 if ((p == (char *) NULL) && (q == (char *) NULL))
1526 return(0);
1527 if (p == (char *) NULL)
1528 return(-1);
1529 if (q == (char *) NULL)
1530 return(1);
1531#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001532 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001533#else
1534 {
cristyde58b412010-02-18 03:53:40 +00001535 register int
cristy3ed852e2009-09-05 21:47:34 +00001536 c,
cristya72c2d12010-02-18 01:20:28 +00001537 d;
cristy3ed852e2009-09-05 21:47:34 +00001538
cristya72c2d12010-02-18 01:20:28 +00001539 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001540 {
cristyde58b412010-02-18 03:53:40 +00001541 c=(int) *((unsigned char *) p);
1542 d=(int) *((unsigned char *) q);
1543 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001544 break;
cristya72c2d12010-02-18 01:20:28 +00001545 p++;
1546 q++;
cristy3ed852e2009-09-05 21:47:34 +00001547 }
cristyde58b412010-02-18 03:53:40 +00001548 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001549 }
1550#endif
1551}
1552
1553/*
1554%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1555% %
1556% %
1557% %
1558% L o c a l e L o w e r %
1559% %
1560% %
1561% %
1562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1563%
1564% LocaleLower() transforms all of the characters in the supplied
1565% null-terminated string, changing all uppercase letters to lowercase.
1566%
1567% The format of the LocaleLower method is:
1568%
1569% void LocaleLower(char *string)
1570%
1571% A description of each parameter follows:
1572%
1573% o string: A pointer to the string to convert to lower-case Locale.
1574%
1575*/
1576MagickExport void LocaleLower(char *string)
1577{
1578 register char
1579 *q;
1580
1581 assert(string != (char *) NULL);
1582 for (q=string; *q != '\0'; q++)
1583 *q=(char) tolower((int) *q);
1584}
1585
1586/*
1587%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1588% %
1589% %
1590% %
1591% L o c a l e N C o m p a r e %
1592% %
1593% %
1594% %
1595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596%
anthony06762232012-04-29 11:45:40 +00001597% LocaleNCompare() performs a case-insensitive comparison of two strings
1598% byte-by-byte, according to the ordering of the current locale encoding.
1599%
1600% LocaleNCompare returns an integer greater than, equal to, or less than 0,
1601% if the string pointed to by p is greater than, equal to, or less than the
1602% string pointed to by q respectively. The sign of a non-zero return value
1603% is determined by the sign of the difference between the values of the first
1604% pair of bytes that differ in the strings being compared.
1605%
1606% The LocaleNCompare method makes the same comparison as LocaleCompare but
1607% looks at a maximum of n bytes. Bytes following a null byte are not
1608% compared.
cristy3ed852e2009-09-05 21:47:34 +00001609%
1610% The format of the LocaleNCompare method is:
1611%
cristyde58b412010-02-18 03:53:40 +00001612% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001613%
1614% A description of each parameter follows:
1615%
1616% o p: A pointer to a character string.
1617%
1618% o q: A pointer to a character string to compare to p.
1619%
cristy7a40ba82011-01-08 20:31:18 +00001620% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001621%
1622*/
cristyde58b412010-02-18 03:53:40 +00001623MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001624{
cristy78c21692011-10-06 14:57:26 +00001625 if ((p == (char *) NULL) && (q == (char *) NULL))
1626 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001627 if (p == (char *) NULL)
1628 return(-1);
1629 if (q == (char *) NULL)
1630 return(1);
1631#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001632 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001633#else
1634 {
cristyde58b412010-02-18 03:53:40 +00001635 register int
cristy3ed852e2009-09-05 21:47:34 +00001636 c,
1637 d;
1638
cristyb6af4a52009-10-06 13:56:23 +00001639 register size_t
cristyc4cded12010-02-18 14:40:57 +00001640 i;
cristyb6af4a52009-10-06 13:56:23 +00001641
cristyc4cded12010-02-18 14:40:57 +00001642 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001643 {
cristyde58b412010-02-18 03:53:40 +00001644 c=(int) *((unsigned char *) p);
1645 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001646 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001647 return(AsciiMap[c]-(int) AsciiMap[d]);
1648 if (c == 0)
1649 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001650 p++;
1651 q++;
1652 }
cristyde58b412010-02-18 03:53:40 +00001653 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001654 }
1655#endif
1656}
1657
1658/*
1659%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1660% %
1661% %
1662% %
1663% L o c a l e U p p e r %
1664% %
1665% %
1666% %
1667%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1668%
1669% LocaleUpper() transforms all of the characters in the supplied
1670% null-terminated string, changing all lowercase letters to uppercase.
1671%
1672% The format of the LocaleUpper method is:
1673%
1674% void LocaleUpper(char *string)
1675%
1676% A description of each parameter follows:
1677%
1678% o string: A pointer to the string to convert to upper-case Locale.
1679%
1680*/
1681MagickExport void LocaleUpper(char *string)
1682{
1683 register char
1684 *q;
1685
1686 assert(string != (char *) NULL);
1687 for (q=string; *q != '\0'; q++)
1688 *q=(char) toupper((int) *q);
1689}
1690
1691/*
1692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693% %
1694% %
1695% %
1696% P r i n t S t r i n g I n f o %
1697% %
1698% %
1699% %
1700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1701%
1702% PrintStringInfo() prints the string.
1703%
1704% The format of the PrintStringInfo method is:
1705%
1706% void PrintStringInfo(FILE *file,const char *id,
1707% const StringInfo *string_info)
1708%
1709% A description of each parameter follows:
1710%
1711% o file: the file, typically stdout.
1712%
1713% o id: the string id.
1714%
1715% o string_info: the string info.
1716%
1717*/
1718MagickExport void PrintStringInfo(FILE *file,const char *id,
1719 const StringInfo *string_info)
1720{
1721 register const char
1722 *p;
1723
1724 register size_t
1725 i,
1726 j;
1727
1728 assert(id != (const char *) NULL);
cristy3ed852e2009-09-05 21:47:34 +00001729 assert(string_info != (StringInfo *) NULL);
1730 assert(string_info->signature == MagickSignature);
1731 p=(char *) string_info->datum;
1732 for (i=0; i < string_info->length; i++)
1733 {
1734 if (((int) ((unsigned char) *p) < 32) &&
1735 (isspace((int) ((unsigned char) *p)) == 0))
1736 break;
1737 p++;
1738 }
cristy2d8723c2013-11-14 16:41:27 +00001739 (void) FormatLocaleFile(file,"%s(%.20g): ",id,(double) string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001740 if (i == string_info->length)
1741 {
cristy53ea28b2012-06-10 22:11:59 +00001742 for (i=0; i < string_info->length; i++)
1743 (void) fputc(string_info->datum[i],file);
cristy3ed852e2009-09-05 21:47:34 +00001744 (void) fputc('\n',file);
1745 return;
1746 }
1747 /*
1748 Convert string to a HEX list.
1749 */
1750 p=(char *) string_info->datum;
1751 for (i=0; i < string_info->length; i+=0x14)
1752 {
cristyb51dff52011-05-19 16:55:47 +00001753 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001754 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1755 {
cristyb51dff52011-05-19 16:55:47 +00001756 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001757 if ((j % 0x04) == 0)
1758 (void) fputc(' ',file);
1759 }
1760 for ( ; j <= 0x14; j++)
1761 {
1762 (void) fputc(' ',file);
1763 (void) fputc(' ',file);
1764 if ((j % 0x04) == 0)
1765 (void) fputc(' ',file);
1766 }
1767 (void) fputc(' ',file);
1768 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1769 {
1770 if (isprint((int) ((unsigned char) *p)) != 0)
1771 (void) fputc(*p,file);
1772 else
1773 (void) fputc('-',file);
1774 p++;
1775 }
1776 (void) fputc('\n',file);
1777 }
1778}
1779
1780/*
1781%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1782% %
1783% %
1784% %
1785% R e s e t S t r i n g I n f o %
1786% %
1787% %
1788% %
1789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1790%
1791% ResetStringInfo() reset the string to all null bytes.
1792%
1793% The format of the ResetStringInfo method is:
1794%
1795% void ResetStringInfo(StringInfo *string_info)
1796%
1797% A description of each parameter follows:
1798%
1799% o string_info: the string info.
1800%
1801*/
1802MagickExport void ResetStringInfo(StringInfo *string_info)
1803{
cristy3ed852e2009-09-05 21:47:34 +00001804 assert(string_info != (StringInfo *) NULL);
1805 assert(string_info->signature == MagickSignature);
1806 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1807}
1808
1809/*
1810%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1811% %
1812% %
1813% %
1814% S e t S t r i n g I n f o %
1815% %
1816% %
1817% %
1818%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1819%
1820% SetStringInfo() copies the source string to the destination string.
1821%
1822% The format of the SetStringInfo method is:
1823%
1824% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1825%
1826% A description of each parameter follows:
1827%
1828% o string_info: the string info.
1829%
1830% o source: the source string.
1831%
1832*/
1833MagickExport void SetStringInfo(StringInfo *string_info,
1834 const StringInfo *source)
1835{
cristy3ed852e2009-09-05 21:47:34 +00001836 assert(string_info != (StringInfo *) NULL);
1837 assert(string_info->signature == MagickSignature);
1838 assert(source != (StringInfo *) NULL);
1839 assert(source->signature == MagickSignature);
1840 if (string_info->length == 0)
1841 return;
1842 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001843 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1844 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001845}
1846
1847/*
1848%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1849% %
1850% %
1851% %
1852% S e t S t r i n g I n f o D a t u m %
1853% %
1854% %
1855% %
1856%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1857%
1858% SetStringInfoDatum() copies bytes from the source string for the length of
1859% the destination string.
1860%
1861% The format of the SetStringInfoDatum method is:
1862%
1863% void SetStringInfoDatum(StringInfo *string_info,
1864% const unsigned char *source)
1865%
1866% A description of each parameter follows:
1867%
1868% o string_info: the string info.
1869%
1870% o source: the source string.
1871%
1872*/
1873MagickExport void SetStringInfoDatum(StringInfo *string_info,
1874 const unsigned char *source)
1875{
cristy3ed852e2009-09-05 21:47:34 +00001876 assert(string_info != (StringInfo *) NULL);
1877 assert(string_info->signature == MagickSignature);
1878 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001879 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001880}
1881
1882/*
1883%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1884% %
1885% %
1886% %
1887% S e t S t r i n g I n f o L e n g t h %
1888% %
1889% %
1890% %
1891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1892%
1893% SetStringInfoLength() set the string length to the specified value.
1894%
1895% The format of the SetStringInfoLength method is:
1896%
1897% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1898%
1899% A description of each parameter follows:
1900%
1901% o string_info: the string info.
1902%
1903% o length: the string length.
1904%
1905*/
1906MagickExport void SetStringInfoLength(StringInfo *string_info,
1907 const size_t length)
1908{
cristy3ed852e2009-09-05 21:47:34 +00001909 assert(string_info != (StringInfo *) NULL);
1910 assert(string_info->signature == MagickSignature);
1911 if (~length < MaxTextExtent)
1912 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1913 string_info->length=length;
1914 if (string_info->datum == (unsigned char *) NULL)
1915 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1916 MaxTextExtent,sizeof(*string_info->datum));
1917 else
1918 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1919 length+MaxTextExtent,sizeof(*string_info->datum));
1920 if (string_info->datum == (unsigned char *) NULL)
1921 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1922}
1923
1924/*
1925%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1926% %
1927% %
1928% %
1929% S e t S t r i n g I n f o D a t u m %
1930% %
1931% %
1932% %
1933%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1934%
1935% SetStringInfoPath() sets the path associated with the string.
1936%
1937% The format of the SetStringInfoPath method is:
1938%
1939% void SetStringInfoPath(StringInfo *string_info,const char *path)
1940%
1941% A description of each parameter follows:
1942%
1943% o string_info: the string info.
1944%
1945% o path: the path.
1946%
1947*/
1948MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1949{
cristy3ed852e2009-09-05 21:47:34 +00001950 assert(string_info != (StringInfo *) NULL);
1951 assert(string_info->signature == MagickSignature);
1952 assert(path != (const char *) NULL);
1953 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1954}
1955
1956/*
1957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1958% %
1959% %
1960% %
1961% S p l i t S t r i n g I n f o %
1962% %
1963% %
1964% %
1965%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1966%
1967% SplitStringInfo() splits a string into two and returns it.
1968%
1969% The format of the SplitStringInfo method is:
1970%
1971% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1972%
1973% A description of each parameter follows:
1974%
1975% o string_info: the string info.
1976%
1977*/
1978MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1979 const size_t offset)
1980{
1981 StringInfo
1982 *split_info;
1983
cristy3ed852e2009-09-05 21:47:34 +00001984 assert(string_info != (StringInfo *) NULL);
1985 assert(string_info->signature == MagickSignature);
1986 if (offset > string_info->length)
1987 return((StringInfo *) NULL);
1988 split_info=AcquireStringInfo(offset);
1989 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00001990 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00001991 string_info->length-offset+MaxTextExtent);
1992 SetStringInfoLength(string_info,string_info->length-offset);
1993 return(split_info);
1994}
1995
1996/*
1997%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1998% %
1999% %
2000% %
2001% S t r i n g I n f o T o S t r i n g %
2002% %
2003% %
2004% %
2005%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2006%
2007% StringInfoToString() converts a string info string to a C string.
2008%
2009% The format of the StringInfoToString method is:
2010%
2011% char *StringInfoToString(const StringInfo *string_info)
2012%
2013% A description of each parameter follows:
2014%
2015% o string_info: the string.
2016%
2017*/
2018MagickExport char *StringInfoToString(const StringInfo *string_info)
2019{
2020 char
2021 *string;
2022
2023 size_t
2024 length;
2025
2026 string=(char *) NULL;
2027 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00002028 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002029 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002030 if (string == (char *) NULL)
2031 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00002032 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002033 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002034 return(string);
2035}
2036
2037/*
2038%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2039% %
2040% %
2041% %
anthonyb1d483a2012-04-14 12:53:56 +00002042% S t r i n g I n f o T o H e x S t r i n g %
2043% %
2044% %
2045% %
2046%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2047%
2048% StringInfoToHexString() converts a string info string to a C string.
2049%
2050% The format of the StringInfoToHexString method is:
2051%
2052% char *StringInfoToHexString(const StringInfo *string_info)
2053%
2054% A description of each parameter follows:
2055%
2056% o string_info: the string.
2057%
2058*/
2059MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2060{
2061 char
2062 *string;
2063
2064 register const unsigned char
2065 *p;
2066
2067 register ssize_t
2068 i;
2069
2070 register unsigned char
2071 *q;
2072
2073 size_t
2074 length;
2075
2076 unsigned char
2077 hex_digits[16];
2078
2079 length=string_info->length;
2080 if (~length < MaxTextExtent)
2081 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2082 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2083 if (string == (char *) NULL)
2084 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2085 hex_digits[0]='0';
2086 hex_digits[1]='1';
2087 hex_digits[2]='2';
2088 hex_digits[3]='3';
2089 hex_digits[4]='4';
2090 hex_digits[5]='5';
2091 hex_digits[6]='6';
2092 hex_digits[7]='7';
2093 hex_digits[8]='8';
2094 hex_digits[9]='9';
2095 hex_digits[10]='a';
2096 hex_digits[11]='b';
2097 hex_digits[12]='c';
2098 hex_digits[13]='d';
2099 hex_digits[14]='e';
2100 hex_digits[15]='f';
2101 p=string_info->datum;
2102 q=(unsigned char *) string;
2103 for (i=0; i < (ssize_t) string_info->length; i++)
2104 {
2105 *q++=hex_digits[(*p >> 4) & 0x0f];
2106 *q++=hex_digits[*p & 0x0f];
2107 p++;
2108 }
2109 *q='\0';
2110 return(string);
2111}
2112
2113/*
2114%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2115% %
2116% %
2117% %
cristy3ed852e2009-09-05 21:47:34 +00002118% S t r i n g T o A r g v %
2119% %
2120% %
2121% %
2122%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2123%
2124% StringToArgv() converts a text string into command line arguments.
anthony31f1bf72012-01-30 12:37:22 +00002125% The 'argv' array of arguments, is returned while the number of arguments
2126% is returned via the provided integer variable pointer.
2127%
2128% Simple 'word' tokenizer, which allows for each word to be optionally
2129% quoted. However it will not allow use of partial quotes, or escape
2130% characters.
cristy3ed852e2009-09-05 21:47:34 +00002131%
2132% The format of the StringToArgv method is:
2133%
2134% char **StringToArgv(const char *text,int *argc)
2135%
2136% A description of each parameter follows:
2137%
2138% o argv: Method StringToArgv returns the string list unless an error
2139% occurs, otherwise NULL.
2140%
2141% o text: Specifies the string to segment into a list.
2142%
2143% o argc: This integer pointer returns the number of arguments in the
2144% list.
2145%
2146*/
2147MagickExport char **StringToArgv(const char *text,int *argc)
2148{
2149 char
2150 **argv;
2151
2152 register const char
2153 *p,
2154 *q;
2155
cristybb503372010-05-27 20:51:26 +00002156 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002157 i;
2158
2159 *argc=0;
2160 if (text == (char *) NULL)
2161 return((char **) NULL);
2162 /*
2163 Determine the number of arguments.
2164 */
2165 for (p=text; *p != '\0'; )
2166 {
2167 while (isspace((int) ((unsigned char) *p)) != 0)
2168 p++;
cristya20c9042011-05-19 13:22:18 +00002169 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00002170 break;
cristy3ed852e2009-09-05 21:47:34 +00002171 (*argc)++;
2172 if (*p == '"')
2173 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2174 if (*p == '\'')
2175 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2176 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2177 p++;
2178 }
2179 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002180 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002181 if (argv == (char **) NULL)
2182 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2183 /*
2184 Convert string to an ASCII list.
2185 */
2186 argv[0]=AcquireString("magick");
2187 p=text;
cristybb503372010-05-27 20:51:26 +00002188 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002189 {
2190 while (isspace((int) ((unsigned char) *p)) != 0)
2191 p++;
2192 q=p;
2193 if (*q == '"')
2194 {
2195 p++;
2196 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2197 }
2198 else
2199 if (*q == '\'')
2200 {
cristy06b15f42011-01-22 21:36:24 +00002201 p++;
cristy3ed852e2009-09-05 21:47:34 +00002202 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002203 }
2204 else
2205 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2206 q++;
2207 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2208 sizeof(**argv));
2209 if (argv[i] == (char *) NULL)
2210 {
2211 for (i--; i >= 0; i--)
2212 argv[i]=DestroyString(argv[i]);
2213 argv=(char **) RelinquishMagickMemory(argv);
2214 ThrowFatalException(ResourceLimitFatalError,
2215 "UnableToConvertStringToARGV");
2216 }
cristy54aad5e2010-09-03 16:02:04 +00002217 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002218 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002219 p=q;
2220 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2221 p++;
2222 }
2223 argv[i]=(char *) NULL;
2224 return(argv);
2225}
2226
2227/*
2228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2229% %
2230% %
2231% %
anthonyb1d483a2012-04-14 12:53:56 +00002232% 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 +00002233% %
2234% %
2235% %
2236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2237%
glennrp6ab82382013-10-28 13:54:30 +00002238% StringToArrayOfDoubles() converts a string of space or comma separated
anthonyb1d483a2012-04-14 12:53:56 +00002239% numbers into array of floating point numbers (doubles). Any number that
2240% failes to parse properly will produce a syntax error. As will two commas
2241% without a number between them. However a final comma at the end will
2242% not be regarded as an error so as to simplify automatic list generation.
cristy3ed852e2009-09-05 21:47:34 +00002243%
anthonyb1d483a2012-04-14 12:53:56 +00002244% A NULL value is returned on syntax or memory errors.
cristy3ed852e2009-09-05 21:47:34 +00002245%
anthonyb1d483a2012-04-14 12:53:56 +00002246% Use RelinquishMagickMemory() to free returned array when finished.
2247%
2248% The format of the StringToArrayOfDoubles method is:
2249%
cristy8f52b3f2013-11-09 02:28:05 +00002250% double *StringToArrayOfDoubles(const char *string,size_t *count)
cristy3ed852e2009-09-05 21:47:34 +00002251%
2252% A description of each parameter follows:
2253%
glennrp6ab82382013-10-28 13:54:30 +00002254% o string: the string containing the comma/space separated values.
anthonyb1d483a2012-04-14 12:53:56 +00002255%
2256% o count: returns number of arguments in returned array
2257%
cristy52085732013-11-09 02:32:27 +00002258% o exception: return any errors or warnings in this structure.
2259%
cristy3ed852e2009-09-05 21:47:34 +00002260*/
cristy52085732013-11-09 02:32:27 +00002261MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2262 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002263{
anthonyb1d483a2012-04-14 12:53:56 +00002264 char
2265 *q;
2266
cristy0a887dc2012-08-15 22:58:36 +00002267 const char
2268 *p;
2269
anthonyb1d483a2012-04-14 12:53:56 +00002270 double
2271 *array;
2272
cristybb503372010-05-27 20:51:26 +00002273 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002274 i;
2275
cristy0a887dc2012-08-15 22:58:36 +00002276 /*
2277 Determine count of values, and check syntax.
2278 */
cristyb0de93f2013-05-03 13:39:25 +00002279 assert(exception != (ExceptionInfo *) NULL);
2280 assert(exception->signature == MagickSignature);
anthonyb1d483a2012-04-14 12:53:56 +00002281 *count=0;
anthonyb1d483a2012-04-14 12:53:56 +00002282 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002283 p=string;
2284 while (*p != '\0')
cristy3ed852e2009-09-05 21:47:34 +00002285 {
cristy0a887dc2012-08-15 22:58:36 +00002286 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2287 if (p == q)
2288 return((double *) NULL); /* no value found */
2289 p=q;
2290 i++; /* increment value count */
2291 while (isspace((int) ((unsigned char) *p)) != 0)
2292 p++; /* skip spaces */
2293 if (*p == ',')
2294 p++; /* skip comma */
2295 while (isspace((int) ((unsigned char) *p)) != 0)
2296 p++; /* and more spaces */
cristy3ed852e2009-09-05 21:47:34 +00002297 }
cristy0a887dc2012-08-15 22:58:36 +00002298 /*
2299 Allocate floating point argument list.
2300 */
anthonyb1d483a2012-04-14 12:53:56 +00002301 *count=i;
cristy0a887dc2012-08-15 22:58:36 +00002302 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2303 if (array == (double *) NULL)
cristy70ca0222013-11-09 02:34:16 +00002304 {
2305 (void) ThrowMagickException(exception,GetMagickModule(),
2306 ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2307 return((double *) NULL);
2308 }
cristy0a887dc2012-08-15 22:58:36 +00002309 /*
2310 Fill in the floating point values.
2311 */
anthonyb1d483a2012-04-14 12:53:56 +00002312 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002313 p=string;
2314 while ((*p != '\0') && (i < *count))
2315 {
anthonyb1d483a2012-04-14 12:53:56 +00002316 array[i++]=StringToDouble(p,&q);
2317 p=q;
cristy0a887dc2012-08-15 22:58:36 +00002318 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2319 p++;
anthonyb1d483a2012-04-14 12:53:56 +00002320 }
anthonyb1d483a2012-04-14 12:53:56 +00002321 return(array);
cristy3ed852e2009-09-05 21:47:34 +00002322}
2323
2324/*
2325%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2326% %
2327% %
2328% %
anthonyb1d483a2012-04-14 12:53:56 +00002329+ S t r i n g T o k e n %
cristy3ed852e2009-09-05 21:47:34 +00002330% %
2331% %
2332% %
2333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2334%
anthonyb1d483a2012-04-14 12:53:56 +00002335% StringToken() Looks for any one of given delimiters and splits the string
2336% into two separate strings by replacing the delimiter character found with a
2337% nul character.
2338%
2339% The given string pointer is changed to point to the string following the
2340% delimiter character found, or NULL. A pointer to the start of the
2341% string is returned, representing the token before the delimiter.
2342%
2343% In may ways this is equivent to the strtok() C library function, but with
2344% multiple delimiter characters rather than a delimiter string.
cristy3ed852e2009-09-05 21:47:34 +00002345%
2346% The format of the StringToken method is:
2347%
2348% char *StringToken(const char *delimiters,char **string)
2349%
2350% A description of each parameter follows:
2351%
2352% o delimiters: one or more delimiters.
2353%
2354% o string: return the first token in the string. If none is found, return
2355% NULL.
2356%
2357*/
2358MagickExport char *StringToken(const char *delimiters,char **string)
2359{
2360 char
2361 *q;
2362
2363 register char
2364 *p;
2365
2366 register const char
2367 *r;
2368
2369 register int
2370 c,
2371 d;
2372
2373 p=(*string);
2374 if (p == (char *) NULL)
2375 return((char *) NULL);
anthonyb1d483a2012-04-14 12:53:56 +00002376 q=p;
2377 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00002378 {
2379 c=(*p++);
2380 r=delimiters;
2381 do
2382 {
2383 d=(*r++);
2384 if (c == d)
2385 {
2386 if (c == '\0')
2387 p=(char *) NULL;
2388 else
2389 p[-1]='\0';
2390 *string=p;
2391 return(q);
2392 }
2393 } while (d != '\0');
2394 }
2395}
2396
2397/*
2398%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2399% %
2400% %
2401% %
2402% S t r i n g T o L i s t %
2403% %
2404% %
2405% %
2406%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2407%
2408% StringToList() converts a text string into a list by segmenting the text
2409% string at each carriage return discovered. The list is converted to HEX
2410% characters if any control characters are discovered within the text string.
2411%
2412% The format of the StringToList method is:
2413%
2414% char **StringToList(const char *text)
2415%
2416% A description of each parameter follows:
2417%
cristy3ed852e2009-09-05 21:47:34 +00002418% o text: Specifies the string to segment into a list.
2419%
2420*/
2421MagickExport char **StringToList(const char *text)
2422{
2423 char
2424 **textlist;
2425
2426 register const char
2427 *p;
2428
cristybb503372010-05-27 20:51:26 +00002429 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002430 i;
2431
cristybb503372010-05-27 20:51:26 +00002432 size_t
cristy3ed852e2009-09-05 21:47:34 +00002433 lines;
2434
2435 if (text == (char *) NULL)
2436 return((char **) NULL);
2437 for (p=text; *p != '\0'; p++)
2438 if (((int) ((unsigned char) *p) < 32) &&
2439 (isspace((int) ((unsigned char) *p)) == 0))
2440 break;
2441 if (*p == '\0')
2442 {
2443 register const char
2444 *q;
2445
2446 /*
2447 Convert string to an ASCII list.
2448 */
2449 lines=1;
2450 for (p=text; *p != '\0'; p++)
2451 if (*p == '\n')
2452 lines++;
2453 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2454 sizeof(*textlist));
2455 if (textlist == (char **) NULL)
2456 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2457 p=text;
cristybb503372010-05-27 20:51:26 +00002458 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002459 {
2460 for (q=p; *q != '\0'; q++)
2461 if ((*q == '\r') || (*q == '\n'))
2462 break;
2463 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002464 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002465 if (textlist[i] == (char *) NULL)
2466 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002467 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002468 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002469 if (*q == '\r')
2470 q++;
2471 p=q+1;
2472 }
2473 }
2474 else
2475 {
2476 char
2477 hex_string[MaxTextExtent];
2478
2479 register char
2480 *q;
2481
cristybb503372010-05-27 20:51:26 +00002482 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002483 j;
2484
2485 /*
2486 Convert string to a HEX list.
2487 */
cristybb503372010-05-27 20:51:26 +00002488 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002489 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2490 sizeof(*textlist));
2491 if (textlist == (char **) NULL)
2492 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2493 p=text;
cristybb503372010-05-27 20:51:26 +00002494 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002495 {
2496 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002497 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002498 if (textlist[i] == (char *) NULL)
2499 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002500 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002501 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002502 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002503 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002504 {
cristyb51dff52011-05-19 16:55:47 +00002505 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002506 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2507 q+=2;
2508 if ((j % 0x04) == 0)
2509 *q++=' ';
2510 }
2511 for ( ; j <= 0x14; j++)
2512 {
2513 *q++=' ';
2514 *q++=' ';
2515 if ((j % 0x04) == 0)
2516 *q++=' ';
2517 }
2518 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002519 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002520 {
2521 if (isprint((int) ((unsigned char) *p)) != 0)
2522 *q++=(*p);
2523 else
2524 *q++='-';
2525 p++;
2526 }
2527 *q='\0';
2528 }
2529 }
2530 textlist[i]=(char *) NULL;
2531 return(textlist);
2532}
2533
2534/*
2535%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2536% %
2537% %
2538% %
2539% S t r i n g T o S t r i n g I n f o %
2540% %
2541% %
2542% %
2543%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2544%
cristybca58f32011-08-21 14:48:50 +00002545% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002546%
2547% The format of the StringToStringInfo method is:
2548%
2549% StringInfo *StringToStringInfo(const char *string)
2550%
2551% A description of each parameter follows:
2552%
2553% o string: The string.
2554%
2555*/
2556MagickExport StringInfo *StringToStringInfo(const char *string)
2557{
2558 StringInfo
2559 *string_info;
2560
cristy3ed852e2009-09-05 21:47:34 +00002561 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002562 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002563 SetStringInfoDatum(string_info,(const unsigned char *) string);
2564 return(string_info);
2565}
2566
2567/*
2568%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2569% %
2570% %
2571% %
2572% S t r i p S t r i n g %
2573% %
2574% %
2575% %
2576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2577%
2578% StripString() strips any whitespace or quotes from the beginning and end of
2579% a string of characters.
2580%
2581% The format of the StripString method is:
2582%
2583% void StripString(char *message)
2584%
2585% A description of each parameter follows:
2586%
2587% o message: Specifies an array of characters.
2588%
2589*/
2590MagickExport void StripString(char *message)
2591{
2592 register char
2593 *p,
2594 *q;
2595
2596 size_t
2597 length;
2598
2599 assert(message != (char *) NULL);
2600 if (*message == '\0')
2601 return;
2602 length=strlen(message);
2603 p=message;
2604 while (isspace((int) ((unsigned char) *p)) != 0)
2605 p++;
2606 if ((*p == '\'') || (*p == '"'))
2607 p++;
2608 q=message+length-1;
2609 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2610 q--;
2611 if (q > p)
2612 if ((*q == '\'') || (*q == '"'))
2613 q--;
cristya63c1ba2011-06-02 20:33:43 +00002614 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002615 message[q-p+1]='\0';
2616 for (p=message; *p != '\0'; p++)
2617 if (*p == '\n')
2618 *p=' ';
2619}
2620
2621/*
2622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2623% %
2624% %
2625% %
2626% S u b s t i t u t e S t r i n g %
2627% %
2628% %
2629% %
2630%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2631%
cristyf1b72c12009-10-06 13:25:21 +00002632% SubstituteString() performs string substitution on a string, replacing the
2633% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002634% If the string is matched and status, MagickTrue is returned otherwise
2635% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002636%
2637% The format of the SubstituteString method is:
2638%
cristyf1b72c12009-10-06 13:25:21 +00002639% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002640% const char *replace)
2641%
2642% A description of each parameter follows:
2643%
cristyf1b72c12009-10-06 13:25:21 +00002644% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002645% allocation if a replacement is made.
2646%
cristybc3392a2009-10-06 03:15:57 +00002647% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002648%
cristybc3392a2009-10-06 03:15:57 +00002649% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002650%
2651*/
cristyf1b72c12009-10-06 13:25:21 +00002652MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002653 const char *search,const char *replace)
2654{
cristybc3392a2009-10-06 03:15:57 +00002655 MagickBooleanType
2656 status;
cristy3ed852e2009-09-05 21:47:34 +00002657
cristybc3392a2009-10-06 03:15:57 +00002658 register char
2659 *p;
cristy3ed852e2009-09-05 21:47:34 +00002660
cristy3ed852e2009-09-05 21:47:34 +00002661 size_t
cristybc3392a2009-10-06 03:15:57 +00002662 extent,
2663 replace_extent,
2664 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002665
cristyf1b72c12009-10-06 13:25:21 +00002666 ssize_t
2667 offset;
2668
cristybc3392a2009-10-06 03:15:57 +00002669 status=MagickFalse;
2670 search_extent=0,
2671 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002672 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002673 {
cristyf1b72c12009-10-06 13:25:21 +00002674 if (search_extent == 0)
2675 search_extent=strlen(search);
2676 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002677 continue;
cristy3ed852e2009-09-05 21:47:34 +00002678 /*
cristybc3392a2009-10-06 03:15:57 +00002679 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002680 */
cristyf1b72c12009-10-06 13:25:21 +00002681 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002682 if (replace_extent == 0)
2683 replace_extent=strlen(replace);
2684 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002685 {
cristybc3392a2009-10-06 03:15:57 +00002686 /*
2687 Make room for the replacement string.
2688 */
cristyde58b412010-02-18 03:53:40 +00002689 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002690 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002691 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2692 sizeof(*p));
2693 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002694 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002695 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002696 }
cristy3ed852e2009-09-05 21:47:34 +00002697 /*
cristybc3392a2009-10-06 03:15:57 +00002698 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002699 */
cristybc3392a2009-10-06 03:15:57 +00002700 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002701 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2702 strlen(p+search_extent)+1);
2703 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002704 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002705 }
cristybc3392a2009-10-06 03:15:57 +00002706 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002707}