blob: 86692e5b3e51bc599fe0f5ec2d8ef79b0f78a42f [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 %
16% John Cristy %
17% August 2003 %
cristy3ed852e2009-09-05 21:47:34 +000018% %
19% %
cristy45ef08f2012-12-07 13:13:34 +000020% Copyright 1999-2013 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
cristy99bbf2c2011-09-26 18:27:50 +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
106% to allow for the string to be activally worked on.
107%
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;
176 if (string_info->length != 0)
177 {
178 string_info->datum=(unsigned char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000179 if (~string_info->length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000180 string_info->datum=(unsigned char *) AcquireQuantumMemory(
181 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
182 if (string_info->datum == (unsigned char *) NULL)
183 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
184 }
185 return(string_info);
186}
187
188/*
189%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190% %
191% %
192% %
cristy8723e4b2011-09-01 13:11:19 +0000193% B l o b T o S t r i n g I n f o %
194% %
195% %
196% %
197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
198%
anthony104f8932012-05-13 01:54:53 +0000199% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
200% with MaxTextExtent extra space.
cristy8723e4b2011-09-01 13:11:19 +0000201%
202% The format of the BlobToStringInfo method is:
203%
204% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
205%
206% A description of each parameter follows:
207%
208% o blob: the blob.
209%
210% o length: the length of the blob.
211%
212*/
213MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
214{
215 StringInfo
216 *string_info;
217
218 string_info=AcquireStringInfo(0);
cristyf8316342011-09-01 13:55:00 +0000219 string_info->length=length;
cristya10e0742011-09-01 13:50:43 +0000220 if (~string_info->length >= (MaxTextExtent-1))
cristyf8316342011-09-01 13:55:00 +0000221 string_info->datum=(unsigned char *) AcquireQuantumMemory(
222 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
cristy8723e4b2011-09-01 13:11:19 +0000223 if (string_info->datum == (unsigned char *) NULL)
224 {
225 string_info=DestroyStringInfo(string_info);
226 return((StringInfo *) NULL);
227 }
228 if (blob != (const void *) NULL)
229 (void) memcpy(string_info->datum,blob,length);
230 return(string_info);
231}
232
233/*
234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235% %
236% %
237% %
cristy3ed852e2009-09-05 21:47:34 +0000238% C l o n e S t r i n g %
239% %
240% %
241% %
242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
243%
anthony104f8932012-05-13 01:54:53 +0000244% CloneString() replaces or frees the destination string to make it
245% a clone of the input string plus MaxTextExtent more space so the string may
246% be worked on on.
cristy3ed852e2009-09-05 21:47:34 +0000247%
anthony104f8932012-05-13 01:54:53 +0000248% If source is a NULL pointer the destination string will be freed and set to
249% a NULL pointer. A pointer to the stored in the destination is also returned.
anthony72feaa62012-01-17 06:46:23 +0000250%
anthony104f8932012-05-13 01:54:53 +0000251% When finished the non-NULL string should be freed using DestoryString()
252% or using CloneString() with a NULL pointed for the source.
anthony06762232012-04-29 11:45:40 +0000253%
cristy3ed852e2009-09-05 21:47:34 +0000254% The format of the CloneString method is:
255%
256% char *CloneString(char **destination,const char *source)
257%
258% A description of each parameter follows:
259%
260% o destination: A pointer to a character string.
261%
262% o source: A character string.
263%
264*/
265MagickExport char *CloneString(char **destination,const char *source)
266{
267 size_t
268 length;
269
270 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
271 assert(destination != (char **) NULL);
272 if (source == (const char *) NULL)
273 {
274 if (*destination != (char *) NULL)
275 *destination=DestroyString(*destination);
276 return(*destination);
277 }
278 if (*destination == (char *) NULL)
279 {
280 *destination=AcquireString(source);
281 return(*destination);
282 }
283 length=strlen(source);
284 if (~length < MaxTextExtent)
285 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
286 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000287 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000288 if (*destination == (char *) NULL)
289 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000290 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000291 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000292 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000293 return(*destination);
294}
295
296/*
297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
298% %
299% %
300% %
301% C l o n e S t r i n g I n f o %
302% %
303% %
304% %
305%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306%
307% CloneStringInfo() clones a copy of the StringInfo structure.
308%
309% The format of the CloneStringInfo method is:
310%
311% StringInfo *CloneStringInfo(const StringInfo *string_info)
312%
313% A description of each parameter follows:
314%
315% o string_info: the string info.
316%
317*/
318MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
319{
320 StringInfo
321 *clone_info;
322
323 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
324 assert(string_info != (StringInfo *) NULL);
325 assert(string_info->signature == MagickSignature);
326 clone_info=AcquireStringInfo(string_info->length);
327 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000328 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000329 return(clone_info);
330}
331
332/*
333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
334% %
335% %
336% %
337% C o m p a r e S t r i n g I n f o %
338% %
339% %
340% %
341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
342%
343% CompareStringInfo() compares the two datums target and source. It returns
344% an integer less than, equal to, or greater than zero if target is found,
345% respectively, to be less than, to match, or be greater than source.
346%
347% The format of the CompareStringInfo method is:
348%
349% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
350%
351% A description of each parameter follows:
352%
353% o target: the target string.
354%
355% o source: the source string.
356%
357*/
358
359static inline size_t MagickMin(const size_t x,const size_t y)
360{
361 if (x < y)
362 return(x);
363 return(y);
364}
365
366MagickExport int CompareStringInfo(const StringInfo *target,
367 const StringInfo *source)
368{
369 int
370 status;
371
372 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
373 assert(target != (StringInfo *) NULL);
374 assert(target->signature == MagickSignature);
375 assert(source != (StringInfo *) NULL);
376 assert(source->signature == MagickSignature);
377 status=memcmp(target->datum,source->datum,MagickMin(target->length,
378 source->length));
379 if (status != 0)
380 return(status);
381 if (target->length == source->length)
382 return(0);
383 return(target->length < source->length ? -1 : 1);
384}
385
386/*
387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388% %
389% %
390% %
391% C o n c a t e n a t e M a g i c k S t r i n g %
392% %
393% %
394% %
395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396%
397% ConcatenateMagickString() concatenates the source string to the destination
398% string. The destination buffer is always null-terminated even if the
399% string must be truncated.
400%
401% The format of the ConcatenateMagickString method is:
402%
403% size_t ConcatenateMagickString(char *destination,const char *source,
404% const size_t length)
405%
406% A description of each parameter follows:
407%
408% o destination: the destination string.
409%
410% o source: the source string.
411%
412% o length: the length of the destination string.
413%
414*/
415MagickExport size_t ConcatenateMagickString(char *destination,
416 const char *source,const size_t length)
417{
418 register char
419 *q;
420
421 register const char
422 *p;
423
424 register size_t
425 i;
426
427 size_t
428 count;
429
430 assert(destination != (char *) NULL);
431 assert(source != (const char *) NULL);
432 assert(length >= 1);
433 p=source;
434 q=destination;
435 i=length;
436 while ((i-- != 0) && (*q != '\0'))
437 q++;
438 count=(size_t) (q-destination);
439 i=length-count;
440 if (i == 0)
441 return(count+strlen(p));
442 while (*p != '\0')
443 {
444 if (i != 1)
445 {
446 *q++=(*p);
447 i--;
448 }
449 p++;
450 }
451 *q='\0';
452 return(count+(p-source));
453}
454
455/*
456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457% %
458% %
459% %
460% C o n c a t e n a t e S t r i n g %
461% %
462% %
463% %
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465%
466% ConcatenateString() appends a copy of string source, including the
467% terminating null character, to the end of string destination.
468%
469% The format of the ConcatenateString method is:
470%
471% MagickBooleanType ConcatenateString(char **destination,
472% const char *source)
473%
474% A description of each parameter follows:
475%
476% o destination: A pointer to a character string.
477%
478% o source: A character string.
479%
480*/
481MagickExport MagickBooleanType ConcatenateString(char **destination,
482 const char *source)
483{
484 size_t
cristy54aad5e2010-09-03 16:02:04 +0000485 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000486 length,
487 source_length;
488
489 assert(destination != (char **) NULL);
490 if (source == (const char *) NULL)
491 return(MagickTrue);
492 if (*destination == (char *) NULL)
493 {
494 *destination=AcquireString(source);
495 return(MagickTrue);
496 }
cristy54aad5e2010-09-03 16:02:04 +0000497 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000498 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000499 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000500 if (~length < source_length)
501 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
502 length+=source_length;
503 if (~length < MaxTextExtent)
504 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
505 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000506 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000507 if (*destination == (char *) NULL)
508 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000509 if (source_length != 0)
510 (void) memcpy((*destination)+destination_length,source,source_length);
511 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000512 return(MagickTrue);
513}
514
515/*
516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
517% %
518% %
519% %
520% C o n c a t e n a t e S t r i n g I n f o %
521% %
522% %
523% %
524%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
525%
526% ConcatenateStringInfo() concatenates the source string to the destination
527% string.
528%
529% The format of the ConcatenateStringInfo method is:
530%
531% void ConcatenateStringInfo(StringInfo *string_info,
532% const StringInfo *source)
533%
534% A description of each parameter follows:
535%
536% o string_info: the string info.
537%
538% o source: the source string.
539%
540*/
541MagickExport void ConcatenateStringInfo(StringInfo *string_info,
542 const StringInfo *source)
543{
544 size_t
545 length;
546
547 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
548 assert(string_info != (StringInfo *) NULL);
549 assert(string_info->signature == MagickSignature);
550 assert(source != (const StringInfo *) NULL);
551 length=string_info->length;
552 if (~length < source->length)
553 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
554 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000555 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000556}
557
558/*
559%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
560% %
561% %
562% %
563% 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 %
564% %
565% %
566% %
567%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
568%
569% ConfigureFileToStringInfo() returns the contents of a configure file as a
570% string.
571%
572% The format of the ConfigureFileToStringInfo method is:
573%
574% StringInfo *ConfigureFileToStringInfo(const char *filename)
575% ExceptionInfo *exception)
576%
577% A description of each parameter follows:
578%
579% o filename: the filename.
580%
581*/
cristy99bbf2c2011-09-26 18:27:50 +0000582MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +0000583{
584 char
585 *string;
586
587 int
588 file;
589
590 MagickOffsetType
591 offset;
592
593 size_t
594 length;
595
596 StringInfo
597 *string_info;
598
599 void
600 *map;
601
602 assert(filename != (const char *) NULL);
cristy18c6c272011-09-23 14:40:37 +0000603 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
cristy3ed852e2009-09-05 21:47:34 +0000604 if (file == -1)
605 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000606 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000607 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
608 {
609 file=close(file)-1;
610 return((StringInfo *) NULL);
611 }
612 length=(size_t) offset;
613 string=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000614 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000615 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
616 if (string == (char *) NULL)
617 {
618 file=close(file)-1;
619 return((StringInfo *) NULL);
620 }
621 map=MapBlob(file,ReadMode,0,length);
622 if (map != (void *) NULL)
623 {
cristy54aad5e2010-09-03 16:02:04 +0000624 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000625 (void) UnmapBlob(map,length);
626 }
627 else
628 {
629 register size_t
630 i;
631
632 ssize_t
633 count;
634
cristy7f317702011-02-18 20:40:28 +0000635 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000636 for (i=0; i < length; i+=count)
637 {
638 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
639 SSIZE_MAX));
640 if (count <= 0)
641 {
642 count=0;
643 if (errno != EINTR)
644 break;
645 }
646 }
647 if (i < length)
648 {
649 file=close(file)-1;
650 string=DestroyString(string);
651 return((StringInfo *) NULL);
652 }
653 }
654 string[length]='\0';
655 file=close(file)-1;
656 string_info=AcquireStringInfo(0);
657 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
658 string_info->length=length;
659 string_info->datum=(unsigned char *) string;
660 return(string_info);
661}
662
663/*
664%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665% %
666% %
667% %
668% C o n s t a n t S t r i n g %
669% %
670% %
671% %
672%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673%
anthony104f8932012-05-13 01:54:53 +0000674% ConstantString() allocates exactly the needed memory for a string and
675% copies the source string to that memory location. A NULL string pointer
676% will allocate an empty string containing just the NUL character.
cristy3ed852e2009-09-05 21:47:34 +0000677%
anthony104f8932012-05-13 01:54:53 +0000678% When finished the string should be freed using DestoryString()
anthony06762232012-04-29 11:45:40 +0000679%
cristy3ed852e2009-09-05 21:47:34 +0000680% The format of the ConstantString method is:
681%
682% char *ConstantString(const char *source)
683%
684% A description of each parameter follows:
685%
686% o source: A character string.
687%
688*/
689MagickExport char *ConstantString(const char *source)
690{
691 char
692 *destination;
693
694 size_t
695 length;
696
697 length=0;
698 if (source != (char *) NULL)
699 length+=strlen(source);
700 destination=(char *) NULL;
701 if (~length >= 1UL)
702 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
703 if (destination == (char *) NULL)
704 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
705 *destination='\0';
706 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000707 (void) memcpy(destination,source,length*sizeof(*destination));
708 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000709 return(destination);
710}
711
712/*
713%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714% %
715% %
716% %
717% C o p y M a g i c k S t r i n g %
718% %
719% %
720% %
721%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722%
anthony06762232012-04-29 11:45:40 +0000723% CopyMagickString() copies the source string to the destination string, with
724% out exceeding the given pre-declared length.
725%
726% The destination buffer is always null-terminated even if the string must be
727% truncated. The return value is the minimum of the source string length or
728% the length parameter.
cristy3ed852e2009-09-05 21:47:34 +0000729%
730% The format of the CopyMagickString method is:
731%
732% size_t CopyMagickString(const char *destination,char *source,
733% const size_t length)
734%
735% A description of each parameter follows:
736%
737% o destination: the destination string.
738%
739% o source: the source string.
740%
741% o length: the length of the destination string.
742%
743*/
744MagickExport size_t CopyMagickString(char *destination,const char *source,
745 const size_t length)
746{
747 register char
748 *q;
749
750 register const char
751 *p;
752
753 register size_t
754 n;
755
cristy77e3fcc2011-10-11 00:04:41 +0000756 if (source == (const char *) NULL)
757 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000758 p=source;
759 q=destination;
760 for (n=length; n > 4; n-=4)
761 {
762 *q=(*p++);
763 if (*q == '\0')
764 return((size_t) (p-source-1));
765 q++;
766 *q=(*p++);
767 if (*q == '\0')
768 return((size_t) (p-source-1));
769 q++;
770 *q=(*p++);
771 if (*q == '\0')
772 return((size_t) (p-source-1));
773 q++;
774 *q=(*p++);
775 if (*q == '\0')
776 return((size_t) (p-source-1));
777 q++;
778 }
779 if (n != 0)
780 for (n--; n != 0; n--)
781 {
782 *q=(*p++);
783 if (*q == '\0')
784 return((size_t) (p-source-1));
785 q++;
786 }
787 if (length != 0)
788 *q='\0';
789 return((size_t) (p-source-1));
790}
791
792/*
793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
794% %
795% %
796% %
797% D e s t r o y S t r i n g %
798% %
799% %
800% %
801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802%
803% DestroyString() destroys memory associated with a string.
804%
805% The format of the DestroyString method is:
806%
807% char *DestroyString(char *string)
808%
809% A description of each parameter follows:
810%
811% o string: the string.
812%
813*/
814MagickExport char *DestroyString(char *string)
815{
816 return((char *) RelinquishMagickMemory(string));
817}
818
819/*
820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821% %
822% %
823% %
824% D e s t r o y S t r i n g I n f o %
825% %
826% %
827% %
828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829%
830% DestroyStringInfo() destroys memory associated with the StringInfo structure.
831%
832% The format of the DestroyStringInfo method is:
833%
834% StringInfo *DestroyStringInfo(StringInfo *string_info)
835%
836% A description of each parameter follows:
837%
838% o string_info: the string info.
839%
840*/
841MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
842{
843 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
844 assert(string_info != (StringInfo *) NULL);
845 assert(string_info->signature == MagickSignature);
846 if (string_info->datum != (unsigned char *) NULL)
847 string_info->datum=(unsigned char *) RelinquishMagickMemory(
848 string_info->datum);
849 string_info->signature=(~MagickSignature);
850 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
931 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
932 assert(source != (const char *) NULL);
933 length=strlen(source);
934 for (p=source; *p != '\0'; p++)
935 if ((*p == '\\') || (*p == escape))
936 {
937 if (~length < 1)
938 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
939 length++;
940 }
941 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000942 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000943 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
944 sizeof(*destination));
945 if (destination == (char *) NULL)
946 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
947 *destination='\0';
948 if (source != (char *) NULL)
949 {
950 q=destination;
951 for (p=source; *p != '\0'; p++)
952 {
953 if ((*p == '\\') || (*p == escape))
954 *q++='\\';
955 *q++=(*p);
956 }
957 *q='\0';
958 }
959 return(destination);
960}
961
962/*
963%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964% %
965% %
966% %
967% F i l e T o S t r i n g %
968% %
969% %
970% %
971%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
972%
973% FileToString() returns the contents of a file as a string.
974%
975% The format of the FileToString method is:
976%
977% char *FileToString(const char *filename,const size_t extent,
978% ExceptionInfo *exception)
979%
980% A description of each parameter follows:
981%
982% o filename: the filename.
983%
984% o extent: Maximum length of the string.
985%
986% o exception: return any errors or warnings in this structure.
987%
988*/
989MagickExport char *FileToString(const char *filename,const size_t extent,
990 ExceptionInfo *exception)
991{
992 size_t
993 length;
994
995 assert(filename != (const char *) NULL);
996 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
997 assert(exception != (ExceptionInfo *) NULL);
998 return((char *) FileToBlob(filename,extent,&length,exception));
999}
1000
1001/*
1002%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003% %
1004% %
1005% %
1006% F i l e T o S t r i n g I n f o %
1007% %
1008% %
1009% %
1010%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1011%
1012% FileToStringInfo() returns the contents of a file as a string.
1013%
1014% The format of the FileToStringInfo method is:
1015%
1016% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1017% ExceptionInfo *exception)
1018%
1019% A description of each parameter follows:
1020%
1021% o filename: the filename.
1022%
1023% o extent: Maximum length of the string.
1024%
1025% o exception: return any errors or warnings in this structure.
1026%
1027*/
1028MagickExport StringInfo *FileToStringInfo(const char *filename,
1029 const size_t extent,ExceptionInfo *exception)
1030{
1031 StringInfo
1032 *string_info;
1033
1034 assert(filename != (const char *) NULL);
1035 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1036 assert(exception != (ExceptionInfo *) NULL);
1037 string_info=AcquireStringInfo(0);
1038 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1039 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1040 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%
cristybb503372010-05-27 20:51:26 +00001065% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001066%
1067% A description of each parameter follows:
1068%
1069% o size: convert this size to a human readable format.
1070%
cristyb9080c92009-12-01 20:13:26 +00001071% o bi: use power of two rather than power of ten.
1072%
cristy3ed852e2009-09-05 21:47:34 +00001073% o format: human readable format.
1074%
1075*/
cristy99bbf2c2011-09-26 18:27:50 +00001076MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001077 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001078{
cristyb9080c92009-12-01 20:13:26 +00001079 const char
1080 **units;
1081
cristy3ed852e2009-09-05 21:47:34 +00001082 double
cristyb9080c92009-12-01 20:13:26 +00001083 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001084 length;
1085
cristybb503372010-05-27 20:51:26 +00001086 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001087 i,
1088 j;
1089
cristy9d314ff2011-03-09 01:30:28 +00001090 ssize_t
1091 count;
1092
cristy3ed852e2009-09-05 21:47:34 +00001093 static const char
cristyb9080c92009-12-01 20:13:26 +00001094 *bi_units[] =
1095 {
cristy2ce15c92010-03-12 14:03:41 +00001096 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001097 },
1098 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001099 {
cristy2ce15c92010-03-12 14:03:41 +00001100 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001101 };
cristy3ed852e2009-09-05 21:47:34 +00001102
cristyb9080c92009-12-01 20:13:26 +00001103 bytes=1000.0;
1104 units=traditional_units;
1105 if (bi != MagickFalse)
1106 {
1107 bytes=1024.0;
1108 units=bi_units;
1109 }
cristy3ed852e2009-09-05 21:47:34 +00001110#if defined(_MSC_VER) && (_MSC_VER == 1200)
1111 length=(double) ((MagickOffsetType) size);
1112#else
1113 length=(double) size;
1114#endif
cristyb9080c92009-12-01 20:13:26 +00001115 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1116 length/=bytes;
cristy9bf9da32009-09-27 16:48:34 +00001117 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001118 {
cristyb51dff52011-05-19 16:55:47 +00001119 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001120 units[i]);
1121 if (strchr(format,'+') == (char *) NULL)
1122 break;
1123 }
1124 return(count);
1125}
1126
1127/*
1128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1129% %
1130% %
1131% %
cristy3ed852e2009-09-05 21:47:34 +00001132% F o r m a t M a g i c k T i m e %
1133% %
1134% %
1135% %
1136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1137%
1138% FormatMagickTime() returns the specified time in the Internet date/time
1139% format and the length of the timestamp.
1140%
1141% The format of the FormatMagickTime method is:
1142%
cristybb503372010-05-27 20:51:26 +00001143% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001144% char *timestamp)
1145%
1146% A description of each parameter follows.
1147%
1148% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1149% measured in seconds.
1150%
1151% o length: the maximum length of the string.
1152%
1153% o timestamp: Return the Internet date/time here.
1154%
1155*/
cristybb503372010-05-27 20:51:26 +00001156MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001157 char *timestamp)
1158{
cristybb503372010-05-27 20:51:26 +00001159 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001160 count;
1161
1162 struct tm
1163 gm_time,
1164 local_time;
1165
1166 time_t
1167 timezone;
1168
1169 assert(timestamp != (char *) NULL);
1170 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1171 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1172#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1173 (void) localtime_r(&time,&local_time);
1174#else
1175 {
cristybc3392a2009-10-06 03:15:57 +00001176 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001177 *my_time;
1178
1179 my_time=localtime(&time);
1180 if (my_time != (struct tm *) NULL)
1181 (void) memcpy(&local_time,my_time,sizeof(local_time));
1182 }
1183#endif
1184#if defined(MAGICKCORE_HAVE_GMTIME_R)
1185 (void) gmtime_r(&time,&gm_time);
1186#else
1187 {
cristybc3392a2009-10-06 03:15:57 +00001188 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001189 *my_time;
1190
1191 my_time=gmtime(&time);
1192 if (my_time != (struct tm *) NULL)
1193 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1194 }
1195#endif
1196 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1197 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1198 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1199 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001200 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001201 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1202 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001203 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001204 return(count);
1205}
1206
1207/*
1208%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1209% %
1210% %
1211% %
1212% G e t E n v i r o n m e n t V a l u e %
1213% %
1214% %
1215% %
1216%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1217%
1218% GetEnvironmentValue() returns the environment string that matches the
1219% specified name.
1220%
1221% The format of the GetEnvironmentValue method is:
1222%
1223% char *GetEnvironmentValue(const char *name)
1224%
1225% A description of each parameter follows:
1226%
1227% o name: the environment name.
1228%
1229*/
cristy99bbf2c2011-09-26 18:27:50 +00001230MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001231{
1232 const char
1233 *environment;
1234
1235 environment=getenv(name);
1236 if (environment == (const char *) NULL)
1237 return((char *) NULL);
1238 return(ConstantString(environment));
1239}
1240
1241/*
1242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1243% %
1244% %
1245% %
1246% G e t S t r i n g I n f o D a t u m %
1247% %
1248% %
1249% %
1250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1251%
1252% GetStringInfoDatum() returns the datum associated with the string.
1253%
1254% The format of the GetStringInfoDatum method is:
1255%
1256% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1257%
1258% A description of each parameter follows:
1259%
1260% o string_info: the string info.
1261%
1262*/
1263MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1264{
1265 assert(string_info != (StringInfo *) NULL);
1266 assert(string_info->signature == MagickSignature);
1267 return(string_info->datum);
1268}
1269
1270/*
1271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272% %
1273% %
1274% %
1275% G e t S t r i n g I n f o L e n g t h %
1276% %
1277% %
1278% %
1279%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1280%
1281% GetStringInfoLength() returns the string length.
1282%
1283% The format of the GetStringInfoLength method is:
1284%
1285% size_t GetStringInfoLength(const StringInfo *string_info)
1286%
1287% A description of each parameter follows:
1288%
1289% o string_info: the string info.
1290%
1291*/
1292MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1293{
1294 assert(string_info != (StringInfo *) NULL);
1295 assert(string_info->signature == MagickSignature);
1296 return(string_info->length);
1297}
1298
1299/*
1300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301% %
1302% %
1303% %
1304% G e t S t r i n g I n f o P a t h %
1305% %
1306% %
1307% %
1308%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1309%
1310% GetStringInfoPath() returns the path associated with the string.
1311%
1312% The format of the GetStringInfoPath method is:
1313%
1314% const char *GetStringInfoPath(const StringInfo *string_info)
1315%
1316% A description of each parameter follows:
1317%
1318% o string_info: the string info.
1319%
1320*/
1321MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1322{
1323 assert(string_info != (StringInfo *) NULL);
1324 assert(string_info->signature == MagickSignature);
1325 return(string_info->path);
1326}
1327
1328/*
1329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1330% %
1331% %
1332% %
cristydbdd0e32011-11-04 23:29:40 +00001333+ I n t e r p r e t S i P r e f i x V a l u e %
1334% %
1335% %
1336% %
1337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1338%
1339% InterpretSiPrefixValue() converts the initial portion of the string to a
1340% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1341% etc.).
1342%
1343% The format of the InterpretSiPrefixValue method is:
1344%
1345% double InterpretSiPrefixValue(const char *value,char **sentinal)
1346%
1347% A description of each parameter follows:
1348%
1349% o value: the string value.
1350%
1351% o sentinal: if sentinal is not NULL, return a pointer to the character
1352% after the last character used in the conversion.
1353%
1354*/
1355MagickExport double InterpretSiPrefixValue(const char *restrict string,
1356 char **restrict sentinal)
1357{
1358 char
1359 *q;
1360
1361 double
1362 value;
1363
cristydbdd0e32011-11-04 23:29:40 +00001364 value=InterpretLocaleValue(string,&q);
1365 if (q != string)
1366 {
1367 if ((*q >= 'E') && (*q <= 'z'))
1368 {
1369 double
1370 e;
1371
cristy0c2684f2011-11-05 21:39:43 +00001372 switch ((int) ((unsigned char) *q))
1373 {
1374 case 'y': e=(-24.0); break;
1375 case 'z': e=(-21.0); break;
1376 case 'a': e=(-18.0); break;
1377 case 'f': e=(-15.0); break;
1378 case 'p': e=(-12.0); break;
1379 case 'n': e=(-9.0); break;
1380 case 'u': e=(-6.0); break;
1381 case 'm': e=(-3.0); break;
1382 case 'c': e=(-2.0); break;
1383 case 'd': e=(-1.0); break;
1384 case 'h': e=2.0; break;
1385 case 'k': e=3.0; break;
1386 case 'K': e=3.0; break;
1387 case 'M': e=6.0; break;
1388 case 'G': e=9.0; break;
1389 case 'T': e=12.0; break;
1390 case 'P': e=15.0; break;
1391 case 'E': e=18.0; break;
1392 case 'Z': e=21.0; break;
1393 case 'Y': e=24.0; break;
1394 default: e=0.0; break;
1395 }
cristydbdd0e32011-11-04 23:29:40 +00001396 if (e >= MagickEpsilon)
1397 {
1398 if (q[1] == 'i')
1399 {
1400 value*=pow(2.0,e/0.3);
1401 q+=2;
1402 }
1403 else
1404 {
1405 value*=pow(10.0,e);
1406 q++;
1407 }
1408 }
1409 }
cristyc0f1ed12011-11-09 14:50:15 +00001410 if (*q == 'B')
cristy099a7352011-11-09 14:31:35 +00001411 q++;
cristydbdd0e32011-11-04 23:29:40 +00001412 }
1413 if (sentinal != (char **) NULL)
1414 *sentinal=q;
1415 return(value);
1416}
1417
1418/*
1419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1420% %
1421% %
1422% %
anthony6f201312012-03-30 04:08:15 +00001423% I s S t r i n g T r u e %
1424% %
1425% %
1426% %
1427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428%
1429% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1430% "1". Any other string or undefined returns MagickFalse.
1431%
1432% Typically this is used to look at strings (options or artifacts) which
1433% has a default value of "false", when not defined.
1434%
1435% The format of the IsStringTrue method is:
1436%
1437% MagickBooleanType IsStringTrue(const char *value)
1438%
1439% A description of each parameter follows:
1440%
1441% o value: Specifies a pointer to a character array.
1442%
1443*/
1444MagickExport MagickBooleanType IsStringTrue(const char *value)
1445{
1446 if (value == (const char *) NULL)
1447 return(MagickFalse);
1448 if (LocaleCompare(value,"true") == 0)
1449 return(MagickTrue);
1450 if (LocaleCompare(value,"on") == 0)
1451 return(MagickTrue);
1452 if (LocaleCompare(value,"yes") == 0)
1453 return(MagickTrue);
1454 if (LocaleCompare(value,"1") == 0)
1455 return(MagickTrue);
1456 return(MagickFalse);
1457}
1458
1459/*
1460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1461% %
1462% %
1463% %
1464% I s S t r i n g N o t F a l s e %
1465% %
1466% %
1467% %
1468%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469%
1470% IsStringNotFalse() returns MagickTrue, unless the string specifically
1471% has a value that makes this false. that is if it has a value of
1472% "false", "off", "no" or "0".
1473%
1474% Typically this is used to look at strings (options or artifacts) which
1475% has a default value of "true", when it has not been defined.
1476%
1477% The format of the IsStringNotFalse method is:
1478%
1479% MagickBooleanType IsStringNotFalse(const char *value)
1480%
1481% A description of each parameter follows:
1482%
1483% o value: Specifies a pointer to a character array.
1484%
1485*/
1486MagickExport MagickBooleanType IsStringNotFalse(const char *value)
1487{
1488 if (value == (const char *) NULL)
1489 return(MagickTrue);
1490 if (LocaleCompare(value,"false") == 0)
1491 return(MagickFalse);
1492 if (LocaleCompare(value,"off") == 0)
1493 return(MagickFalse);
1494 if (LocaleCompare(value,"no") == 0)
1495 return(MagickFalse);
1496 if (LocaleCompare(value,"0") == 0)
1497 return(MagickFalse);
1498 return(MagickTrue);
1499}
1500
1501/*
1502%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1503% %
1504% %
1505% %
cristy3ed852e2009-09-05 21:47:34 +00001506% L o c a l e C o m p a r e %
1507% %
1508% %
1509% %
1510%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1511%
1512% LocaleCompare() performs a case-insensitive comparison of two strings
1513% byte-by-byte, according to the ordering of the current locale encoding.
1514% LocaleCompare returns an integer greater than, equal to, or less than 0,
1515% if the string pointed to by p is greater than, equal to, or less than the
1516% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001517% is determined by the sign of the difference between the values of the first
1518% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001519%
1520% The format of the LocaleCompare method is:
1521%
cristyde58b412010-02-18 03:53:40 +00001522% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001523%
1524% A description of each parameter follows:
1525%
1526% o p: A pointer to a character string.
1527%
1528% o q: A pointer to a character string to compare to p.
1529%
1530*/
cristyde58b412010-02-18 03:53:40 +00001531MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001532{
1533 if ((p == (char *) NULL) && (q == (char *) NULL))
1534 return(0);
1535 if (p == (char *) NULL)
1536 return(-1);
1537 if (q == (char *) NULL)
1538 return(1);
1539#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001540 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001541#else
1542 {
cristyde58b412010-02-18 03:53:40 +00001543 register int
cristy3ed852e2009-09-05 21:47:34 +00001544 c,
cristya72c2d12010-02-18 01:20:28 +00001545 d;
cristy3ed852e2009-09-05 21:47:34 +00001546
cristya72c2d12010-02-18 01:20:28 +00001547 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001548 {
cristyde58b412010-02-18 03:53:40 +00001549 c=(int) *((unsigned char *) p);
1550 d=(int) *((unsigned char *) q);
1551 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001552 break;
cristya72c2d12010-02-18 01:20:28 +00001553 p++;
1554 q++;
cristy3ed852e2009-09-05 21:47:34 +00001555 }
cristyde58b412010-02-18 03:53:40 +00001556 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001557 }
1558#endif
1559}
1560
1561/*
1562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1563% %
1564% %
1565% %
1566% L o c a l e L o w e r %
1567% %
1568% %
1569% %
1570%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1571%
1572% LocaleLower() transforms all of the characters in the supplied
1573% null-terminated string, changing all uppercase letters to lowercase.
1574%
1575% The format of the LocaleLower method is:
1576%
1577% void LocaleLower(char *string)
1578%
1579% A description of each parameter follows:
1580%
1581% o string: A pointer to the string to convert to lower-case Locale.
1582%
1583*/
1584MagickExport void LocaleLower(char *string)
1585{
1586 register char
1587 *q;
1588
1589 assert(string != (char *) NULL);
1590 for (q=string; *q != '\0'; q++)
1591 *q=(char) tolower((int) *q);
1592}
1593
1594/*
1595%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596% %
1597% %
1598% %
1599% L o c a l e N C o m p a r e %
1600% %
1601% %
1602% %
1603%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1604%
anthony06762232012-04-29 11:45:40 +00001605% LocaleNCompare() performs a case-insensitive comparison of two strings
1606% byte-by-byte, according to the ordering of the current locale encoding.
1607%
1608% LocaleNCompare returns an integer greater than, equal to, or less than 0,
1609% if the string pointed to by p is greater than, equal to, or less than the
1610% string pointed to by q respectively. The sign of a non-zero return value
1611% is determined by the sign of the difference between the values of the first
1612% pair of bytes that differ in the strings being compared.
1613%
1614% The LocaleNCompare method makes the same comparison as LocaleCompare but
1615% looks at a maximum of n bytes. Bytes following a null byte are not
1616% compared.
cristy3ed852e2009-09-05 21:47:34 +00001617%
1618% The format of the LocaleNCompare method is:
1619%
cristyde58b412010-02-18 03:53:40 +00001620% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001621%
1622% A description of each parameter follows:
1623%
1624% o p: A pointer to a character string.
1625%
1626% o q: A pointer to a character string to compare to p.
1627%
cristy7a40ba82011-01-08 20:31:18 +00001628% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001629%
1630*/
cristyde58b412010-02-18 03:53:40 +00001631MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001632{
cristy78c21692011-10-06 14:57:26 +00001633 if ((p == (char *) NULL) && (q == (char *) NULL))
1634 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001635 if (p == (char *) NULL)
1636 return(-1);
1637 if (q == (char *) NULL)
1638 return(1);
1639#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001640 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001641#else
1642 {
cristyde58b412010-02-18 03:53:40 +00001643 register int
cristy3ed852e2009-09-05 21:47:34 +00001644 c,
1645 d;
1646
cristyb6af4a52009-10-06 13:56:23 +00001647 register size_t
cristyc4cded12010-02-18 14:40:57 +00001648 i;
cristyb6af4a52009-10-06 13:56:23 +00001649
cristyc4cded12010-02-18 14:40:57 +00001650 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001651 {
cristyde58b412010-02-18 03:53:40 +00001652 c=(int) *((unsigned char *) p);
1653 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001654 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001655 return(AsciiMap[c]-(int) AsciiMap[d]);
1656 if (c == 0)
1657 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001658 p++;
1659 q++;
1660 }
cristyde58b412010-02-18 03:53:40 +00001661 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001662 }
1663#endif
1664}
1665
1666/*
1667%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1668% %
1669% %
1670% %
1671% L o c a l e U p p e r %
1672% %
1673% %
1674% %
1675%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1676%
1677% LocaleUpper() transforms all of the characters in the supplied
1678% null-terminated string, changing all lowercase letters to uppercase.
1679%
1680% The format of the LocaleUpper method is:
1681%
1682% void LocaleUpper(char *string)
1683%
1684% A description of each parameter follows:
1685%
1686% o string: A pointer to the string to convert to upper-case Locale.
1687%
1688*/
1689MagickExport void LocaleUpper(char *string)
1690{
1691 register char
1692 *q;
1693
1694 assert(string != (char *) NULL);
1695 for (q=string; *q != '\0'; q++)
1696 *q=(char) toupper((int) *q);
1697}
1698
1699/*
1700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1701% %
1702% %
1703% %
1704% P r i n t S t r i n g I n f o %
1705% %
1706% %
1707% %
1708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1709%
1710% PrintStringInfo() prints the string.
1711%
1712% The format of the PrintStringInfo method is:
1713%
1714% void PrintStringInfo(FILE *file,const char *id,
1715% const StringInfo *string_info)
1716%
1717% A description of each parameter follows:
1718%
1719% o file: the file, typically stdout.
1720%
1721% o id: the string id.
1722%
1723% o string_info: the string info.
1724%
1725*/
1726MagickExport void PrintStringInfo(FILE *file,const char *id,
1727 const StringInfo *string_info)
1728{
1729 register const char
1730 *p;
1731
1732 register size_t
1733 i,
1734 j;
1735
1736 assert(id != (const char *) NULL);
1737 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1738 assert(string_info != (StringInfo *) NULL);
1739 assert(string_info->signature == MagickSignature);
1740 p=(char *) string_info->datum;
1741 for (i=0; i < string_info->length; i++)
1742 {
1743 if (((int) ((unsigned char) *p) < 32) &&
1744 (isspace((int) ((unsigned char) *p)) == 0))
1745 break;
1746 p++;
1747 }
1748 if (i == string_info->length)
1749 {
cristy53ea28b2012-06-10 22:11:59 +00001750 for (i=0; i < string_info->length; i++)
1751 (void) fputc(string_info->datum[i],file);
cristy3ed852e2009-09-05 21:47:34 +00001752 (void) fputc('\n',file);
1753 return;
1754 }
1755 /*
1756 Convert string to a HEX list.
1757 */
1758 p=(char *) string_info->datum;
1759 for (i=0; i < string_info->length; i+=0x14)
1760 {
cristyb51dff52011-05-19 16:55:47 +00001761 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001762 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1763 {
cristyb51dff52011-05-19 16:55:47 +00001764 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001765 if ((j % 0x04) == 0)
1766 (void) fputc(' ',file);
1767 }
1768 for ( ; j <= 0x14; j++)
1769 {
1770 (void) fputc(' ',file);
1771 (void) fputc(' ',file);
1772 if ((j % 0x04) == 0)
1773 (void) fputc(' ',file);
1774 }
1775 (void) fputc(' ',file);
1776 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1777 {
1778 if (isprint((int) ((unsigned char) *p)) != 0)
1779 (void) fputc(*p,file);
1780 else
1781 (void) fputc('-',file);
1782 p++;
1783 }
1784 (void) fputc('\n',file);
1785 }
1786}
1787
1788/*
1789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1790% %
1791% %
1792% %
1793% R e s e t S t r i n g I n f o %
1794% %
1795% %
1796% %
1797%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1798%
1799% ResetStringInfo() reset the string to all null bytes.
1800%
1801% The format of the ResetStringInfo method is:
1802%
1803% void ResetStringInfo(StringInfo *string_info)
1804%
1805% A description of each parameter follows:
1806%
1807% o string_info: the string info.
1808%
1809*/
1810MagickExport void ResetStringInfo(StringInfo *string_info)
1811{
1812 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1813 assert(string_info != (StringInfo *) NULL);
1814 assert(string_info->signature == MagickSignature);
1815 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1816}
1817
1818/*
1819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1820% %
1821% %
1822% %
1823% S e t S t r i n g I n f o %
1824% %
1825% %
1826% %
1827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828%
1829% SetStringInfo() copies the source string to the destination string.
1830%
1831% The format of the SetStringInfo method is:
1832%
1833% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1834%
1835% A description of each parameter follows:
1836%
1837% o string_info: the string info.
1838%
1839% o source: the source string.
1840%
1841*/
1842MagickExport void SetStringInfo(StringInfo *string_info,
1843 const StringInfo *source)
1844{
1845 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1846 assert(string_info != (StringInfo *) NULL);
1847 assert(string_info->signature == MagickSignature);
1848 assert(source != (StringInfo *) NULL);
1849 assert(source->signature == MagickSignature);
1850 if (string_info->length == 0)
1851 return;
1852 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001853 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1854 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001855}
1856
1857/*
1858%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1859% %
1860% %
1861% %
1862% S e t S t r i n g I n f o D a t u m %
1863% %
1864% %
1865% %
1866%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1867%
1868% SetStringInfoDatum() copies bytes from the source string for the length of
1869% the destination string.
1870%
1871% The format of the SetStringInfoDatum method is:
1872%
1873% void SetStringInfoDatum(StringInfo *string_info,
1874% const unsigned char *source)
1875%
1876% A description of each parameter follows:
1877%
1878% o string_info: the string info.
1879%
1880% o source: the source string.
1881%
1882*/
1883MagickExport void SetStringInfoDatum(StringInfo *string_info,
1884 const unsigned char *source)
1885{
1886 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1887 assert(string_info != (StringInfo *) NULL);
1888 assert(string_info->signature == MagickSignature);
1889 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001890 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001891}
1892
1893/*
1894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1895% %
1896% %
1897% %
1898% S e t S t r i n g I n f o L e n g t h %
1899% %
1900% %
1901% %
1902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1903%
1904% SetStringInfoLength() set the string length to the specified value.
1905%
1906% The format of the SetStringInfoLength method is:
1907%
1908% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1909%
1910% A description of each parameter follows:
1911%
1912% o string_info: the string info.
1913%
1914% o length: the string length.
1915%
1916*/
1917MagickExport void SetStringInfoLength(StringInfo *string_info,
1918 const size_t length)
1919{
1920 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1921 assert(string_info != (StringInfo *) NULL);
1922 assert(string_info->signature == MagickSignature);
1923 if (~length < MaxTextExtent)
1924 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1925 string_info->length=length;
1926 if (string_info->datum == (unsigned char *) NULL)
1927 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1928 MaxTextExtent,sizeof(*string_info->datum));
1929 else
1930 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1931 length+MaxTextExtent,sizeof(*string_info->datum));
1932 if (string_info->datum == (unsigned char *) NULL)
1933 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1934}
1935
1936/*
1937%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1938% %
1939% %
1940% %
1941% S e t S t r i n g I n f o D a t u m %
1942% %
1943% %
1944% %
1945%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1946%
1947% SetStringInfoPath() sets the path associated with the string.
1948%
1949% The format of the SetStringInfoPath method is:
1950%
1951% void SetStringInfoPath(StringInfo *string_info,const char *path)
1952%
1953% A description of each parameter follows:
1954%
1955% o string_info: the string info.
1956%
1957% o path: the path.
1958%
1959*/
1960MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1961{
1962 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1963 assert(string_info != (StringInfo *) NULL);
1964 assert(string_info->signature == MagickSignature);
1965 assert(path != (const char *) NULL);
1966 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1967}
1968
1969/*
1970%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1971% %
1972% %
1973% %
1974% S p l i t S t r i n g I n f o %
1975% %
1976% %
1977% %
1978%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1979%
1980% SplitStringInfo() splits a string into two and returns it.
1981%
1982% The format of the SplitStringInfo method is:
1983%
1984% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1985%
1986% A description of each parameter follows:
1987%
1988% o string_info: the string info.
1989%
1990*/
1991MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1992 const size_t offset)
1993{
1994 StringInfo
1995 *split_info;
1996
1997 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1998 assert(string_info != (StringInfo *) NULL);
1999 assert(string_info->signature == MagickSignature);
2000 if (offset > string_info->length)
2001 return((StringInfo *) NULL);
2002 split_info=AcquireStringInfo(offset);
2003 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00002004 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00002005 string_info->length-offset+MaxTextExtent);
2006 SetStringInfoLength(string_info,string_info->length-offset);
2007 return(split_info);
2008}
2009
2010/*
2011%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2012% %
2013% %
2014% %
2015% S t r i n g I n f o T o S t r i n g %
2016% %
2017% %
2018% %
2019%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2020%
2021% StringInfoToString() converts a string info string to a C string.
2022%
2023% The format of the StringInfoToString method is:
2024%
2025% char *StringInfoToString(const StringInfo *string_info)
2026%
2027% A description of each parameter follows:
2028%
2029% o string_info: the string.
2030%
2031*/
2032MagickExport char *StringInfoToString(const StringInfo *string_info)
2033{
2034 char
2035 *string;
2036
2037 size_t
2038 length;
2039
2040 string=(char *) NULL;
2041 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00002042 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00002043 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002044 if (string == (char *) NULL)
2045 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00002046 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00002047 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002048 return(string);
2049}
2050
2051/*
2052%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2053% %
2054% %
2055% %
anthonyb1d483a2012-04-14 12:53:56 +00002056% S t r i n g I n f o T o H e x S t r i n g %
2057% %
2058% %
2059% %
2060%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2061%
2062% StringInfoToHexString() converts a string info string to a C string.
2063%
2064% The format of the StringInfoToHexString method is:
2065%
2066% char *StringInfoToHexString(const StringInfo *string_info)
2067%
2068% A description of each parameter follows:
2069%
2070% o string_info: the string.
2071%
2072*/
2073MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2074{
2075 char
2076 *string;
2077
2078 register const unsigned char
2079 *p;
2080
2081 register ssize_t
2082 i;
2083
2084 register unsigned char
2085 *q;
2086
2087 size_t
2088 length;
2089
2090 unsigned char
2091 hex_digits[16];
2092
2093 length=string_info->length;
2094 if (~length < MaxTextExtent)
2095 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2096 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2097 if (string == (char *) NULL)
2098 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2099 hex_digits[0]='0';
2100 hex_digits[1]='1';
2101 hex_digits[2]='2';
2102 hex_digits[3]='3';
2103 hex_digits[4]='4';
2104 hex_digits[5]='5';
2105 hex_digits[6]='6';
2106 hex_digits[7]='7';
2107 hex_digits[8]='8';
2108 hex_digits[9]='9';
2109 hex_digits[10]='a';
2110 hex_digits[11]='b';
2111 hex_digits[12]='c';
2112 hex_digits[13]='d';
2113 hex_digits[14]='e';
2114 hex_digits[15]='f';
2115 p=string_info->datum;
2116 q=(unsigned char *) string;
2117 for (i=0; i < (ssize_t) string_info->length; i++)
2118 {
2119 *q++=hex_digits[(*p >> 4) & 0x0f];
2120 *q++=hex_digits[*p & 0x0f];
2121 p++;
2122 }
2123 *q='\0';
2124 return(string);
2125}
2126
2127/*
2128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2129% %
2130% %
2131% %
cristy3ed852e2009-09-05 21:47:34 +00002132% S t r i n g T o A r g v %
2133% %
2134% %
2135% %
2136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2137%
2138% StringToArgv() converts a text string into command line arguments.
anthony31f1bf72012-01-30 12:37:22 +00002139% The 'argv' array of arguments, is returned while the number of arguments
2140% is returned via the provided integer variable pointer.
2141%
2142% Simple 'word' tokenizer, which allows for each word to be optionally
2143% quoted. However it will not allow use of partial quotes, or escape
2144% characters.
cristy3ed852e2009-09-05 21:47:34 +00002145%
2146% The format of the StringToArgv method is:
2147%
2148% char **StringToArgv(const char *text,int *argc)
2149%
2150% A description of each parameter follows:
2151%
2152% o argv: Method StringToArgv returns the string list unless an error
2153% occurs, otherwise NULL.
2154%
2155% o text: Specifies the string to segment into a list.
2156%
2157% o argc: This integer pointer returns the number of arguments in the
2158% list.
2159%
2160*/
2161MagickExport char **StringToArgv(const char *text,int *argc)
2162{
2163 char
2164 **argv;
2165
2166 register const char
2167 *p,
2168 *q;
2169
cristybb503372010-05-27 20:51:26 +00002170 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002171 i;
2172
2173 *argc=0;
2174 if (text == (char *) NULL)
2175 return((char **) NULL);
2176 /*
2177 Determine the number of arguments.
2178 */
2179 for (p=text; *p != '\0'; )
2180 {
2181 while (isspace((int) ((unsigned char) *p)) != 0)
2182 p++;
cristya20c9042011-05-19 13:22:18 +00002183 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00002184 break;
cristy3ed852e2009-09-05 21:47:34 +00002185 (*argc)++;
2186 if (*p == '"')
2187 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2188 if (*p == '\'')
2189 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2190 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2191 p++;
2192 }
2193 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002194 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002195 if (argv == (char **) NULL)
2196 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2197 /*
2198 Convert string to an ASCII list.
2199 */
2200 argv[0]=AcquireString("magick");
2201 p=text;
cristybb503372010-05-27 20:51:26 +00002202 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002203 {
2204 while (isspace((int) ((unsigned char) *p)) != 0)
2205 p++;
2206 q=p;
2207 if (*q == '"')
2208 {
2209 p++;
2210 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2211 }
2212 else
2213 if (*q == '\'')
2214 {
cristy06b15f42011-01-22 21:36:24 +00002215 p++;
cristy3ed852e2009-09-05 21:47:34 +00002216 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002217 }
2218 else
2219 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2220 q++;
2221 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2222 sizeof(**argv));
2223 if (argv[i] == (char *) NULL)
2224 {
2225 for (i--; i >= 0; i--)
2226 argv[i]=DestroyString(argv[i]);
2227 argv=(char **) RelinquishMagickMemory(argv);
2228 ThrowFatalException(ResourceLimitFatalError,
2229 "UnableToConvertStringToARGV");
2230 }
cristy54aad5e2010-09-03 16:02:04 +00002231 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002232 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002233 p=q;
2234 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2235 p++;
2236 }
2237 argv[i]=(char *) NULL;
2238 return(argv);
2239}
2240
2241/*
2242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2243% %
2244% %
2245% %
anthonyb1d483a2012-04-14 12:53:56 +00002246% 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 +00002247% %
2248% %
2249% %
2250%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2251%
anthonyb1d483a2012-04-14 12:53:56 +00002252% StringToArrayOfDoubles() converts a string of space or comma seperated
2253% numbers into array of floating point numbers (doubles). Any number that
2254% failes to parse properly will produce a syntax error. As will two commas
2255% without a number between them. However a final comma at the end will
2256% not be regarded as an error so as to simplify automatic list generation.
cristy3ed852e2009-09-05 21:47:34 +00002257%
anthonyb1d483a2012-04-14 12:53:56 +00002258% A NULL value is returned on syntax or memory errors.
cristy3ed852e2009-09-05 21:47:34 +00002259%
anthonyb1d483a2012-04-14 12:53:56 +00002260% Use RelinquishMagickMemory() to free returned array when finished.
2261%
2262% The format of the StringToArrayOfDoubles method is:
2263%
cristy0a887dc2012-08-15 22:58:36 +00002264% double *StringToArrayOfDoubles(const char *string,size_t *count,
2265% ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002266%
2267% A description of each parameter follows:
2268%
anthonyb1d483a2012-04-14 12:53:56 +00002269% o string: the string containing the comma/space seperated values.
2270%
2271% o count: returns number of arguments in returned array
2272%
cristyb86be3d2012-04-14 14:53:30 +00002273% o exception: return 'memory failure' exceptions
cristy3ed852e2009-09-05 21:47:34 +00002274%
2275*/
cristy0a887dc2012-08-15 22:58:36 +00002276MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2277 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002278{
anthonyb1d483a2012-04-14 12:53:56 +00002279 char
2280 *q;
2281
cristy0a887dc2012-08-15 22:58:36 +00002282 const char
2283 *p;
2284
anthonyb1d483a2012-04-14 12:53:56 +00002285 double
2286 *array;
2287
cristybb503372010-05-27 20:51:26 +00002288 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002289 i;
2290
cristy0a887dc2012-08-15 22:58:36 +00002291 /*
2292 Determine count of values, and check syntax.
2293 */
cristyb0de93f2013-05-03 13:39:25 +00002294 assert(exception != (ExceptionInfo *) NULL);
2295 assert(exception->signature == MagickSignature);
anthonyb1d483a2012-04-14 12:53:56 +00002296 *count=0;
anthonyb1d483a2012-04-14 12:53:56 +00002297 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002298 p=string;
2299 while (*p != '\0')
cristy3ed852e2009-09-05 21:47:34 +00002300 {
cristy0a887dc2012-08-15 22:58:36 +00002301 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2302 if (p == q)
2303 return((double *) NULL); /* no value found */
2304 p=q;
2305 i++; /* increment value count */
2306 while (isspace((int) ((unsigned char) *p)) != 0)
2307 p++; /* skip spaces */
2308 if (*p == ',')
2309 p++; /* skip comma */
2310 while (isspace((int) ((unsigned char) *p)) != 0)
2311 p++; /* and more spaces */
cristy3ed852e2009-09-05 21:47:34 +00002312 }
cristy0a887dc2012-08-15 22:58:36 +00002313 /*
2314 Allocate floating point argument list.
2315 */
anthonyb1d483a2012-04-14 12:53:56 +00002316 *count=i;
cristy0a887dc2012-08-15 22:58:36 +00002317 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2318 if (array == (double *) NULL)
anthonyb1d483a2012-04-14 12:53:56 +00002319 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristy0a887dc2012-08-15 22:58:36 +00002320 /*
2321 Fill in the floating point values.
2322 */
anthonyb1d483a2012-04-14 12:53:56 +00002323 i=0;
cristy0a887dc2012-08-15 22:58:36 +00002324 p=string;
2325 while ((*p != '\0') && (i < *count))
2326 {
anthonyb1d483a2012-04-14 12:53:56 +00002327 array[i++]=StringToDouble(p,&q);
2328 p=q;
cristy0a887dc2012-08-15 22:58:36 +00002329 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2330 p++;
anthonyb1d483a2012-04-14 12:53:56 +00002331 }
anthonyb1d483a2012-04-14 12:53:56 +00002332 return(array);
cristy3ed852e2009-09-05 21:47:34 +00002333}
2334
2335/*
2336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2337% %
2338% %
2339% %
anthonyb1d483a2012-04-14 12:53:56 +00002340+ S t r i n g T o k e n %
cristy3ed852e2009-09-05 21:47:34 +00002341% %
2342% %
2343% %
2344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2345%
anthonyb1d483a2012-04-14 12:53:56 +00002346% StringToken() Looks for any one of given delimiters and splits the string
2347% into two separate strings by replacing the delimiter character found with a
2348% nul character.
2349%
2350% The given string pointer is changed to point to the string following the
2351% delimiter character found, or NULL. A pointer to the start of the
2352% string is returned, representing the token before the delimiter.
2353%
2354% In may ways this is equivent to the strtok() C library function, but with
2355% multiple delimiter characters rather than a delimiter string.
cristy3ed852e2009-09-05 21:47:34 +00002356%
2357% The format of the StringToken method is:
2358%
2359% char *StringToken(const char *delimiters,char **string)
2360%
2361% A description of each parameter follows:
2362%
2363% o delimiters: one or more delimiters.
2364%
2365% o string: return the first token in the string. If none is found, return
2366% NULL.
2367%
2368*/
2369MagickExport char *StringToken(const char *delimiters,char **string)
2370{
2371 char
2372 *q;
2373
2374 register char
2375 *p;
2376
2377 register const char
2378 *r;
2379
2380 register int
2381 c,
2382 d;
2383
2384 p=(*string);
2385 if (p == (char *) NULL)
2386 return((char *) NULL);
anthonyb1d483a2012-04-14 12:53:56 +00002387 q=p;
2388 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00002389 {
2390 c=(*p++);
2391 r=delimiters;
2392 do
2393 {
2394 d=(*r++);
2395 if (c == d)
2396 {
2397 if (c == '\0')
2398 p=(char *) NULL;
2399 else
2400 p[-1]='\0';
2401 *string=p;
2402 return(q);
2403 }
2404 } while (d != '\0');
2405 }
2406}
2407
2408/*
2409%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2410% %
2411% %
2412% %
2413% S t r i n g T o L i s t %
2414% %
2415% %
2416% %
2417%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2418%
2419% StringToList() converts a text string into a list by segmenting the text
2420% string at each carriage return discovered. The list is converted to HEX
2421% characters if any control characters are discovered within the text string.
2422%
2423% The format of the StringToList method is:
2424%
2425% char **StringToList(const char *text)
2426%
2427% A description of each parameter follows:
2428%
cristy3ed852e2009-09-05 21:47:34 +00002429% o text: Specifies the string to segment into a list.
2430%
2431*/
2432MagickExport char **StringToList(const char *text)
2433{
2434 char
2435 **textlist;
2436
2437 register const char
2438 *p;
2439
cristybb503372010-05-27 20:51:26 +00002440 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002441 i;
2442
cristybb503372010-05-27 20:51:26 +00002443 size_t
cristy3ed852e2009-09-05 21:47:34 +00002444 lines;
2445
2446 if (text == (char *) NULL)
2447 return((char **) NULL);
2448 for (p=text; *p != '\0'; p++)
2449 if (((int) ((unsigned char) *p) < 32) &&
2450 (isspace((int) ((unsigned char) *p)) == 0))
2451 break;
2452 if (*p == '\0')
2453 {
2454 register const char
2455 *q;
2456
2457 /*
2458 Convert string to an ASCII list.
2459 */
2460 lines=1;
2461 for (p=text; *p != '\0'; p++)
2462 if (*p == '\n')
2463 lines++;
2464 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2465 sizeof(*textlist));
2466 if (textlist == (char **) NULL)
2467 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2468 p=text;
cristybb503372010-05-27 20:51:26 +00002469 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002470 {
2471 for (q=p; *q != '\0'; q++)
2472 if ((*q == '\r') || (*q == '\n'))
2473 break;
2474 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002475 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002476 if (textlist[i] == (char *) NULL)
2477 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002478 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002479 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002480 if (*q == '\r')
2481 q++;
2482 p=q+1;
2483 }
2484 }
2485 else
2486 {
2487 char
2488 hex_string[MaxTextExtent];
2489
2490 register char
2491 *q;
2492
cristybb503372010-05-27 20:51:26 +00002493 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002494 j;
2495
2496 /*
2497 Convert string to a HEX list.
2498 */
cristybb503372010-05-27 20:51:26 +00002499 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002500 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2501 sizeof(*textlist));
2502 if (textlist == (char **) NULL)
2503 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2504 p=text;
cristybb503372010-05-27 20:51:26 +00002505 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002506 {
2507 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002508 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002509 if (textlist[i] == (char *) NULL)
2510 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002511 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002512 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002513 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002514 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002515 {
cristyb51dff52011-05-19 16:55:47 +00002516 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002517 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2518 q+=2;
2519 if ((j % 0x04) == 0)
2520 *q++=' ';
2521 }
2522 for ( ; j <= 0x14; j++)
2523 {
2524 *q++=' ';
2525 *q++=' ';
2526 if ((j % 0x04) == 0)
2527 *q++=' ';
2528 }
2529 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002530 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002531 {
2532 if (isprint((int) ((unsigned char) *p)) != 0)
2533 *q++=(*p);
2534 else
2535 *q++='-';
2536 p++;
2537 }
2538 *q='\0';
2539 }
2540 }
2541 textlist[i]=(char *) NULL;
2542 return(textlist);
2543}
2544
2545/*
2546%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2547% %
2548% %
2549% %
2550% S t r i n g T o S t r i n g I n f o %
2551% %
2552% %
2553% %
2554%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2555%
cristybca58f32011-08-21 14:48:50 +00002556% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002557%
2558% The format of the StringToStringInfo method is:
2559%
2560% StringInfo *StringToStringInfo(const char *string)
2561%
2562% A description of each parameter follows:
2563%
2564% o string: The string.
2565%
2566*/
2567MagickExport StringInfo *StringToStringInfo(const char *string)
2568{
2569 StringInfo
2570 *string_info;
2571
2572 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2573 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002574 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002575 SetStringInfoDatum(string_info,(const unsigned char *) string);
2576 return(string_info);
2577}
2578
2579/*
2580%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2581% %
2582% %
2583% %
2584% S t r i p S t r i n g %
2585% %
2586% %
2587% %
2588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2589%
2590% StripString() strips any whitespace or quotes from the beginning and end of
2591% a string of characters.
2592%
2593% The format of the StripString method is:
2594%
2595% void StripString(char *message)
2596%
2597% A description of each parameter follows:
2598%
2599% o message: Specifies an array of characters.
2600%
2601*/
2602MagickExport void StripString(char *message)
2603{
2604 register char
2605 *p,
2606 *q;
2607
2608 size_t
2609 length;
2610
2611 assert(message != (char *) NULL);
2612 if (*message == '\0')
2613 return;
2614 length=strlen(message);
2615 p=message;
2616 while (isspace((int) ((unsigned char) *p)) != 0)
2617 p++;
2618 if ((*p == '\'') || (*p == '"'))
2619 p++;
2620 q=message+length-1;
2621 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2622 q--;
2623 if (q > p)
2624 if ((*q == '\'') || (*q == '"'))
2625 q--;
cristya63c1ba2011-06-02 20:33:43 +00002626 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002627 message[q-p+1]='\0';
2628 for (p=message; *p != '\0'; p++)
2629 if (*p == '\n')
2630 *p=' ';
2631}
2632
2633/*
2634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2635% %
2636% %
2637% %
2638% S u b s t i t u t e S t r i n g %
2639% %
2640% %
2641% %
2642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2643%
cristyf1b72c12009-10-06 13:25:21 +00002644% SubstituteString() performs string substitution on a string, replacing the
2645% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002646% If the string is matched and status, MagickTrue is returned otherwise
2647% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002648%
2649% The format of the SubstituteString method is:
2650%
cristyf1b72c12009-10-06 13:25:21 +00002651% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002652% const char *replace)
2653%
2654% A description of each parameter follows:
2655%
cristyf1b72c12009-10-06 13:25:21 +00002656% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002657% allocation if a replacement is made.
2658%
cristybc3392a2009-10-06 03:15:57 +00002659% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002660%
cristybc3392a2009-10-06 03:15:57 +00002661% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002662%
2663*/
cristyf1b72c12009-10-06 13:25:21 +00002664MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002665 const char *search,const char *replace)
2666{
cristybc3392a2009-10-06 03:15:57 +00002667 MagickBooleanType
2668 status;
cristy3ed852e2009-09-05 21:47:34 +00002669
cristybc3392a2009-10-06 03:15:57 +00002670 register char
2671 *p;
cristy3ed852e2009-09-05 21:47:34 +00002672
cristy3ed852e2009-09-05 21:47:34 +00002673 size_t
cristybc3392a2009-10-06 03:15:57 +00002674 extent,
2675 replace_extent,
2676 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002677
cristyf1b72c12009-10-06 13:25:21 +00002678 ssize_t
2679 offset;
2680
cristybc3392a2009-10-06 03:15:57 +00002681 status=MagickFalse;
2682 search_extent=0,
2683 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002684 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002685 {
cristyf1b72c12009-10-06 13:25:21 +00002686 if (search_extent == 0)
2687 search_extent=strlen(search);
2688 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002689 continue;
cristy3ed852e2009-09-05 21:47:34 +00002690 /*
cristybc3392a2009-10-06 03:15:57 +00002691 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002692 */
cristyf1b72c12009-10-06 13:25:21 +00002693 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002694 if (replace_extent == 0)
2695 replace_extent=strlen(replace);
2696 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002697 {
cristybc3392a2009-10-06 03:15:57 +00002698 /*
2699 Make room for the replacement string.
2700 */
cristyde58b412010-02-18 03:53:40 +00002701 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002702 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002703 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2704 sizeof(*p));
2705 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002706 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002707 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002708 }
cristy3ed852e2009-09-05 21:47:34 +00002709 /*
cristybc3392a2009-10-06 03:15:57 +00002710 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002711 */
cristybc3392a2009-10-06 03:15:57 +00002712 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002713 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2714 strlen(p+search_extent)+1);
2715 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002716 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002717 }
cristybc3392a2009-10-06 03:15:57 +00002718 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002719}