blob: 71856b47dd70906e502b5e831a0b3a0f1de6d6cc [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% %
cristy1454be72011-12-19 01:52:48 +000020% Copyright 1999-2012 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"
51#include "MagickCore/property.h"
52#include "MagickCore/resource_.h"
53#include "MagickCore/signature-private.h"
54#include "MagickCore/string_.h"
cristy18c6c272011-09-23 14:40:37 +000055#include "MagickCore/utility-private.h"
cristy3ed852e2009-09-05 21:47:34 +000056
57/*
cristy99bbf2c2011-09-26 18:27:50 +000058 static declarations.
cristy3ed852e2009-09-05 21:47:34 +000059*/
60#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
61static const unsigned char
cristy99bbf2c2011-09-26 18:27:50 +000062 asciimap[] =
cristy3ed852e2009-09-05 21:47:34 +000063 {
64 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
65 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
66 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
67 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
68 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
69 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
70 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
71 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
72 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
73 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
74 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
75 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
76 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
77 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
78 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
79 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
80 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
81 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
82 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
83 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
84 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
85 0xfc, 0xfd, 0xfe, 0xff,
86 };
87#endif
88
89/*
90%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91% %
92% %
93% %
94% A c q u i r e S t r i n g %
95% %
96% %
97% %
98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99%
100% AcquireString() allocates memory for a string and copies the source string
101% to that memory location (and returns it).
102%
103% The format of the AcquireString method is:
104%
105% char *AcquireString(const char *source)
106%
107% A description of each parameter follows:
108%
109% o source: A character string.
110%
111*/
112MagickExport char *AcquireString(const char *source)
113{
114 char
115 *destination;
116
117 size_t
118 length;
119
120 length=0;
121 if (source != (char *) NULL)
122 length+=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000123 if (~length < MaxTextExtent)
124 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
125 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
126 sizeof(*destination));
cristy3ed852e2009-09-05 21:47:34 +0000127 if (destination == (char *) NULL)
128 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
129 *destination='\0';
130 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000131 (void) memcpy(destination,source,length*sizeof(*destination));
132 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000133 return(destination);
134}
135
136/*
137%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138% %
139% %
140% %
141% A c q u i r e S t r i n g I n f o %
142% %
143% %
144% %
145%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146%
147% AcquireStringInfo() allocates the StringInfo structure.
148%
149% The format of the AcquireStringInfo method is:
150%
151% StringInfo *AcquireStringInfo(const size_t length)
152%
153% A description of each parameter follows:
154%
155% o length: the string length.
156%
157*/
158MagickExport StringInfo *AcquireStringInfo(const size_t length)
159{
160 StringInfo
161 *string_info;
162
cristy73bd4a52010-10-05 11:24:23 +0000163 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000164 if (string_info == (StringInfo *) NULL)
165 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
166 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
167 string_info->signature=MagickSignature;
168 string_info->length=length;
169 if (string_info->length != 0)
170 {
171 string_info->datum=(unsigned char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000172 if (~string_info->length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000173 string_info->datum=(unsigned char *) AcquireQuantumMemory(
174 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
175 if (string_info->datum == (unsigned char *) NULL)
176 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
177 }
178 return(string_info);
179}
180
181/*
182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183% %
184% %
185% %
cristy8723e4b2011-09-01 13:11:19 +0000186% B l o b T o S t r i n g I n f o %
187% %
188% %
189% %
190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191%
192% BlobToStringInfo() returns the contents of a blob as a string.
193%
194% The format of the BlobToStringInfo method is:
195%
196% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
197%
198% A description of each parameter follows:
199%
200% o blob: the blob.
201%
202% o length: the length of the blob.
203%
204*/
205MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
206{
207 StringInfo
208 *string_info;
209
210 string_info=AcquireStringInfo(0);
cristyf8316342011-09-01 13:55:00 +0000211 string_info->length=length;
cristya10e0742011-09-01 13:50:43 +0000212 if (~string_info->length >= (MaxTextExtent-1))
cristyf8316342011-09-01 13:55:00 +0000213 string_info->datum=(unsigned char *) AcquireQuantumMemory(
214 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
cristy8723e4b2011-09-01 13:11:19 +0000215 if (string_info->datum == (unsigned char *) NULL)
216 {
217 string_info=DestroyStringInfo(string_info);
218 return((StringInfo *) NULL);
219 }
220 if (blob != (const void *) NULL)
221 (void) memcpy(string_info->datum,blob,length);
222 return(string_info);
223}
224
225/*
226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227% %
228% %
229% %
cristy3ed852e2009-09-05 21:47:34 +0000230% C l o n e S t r i n g %
231% %
232% %
233% %
234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235%
236% CloneString() allocates memory for the destination string and copies
237% the source string to that memory location.
238%
anthony72feaa62012-01-17 06:46:23 +0000239% If source is a NULL pointer the destination will also be set to a NULL
240% point (any existing string is freed). Otherwise the memory is allocated
241% (or resized) and the source string copied into it.
242%
243% A pointer to the copy of the source string, or NULL is returned.
244%
cristy3ed852e2009-09-05 21:47:34 +0000245% The format of the CloneString method is:
246%
247% char *CloneString(char **destination,const char *source)
248%
249% A description of each parameter follows:
250%
251% o destination: A pointer to a character string.
252%
253% o source: A character string.
254%
255*/
256MagickExport char *CloneString(char **destination,const char *source)
257{
258 size_t
259 length;
260
261 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
262 assert(destination != (char **) NULL);
263 if (source == (const char *) NULL)
264 {
265 if (*destination != (char *) NULL)
266 *destination=DestroyString(*destination);
267 return(*destination);
268 }
269 if (*destination == (char *) NULL)
270 {
271 *destination=AcquireString(source);
272 return(*destination);
273 }
274 length=strlen(source);
275 if (~length < MaxTextExtent)
276 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
277 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000278 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000279 if (*destination == (char *) NULL)
280 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000281 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000282 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000283 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000284 return(*destination);
285}
286
287/*
288%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289% %
290% %
291% %
292% C l o n e S t r i n g I n f o %
293% %
294% %
295% %
296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297%
298% CloneStringInfo() clones a copy of the StringInfo structure.
299%
300% The format of the CloneStringInfo method is:
301%
302% StringInfo *CloneStringInfo(const StringInfo *string_info)
303%
304% A description of each parameter follows:
305%
306% o string_info: the string info.
307%
308*/
309MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
310{
311 StringInfo
312 *clone_info;
313
314 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
315 assert(string_info != (StringInfo *) NULL);
316 assert(string_info->signature == MagickSignature);
317 clone_info=AcquireStringInfo(string_info->length);
318 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000319 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000320 return(clone_info);
321}
322
323/*
324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325% %
326% %
327% %
328% C o m p a r e S t r i n g I n f o %
329% %
330% %
331% %
332%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333%
334% CompareStringInfo() compares the two datums target and source. It returns
335% an integer less than, equal to, or greater than zero if target is found,
336% respectively, to be less than, to match, or be greater than source.
337%
338% The format of the CompareStringInfo method is:
339%
340% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
341%
342% A description of each parameter follows:
343%
344% o target: the target string.
345%
346% o source: the source string.
347%
348*/
349
350static inline size_t MagickMin(const size_t x,const size_t y)
351{
352 if (x < y)
353 return(x);
354 return(y);
355}
356
357MagickExport int CompareStringInfo(const StringInfo *target,
358 const StringInfo *source)
359{
360 int
361 status;
362
363 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
364 assert(target != (StringInfo *) NULL);
365 assert(target->signature == MagickSignature);
366 assert(source != (StringInfo *) NULL);
367 assert(source->signature == MagickSignature);
368 status=memcmp(target->datum,source->datum,MagickMin(target->length,
369 source->length));
370 if (status != 0)
371 return(status);
372 if (target->length == source->length)
373 return(0);
374 return(target->length < source->length ? -1 : 1);
375}
376
377/*
378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379% %
380% %
381% %
382% C o n c a t e n a t e M a g i c k S t r i n g %
383% %
384% %
385% %
386%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387%
388% ConcatenateMagickString() concatenates the source string to the destination
389% string. The destination buffer is always null-terminated even if the
390% string must be truncated.
391%
392% The format of the ConcatenateMagickString method is:
393%
394% size_t ConcatenateMagickString(char *destination,const char *source,
395% const size_t length)
396%
397% A description of each parameter follows:
398%
399% o destination: the destination string.
400%
401% o source: the source string.
402%
403% o length: the length of the destination string.
404%
405*/
406MagickExport size_t ConcatenateMagickString(char *destination,
407 const char *source,const size_t length)
408{
409 register char
410 *q;
411
412 register const char
413 *p;
414
415 register size_t
416 i;
417
418 size_t
419 count;
420
421 assert(destination != (char *) NULL);
422 assert(source != (const char *) NULL);
423 assert(length >= 1);
424 p=source;
425 q=destination;
426 i=length;
427 while ((i-- != 0) && (*q != '\0'))
428 q++;
429 count=(size_t) (q-destination);
430 i=length-count;
431 if (i == 0)
432 return(count+strlen(p));
433 while (*p != '\0')
434 {
435 if (i != 1)
436 {
437 *q++=(*p);
438 i--;
439 }
440 p++;
441 }
442 *q='\0';
443 return(count+(p-source));
444}
445
446/*
447%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448% %
449% %
450% %
451% C o n c a t e n a t e S t r i n g %
452% %
453% %
454% %
455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456%
457% ConcatenateString() appends a copy of string source, including the
458% terminating null character, to the end of string destination.
459%
460% The format of the ConcatenateString method is:
461%
462% MagickBooleanType ConcatenateString(char **destination,
463% const char *source)
464%
465% A description of each parameter follows:
466%
467% o destination: A pointer to a character string.
468%
469% o source: A character string.
470%
471*/
472MagickExport MagickBooleanType ConcatenateString(char **destination,
473 const char *source)
474{
475 size_t
cristy54aad5e2010-09-03 16:02:04 +0000476 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000477 length,
478 source_length;
479
480 assert(destination != (char **) NULL);
481 if (source == (const char *) NULL)
482 return(MagickTrue);
483 if (*destination == (char *) NULL)
484 {
485 *destination=AcquireString(source);
486 return(MagickTrue);
487 }
cristy54aad5e2010-09-03 16:02:04 +0000488 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000489 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000490 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000491 if (~length < source_length)
492 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
493 length+=source_length;
494 if (~length < MaxTextExtent)
495 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
496 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000497 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000498 if (*destination == (char *) NULL)
499 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000500 if (source_length != 0)
501 (void) memcpy((*destination)+destination_length,source,source_length);
502 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000503 return(MagickTrue);
504}
505
506/*
507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
508% %
509% %
510% %
511% C o n c a t e n a t e S t r i n g I n f o %
512% %
513% %
514% %
515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
516%
517% ConcatenateStringInfo() concatenates the source string to the destination
518% string.
519%
520% The format of the ConcatenateStringInfo method is:
521%
522% void ConcatenateStringInfo(StringInfo *string_info,
523% const StringInfo *source)
524%
525% A description of each parameter follows:
526%
527% o string_info: the string info.
528%
529% o source: the source string.
530%
531*/
532MagickExport void ConcatenateStringInfo(StringInfo *string_info,
533 const StringInfo *source)
534{
535 size_t
536 length;
537
538 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
539 assert(string_info != (StringInfo *) NULL);
540 assert(string_info->signature == MagickSignature);
541 assert(source != (const StringInfo *) NULL);
542 length=string_info->length;
543 if (~length < source->length)
544 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
545 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000546 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000547}
548
549/*
550%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
551% %
552% %
553% %
554% 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 %
555% %
556% %
557% %
558%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
559%
560% ConfigureFileToStringInfo() returns the contents of a configure file as a
561% string.
562%
563% The format of the ConfigureFileToStringInfo method is:
564%
565% StringInfo *ConfigureFileToStringInfo(const char *filename)
566% ExceptionInfo *exception)
567%
568% A description of each parameter follows:
569%
570% o filename: the filename.
571%
572*/
cristy99bbf2c2011-09-26 18:27:50 +0000573MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +0000574{
575 char
576 *string;
577
578 int
579 file;
580
581 MagickOffsetType
582 offset;
583
584 size_t
585 length;
586
587 StringInfo
588 *string_info;
589
590 void
591 *map;
592
593 assert(filename != (const char *) NULL);
cristy18c6c272011-09-23 14:40:37 +0000594 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
cristy3ed852e2009-09-05 21:47:34 +0000595 if (file == -1)
596 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000597 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000598 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
599 {
600 file=close(file)-1;
601 return((StringInfo *) NULL);
602 }
603 length=(size_t) offset;
604 string=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000605 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000606 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
607 if (string == (char *) NULL)
608 {
609 file=close(file)-1;
610 return((StringInfo *) NULL);
611 }
612 map=MapBlob(file,ReadMode,0,length);
613 if (map != (void *) NULL)
614 {
cristy54aad5e2010-09-03 16:02:04 +0000615 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000616 (void) UnmapBlob(map,length);
617 }
618 else
619 {
620 register size_t
621 i;
622
623 ssize_t
624 count;
625
cristy7f317702011-02-18 20:40:28 +0000626 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000627 for (i=0; i < length; i+=count)
628 {
629 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
630 SSIZE_MAX));
631 if (count <= 0)
632 {
633 count=0;
634 if (errno != EINTR)
635 break;
636 }
637 }
638 if (i < length)
639 {
640 file=close(file)-1;
641 string=DestroyString(string);
642 return((StringInfo *) NULL);
643 }
644 }
645 string[length]='\0';
646 file=close(file)-1;
647 string_info=AcquireStringInfo(0);
648 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
649 string_info->length=length;
650 string_info->datum=(unsigned char *) string;
651 return(string_info);
652}
653
654/*
655%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
656% %
657% %
658% %
659% C o n s t a n t S t r i n g %
660% %
661% %
662% %
663%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664%
665% ConstantString() allocates memory for a string and copies the source string
666% to that memory location (and returns it). Use it for strings that you do
667% do not expect to change over its lifetime.
668%
669% The format of the ConstantString method is:
670%
671% char *ConstantString(const char *source)
672%
673% A description of each parameter follows:
674%
675% o source: A character string.
676%
677*/
678MagickExport char *ConstantString(const char *source)
679{
680 char
681 *destination;
682
683 size_t
684 length;
685
686 length=0;
687 if (source != (char *) NULL)
688 length+=strlen(source);
689 destination=(char *) NULL;
690 if (~length >= 1UL)
691 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
692 if (destination == (char *) NULL)
693 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
694 *destination='\0';
695 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000696 (void) memcpy(destination,source,length*sizeof(*destination));
697 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000698 return(destination);
699}
700
701/*
702%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
703% %
704% %
705% %
706% C o p y M a g i c k S t r i n g %
707% %
708% %
709% %
710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
711%
712% CopyMagickString() copies the source string to the destination string. The
713% destination buffer is always null-terminated even if the string must be
714% truncated. The return value is the minimum of the source string length
715% or the length parameter.
716%
717% The format of the CopyMagickString method is:
718%
719% size_t CopyMagickString(const char *destination,char *source,
720% const size_t length)
721%
722% A description of each parameter follows:
723%
724% o destination: the destination string.
725%
726% o source: the source string.
727%
728% o length: the length of the destination string.
729%
730*/
731MagickExport size_t CopyMagickString(char *destination,const char *source,
732 const size_t length)
733{
734 register char
735 *q;
736
737 register const char
738 *p;
739
740 register size_t
741 n;
742
cristy77e3fcc2011-10-11 00:04:41 +0000743 if (source == (const char *) NULL)
744 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000745 p=source;
746 q=destination;
747 for (n=length; n > 4; n-=4)
748 {
749 *q=(*p++);
750 if (*q == '\0')
751 return((size_t) (p-source-1));
752 q++;
753 *q=(*p++);
754 if (*q == '\0')
755 return((size_t) (p-source-1));
756 q++;
757 *q=(*p++);
758 if (*q == '\0')
759 return((size_t) (p-source-1));
760 q++;
761 *q=(*p++);
762 if (*q == '\0')
763 return((size_t) (p-source-1));
764 q++;
765 }
766 if (n != 0)
767 for (n--; n != 0; n--)
768 {
769 *q=(*p++);
770 if (*q == '\0')
771 return((size_t) (p-source-1));
772 q++;
773 }
774 if (length != 0)
775 *q='\0';
776 return((size_t) (p-source-1));
777}
778
779/*
780%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781% %
782% %
783% %
784% D e s t r o y S t r i n g %
785% %
786% %
787% %
788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789%
790% DestroyString() destroys memory associated with a string.
791%
792% The format of the DestroyString method is:
793%
794% char *DestroyString(char *string)
795%
796% A description of each parameter follows:
797%
798% o string: the string.
799%
800*/
801MagickExport char *DestroyString(char *string)
802{
803 return((char *) RelinquishMagickMemory(string));
804}
805
806/*
807%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
808% %
809% %
810% %
811% D e s t r o y S t r i n g I n f o %
812% %
813% %
814% %
815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816%
817% DestroyStringInfo() destroys memory associated with the StringInfo structure.
818%
819% The format of the DestroyStringInfo method is:
820%
821% StringInfo *DestroyStringInfo(StringInfo *string_info)
822%
823% A description of each parameter follows:
824%
825% o string_info: the string info.
826%
827*/
828MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
829{
830 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
831 assert(string_info != (StringInfo *) NULL);
832 assert(string_info->signature == MagickSignature);
833 if (string_info->datum != (unsigned char *) NULL)
834 string_info->datum=(unsigned char *) RelinquishMagickMemory(
835 string_info->datum);
836 string_info->signature=(~MagickSignature);
837 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
838 return(string_info);
839}
840
841/*
842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843% %
844% %
845% %
846% D e s t r o y S t r i n g L i s t %
847% %
848% %
849% %
850%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851%
852% DestroyStringList() zeros memory associated with a string list.
853%
854% The format of the DestroyStringList method is:
855%
856% char **DestroyStringList(char **list)
857%
858% A description of each parameter follows:
859%
860% o list: the string list.
861%
862*/
863MagickExport char **DestroyStringList(char **list)
864{
cristybb503372010-05-27 20:51:26 +0000865 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000866 i;
867
868 assert(list != (char **) NULL);
869 for (i=0; list[i] != (char *) NULL; i++)
870 list[i]=DestroyString(list[i]);
871 list=(char **) RelinquishMagickMemory(list);
872 return(list);
873}
874
875/*
876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
877% %
878% %
879% %
880% E s c a p e S t r i n g %
881% %
882% %
883% %
884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
885%
886% EscapeString() allocates memory for a backslash-escaped version of a
887% source text string, copies the escaped version of the text to that
888% memory location while adding backslash characters, and returns the
889% escaped string.
890%
891% The format of the EscapeString method is:
892%
893% char *EscapeString(const char *source,const char escape)
894%
895% A description of each parameter follows:
896%
897% o allocate_string: Method EscapeString returns the escaped string.
898%
899% o source: A character string.
900%
901% o escape: the quoted string termination character to escape (e.g. '"').
902%
903*/
904MagickExport char *EscapeString(const char *source,const char escape)
905{
906 char
907 *destination;
908
909 register char
910 *q;
911
912 register const char
913 *p;
914
915 size_t
916 length;
917
918 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
919 assert(source != (const char *) NULL);
920 length=strlen(source);
921 for (p=source; *p != '\0'; p++)
922 if ((*p == '\\') || (*p == escape))
923 {
924 if (~length < 1)
925 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
926 length++;
927 }
928 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000929 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000930 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
931 sizeof(*destination));
932 if (destination == (char *) NULL)
933 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
934 *destination='\0';
935 if (source != (char *) NULL)
936 {
937 q=destination;
938 for (p=source; *p != '\0'; p++)
939 {
940 if ((*p == '\\') || (*p == escape))
941 *q++='\\';
942 *q++=(*p);
943 }
944 *q='\0';
945 }
946 return(destination);
947}
948
949/*
950%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951% %
952% %
953% %
954% F i l e T o S t r i n g %
955% %
956% %
957% %
958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959%
960% FileToString() returns the contents of a file as a string.
961%
962% The format of the FileToString method is:
963%
964% char *FileToString(const char *filename,const size_t extent,
965% ExceptionInfo *exception)
966%
967% A description of each parameter follows:
968%
969% o filename: the filename.
970%
971% o extent: Maximum length of the string.
972%
973% o exception: return any errors or warnings in this structure.
974%
975*/
976MagickExport char *FileToString(const char *filename,const size_t extent,
977 ExceptionInfo *exception)
978{
979 size_t
980 length;
981
982 assert(filename != (const char *) NULL);
983 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
984 assert(exception != (ExceptionInfo *) NULL);
985 return((char *) FileToBlob(filename,extent,&length,exception));
986}
987
988/*
989%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
990% %
991% %
992% %
993% F i l e T o S t r i n g I n f o %
994% %
995% %
996% %
997%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
998%
999% FileToStringInfo() returns the contents of a file as a string.
1000%
1001% The format of the FileToStringInfo method is:
1002%
1003% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1004% ExceptionInfo *exception)
1005%
1006% A description of each parameter follows:
1007%
1008% o filename: the filename.
1009%
1010% o extent: Maximum length of the string.
1011%
1012% o exception: return any errors or warnings in this structure.
1013%
1014*/
1015MagickExport StringInfo *FileToStringInfo(const char *filename,
1016 const size_t extent,ExceptionInfo *exception)
1017{
1018 StringInfo
1019 *string_info;
1020
1021 assert(filename != (const char *) NULL);
1022 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1023 assert(exception != (ExceptionInfo *) NULL);
1024 string_info=AcquireStringInfo(0);
1025 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1026 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1027 if (string_info->datum == (unsigned char *) NULL)
1028 {
1029 string_info=DestroyStringInfo(string_info);
1030 return((StringInfo *) NULL);
1031 }
1032 return(string_info);
1033}
1034
1035/*
1036%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1037% %
1038% %
1039% %
1040% F o r m a t M a g i c k S i z e %
1041% %
1042% %
1043% %
1044%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1045%
1046% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +00001047% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +00001048% 1000.
cristy3ed852e2009-09-05 21:47:34 +00001049%
1050% The format of the FormatMagickSize method is:
1051%
cristybb503372010-05-27 20:51:26 +00001052% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001053%
1054% A description of each parameter follows:
1055%
1056% o size: convert this size to a human readable format.
1057%
cristyb9080c92009-12-01 20:13:26 +00001058% o bi: use power of two rather than power of ten.
1059%
cristy3ed852e2009-09-05 21:47:34 +00001060% o format: human readable format.
1061%
1062*/
cristy99bbf2c2011-09-26 18:27:50 +00001063MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001064 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001065{
cristyb9080c92009-12-01 20:13:26 +00001066 const char
1067 **units;
1068
cristy3ed852e2009-09-05 21:47:34 +00001069 double
cristyb9080c92009-12-01 20:13:26 +00001070 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001071 length;
1072
cristybb503372010-05-27 20:51:26 +00001073 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001074 i,
1075 j;
1076
cristy9d314ff2011-03-09 01:30:28 +00001077 ssize_t
1078 count;
1079
cristy3ed852e2009-09-05 21:47:34 +00001080 static const char
cristyb9080c92009-12-01 20:13:26 +00001081 *bi_units[] =
1082 {
cristy2ce15c92010-03-12 14:03:41 +00001083 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001084 },
1085 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001086 {
cristy2ce15c92010-03-12 14:03:41 +00001087 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001088 };
cristy3ed852e2009-09-05 21:47:34 +00001089
cristyb9080c92009-12-01 20:13:26 +00001090 bytes=1000.0;
1091 units=traditional_units;
1092 if (bi != MagickFalse)
1093 {
1094 bytes=1024.0;
1095 units=bi_units;
1096 }
cristy3ed852e2009-09-05 21:47:34 +00001097#if defined(_MSC_VER) && (_MSC_VER == 1200)
1098 length=(double) ((MagickOffsetType) size);
1099#else
1100 length=(double) size;
1101#endif
cristyb9080c92009-12-01 20:13:26 +00001102 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1103 length/=bytes;
cristy9bf9da32009-09-27 16:48:34 +00001104 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001105 {
cristyb51dff52011-05-19 16:55:47 +00001106 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001107 units[i]);
1108 if (strchr(format,'+') == (char *) NULL)
1109 break;
1110 }
1111 return(count);
1112}
1113
1114/*
1115%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1116% %
1117% %
1118% %
cristy3ed852e2009-09-05 21:47:34 +00001119% F o r m a t M a g i c k T i m e %
1120% %
1121% %
1122% %
1123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124%
1125% FormatMagickTime() returns the specified time in the Internet date/time
1126% format and the length of the timestamp.
1127%
1128% The format of the FormatMagickTime method is:
1129%
cristybb503372010-05-27 20:51:26 +00001130% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001131% char *timestamp)
1132%
1133% A description of each parameter follows.
1134%
1135% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1136% measured in seconds.
1137%
1138% o length: the maximum length of the string.
1139%
1140% o timestamp: Return the Internet date/time here.
1141%
1142*/
cristybb503372010-05-27 20:51:26 +00001143MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001144 char *timestamp)
1145{
cristybb503372010-05-27 20:51:26 +00001146 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001147 count;
1148
1149 struct tm
1150 gm_time,
1151 local_time;
1152
1153 time_t
1154 timezone;
1155
1156 assert(timestamp != (char *) NULL);
1157 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1158 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1159#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1160 (void) localtime_r(&time,&local_time);
1161#else
1162 {
cristybc3392a2009-10-06 03:15:57 +00001163 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001164 *my_time;
1165
1166 my_time=localtime(&time);
1167 if (my_time != (struct tm *) NULL)
1168 (void) memcpy(&local_time,my_time,sizeof(local_time));
1169 }
1170#endif
1171#if defined(MAGICKCORE_HAVE_GMTIME_R)
1172 (void) gmtime_r(&time,&gm_time);
1173#else
1174 {
cristybc3392a2009-10-06 03:15:57 +00001175 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001176 *my_time;
1177
1178 my_time=gmtime(&time);
1179 if (my_time != (struct tm *) NULL)
1180 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1181 }
1182#endif
1183 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1184 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1185 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1186 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001187 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001188 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1189 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001190 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001191 return(count);
1192}
1193
1194/*
1195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1196% %
1197% %
1198% %
1199% G e t E n v i r o n m e n t V a l u e %
1200% %
1201% %
1202% %
1203%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1204%
1205% GetEnvironmentValue() returns the environment string that matches the
1206% specified name.
1207%
1208% The format of the GetEnvironmentValue method is:
1209%
1210% char *GetEnvironmentValue(const char *name)
1211%
1212% A description of each parameter follows:
1213%
1214% o name: the environment name.
1215%
1216*/
cristy99bbf2c2011-09-26 18:27:50 +00001217MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001218{
1219 const char
1220 *environment;
1221
1222 environment=getenv(name);
1223 if (environment == (const char *) NULL)
1224 return((char *) NULL);
1225 return(ConstantString(environment));
1226}
1227
1228/*
1229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1230% %
1231% %
1232% %
1233% G e t S t r i n g I n f o D a t u m %
1234% %
1235% %
1236% %
1237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1238%
1239% GetStringInfoDatum() returns the datum associated with the string.
1240%
1241% The format of the GetStringInfoDatum method is:
1242%
1243% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1244%
1245% A description of each parameter follows:
1246%
1247% o string_info: the string info.
1248%
1249*/
1250MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1251{
1252 assert(string_info != (StringInfo *) NULL);
1253 assert(string_info->signature == MagickSignature);
1254 return(string_info->datum);
1255}
1256
1257/*
1258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259% %
1260% %
1261% %
1262% G e t S t r i n g I n f o L e n g t h %
1263% %
1264% %
1265% %
1266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267%
1268% GetStringInfoLength() returns the string length.
1269%
1270% The format of the GetStringInfoLength method is:
1271%
1272% size_t GetStringInfoLength(const StringInfo *string_info)
1273%
1274% A description of each parameter follows:
1275%
1276% o string_info: the string info.
1277%
1278*/
1279MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1280{
1281 assert(string_info != (StringInfo *) NULL);
1282 assert(string_info->signature == MagickSignature);
1283 return(string_info->length);
1284}
1285
1286/*
1287%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288% %
1289% %
1290% %
1291% G e t S t r i n g I n f o P a t h %
1292% %
1293% %
1294% %
1295%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1296%
1297% GetStringInfoPath() returns the path associated with the string.
1298%
1299% The format of the GetStringInfoPath method is:
1300%
1301% const char *GetStringInfoPath(const StringInfo *string_info)
1302%
1303% A description of each parameter follows:
1304%
1305% o string_info: the string info.
1306%
1307*/
1308MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1309{
1310 assert(string_info != (StringInfo *) NULL);
1311 assert(string_info->signature == MagickSignature);
1312 return(string_info->path);
1313}
1314
1315/*
1316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1317% %
1318% %
1319% %
cristydbdd0e32011-11-04 23:29:40 +00001320+ I n t e r p r e t S i P r e f i x V a l u e %
1321% %
1322% %
1323% %
1324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1325%
1326% InterpretSiPrefixValue() converts the initial portion of the string to a
1327% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1328% etc.).
1329%
1330% The format of the InterpretSiPrefixValue method is:
1331%
1332% double InterpretSiPrefixValue(const char *value,char **sentinal)
1333%
1334% A description of each parameter follows:
1335%
1336% o value: the string value.
1337%
1338% o sentinal: if sentinal is not NULL, return a pointer to the character
1339% after the last character used in the conversion.
1340%
1341*/
1342MagickExport double InterpretSiPrefixValue(const char *restrict string,
1343 char **restrict sentinal)
1344{
1345 char
1346 *q;
1347
1348 double
1349 value;
1350
cristydbdd0e32011-11-04 23:29:40 +00001351 value=InterpretLocaleValue(string,&q);
1352 if (q != string)
1353 {
1354 if ((*q >= 'E') && (*q <= 'z'))
1355 {
1356 double
1357 e;
1358
cristy0c2684f2011-11-05 21:39:43 +00001359 switch ((int) ((unsigned char) *q))
1360 {
1361 case 'y': e=(-24.0); break;
1362 case 'z': e=(-21.0); break;
1363 case 'a': e=(-18.0); break;
1364 case 'f': e=(-15.0); break;
1365 case 'p': e=(-12.0); break;
1366 case 'n': e=(-9.0); break;
1367 case 'u': e=(-6.0); break;
1368 case 'm': e=(-3.0); break;
1369 case 'c': e=(-2.0); break;
1370 case 'd': e=(-1.0); break;
1371 case 'h': e=2.0; break;
1372 case 'k': e=3.0; break;
1373 case 'K': e=3.0; break;
1374 case 'M': e=6.0; break;
1375 case 'G': e=9.0; break;
1376 case 'T': e=12.0; break;
1377 case 'P': e=15.0; break;
1378 case 'E': e=18.0; break;
1379 case 'Z': e=21.0; break;
1380 case 'Y': e=24.0; break;
1381 default: e=0.0; break;
1382 }
cristydbdd0e32011-11-04 23:29:40 +00001383 if (e >= MagickEpsilon)
1384 {
1385 if (q[1] == 'i')
1386 {
1387 value*=pow(2.0,e/0.3);
1388 q+=2;
1389 }
1390 else
1391 {
1392 value*=pow(10.0,e);
1393 q++;
1394 }
1395 }
1396 }
cristyc0f1ed12011-11-09 14:50:15 +00001397 if (*q == 'B')
cristy099a7352011-11-09 14:31:35 +00001398 q++;
cristydbdd0e32011-11-04 23:29:40 +00001399 }
1400 if (sentinal != (char **) NULL)
1401 *sentinal=q;
1402 return(value);
1403}
1404
1405/*
1406%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1407% %
1408% %
1409% %
cristy3ed852e2009-09-05 21:47:34 +00001410% L o c a l e C o m p a r e %
1411% %
1412% %
1413% %
1414%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1415%
1416% LocaleCompare() performs a case-insensitive comparison of two strings
1417% byte-by-byte, according to the ordering of the current locale encoding.
1418% LocaleCompare returns an integer greater than, equal to, or less than 0,
1419% if the string pointed to by p is greater than, equal to, or less than the
1420% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001421% is determined by the sign of the difference between the values of the first
1422% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001423%
1424% The format of the LocaleCompare method is:
1425%
cristyde58b412010-02-18 03:53:40 +00001426% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001427%
1428% A description of each parameter follows:
1429%
1430% o p: A pointer to a character string.
1431%
1432% o q: A pointer to a character string to compare to p.
1433%
1434*/
cristyde58b412010-02-18 03:53:40 +00001435MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001436{
1437 if ((p == (char *) NULL) && (q == (char *) NULL))
1438 return(0);
1439 if (p == (char *) NULL)
1440 return(-1);
1441 if (q == (char *) NULL)
1442 return(1);
1443#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001444 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001445#else
1446 {
cristyde58b412010-02-18 03:53:40 +00001447 register int
cristy3ed852e2009-09-05 21:47:34 +00001448 c,
cristya72c2d12010-02-18 01:20:28 +00001449 d;
cristy3ed852e2009-09-05 21:47:34 +00001450
cristya72c2d12010-02-18 01:20:28 +00001451 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001452 {
cristyde58b412010-02-18 03:53:40 +00001453 c=(int) *((unsigned char *) p);
1454 d=(int) *((unsigned char *) q);
1455 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001456 break;
cristya72c2d12010-02-18 01:20:28 +00001457 p++;
1458 q++;
cristy3ed852e2009-09-05 21:47:34 +00001459 }
cristyde58b412010-02-18 03:53:40 +00001460 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001461 }
1462#endif
1463}
1464
1465/*
1466%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1467% %
1468% %
1469% %
1470% L o c a l e L o w e r %
1471% %
1472% %
1473% %
1474%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1475%
1476% LocaleLower() transforms all of the characters in the supplied
1477% null-terminated string, changing all uppercase letters to lowercase.
1478%
1479% The format of the LocaleLower method is:
1480%
1481% void LocaleLower(char *string)
1482%
1483% A description of each parameter follows:
1484%
1485% o string: A pointer to the string to convert to lower-case Locale.
1486%
1487*/
1488MagickExport void LocaleLower(char *string)
1489{
1490 register char
1491 *q;
1492
1493 assert(string != (char *) NULL);
1494 for (q=string; *q != '\0'; q++)
1495 *q=(char) tolower((int) *q);
1496}
1497
1498/*
1499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1500% %
1501% %
1502% %
1503% L o c a l e N C o m p a r e %
1504% %
1505% %
1506% %
1507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1508%
1509% LocaleNCompare() performs a case-insensitive comparison of two
1510% strings byte-by-byte, according to the ordering of the current locale
1511% encoding. LocaleNCompare returns an integer greater than, equal to, or
1512% less than 0, if the string pointed to by p is greater than, equal to, or
1513% less than the string pointed to by q respectively. The sign of a non-zero
1514% return value is determined by the sign of the difference between the
1515% values of the first pair of bytes that differ in the strings being
1516% compared. The LocaleNCompare method makes the same comparison as
1517% LocaleCompare but looks at a maximum of n bytes. Bytes following a
1518% null byte are not compared.
1519%
1520% The format of the LocaleNCompare method is:
1521%
cristyde58b412010-02-18 03:53:40 +00001522% int LocaleNCompare(const char *p,const char *q,const size_t n)
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%
cristy7a40ba82011-01-08 20:31:18 +00001530% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001531%
1532*/
cristyde58b412010-02-18 03:53:40 +00001533MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001534{
cristy78c21692011-10-06 14:57:26 +00001535 if ((p == (char *) NULL) && (q == (char *) NULL))
1536 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001537 if (p == (char *) NULL)
1538 return(-1);
1539 if (q == (char *) NULL)
1540 return(1);
1541#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001542 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001543#else
1544 {
cristyde58b412010-02-18 03:53:40 +00001545 register int
cristy3ed852e2009-09-05 21:47:34 +00001546 c,
1547 d;
1548
cristyb6af4a52009-10-06 13:56:23 +00001549 register size_t
cristyc4cded12010-02-18 14:40:57 +00001550 i;
cristyb6af4a52009-10-06 13:56:23 +00001551
cristyc4cded12010-02-18 14:40:57 +00001552 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001553 {
cristyde58b412010-02-18 03:53:40 +00001554 c=(int) *((unsigned char *) p);
1555 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001556 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001557 return(AsciiMap[c]-(int) AsciiMap[d]);
1558 if (c == 0)
1559 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001560 p++;
1561 q++;
1562 }
cristyde58b412010-02-18 03:53:40 +00001563 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001564 }
1565#endif
1566}
1567
1568/*
1569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1570% %
1571% %
1572% %
1573% L o c a l e U p p e r %
1574% %
1575% %
1576% %
1577%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1578%
1579% LocaleUpper() transforms all of the characters in the supplied
1580% null-terminated string, changing all lowercase letters to uppercase.
1581%
1582% The format of the LocaleUpper method is:
1583%
1584% void LocaleUpper(char *string)
1585%
1586% A description of each parameter follows:
1587%
1588% o string: A pointer to the string to convert to upper-case Locale.
1589%
1590*/
1591MagickExport void LocaleUpper(char *string)
1592{
1593 register char
1594 *q;
1595
1596 assert(string != (char *) NULL);
1597 for (q=string; *q != '\0'; q++)
1598 *q=(char) toupper((int) *q);
1599}
1600
1601/*
1602%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1603% %
1604% %
1605% %
1606% P r i n t S t r i n g I n f o %
1607% %
1608% %
1609% %
1610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1611%
1612% PrintStringInfo() prints the string.
1613%
1614% The format of the PrintStringInfo method is:
1615%
1616% void PrintStringInfo(FILE *file,const char *id,
1617% const StringInfo *string_info)
1618%
1619% A description of each parameter follows:
1620%
1621% o file: the file, typically stdout.
1622%
1623% o id: the string id.
1624%
1625% o string_info: the string info.
1626%
1627*/
1628MagickExport void PrintStringInfo(FILE *file,const char *id,
1629 const StringInfo *string_info)
1630{
1631 register const char
1632 *p;
1633
1634 register size_t
1635 i,
1636 j;
1637
1638 assert(id != (const char *) NULL);
1639 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1640 assert(string_info != (StringInfo *) NULL);
1641 assert(string_info->signature == MagickSignature);
1642 p=(char *) string_info->datum;
1643 for (i=0; i < string_info->length; i++)
1644 {
1645 if (((int) ((unsigned char) *p) < 32) &&
1646 (isspace((int) ((unsigned char) *p)) == 0))
1647 break;
1648 p++;
1649 }
1650 if (i == string_info->length)
1651 {
1652 (void) fputs((char *) string_info->datum,file);
1653 (void) fputc('\n',file);
1654 return;
1655 }
1656 /*
1657 Convert string to a HEX list.
1658 */
1659 p=(char *) string_info->datum;
1660 for (i=0; i < string_info->length; i+=0x14)
1661 {
cristyb51dff52011-05-19 16:55:47 +00001662 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001663 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1664 {
cristyb51dff52011-05-19 16:55:47 +00001665 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001666 if ((j % 0x04) == 0)
1667 (void) fputc(' ',file);
1668 }
1669 for ( ; j <= 0x14; j++)
1670 {
1671 (void) fputc(' ',file);
1672 (void) fputc(' ',file);
1673 if ((j % 0x04) == 0)
1674 (void) fputc(' ',file);
1675 }
1676 (void) fputc(' ',file);
1677 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1678 {
1679 if (isprint((int) ((unsigned char) *p)) != 0)
1680 (void) fputc(*p,file);
1681 else
1682 (void) fputc('-',file);
1683 p++;
1684 }
1685 (void) fputc('\n',file);
1686 }
1687}
1688
1689/*
1690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1691% %
1692% %
1693% %
1694% R e s e t S t r i n g I n f o %
1695% %
1696% %
1697% %
1698%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1699%
1700% ResetStringInfo() reset the string to all null bytes.
1701%
1702% The format of the ResetStringInfo method is:
1703%
1704% void ResetStringInfo(StringInfo *string_info)
1705%
1706% A description of each parameter follows:
1707%
1708% o string_info: the string info.
1709%
1710*/
1711MagickExport void ResetStringInfo(StringInfo *string_info)
1712{
1713 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1714 assert(string_info != (StringInfo *) NULL);
1715 assert(string_info->signature == MagickSignature);
1716 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1717}
1718
1719/*
1720%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1721% %
1722% %
1723% %
1724% S e t S t r i n g I n f o %
1725% %
1726% %
1727% %
1728%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1729%
1730% SetStringInfo() copies the source string to the destination string.
1731%
1732% The format of the SetStringInfo method is:
1733%
1734% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1735%
1736% A description of each parameter follows:
1737%
1738% o string_info: the string info.
1739%
1740% o source: the source string.
1741%
1742*/
1743MagickExport void SetStringInfo(StringInfo *string_info,
1744 const StringInfo *source)
1745{
1746 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1747 assert(string_info != (StringInfo *) NULL);
1748 assert(string_info->signature == MagickSignature);
1749 assert(source != (StringInfo *) NULL);
1750 assert(source->signature == MagickSignature);
1751 if (string_info->length == 0)
1752 return;
1753 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001754 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1755 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001756}
1757
1758/*
1759%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1760% %
1761% %
1762% %
1763% S e t S t r i n g I n f o D a t u m %
1764% %
1765% %
1766% %
1767%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1768%
1769% SetStringInfoDatum() copies bytes from the source string for the length of
1770% the destination string.
1771%
1772% The format of the SetStringInfoDatum method is:
1773%
1774% void SetStringInfoDatum(StringInfo *string_info,
1775% const unsigned char *source)
1776%
1777% A description of each parameter follows:
1778%
1779% o string_info: the string info.
1780%
1781% o source: the source string.
1782%
1783*/
1784MagickExport void SetStringInfoDatum(StringInfo *string_info,
1785 const unsigned char *source)
1786{
1787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1788 assert(string_info != (StringInfo *) NULL);
1789 assert(string_info->signature == MagickSignature);
1790 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001791 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001792}
1793
1794/*
1795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1796% %
1797% %
1798% %
1799% S e t S t r i n g I n f o L e n g t h %
1800% %
1801% %
1802% %
1803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1804%
1805% SetStringInfoLength() set the string length to the specified value.
1806%
1807% The format of the SetStringInfoLength method is:
1808%
1809% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1810%
1811% A description of each parameter follows:
1812%
1813% o string_info: the string info.
1814%
1815% o length: the string length.
1816%
1817*/
1818MagickExport void SetStringInfoLength(StringInfo *string_info,
1819 const size_t length)
1820{
1821 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1822 assert(string_info != (StringInfo *) NULL);
1823 assert(string_info->signature == MagickSignature);
1824 if (~length < MaxTextExtent)
1825 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1826 string_info->length=length;
1827 if (string_info->datum == (unsigned char *) NULL)
1828 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1829 MaxTextExtent,sizeof(*string_info->datum));
1830 else
1831 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1832 length+MaxTextExtent,sizeof(*string_info->datum));
1833 if (string_info->datum == (unsigned char *) NULL)
1834 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1835}
1836
1837/*
1838%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1839% %
1840% %
1841% %
1842% S e t S t r i n g I n f o D a t u m %
1843% %
1844% %
1845% %
1846%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1847%
1848% SetStringInfoPath() sets the path associated with the string.
1849%
1850% The format of the SetStringInfoPath method is:
1851%
1852% void SetStringInfoPath(StringInfo *string_info,const char *path)
1853%
1854% A description of each parameter follows:
1855%
1856% o string_info: the string info.
1857%
1858% o path: the path.
1859%
1860*/
1861MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1862{
1863 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1864 assert(string_info != (StringInfo *) NULL);
1865 assert(string_info->signature == MagickSignature);
1866 assert(path != (const char *) NULL);
1867 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1868}
1869
1870/*
1871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1872% %
1873% %
1874% %
1875% S p l i t S t r i n g I n f o %
1876% %
1877% %
1878% %
1879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1880%
1881% SplitStringInfo() splits a string into two and returns it.
1882%
1883% The format of the SplitStringInfo method is:
1884%
1885% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1886%
1887% A description of each parameter follows:
1888%
1889% o string_info: the string info.
1890%
1891*/
1892MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1893 const size_t offset)
1894{
1895 StringInfo
1896 *split_info;
1897
1898 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1899 assert(string_info != (StringInfo *) NULL);
1900 assert(string_info->signature == MagickSignature);
1901 if (offset > string_info->length)
1902 return((StringInfo *) NULL);
1903 split_info=AcquireStringInfo(offset);
1904 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00001905 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00001906 string_info->length-offset+MaxTextExtent);
1907 SetStringInfoLength(string_info,string_info->length-offset);
1908 return(split_info);
1909}
1910
1911/*
1912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1913% %
1914% %
1915% %
1916% S t r i n g I n f o T o S t r i n g %
1917% %
1918% %
1919% %
1920%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1921%
1922% StringInfoToString() converts a string info string to a C string.
1923%
1924% The format of the StringInfoToString method is:
1925%
1926% char *StringInfoToString(const StringInfo *string_info)
1927%
1928% A description of each parameter follows:
1929%
1930% o string_info: the string.
1931%
1932*/
1933MagickExport char *StringInfoToString(const StringInfo *string_info)
1934{
1935 char
1936 *string;
1937
1938 size_t
1939 length;
1940
1941 string=(char *) NULL;
1942 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00001943 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001944 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001945 if (string == (char *) NULL)
1946 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00001947 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001948 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001949 return(string);
1950}
1951
1952/*
1953%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1954% %
1955% %
1956% %
1957% S t r i n g T o A r g v %
1958% %
1959% %
1960% %
1961%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1962%
1963% StringToArgv() converts a text string into command line arguments.
anthony31f1bf72012-01-30 12:37:22 +00001964% The 'argv' array of arguments, is returned while the number of arguments
1965% is returned via the provided integer variable pointer.
1966%
1967% Simple 'word' tokenizer, which allows for each word to be optionally
1968% quoted. However it will not allow use of partial quotes, or escape
1969% characters.
cristy3ed852e2009-09-05 21:47:34 +00001970%
1971% The format of the StringToArgv method is:
1972%
1973% char **StringToArgv(const char *text,int *argc)
1974%
1975% A description of each parameter follows:
1976%
1977% o argv: Method StringToArgv returns the string list unless an error
1978% occurs, otherwise NULL.
1979%
1980% o text: Specifies the string to segment into a list.
1981%
1982% o argc: This integer pointer returns the number of arguments in the
1983% list.
1984%
1985*/
1986MagickExport char **StringToArgv(const char *text,int *argc)
1987{
1988 char
1989 **argv;
1990
1991 register const char
1992 *p,
1993 *q;
1994
cristybb503372010-05-27 20:51:26 +00001995 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001996 i;
1997
1998 *argc=0;
1999 if (text == (char *) NULL)
2000 return((char **) NULL);
2001 /*
2002 Determine the number of arguments.
2003 */
2004 for (p=text; *p != '\0'; )
2005 {
2006 while (isspace((int) ((unsigned char) *p)) != 0)
2007 p++;
cristya20c9042011-05-19 13:22:18 +00002008 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00002009 break;
cristy3ed852e2009-09-05 21:47:34 +00002010 (*argc)++;
2011 if (*p == '"')
2012 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2013 if (*p == '\'')
2014 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2015 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2016 p++;
2017 }
2018 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002019 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002020 if (argv == (char **) NULL)
2021 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2022 /*
2023 Convert string to an ASCII list.
2024 */
2025 argv[0]=AcquireString("magick");
2026 p=text;
cristybb503372010-05-27 20:51:26 +00002027 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002028 {
2029 while (isspace((int) ((unsigned char) *p)) != 0)
2030 p++;
2031 q=p;
2032 if (*q == '"')
2033 {
2034 p++;
2035 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2036 }
2037 else
2038 if (*q == '\'')
2039 {
cristy06b15f42011-01-22 21:36:24 +00002040 p++;
cristy3ed852e2009-09-05 21:47:34 +00002041 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002042 }
2043 else
2044 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2045 q++;
2046 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2047 sizeof(**argv));
2048 if (argv[i] == (char *) NULL)
2049 {
2050 for (i--; i >= 0; i--)
2051 argv[i]=DestroyString(argv[i]);
2052 argv=(char **) RelinquishMagickMemory(argv);
2053 ThrowFatalException(ResourceLimitFatalError,
2054 "UnableToConvertStringToARGV");
2055 }
cristy54aad5e2010-09-03 16:02:04 +00002056 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002057 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002058 p=q;
2059 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2060 p++;
2061 }
2062 argv[i]=(char *) NULL;
2063 return(argv);
2064}
2065
2066/*
2067%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2068% %
2069% %
2070% %
cristy3ed852e2009-09-05 21:47:34 +00002071% S t r i n g I n f o T o H e x S t r i n g %
2072% %
2073% %
2074% %
2075%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2076%
2077% StringInfoToHexString() converts a string info string to a C string.
2078%
2079% The format of the StringInfoToHexString method is:
2080%
2081% char *StringInfoToHexString(const StringInfo *string_info)
2082%
2083% A description of each parameter follows:
2084%
2085% o string_info: the string.
2086%
2087*/
2088MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2089{
2090 char
2091 *string;
2092
2093 register const unsigned char
2094 *p;
2095
cristybb503372010-05-27 20:51:26 +00002096 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002097 i;
2098
2099 register unsigned char
2100 *q;
2101
2102 size_t
2103 length;
2104
2105 unsigned char
2106 hex_digits[16];
2107
2108 length=string_info->length;
2109 if (~length < MaxTextExtent)
2110 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2111 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2112 if (string == (char *) NULL)
2113 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2114 hex_digits[0]='0';
2115 hex_digits[1]='1';
2116 hex_digits[2]='2';
2117 hex_digits[3]='3';
2118 hex_digits[4]='4';
2119 hex_digits[5]='5';
2120 hex_digits[6]='6';
2121 hex_digits[7]='7';
2122 hex_digits[8]='8';
2123 hex_digits[9]='9';
2124 hex_digits[10]='a';
2125 hex_digits[11]='b';
2126 hex_digits[12]='c';
2127 hex_digits[13]='d';
2128 hex_digits[14]='e';
2129 hex_digits[15]='f';
2130 p=string_info->datum;
2131 q=(unsigned char *) string;
cristybb503372010-05-27 20:51:26 +00002132 for (i=0; i < (ssize_t) string_info->length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002133 {
2134 *q++=hex_digits[(*p >> 4) & 0x0f];
2135 *q++=hex_digits[*p & 0x0f];
2136 p++;
2137 }
2138 *q='\0';
2139 return(string);
2140}
2141
2142/*
2143%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2144% %
2145% %
2146% %
2147% S t r i n g T o k e n %
2148% %
2149% %
2150% %
2151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2152%
2153% StringToken() extracts a token a from the string.
2154%
2155% The format of the StringToken method is:
2156%
2157% char *StringToken(const char *delimiters,char **string)
2158%
2159% A description of each parameter follows:
2160%
2161% o delimiters: one or more delimiters.
2162%
2163% o string: return the first token in the string. If none is found, return
2164% NULL.
2165%
2166*/
2167MagickExport char *StringToken(const char *delimiters,char **string)
2168{
2169 char
2170 *q;
2171
2172 register char
2173 *p;
2174
2175 register const char
2176 *r;
2177
2178 register int
2179 c,
2180 d;
2181
2182 p=(*string);
2183 if (p == (char *) NULL)
2184 return((char *) NULL);
2185 for (q=p; ; )
2186 {
2187 c=(*p++);
2188 r=delimiters;
2189 do
2190 {
2191 d=(*r++);
2192 if (c == d)
2193 {
2194 if (c == '\0')
2195 p=(char *) NULL;
2196 else
2197 p[-1]='\0';
2198 *string=p;
2199 return(q);
2200 }
2201 } while (d != '\0');
2202 }
2203}
2204
2205/*
2206%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2207% %
2208% %
2209% %
2210% S t r i n g T o L i s t %
2211% %
2212% %
2213% %
2214%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2215%
2216% StringToList() converts a text string into a list by segmenting the text
2217% string at each carriage return discovered. The list is converted to HEX
2218% characters if any control characters are discovered within the text string.
2219%
2220% The format of the StringToList method is:
2221%
2222% char **StringToList(const char *text)
2223%
2224% A description of each parameter follows:
2225%
cristy3ed852e2009-09-05 21:47:34 +00002226% o text: Specifies the string to segment into a list.
2227%
2228*/
2229MagickExport char **StringToList(const char *text)
2230{
2231 char
2232 **textlist;
2233
2234 register const char
2235 *p;
2236
cristybb503372010-05-27 20:51:26 +00002237 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002238 i;
2239
cristybb503372010-05-27 20:51:26 +00002240 size_t
cristy3ed852e2009-09-05 21:47:34 +00002241 lines;
2242
2243 if (text == (char *) NULL)
2244 return((char **) NULL);
2245 for (p=text; *p != '\0'; p++)
2246 if (((int) ((unsigned char) *p) < 32) &&
2247 (isspace((int) ((unsigned char) *p)) == 0))
2248 break;
2249 if (*p == '\0')
2250 {
2251 register const char
2252 *q;
2253
2254 /*
2255 Convert string to an ASCII list.
2256 */
2257 lines=1;
2258 for (p=text; *p != '\0'; p++)
2259 if (*p == '\n')
2260 lines++;
2261 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2262 sizeof(*textlist));
2263 if (textlist == (char **) NULL)
2264 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2265 p=text;
cristybb503372010-05-27 20:51:26 +00002266 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002267 {
2268 for (q=p; *q != '\0'; q++)
2269 if ((*q == '\r') || (*q == '\n'))
2270 break;
2271 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002272 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002273 if (textlist[i] == (char *) NULL)
2274 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002275 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002276 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002277 if (*q == '\r')
2278 q++;
2279 p=q+1;
2280 }
2281 }
2282 else
2283 {
2284 char
2285 hex_string[MaxTextExtent];
2286
2287 register char
2288 *q;
2289
cristybb503372010-05-27 20:51:26 +00002290 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002291 j;
2292
2293 /*
2294 Convert string to a HEX list.
2295 */
cristybb503372010-05-27 20:51:26 +00002296 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002297 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2298 sizeof(*textlist));
2299 if (textlist == (char **) NULL)
2300 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2301 p=text;
cristybb503372010-05-27 20:51:26 +00002302 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002303 {
2304 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002305 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002306 if (textlist[i] == (char *) NULL)
2307 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002308 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002309 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002310 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002311 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002312 {
cristyb51dff52011-05-19 16:55:47 +00002313 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002314 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2315 q+=2;
2316 if ((j % 0x04) == 0)
2317 *q++=' ';
2318 }
2319 for ( ; j <= 0x14; j++)
2320 {
2321 *q++=' ';
2322 *q++=' ';
2323 if ((j % 0x04) == 0)
2324 *q++=' ';
2325 }
2326 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002327 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002328 {
2329 if (isprint((int) ((unsigned char) *p)) != 0)
2330 *q++=(*p);
2331 else
2332 *q++='-';
2333 p++;
2334 }
2335 *q='\0';
2336 }
2337 }
2338 textlist[i]=(char *) NULL;
2339 return(textlist);
2340}
2341
2342/*
2343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2344% %
2345% %
2346% %
2347% S t r i n g T o S t r i n g I n f o %
2348% %
2349% %
2350% %
2351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2352%
cristybca58f32011-08-21 14:48:50 +00002353% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002354%
2355% The format of the StringToStringInfo method is:
2356%
2357% StringInfo *StringToStringInfo(const char *string)
2358%
2359% A description of each parameter follows:
2360%
2361% o string: The string.
2362%
2363*/
2364MagickExport StringInfo *StringToStringInfo(const char *string)
2365{
2366 StringInfo
2367 *string_info;
2368
2369 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2370 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002371 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002372 SetStringInfoDatum(string_info,(const unsigned char *) string);
2373 return(string_info);
2374}
2375
2376/*
2377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2378% %
2379% %
2380% %
2381% S t r i p S t r i n g %
2382% %
2383% %
2384% %
2385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2386%
2387% StripString() strips any whitespace or quotes from the beginning and end of
2388% a string of characters.
2389%
2390% The format of the StripString method is:
2391%
2392% void StripString(char *message)
2393%
2394% A description of each parameter follows:
2395%
2396% o message: Specifies an array of characters.
2397%
2398*/
2399MagickExport void StripString(char *message)
2400{
2401 register char
2402 *p,
2403 *q;
2404
2405 size_t
2406 length;
2407
2408 assert(message != (char *) NULL);
2409 if (*message == '\0')
2410 return;
2411 length=strlen(message);
2412 p=message;
2413 while (isspace((int) ((unsigned char) *p)) != 0)
2414 p++;
2415 if ((*p == '\'') || (*p == '"'))
2416 p++;
2417 q=message+length-1;
2418 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2419 q--;
2420 if (q > p)
2421 if ((*q == '\'') || (*q == '"'))
2422 q--;
cristya63c1ba2011-06-02 20:33:43 +00002423 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002424 message[q-p+1]='\0';
2425 for (p=message; *p != '\0'; p++)
2426 if (*p == '\n')
2427 *p=' ';
2428}
2429
2430/*
2431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2432% %
2433% %
2434% %
2435% S u b s t i t u t e S t r i n g %
2436% %
2437% %
2438% %
2439%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2440%
cristyf1b72c12009-10-06 13:25:21 +00002441% SubstituteString() performs string substitution on a string, replacing the
2442% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002443% If the string is matched and status, MagickTrue is returned otherwise
2444% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002445%
2446% The format of the SubstituteString method is:
2447%
cristyf1b72c12009-10-06 13:25:21 +00002448% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002449% const char *replace)
2450%
2451% A description of each parameter follows:
2452%
cristyf1b72c12009-10-06 13:25:21 +00002453% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002454% allocation if a replacement is made.
2455%
cristybc3392a2009-10-06 03:15:57 +00002456% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002457%
cristybc3392a2009-10-06 03:15:57 +00002458% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002459%
2460*/
cristyf1b72c12009-10-06 13:25:21 +00002461MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002462 const char *search,const char *replace)
2463{
cristybc3392a2009-10-06 03:15:57 +00002464 MagickBooleanType
2465 status;
cristy3ed852e2009-09-05 21:47:34 +00002466
cristybc3392a2009-10-06 03:15:57 +00002467 register char
2468 *p;
cristy3ed852e2009-09-05 21:47:34 +00002469
cristy3ed852e2009-09-05 21:47:34 +00002470 size_t
cristybc3392a2009-10-06 03:15:57 +00002471 extent,
2472 replace_extent,
2473 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002474
cristyf1b72c12009-10-06 13:25:21 +00002475 ssize_t
2476 offset;
2477
cristybc3392a2009-10-06 03:15:57 +00002478 status=MagickFalse;
2479 search_extent=0,
2480 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002481 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002482 {
cristyf1b72c12009-10-06 13:25:21 +00002483 if (search_extent == 0)
2484 search_extent=strlen(search);
2485 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002486 continue;
cristy3ed852e2009-09-05 21:47:34 +00002487 /*
cristybc3392a2009-10-06 03:15:57 +00002488 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002489 */
cristyf1b72c12009-10-06 13:25:21 +00002490 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002491 if (replace_extent == 0)
2492 replace_extent=strlen(replace);
2493 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002494 {
cristybc3392a2009-10-06 03:15:57 +00002495 /*
2496 Make room for the replacement string.
2497 */
cristyde58b412010-02-18 03:53:40 +00002498 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002499 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002500 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2501 sizeof(*p));
2502 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002503 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002504 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002505 }
cristy3ed852e2009-09-05 21:47:34 +00002506 /*
cristybc3392a2009-10-06 03:15:57 +00002507 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002508 */
cristybc3392a2009-10-06 03:15:57 +00002509 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002510 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2511 strlen(p+search_extent)+1);
2512 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002513 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002514 }
cristybc3392a2009-10-06 03:15:57 +00002515 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002516}