blob: f5f7cce99445be54c304230eeec77daeb500a95f [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%
239% The format of the CloneString method is:
240%
241% char *CloneString(char **destination,const char *source)
242%
243% A description of each parameter follows:
244%
245% o destination: A pointer to a character string.
246%
247% o source: A character string.
248%
249*/
250MagickExport char *CloneString(char **destination,const char *source)
251{
252 size_t
253 length;
254
255 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
256 assert(destination != (char **) NULL);
257 if (source == (const char *) NULL)
258 {
259 if (*destination != (char *) NULL)
260 *destination=DestroyString(*destination);
261 return(*destination);
262 }
263 if (*destination == (char *) NULL)
264 {
265 *destination=AcquireString(source);
266 return(*destination);
267 }
268 length=strlen(source);
269 if (~length < MaxTextExtent)
270 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
271 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000272 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000273 if (*destination == (char *) NULL)
274 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000275 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000276 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000277 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000278 return(*destination);
279}
280
281/*
282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283% %
284% %
285% %
286% C l o n e S t r i n g I n f o %
287% %
288% %
289% %
290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291%
292% CloneStringInfo() clones a copy of the StringInfo structure.
293%
294% The format of the CloneStringInfo method is:
295%
296% StringInfo *CloneStringInfo(const StringInfo *string_info)
297%
298% A description of each parameter follows:
299%
300% o string_info: the string info.
301%
302*/
303MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
304{
305 StringInfo
306 *clone_info;
307
308 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
309 assert(string_info != (StringInfo *) NULL);
310 assert(string_info->signature == MagickSignature);
311 clone_info=AcquireStringInfo(string_info->length);
312 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000313 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000314 return(clone_info);
315}
316
317/*
318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319% %
320% %
321% %
322% C o m p a r e S t r i n g I n f o %
323% %
324% %
325% %
326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327%
328% CompareStringInfo() compares the two datums target and source. It returns
329% an integer less than, equal to, or greater than zero if target is found,
330% respectively, to be less than, to match, or be greater than source.
331%
332% The format of the CompareStringInfo method is:
333%
334% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
335%
336% A description of each parameter follows:
337%
338% o target: the target string.
339%
340% o source: the source string.
341%
342*/
343
344static inline size_t MagickMin(const size_t x,const size_t y)
345{
346 if (x < y)
347 return(x);
348 return(y);
349}
350
351MagickExport int CompareStringInfo(const StringInfo *target,
352 const StringInfo *source)
353{
354 int
355 status;
356
357 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
358 assert(target != (StringInfo *) NULL);
359 assert(target->signature == MagickSignature);
360 assert(source != (StringInfo *) NULL);
361 assert(source->signature == MagickSignature);
362 status=memcmp(target->datum,source->datum,MagickMin(target->length,
363 source->length));
364 if (status != 0)
365 return(status);
366 if (target->length == source->length)
367 return(0);
368 return(target->length < source->length ? -1 : 1);
369}
370
371/*
372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373% %
374% %
375% %
376% C o n c a t e n a t e M a g i c k S t r i n g %
377% %
378% %
379% %
380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381%
382% ConcatenateMagickString() concatenates the source string to the destination
383% string. The destination buffer is always null-terminated even if the
384% string must be truncated.
385%
386% The format of the ConcatenateMagickString method is:
387%
388% size_t ConcatenateMagickString(char *destination,const char *source,
389% const size_t length)
390%
391% A description of each parameter follows:
392%
393% o destination: the destination string.
394%
395% o source: the source string.
396%
397% o length: the length of the destination string.
398%
399*/
400MagickExport size_t ConcatenateMagickString(char *destination,
401 const char *source,const size_t length)
402{
403 register char
404 *q;
405
406 register const char
407 *p;
408
409 register size_t
410 i;
411
412 size_t
413 count;
414
415 assert(destination != (char *) NULL);
416 assert(source != (const char *) NULL);
417 assert(length >= 1);
418 p=source;
419 q=destination;
420 i=length;
421 while ((i-- != 0) && (*q != '\0'))
422 q++;
423 count=(size_t) (q-destination);
424 i=length-count;
425 if (i == 0)
426 return(count+strlen(p));
427 while (*p != '\0')
428 {
429 if (i != 1)
430 {
431 *q++=(*p);
432 i--;
433 }
434 p++;
435 }
436 *q='\0';
437 return(count+(p-source));
438}
439
440/*
441%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442% %
443% %
444% %
445% C o n c a t e n a t e S t r i n g %
446% %
447% %
448% %
449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450%
451% ConcatenateString() appends a copy of string source, including the
452% terminating null character, to the end of string destination.
453%
454% The format of the ConcatenateString method is:
455%
456% MagickBooleanType ConcatenateString(char **destination,
457% const char *source)
458%
459% A description of each parameter follows:
460%
461% o destination: A pointer to a character string.
462%
463% o source: A character string.
464%
465*/
466MagickExport MagickBooleanType ConcatenateString(char **destination,
467 const char *source)
468{
469 size_t
cristy54aad5e2010-09-03 16:02:04 +0000470 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000471 length,
472 source_length;
473
474 assert(destination != (char **) NULL);
475 if (source == (const char *) NULL)
476 return(MagickTrue);
477 if (*destination == (char *) NULL)
478 {
479 *destination=AcquireString(source);
480 return(MagickTrue);
481 }
cristy54aad5e2010-09-03 16:02:04 +0000482 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000483 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000484 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000485 if (~length < source_length)
486 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
487 length+=source_length;
488 if (~length < MaxTextExtent)
489 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
490 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000491 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000492 if (*destination == (char *) NULL)
493 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000494 if (source_length != 0)
495 (void) memcpy((*destination)+destination_length,source,source_length);
496 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000497 return(MagickTrue);
498}
499
500/*
501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502% %
503% %
504% %
505% C o n c a t e n a t e S t r i n g I n f o %
506% %
507% %
508% %
509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510%
511% ConcatenateStringInfo() concatenates the source string to the destination
512% string.
513%
514% The format of the ConcatenateStringInfo method is:
515%
516% void ConcatenateStringInfo(StringInfo *string_info,
517% const StringInfo *source)
518%
519% A description of each parameter follows:
520%
521% o string_info: the string info.
522%
523% o source: the source string.
524%
525*/
526MagickExport void ConcatenateStringInfo(StringInfo *string_info,
527 const StringInfo *source)
528{
529 size_t
530 length;
531
532 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
533 assert(string_info != (StringInfo *) NULL);
534 assert(string_info->signature == MagickSignature);
535 assert(source != (const StringInfo *) NULL);
536 length=string_info->length;
537 if (~length < source->length)
538 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
539 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000540 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000541}
542
543/*
544%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
545% %
546% %
547% %
548% 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 %
549% %
550% %
551% %
552%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
553%
554% ConfigureFileToStringInfo() returns the contents of a configure file as a
555% string.
556%
557% The format of the ConfigureFileToStringInfo method is:
558%
559% StringInfo *ConfigureFileToStringInfo(const char *filename)
560% ExceptionInfo *exception)
561%
562% A description of each parameter follows:
563%
564% o filename: the filename.
565%
566*/
cristy99bbf2c2011-09-26 18:27:50 +0000567MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
cristy3ed852e2009-09-05 21:47:34 +0000568{
569 char
570 *string;
571
572 int
573 file;
574
575 MagickOffsetType
576 offset;
577
578 size_t
579 length;
580
581 StringInfo
582 *string_info;
583
584 void
585 *map;
586
587 assert(filename != (const char *) NULL);
cristy18c6c272011-09-23 14:40:37 +0000588 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
cristy3ed852e2009-09-05 21:47:34 +0000589 if (file == -1)
590 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000591 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000592 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
593 {
594 file=close(file)-1;
595 return((StringInfo *) NULL);
596 }
597 length=(size_t) offset;
598 string=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000599 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000600 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
601 if (string == (char *) NULL)
602 {
603 file=close(file)-1;
604 return((StringInfo *) NULL);
605 }
606 map=MapBlob(file,ReadMode,0,length);
607 if (map != (void *) NULL)
608 {
cristy54aad5e2010-09-03 16:02:04 +0000609 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000610 (void) UnmapBlob(map,length);
611 }
612 else
613 {
614 register size_t
615 i;
616
617 ssize_t
618 count;
619
cristy7f317702011-02-18 20:40:28 +0000620 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000621 for (i=0; i < length; i+=count)
622 {
623 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
624 SSIZE_MAX));
625 if (count <= 0)
626 {
627 count=0;
628 if (errno != EINTR)
629 break;
630 }
631 }
632 if (i < length)
633 {
634 file=close(file)-1;
635 string=DestroyString(string);
636 return((StringInfo *) NULL);
637 }
638 }
639 string[length]='\0';
640 file=close(file)-1;
641 string_info=AcquireStringInfo(0);
642 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
643 string_info->length=length;
644 string_info->datum=(unsigned char *) string;
645 return(string_info);
646}
647
648/*
649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
650% %
651% %
652% %
653% C o n s t a n t S t r i n g %
654% %
655% %
656% %
657%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
658%
659% ConstantString() allocates memory for a string and copies the source string
660% to that memory location (and returns it). Use it for strings that you do
661% do not expect to change over its lifetime.
662%
663% The format of the ConstantString method is:
664%
665% char *ConstantString(const char *source)
666%
667% A description of each parameter follows:
668%
669% o source: A character string.
670%
671*/
672MagickExport char *ConstantString(const char *source)
673{
674 char
675 *destination;
676
677 size_t
678 length;
679
680 length=0;
681 if (source != (char *) NULL)
682 length+=strlen(source);
683 destination=(char *) NULL;
684 if (~length >= 1UL)
685 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
686 if (destination == (char *) NULL)
687 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
688 *destination='\0';
689 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000690 (void) memcpy(destination,source,length*sizeof(*destination));
691 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000692 return(destination);
693}
694
695/*
696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697% %
698% %
699% %
700% C o p y M a g i c k S t r i n g %
701% %
702% %
703% %
704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
705%
706% CopyMagickString() copies the source string to the destination string. The
707% destination buffer is always null-terminated even if the string must be
708% truncated. The return value is the minimum of the source string length
709% or the length parameter.
710%
711% The format of the CopyMagickString method is:
712%
713% size_t CopyMagickString(const char *destination,char *source,
714% const size_t length)
715%
716% A description of each parameter follows:
717%
718% o destination: the destination string.
719%
720% o source: the source string.
721%
722% o length: the length of the destination string.
723%
724*/
725MagickExport size_t CopyMagickString(char *destination,const char *source,
726 const size_t length)
727{
728 register char
729 *q;
730
731 register const char
732 *p;
733
734 register size_t
735 n;
736
cristy77e3fcc2011-10-11 00:04:41 +0000737 if (source == (const char *) NULL)
738 return(0);
cristy3ed852e2009-09-05 21:47:34 +0000739 p=source;
740 q=destination;
741 for (n=length; n > 4; n-=4)
742 {
743 *q=(*p++);
744 if (*q == '\0')
745 return((size_t) (p-source-1));
746 q++;
747 *q=(*p++);
748 if (*q == '\0')
749 return((size_t) (p-source-1));
750 q++;
751 *q=(*p++);
752 if (*q == '\0')
753 return((size_t) (p-source-1));
754 q++;
755 *q=(*p++);
756 if (*q == '\0')
757 return((size_t) (p-source-1));
758 q++;
759 }
760 if (n != 0)
761 for (n--; n != 0; n--)
762 {
763 *q=(*p++);
764 if (*q == '\0')
765 return((size_t) (p-source-1));
766 q++;
767 }
768 if (length != 0)
769 *q='\0';
770 return((size_t) (p-source-1));
771}
772
773/*
774%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
775% %
776% %
777% %
778% D e s t r o y S t r i n g %
779% %
780% %
781% %
782%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783%
784% DestroyString() destroys memory associated with a string.
785%
786% The format of the DestroyString method is:
787%
788% char *DestroyString(char *string)
789%
790% A description of each parameter follows:
791%
792% o string: the string.
793%
794*/
795MagickExport char *DestroyString(char *string)
796{
797 return((char *) RelinquishMagickMemory(string));
798}
799
800/*
801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802% %
803% %
804% %
805% D e s t r o y S t r i n g I n f o %
806% %
807% %
808% %
809%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
810%
811% DestroyStringInfo() destroys memory associated with the StringInfo structure.
812%
813% The format of the DestroyStringInfo method is:
814%
815% StringInfo *DestroyStringInfo(StringInfo *string_info)
816%
817% A description of each parameter follows:
818%
819% o string_info: the string info.
820%
821*/
822MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
823{
824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
825 assert(string_info != (StringInfo *) NULL);
826 assert(string_info->signature == MagickSignature);
827 if (string_info->datum != (unsigned char *) NULL)
828 string_info->datum=(unsigned char *) RelinquishMagickMemory(
829 string_info->datum);
830 string_info->signature=(~MagickSignature);
831 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
832 return(string_info);
833}
834
835/*
836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837% %
838% %
839% %
840% D e s t r o y S t r i n g L i s t %
841% %
842% %
843% %
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845%
846% DestroyStringList() zeros memory associated with a string list.
847%
848% The format of the DestroyStringList method is:
849%
850% char **DestroyStringList(char **list)
851%
852% A description of each parameter follows:
853%
854% o list: the string list.
855%
856*/
857MagickExport char **DestroyStringList(char **list)
858{
cristybb503372010-05-27 20:51:26 +0000859 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000860 i;
861
862 assert(list != (char **) NULL);
863 for (i=0; list[i] != (char *) NULL; i++)
864 list[i]=DestroyString(list[i]);
865 list=(char **) RelinquishMagickMemory(list);
866 return(list);
867}
868
869/*
870%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871% %
872% %
873% %
874% E s c a p e S t r i n g %
875% %
876% %
877% %
878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879%
880% EscapeString() allocates memory for a backslash-escaped version of a
881% source text string, copies the escaped version of the text to that
882% memory location while adding backslash characters, and returns the
883% escaped string.
884%
885% The format of the EscapeString method is:
886%
887% char *EscapeString(const char *source,const char escape)
888%
889% A description of each parameter follows:
890%
891% o allocate_string: Method EscapeString returns the escaped string.
892%
893% o source: A character string.
894%
895% o escape: the quoted string termination character to escape (e.g. '"').
896%
897*/
898MagickExport char *EscapeString(const char *source,const char escape)
899{
900 char
901 *destination;
902
903 register char
904 *q;
905
906 register const char
907 *p;
908
909 size_t
910 length;
911
912 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
913 assert(source != (const char *) NULL);
914 length=strlen(source);
915 for (p=source; *p != '\0'; p++)
916 if ((*p == '\\') || (*p == escape))
917 {
918 if (~length < 1)
919 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
920 length++;
921 }
922 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000923 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000924 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
925 sizeof(*destination));
926 if (destination == (char *) NULL)
927 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
928 *destination='\0';
929 if (source != (char *) NULL)
930 {
931 q=destination;
932 for (p=source; *p != '\0'; p++)
933 {
934 if ((*p == '\\') || (*p == escape))
935 *q++='\\';
936 *q++=(*p);
937 }
938 *q='\0';
939 }
940 return(destination);
941}
942
943/*
944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945% %
946% %
947% %
948% F i l e T o S t r i n g %
949% %
950% %
951% %
952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953%
954% FileToString() returns the contents of a file as a string.
955%
956% The format of the FileToString method is:
957%
958% char *FileToString(const char *filename,const size_t extent,
959% ExceptionInfo *exception)
960%
961% A description of each parameter follows:
962%
963% o filename: the filename.
964%
965% o extent: Maximum length of the string.
966%
967% o exception: return any errors or warnings in this structure.
968%
969*/
970MagickExport char *FileToString(const char *filename,const size_t extent,
971 ExceptionInfo *exception)
972{
973 size_t
974 length;
975
976 assert(filename != (const char *) NULL);
977 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
978 assert(exception != (ExceptionInfo *) NULL);
979 return((char *) FileToBlob(filename,extent,&length,exception));
980}
981
982/*
983%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
984% %
985% %
986% %
987% F i l e T o S t r i n g I n f o %
988% %
989% %
990% %
991%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992%
993% FileToStringInfo() returns the contents of a file as a string.
994%
995% The format of the FileToStringInfo method is:
996%
997% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
998% ExceptionInfo *exception)
999%
1000% A description of each parameter follows:
1001%
1002% o filename: the filename.
1003%
1004% o extent: Maximum length of the string.
1005%
1006% o exception: return any errors or warnings in this structure.
1007%
1008*/
1009MagickExport StringInfo *FileToStringInfo(const char *filename,
1010 const size_t extent,ExceptionInfo *exception)
1011{
1012 StringInfo
1013 *string_info;
1014
1015 assert(filename != (const char *) NULL);
1016 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1017 assert(exception != (ExceptionInfo *) NULL);
1018 string_info=AcquireStringInfo(0);
1019 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1020 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1021 if (string_info->datum == (unsigned char *) NULL)
1022 {
1023 string_info=DestroyStringInfo(string_info);
1024 return((StringInfo *) NULL);
1025 }
1026 return(string_info);
1027}
1028
1029/*
1030%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031% %
1032% %
1033% %
1034% F o r m a t M a g i c k S i z e %
1035% %
1036% %
1037% %
1038%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039%
1040% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +00001041% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +00001042% 1000.
cristy3ed852e2009-09-05 21:47:34 +00001043%
1044% The format of the FormatMagickSize method is:
1045%
cristybb503372010-05-27 20:51:26 +00001046% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001047%
1048% A description of each parameter follows:
1049%
1050% o size: convert this size to a human readable format.
1051%
cristyb9080c92009-12-01 20:13:26 +00001052% o bi: use power of two rather than power of ten.
1053%
cristy3ed852e2009-09-05 21:47:34 +00001054% o format: human readable format.
1055%
1056*/
cristy99bbf2c2011-09-26 18:27:50 +00001057MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001058 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001059{
cristyb9080c92009-12-01 20:13:26 +00001060 const char
1061 **units;
1062
cristy3ed852e2009-09-05 21:47:34 +00001063 double
cristyb9080c92009-12-01 20:13:26 +00001064 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001065 length;
1066
cristybb503372010-05-27 20:51:26 +00001067 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001068 i,
1069 j;
1070
cristy9d314ff2011-03-09 01:30:28 +00001071 ssize_t
1072 count;
1073
cristy3ed852e2009-09-05 21:47:34 +00001074 static const char
cristyb9080c92009-12-01 20:13:26 +00001075 *bi_units[] =
1076 {
cristy2ce15c92010-03-12 14:03:41 +00001077 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001078 },
1079 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001080 {
cristy2ce15c92010-03-12 14:03:41 +00001081 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001082 };
cristy3ed852e2009-09-05 21:47:34 +00001083
cristyb9080c92009-12-01 20:13:26 +00001084 bytes=1000.0;
1085 units=traditional_units;
1086 if (bi != MagickFalse)
1087 {
1088 bytes=1024.0;
1089 units=bi_units;
1090 }
cristy3ed852e2009-09-05 21:47:34 +00001091#if defined(_MSC_VER) && (_MSC_VER == 1200)
1092 length=(double) ((MagickOffsetType) size);
1093#else
1094 length=(double) size;
1095#endif
cristyb9080c92009-12-01 20:13:26 +00001096 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1097 length/=bytes;
cristy9bf9da32009-09-27 16:48:34 +00001098 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001099 {
cristyb51dff52011-05-19 16:55:47 +00001100 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001101 units[i]);
1102 if (strchr(format,'+') == (char *) NULL)
1103 break;
1104 }
1105 return(count);
1106}
1107
1108/*
1109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1110% %
1111% %
1112% %
cristy3ed852e2009-09-05 21:47:34 +00001113% F o r m a t M a g i c k T i m e %
1114% %
1115% %
1116% %
1117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118%
1119% FormatMagickTime() returns the specified time in the Internet date/time
1120% format and the length of the timestamp.
1121%
1122% The format of the FormatMagickTime method is:
1123%
cristybb503372010-05-27 20:51:26 +00001124% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001125% char *timestamp)
1126%
1127% A description of each parameter follows.
1128%
1129% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1130% measured in seconds.
1131%
1132% o length: the maximum length of the string.
1133%
1134% o timestamp: Return the Internet date/time here.
1135%
1136*/
cristybb503372010-05-27 20:51:26 +00001137MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001138 char *timestamp)
1139{
cristybb503372010-05-27 20:51:26 +00001140 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001141 count;
1142
1143 struct tm
1144 gm_time,
1145 local_time;
1146
1147 time_t
1148 timezone;
1149
1150 assert(timestamp != (char *) NULL);
1151 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1152 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1153#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1154 (void) localtime_r(&time,&local_time);
1155#else
1156 {
cristybc3392a2009-10-06 03:15:57 +00001157 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001158 *my_time;
1159
1160 my_time=localtime(&time);
1161 if (my_time != (struct tm *) NULL)
1162 (void) memcpy(&local_time,my_time,sizeof(local_time));
1163 }
1164#endif
1165#if defined(MAGICKCORE_HAVE_GMTIME_R)
1166 (void) gmtime_r(&time,&gm_time);
1167#else
1168 {
cristybc3392a2009-10-06 03:15:57 +00001169 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001170 *my_time;
1171
1172 my_time=gmtime(&time);
1173 if (my_time != (struct tm *) NULL)
1174 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1175 }
1176#endif
1177 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1178 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1179 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1180 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001181 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001182 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1183 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001184 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001185 return(count);
1186}
1187
1188/*
1189%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1190% %
1191% %
1192% %
1193% G e t E n v i r o n m e n t V a l u e %
1194% %
1195% %
1196% %
1197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1198%
1199% GetEnvironmentValue() returns the environment string that matches the
1200% specified name.
1201%
1202% The format of the GetEnvironmentValue method is:
1203%
1204% char *GetEnvironmentValue(const char *name)
1205%
1206% A description of each parameter follows:
1207%
1208% o name: the environment name.
1209%
1210*/
cristy99bbf2c2011-09-26 18:27:50 +00001211MagickExport char *GetEnvironmentValue(const char *name)
cristy3ed852e2009-09-05 21:47:34 +00001212{
1213 const char
1214 *environment;
1215
1216 environment=getenv(name);
1217 if (environment == (const char *) NULL)
1218 return((char *) NULL);
1219 return(ConstantString(environment));
1220}
1221
1222/*
1223%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1224% %
1225% %
1226% %
1227% G e t S t r i n g I n f o D a t u m %
1228% %
1229% %
1230% %
1231%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1232%
1233% GetStringInfoDatum() returns the datum associated with the string.
1234%
1235% The format of the GetStringInfoDatum method is:
1236%
1237% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1238%
1239% A description of each parameter follows:
1240%
1241% o string_info: the string info.
1242%
1243*/
1244MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1245{
1246 assert(string_info != (StringInfo *) NULL);
1247 assert(string_info->signature == MagickSignature);
1248 return(string_info->datum);
1249}
1250
1251/*
1252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1253% %
1254% %
1255% %
1256% G e t S t r i n g I n f o L e n g t h %
1257% %
1258% %
1259% %
1260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1261%
1262% GetStringInfoLength() returns the string length.
1263%
1264% The format of the GetStringInfoLength method is:
1265%
1266% size_t GetStringInfoLength(const StringInfo *string_info)
1267%
1268% A description of each parameter follows:
1269%
1270% o string_info: the string info.
1271%
1272*/
1273MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1274{
1275 assert(string_info != (StringInfo *) NULL);
1276 assert(string_info->signature == MagickSignature);
1277 return(string_info->length);
1278}
1279
1280/*
1281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1282% %
1283% %
1284% %
1285% G e t S t r i n g I n f o P a t h %
1286% %
1287% %
1288% %
1289%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290%
1291% GetStringInfoPath() returns the path associated with the string.
1292%
1293% The format of the GetStringInfoPath method is:
1294%
1295% const char *GetStringInfoPath(const StringInfo *string_info)
1296%
1297% A description of each parameter follows:
1298%
1299% o string_info: the string info.
1300%
1301*/
1302MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1303{
1304 assert(string_info != (StringInfo *) NULL);
1305 assert(string_info->signature == MagickSignature);
1306 return(string_info->path);
1307}
1308
1309/*
1310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1311% %
1312% %
1313% %
cristydbdd0e32011-11-04 23:29:40 +00001314+ I n t e r p r e t S i P r e f i x V a l u e %
1315% %
1316% %
1317% %
1318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319%
1320% InterpretSiPrefixValue() converts the initial portion of the string to a
1321% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1322% etc.).
1323%
1324% The format of the InterpretSiPrefixValue method is:
1325%
1326% double InterpretSiPrefixValue(const char *value,char **sentinal)
1327%
1328% A description of each parameter follows:
1329%
1330% o value: the string value.
1331%
1332% o sentinal: if sentinal is not NULL, return a pointer to the character
1333% after the last character used in the conversion.
1334%
1335*/
1336MagickExport double InterpretSiPrefixValue(const char *restrict string,
1337 char **restrict sentinal)
1338{
1339 char
1340 *q;
1341
1342 double
1343 value;
1344
cristydbdd0e32011-11-04 23:29:40 +00001345 value=InterpretLocaleValue(string,&q);
1346 if (q != string)
1347 {
1348 if ((*q >= 'E') && (*q <= 'z'))
1349 {
1350 double
1351 e;
1352
cristy0c2684f2011-11-05 21:39:43 +00001353 switch ((int) ((unsigned char) *q))
1354 {
1355 case 'y': e=(-24.0); break;
1356 case 'z': e=(-21.0); break;
1357 case 'a': e=(-18.0); break;
1358 case 'f': e=(-15.0); break;
1359 case 'p': e=(-12.0); break;
1360 case 'n': e=(-9.0); break;
1361 case 'u': e=(-6.0); break;
1362 case 'm': e=(-3.0); break;
1363 case 'c': e=(-2.0); break;
1364 case 'd': e=(-1.0); break;
1365 case 'h': e=2.0; break;
1366 case 'k': e=3.0; break;
1367 case 'K': e=3.0; break;
1368 case 'M': e=6.0; break;
1369 case 'G': e=9.0; break;
1370 case 'T': e=12.0; break;
1371 case 'P': e=15.0; break;
1372 case 'E': e=18.0; break;
1373 case 'Z': e=21.0; break;
1374 case 'Y': e=24.0; break;
1375 default: e=0.0; break;
1376 }
cristydbdd0e32011-11-04 23:29:40 +00001377 if (e >= MagickEpsilon)
1378 {
1379 if (q[1] == 'i')
1380 {
1381 value*=pow(2.0,e/0.3);
1382 q+=2;
1383 }
1384 else
1385 {
1386 value*=pow(10.0,e);
1387 q++;
1388 }
1389 }
1390 }
cristyc0f1ed12011-11-09 14:50:15 +00001391 if (*q == 'B')
cristy099a7352011-11-09 14:31:35 +00001392 q++;
cristydbdd0e32011-11-04 23:29:40 +00001393 }
1394 if (sentinal != (char **) NULL)
1395 *sentinal=q;
1396 return(value);
1397}
1398
1399/*
1400%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1401% %
1402% %
1403% %
cristy3ed852e2009-09-05 21:47:34 +00001404% L o c a l e C o m p a r e %
1405% %
1406% %
1407% %
1408%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1409%
1410% LocaleCompare() performs a case-insensitive comparison of two strings
1411% byte-by-byte, according to the ordering of the current locale encoding.
1412% LocaleCompare returns an integer greater than, equal to, or less than 0,
1413% if the string pointed to by p is greater than, equal to, or less than the
1414% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001415% is determined by the sign of the difference between the values of the first
1416% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001417%
1418% The format of the LocaleCompare method is:
1419%
cristyde58b412010-02-18 03:53:40 +00001420% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001421%
1422% A description of each parameter follows:
1423%
1424% o p: A pointer to a character string.
1425%
1426% o q: A pointer to a character string to compare to p.
1427%
1428*/
cristyde58b412010-02-18 03:53:40 +00001429MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001430{
1431 if ((p == (char *) NULL) && (q == (char *) NULL))
1432 return(0);
1433 if (p == (char *) NULL)
1434 return(-1);
1435 if (q == (char *) NULL)
1436 return(1);
1437#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001438 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001439#else
1440 {
cristyde58b412010-02-18 03:53:40 +00001441 register int
cristy3ed852e2009-09-05 21:47:34 +00001442 c,
cristya72c2d12010-02-18 01:20:28 +00001443 d;
cristy3ed852e2009-09-05 21:47:34 +00001444
cristya72c2d12010-02-18 01:20:28 +00001445 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001446 {
cristyde58b412010-02-18 03:53:40 +00001447 c=(int) *((unsigned char *) p);
1448 d=(int) *((unsigned char *) q);
1449 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001450 break;
cristya72c2d12010-02-18 01:20:28 +00001451 p++;
1452 q++;
cristy3ed852e2009-09-05 21:47:34 +00001453 }
cristyde58b412010-02-18 03:53:40 +00001454 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001455 }
1456#endif
1457}
1458
1459/*
1460%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1461% %
1462% %
1463% %
1464% L o c a l e L o w e r %
1465% %
1466% %
1467% %
1468%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469%
1470% LocaleLower() transforms all of the characters in the supplied
1471% null-terminated string, changing all uppercase letters to lowercase.
1472%
1473% The format of the LocaleLower method is:
1474%
1475% void LocaleLower(char *string)
1476%
1477% A description of each parameter follows:
1478%
1479% o string: A pointer to the string to convert to lower-case Locale.
1480%
1481*/
1482MagickExport void LocaleLower(char *string)
1483{
1484 register char
1485 *q;
1486
1487 assert(string != (char *) NULL);
1488 for (q=string; *q != '\0'; q++)
1489 *q=(char) tolower((int) *q);
1490}
1491
1492/*
1493%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1494% %
1495% %
1496% %
1497% L o c a l e N C o m p a r e %
1498% %
1499% %
1500% %
1501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1502%
1503% LocaleNCompare() performs a case-insensitive comparison of two
1504% strings byte-by-byte, according to the ordering of the current locale
1505% encoding. LocaleNCompare returns an integer greater than, equal to, or
1506% less than 0, if the string pointed to by p is greater than, equal to, or
1507% less than the string pointed to by q respectively. The sign of a non-zero
1508% return value is determined by the sign of the difference between the
1509% values of the first pair of bytes that differ in the strings being
1510% compared. The LocaleNCompare method makes the same comparison as
1511% LocaleCompare but looks at a maximum of n bytes. Bytes following a
1512% null byte are not compared.
1513%
1514% The format of the LocaleNCompare method is:
1515%
cristyde58b412010-02-18 03:53:40 +00001516% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001517%
1518% A description of each parameter follows:
1519%
1520% o p: A pointer to a character string.
1521%
1522% o q: A pointer to a character string to compare to p.
1523%
cristy7a40ba82011-01-08 20:31:18 +00001524% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001525%
1526*/
cristyde58b412010-02-18 03:53:40 +00001527MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001528{
cristy78c21692011-10-06 14:57:26 +00001529 if ((p == (char *) NULL) && (q == (char *) NULL))
1530 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001531 if (p == (char *) NULL)
1532 return(-1);
1533 if (q == (char *) NULL)
1534 return(1);
1535#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001536 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001537#else
1538 {
cristyde58b412010-02-18 03:53:40 +00001539 register int
cristy3ed852e2009-09-05 21:47:34 +00001540 c,
1541 d;
1542
cristyb6af4a52009-10-06 13:56:23 +00001543 register size_t
cristyc4cded12010-02-18 14:40:57 +00001544 i;
cristyb6af4a52009-10-06 13:56:23 +00001545
cristyc4cded12010-02-18 14:40:57 +00001546 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001547 {
cristyde58b412010-02-18 03:53:40 +00001548 c=(int) *((unsigned char *) p);
1549 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001550 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001551 return(AsciiMap[c]-(int) AsciiMap[d]);
1552 if (c == 0)
1553 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001554 p++;
1555 q++;
1556 }
cristyde58b412010-02-18 03:53:40 +00001557 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001558 }
1559#endif
1560}
1561
1562/*
1563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1564% %
1565% %
1566% %
1567% L o c a l e U p p e r %
1568% %
1569% %
1570% %
1571%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1572%
1573% LocaleUpper() transforms all of the characters in the supplied
1574% null-terminated string, changing all lowercase letters to uppercase.
1575%
1576% The format of the LocaleUpper method is:
1577%
1578% void LocaleUpper(char *string)
1579%
1580% A description of each parameter follows:
1581%
1582% o string: A pointer to the string to convert to upper-case Locale.
1583%
1584*/
1585MagickExport void LocaleUpper(char *string)
1586{
1587 register char
1588 *q;
1589
1590 assert(string != (char *) NULL);
1591 for (q=string; *q != '\0'; q++)
1592 *q=(char) toupper((int) *q);
1593}
1594
1595/*
1596%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1597% %
1598% %
1599% %
1600% P r i n t S t r i n g I n f o %
1601% %
1602% %
1603% %
1604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605%
1606% PrintStringInfo() prints the string.
1607%
1608% The format of the PrintStringInfo method is:
1609%
1610% void PrintStringInfo(FILE *file,const char *id,
1611% const StringInfo *string_info)
1612%
1613% A description of each parameter follows:
1614%
1615% o file: the file, typically stdout.
1616%
1617% o id: the string id.
1618%
1619% o string_info: the string info.
1620%
1621*/
1622MagickExport void PrintStringInfo(FILE *file,const char *id,
1623 const StringInfo *string_info)
1624{
1625 register const char
1626 *p;
1627
1628 register size_t
1629 i,
1630 j;
1631
1632 assert(id != (const char *) NULL);
1633 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1634 assert(string_info != (StringInfo *) NULL);
1635 assert(string_info->signature == MagickSignature);
1636 p=(char *) string_info->datum;
1637 for (i=0; i < string_info->length; i++)
1638 {
1639 if (((int) ((unsigned char) *p) < 32) &&
1640 (isspace((int) ((unsigned char) *p)) == 0))
1641 break;
1642 p++;
1643 }
1644 if (i == string_info->length)
1645 {
1646 (void) fputs((char *) string_info->datum,file);
1647 (void) fputc('\n',file);
1648 return;
1649 }
1650 /*
1651 Convert string to a HEX list.
1652 */
1653 p=(char *) string_info->datum;
1654 for (i=0; i < string_info->length; i+=0x14)
1655 {
cristyb51dff52011-05-19 16:55:47 +00001656 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001657 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1658 {
cristyb51dff52011-05-19 16:55:47 +00001659 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001660 if ((j % 0x04) == 0)
1661 (void) fputc(' ',file);
1662 }
1663 for ( ; j <= 0x14; j++)
1664 {
1665 (void) fputc(' ',file);
1666 (void) fputc(' ',file);
1667 if ((j % 0x04) == 0)
1668 (void) fputc(' ',file);
1669 }
1670 (void) fputc(' ',file);
1671 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1672 {
1673 if (isprint((int) ((unsigned char) *p)) != 0)
1674 (void) fputc(*p,file);
1675 else
1676 (void) fputc('-',file);
1677 p++;
1678 }
1679 (void) fputc('\n',file);
1680 }
1681}
1682
1683/*
1684%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1685% %
1686% %
1687% %
1688% R e s e t S t r i n g I n f o %
1689% %
1690% %
1691% %
1692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693%
1694% ResetStringInfo() reset the string to all null bytes.
1695%
1696% The format of the ResetStringInfo method is:
1697%
1698% void ResetStringInfo(StringInfo *string_info)
1699%
1700% A description of each parameter follows:
1701%
1702% o string_info: the string info.
1703%
1704*/
1705MagickExport void ResetStringInfo(StringInfo *string_info)
1706{
1707 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1708 assert(string_info != (StringInfo *) NULL);
1709 assert(string_info->signature == MagickSignature);
1710 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1711}
1712
1713/*
1714%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1715% %
1716% %
1717% %
1718% S e t S t r i n g I n f o %
1719% %
1720% %
1721% %
1722%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1723%
1724% SetStringInfo() copies the source string to the destination string.
1725%
1726% The format of the SetStringInfo method is:
1727%
1728% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1729%
1730% A description of each parameter follows:
1731%
1732% o string_info: the string info.
1733%
1734% o source: the source string.
1735%
1736*/
1737MagickExport void SetStringInfo(StringInfo *string_info,
1738 const StringInfo *source)
1739{
1740 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1741 assert(string_info != (StringInfo *) NULL);
1742 assert(string_info->signature == MagickSignature);
1743 assert(source != (StringInfo *) NULL);
1744 assert(source->signature == MagickSignature);
1745 if (string_info->length == 0)
1746 return;
1747 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001748 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1749 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001750}
1751
1752/*
1753%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1754% %
1755% %
1756% %
1757% S e t S t r i n g I n f o D a t u m %
1758% %
1759% %
1760% %
1761%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1762%
1763% SetStringInfoDatum() copies bytes from the source string for the length of
1764% the destination string.
1765%
1766% The format of the SetStringInfoDatum method is:
1767%
1768% void SetStringInfoDatum(StringInfo *string_info,
1769% const unsigned char *source)
1770%
1771% A description of each parameter follows:
1772%
1773% o string_info: the string info.
1774%
1775% o source: the source string.
1776%
1777*/
1778MagickExport void SetStringInfoDatum(StringInfo *string_info,
1779 const unsigned char *source)
1780{
1781 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1782 assert(string_info != (StringInfo *) NULL);
1783 assert(string_info->signature == MagickSignature);
1784 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001785 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001786}
1787
1788/*
1789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1790% %
1791% %
1792% %
1793% S e t S t r i n g I n f o L e n g t h %
1794% %
1795% %
1796% %
1797%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1798%
1799% SetStringInfoLength() set the string length to the specified value.
1800%
1801% The format of the SetStringInfoLength method is:
1802%
1803% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1804%
1805% A description of each parameter follows:
1806%
1807% o string_info: the string info.
1808%
1809% o length: the string length.
1810%
1811*/
1812MagickExport void SetStringInfoLength(StringInfo *string_info,
1813 const size_t length)
1814{
1815 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1816 assert(string_info != (StringInfo *) NULL);
1817 assert(string_info->signature == MagickSignature);
1818 if (~length < MaxTextExtent)
1819 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1820 string_info->length=length;
1821 if (string_info->datum == (unsigned char *) NULL)
1822 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1823 MaxTextExtent,sizeof(*string_info->datum));
1824 else
1825 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1826 length+MaxTextExtent,sizeof(*string_info->datum));
1827 if (string_info->datum == (unsigned char *) NULL)
1828 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1829}
1830
1831/*
1832%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1833% %
1834% %
1835% %
1836% S e t S t r i n g I n f o D a t u m %
1837% %
1838% %
1839% %
1840%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1841%
1842% SetStringInfoPath() sets the path associated with the string.
1843%
1844% The format of the SetStringInfoPath method is:
1845%
1846% void SetStringInfoPath(StringInfo *string_info,const char *path)
1847%
1848% A description of each parameter follows:
1849%
1850% o string_info: the string info.
1851%
1852% o path: the path.
1853%
1854*/
1855MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1856{
1857 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1858 assert(string_info != (StringInfo *) NULL);
1859 assert(string_info->signature == MagickSignature);
1860 assert(path != (const char *) NULL);
1861 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1862}
1863
1864/*
1865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1866% %
1867% %
1868% %
1869% S p l i t S t r i n g I n f o %
1870% %
1871% %
1872% %
1873%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1874%
1875% SplitStringInfo() splits a string into two and returns it.
1876%
1877% The format of the SplitStringInfo method is:
1878%
1879% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1880%
1881% A description of each parameter follows:
1882%
1883% o string_info: the string info.
1884%
1885*/
1886MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1887 const size_t offset)
1888{
1889 StringInfo
1890 *split_info;
1891
1892 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1893 assert(string_info != (StringInfo *) NULL);
1894 assert(string_info->signature == MagickSignature);
1895 if (offset > string_info->length)
1896 return((StringInfo *) NULL);
1897 split_info=AcquireStringInfo(offset);
1898 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00001899 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00001900 string_info->length-offset+MaxTextExtent);
1901 SetStringInfoLength(string_info,string_info->length-offset);
1902 return(split_info);
1903}
1904
1905/*
1906%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1907% %
1908% %
1909% %
1910% S t r i n g I n f o T o S t r i n g %
1911% %
1912% %
1913% %
1914%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1915%
1916% StringInfoToString() converts a string info string to a C string.
1917%
1918% The format of the StringInfoToString method is:
1919%
1920% char *StringInfoToString(const StringInfo *string_info)
1921%
1922% A description of each parameter follows:
1923%
1924% o string_info: the string.
1925%
1926*/
1927MagickExport char *StringInfoToString(const StringInfo *string_info)
1928{
1929 char
1930 *string;
1931
1932 size_t
1933 length;
1934
1935 string=(char *) NULL;
1936 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00001937 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001938 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001939 if (string == (char *) NULL)
1940 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00001941 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001942 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001943 return(string);
1944}
1945
1946/*
1947%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1948% %
1949% %
1950% %
1951% S t r i n g T o A r g v %
1952% %
1953% %
1954% %
1955%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1956%
1957% StringToArgv() converts a text string into command line arguments.
1958%
1959% The format of the StringToArgv method is:
1960%
1961% char **StringToArgv(const char *text,int *argc)
1962%
1963% A description of each parameter follows:
1964%
1965% o argv: Method StringToArgv returns the string list unless an error
1966% occurs, otherwise NULL.
1967%
1968% o text: Specifies the string to segment into a list.
1969%
1970% o argc: This integer pointer returns the number of arguments in the
1971% list.
1972%
1973*/
1974MagickExport char **StringToArgv(const char *text,int *argc)
1975{
1976 char
1977 **argv;
1978
1979 register const char
1980 *p,
1981 *q;
1982
cristybb503372010-05-27 20:51:26 +00001983 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001984 i;
1985
1986 *argc=0;
1987 if (text == (char *) NULL)
1988 return((char **) NULL);
1989 /*
1990 Determine the number of arguments.
1991 */
1992 for (p=text; *p != '\0'; )
1993 {
1994 while (isspace((int) ((unsigned char) *p)) != 0)
1995 p++;
cristya20c9042011-05-19 13:22:18 +00001996 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00001997 break;
cristy3ed852e2009-09-05 21:47:34 +00001998 (*argc)++;
1999 if (*p == '"')
2000 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2001 if (*p == '\'')
2002 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2003 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2004 p++;
2005 }
2006 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00002007 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00002008 if (argv == (char **) NULL)
2009 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2010 /*
2011 Convert string to an ASCII list.
2012 */
2013 argv[0]=AcquireString("magick");
2014 p=text;
cristybb503372010-05-27 20:51:26 +00002015 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002016 {
2017 while (isspace((int) ((unsigned char) *p)) != 0)
2018 p++;
2019 q=p;
2020 if (*q == '"')
2021 {
2022 p++;
2023 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2024 }
2025 else
2026 if (*q == '\'')
2027 {
cristy06b15f42011-01-22 21:36:24 +00002028 p++;
cristy3ed852e2009-09-05 21:47:34 +00002029 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00002030 }
2031 else
2032 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2033 q++;
2034 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2035 sizeof(**argv));
2036 if (argv[i] == (char *) NULL)
2037 {
2038 for (i--; i >= 0; i--)
2039 argv[i]=DestroyString(argv[i]);
2040 argv=(char **) RelinquishMagickMemory(argv);
2041 ThrowFatalException(ResourceLimitFatalError,
2042 "UnableToConvertStringToARGV");
2043 }
cristy54aad5e2010-09-03 16:02:04 +00002044 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002045 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002046 p=q;
2047 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2048 p++;
2049 }
2050 argv[i]=(char *) NULL;
2051 return(argv);
2052}
2053
2054/*
2055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2056% %
2057% %
2058% %
cristy3ed852e2009-09-05 21:47:34 +00002059% S t r i n g I n f o T o H e x S t r i n g %
2060% %
2061% %
2062% %
2063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2064%
2065% StringInfoToHexString() converts a string info string to a C string.
2066%
2067% The format of the StringInfoToHexString method is:
2068%
2069% char *StringInfoToHexString(const StringInfo *string_info)
2070%
2071% A description of each parameter follows:
2072%
2073% o string_info: the string.
2074%
2075*/
2076MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2077{
2078 char
2079 *string;
2080
2081 register const unsigned char
2082 *p;
2083
cristybb503372010-05-27 20:51:26 +00002084 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002085 i;
2086
2087 register unsigned char
2088 *q;
2089
2090 size_t
2091 length;
2092
2093 unsigned char
2094 hex_digits[16];
2095
2096 length=string_info->length;
2097 if (~length < MaxTextExtent)
2098 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2099 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2100 if (string == (char *) NULL)
2101 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2102 hex_digits[0]='0';
2103 hex_digits[1]='1';
2104 hex_digits[2]='2';
2105 hex_digits[3]='3';
2106 hex_digits[4]='4';
2107 hex_digits[5]='5';
2108 hex_digits[6]='6';
2109 hex_digits[7]='7';
2110 hex_digits[8]='8';
2111 hex_digits[9]='9';
2112 hex_digits[10]='a';
2113 hex_digits[11]='b';
2114 hex_digits[12]='c';
2115 hex_digits[13]='d';
2116 hex_digits[14]='e';
2117 hex_digits[15]='f';
2118 p=string_info->datum;
2119 q=(unsigned char *) string;
cristybb503372010-05-27 20:51:26 +00002120 for (i=0; i < (ssize_t) string_info->length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002121 {
2122 *q++=hex_digits[(*p >> 4) & 0x0f];
2123 *q++=hex_digits[*p & 0x0f];
2124 p++;
2125 }
2126 *q='\0';
2127 return(string);
2128}
2129
2130/*
2131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2132% %
2133% %
2134% %
2135% S t r i n g T o k e n %
2136% %
2137% %
2138% %
2139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2140%
2141% StringToken() extracts a token a from the string.
2142%
2143% The format of the StringToken method is:
2144%
2145% char *StringToken(const char *delimiters,char **string)
2146%
2147% A description of each parameter follows:
2148%
2149% o delimiters: one or more delimiters.
2150%
2151% o string: return the first token in the string. If none is found, return
2152% NULL.
2153%
2154*/
2155MagickExport char *StringToken(const char *delimiters,char **string)
2156{
2157 char
2158 *q;
2159
2160 register char
2161 *p;
2162
2163 register const char
2164 *r;
2165
2166 register int
2167 c,
2168 d;
2169
2170 p=(*string);
2171 if (p == (char *) NULL)
2172 return((char *) NULL);
2173 for (q=p; ; )
2174 {
2175 c=(*p++);
2176 r=delimiters;
2177 do
2178 {
2179 d=(*r++);
2180 if (c == d)
2181 {
2182 if (c == '\0')
2183 p=(char *) NULL;
2184 else
2185 p[-1]='\0';
2186 *string=p;
2187 return(q);
2188 }
2189 } while (d != '\0');
2190 }
2191}
2192
2193/*
2194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2195% %
2196% %
2197% %
2198% S t r i n g T o L i s t %
2199% %
2200% %
2201% %
2202%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2203%
2204% StringToList() converts a text string into a list by segmenting the text
2205% string at each carriage return discovered. The list is converted to HEX
2206% characters if any control characters are discovered within the text string.
2207%
2208% The format of the StringToList method is:
2209%
2210% char **StringToList(const char *text)
2211%
2212% A description of each parameter follows:
2213%
cristy3ed852e2009-09-05 21:47:34 +00002214% o text: Specifies the string to segment into a list.
2215%
2216*/
2217MagickExport char **StringToList(const char *text)
2218{
2219 char
2220 **textlist;
2221
2222 register const char
2223 *p;
2224
cristybb503372010-05-27 20:51:26 +00002225 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002226 i;
2227
cristybb503372010-05-27 20:51:26 +00002228 size_t
cristy3ed852e2009-09-05 21:47:34 +00002229 lines;
2230
2231 if (text == (char *) NULL)
2232 return((char **) NULL);
2233 for (p=text; *p != '\0'; p++)
2234 if (((int) ((unsigned char) *p) < 32) &&
2235 (isspace((int) ((unsigned char) *p)) == 0))
2236 break;
2237 if (*p == '\0')
2238 {
2239 register const char
2240 *q;
2241
2242 /*
2243 Convert string to an ASCII list.
2244 */
2245 lines=1;
2246 for (p=text; *p != '\0'; p++)
2247 if (*p == '\n')
2248 lines++;
2249 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2250 sizeof(*textlist));
2251 if (textlist == (char **) NULL)
2252 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2253 p=text;
cristybb503372010-05-27 20:51:26 +00002254 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002255 {
2256 for (q=p; *q != '\0'; q++)
2257 if ((*q == '\r') || (*q == '\n'))
2258 break;
2259 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002260 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002261 if (textlist[i] == (char *) NULL)
2262 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002263 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002264 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002265 if (*q == '\r')
2266 q++;
2267 p=q+1;
2268 }
2269 }
2270 else
2271 {
2272 char
2273 hex_string[MaxTextExtent];
2274
2275 register char
2276 *q;
2277
cristybb503372010-05-27 20:51:26 +00002278 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002279 j;
2280
2281 /*
2282 Convert string to a HEX list.
2283 */
cristybb503372010-05-27 20:51:26 +00002284 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002285 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2286 sizeof(*textlist));
2287 if (textlist == (char **) NULL)
2288 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2289 p=text;
cristybb503372010-05-27 20:51:26 +00002290 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002291 {
2292 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002293 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002294 if (textlist[i] == (char *) NULL)
2295 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002296 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002297 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002298 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002299 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002300 {
cristyb51dff52011-05-19 16:55:47 +00002301 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002302 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2303 q+=2;
2304 if ((j % 0x04) == 0)
2305 *q++=' ';
2306 }
2307 for ( ; j <= 0x14; j++)
2308 {
2309 *q++=' ';
2310 *q++=' ';
2311 if ((j % 0x04) == 0)
2312 *q++=' ';
2313 }
2314 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002315 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002316 {
2317 if (isprint((int) ((unsigned char) *p)) != 0)
2318 *q++=(*p);
2319 else
2320 *q++='-';
2321 p++;
2322 }
2323 *q='\0';
2324 }
2325 }
2326 textlist[i]=(char *) NULL;
2327 return(textlist);
2328}
2329
2330/*
2331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2332% %
2333% %
2334% %
2335% S t r i n g T o S t r i n g I n f o %
2336% %
2337% %
2338% %
2339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2340%
cristybca58f32011-08-21 14:48:50 +00002341% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002342%
2343% The format of the StringToStringInfo method is:
2344%
2345% StringInfo *StringToStringInfo(const char *string)
2346%
2347% A description of each parameter follows:
2348%
2349% o string: The string.
2350%
2351*/
2352MagickExport StringInfo *StringToStringInfo(const char *string)
2353{
2354 StringInfo
2355 *string_info;
2356
2357 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2358 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002359 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002360 SetStringInfoDatum(string_info,(const unsigned char *) string);
2361 return(string_info);
2362}
2363
2364/*
2365%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2366% %
2367% %
2368% %
2369% S t r i p S t r i n g %
2370% %
2371% %
2372% %
2373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2374%
2375% StripString() strips any whitespace or quotes from the beginning and end of
2376% a string of characters.
2377%
2378% The format of the StripString method is:
2379%
2380% void StripString(char *message)
2381%
2382% A description of each parameter follows:
2383%
2384% o message: Specifies an array of characters.
2385%
2386*/
2387MagickExport void StripString(char *message)
2388{
2389 register char
2390 *p,
2391 *q;
2392
2393 size_t
2394 length;
2395
2396 assert(message != (char *) NULL);
2397 if (*message == '\0')
2398 return;
2399 length=strlen(message);
2400 p=message;
2401 while (isspace((int) ((unsigned char) *p)) != 0)
2402 p++;
2403 if ((*p == '\'') || (*p == '"'))
2404 p++;
2405 q=message+length-1;
2406 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2407 q--;
2408 if (q > p)
2409 if ((*q == '\'') || (*q == '"'))
2410 q--;
cristya63c1ba2011-06-02 20:33:43 +00002411 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002412 message[q-p+1]='\0';
2413 for (p=message; *p != '\0'; p++)
2414 if (*p == '\n')
2415 *p=' ';
2416}
2417
2418/*
2419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2420% %
2421% %
2422% %
2423% S u b s t i t u t e S t r i n g %
2424% %
2425% %
2426% %
2427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2428%
cristyf1b72c12009-10-06 13:25:21 +00002429% SubstituteString() performs string substitution on a string, replacing the
2430% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002431% If the string is matched and status, MagickTrue is returned otherwise
2432% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002433%
2434% The format of the SubstituteString method is:
2435%
cristyf1b72c12009-10-06 13:25:21 +00002436% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002437% const char *replace)
2438%
2439% A description of each parameter follows:
2440%
cristyf1b72c12009-10-06 13:25:21 +00002441% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002442% allocation if a replacement is made.
2443%
cristybc3392a2009-10-06 03:15:57 +00002444% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002445%
cristybc3392a2009-10-06 03:15:57 +00002446% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002447%
2448*/
cristyf1b72c12009-10-06 13:25:21 +00002449MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002450 const char *search,const char *replace)
2451{
cristybc3392a2009-10-06 03:15:57 +00002452 MagickBooleanType
2453 status;
cristy3ed852e2009-09-05 21:47:34 +00002454
cristybc3392a2009-10-06 03:15:57 +00002455 register char
2456 *p;
cristy3ed852e2009-09-05 21:47:34 +00002457
cristy3ed852e2009-09-05 21:47:34 +00002458 size_t
cristybc3392a2009-10-06 03:15:57 +00002459 extent,
2460 replace_extent,
2461 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002462
cristyf1b72c12009-10-06 13:25:21 +00002463 ssize_t
2464 offset;
2465
cristybc3392a2009-10-06 03:15:57 +00002466 status=MagickFalse;
2467 search_extent=0,
2468 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002469 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002470 {
cristyf1b72c12009-10-06 13:25:21 +00002471 if (search_extent == 0)
2472 search_extent=strlen(search);
2473 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002474 continue;
cristy3ed852e2009-09-05 21:47:34 +00002475 /*
cristybc3392a2009-10-06 03:15:57 +00002476 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002477 */
cristyf1b72c12009-10-06 13:25:21 +00002478 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002479 if (replace_extent == 0)
2480 replace_extent=strlen(replace);
2481 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002482 {
cristybc3392a2009-10-06 03:15:57 +00002483 /*
2484 Make room for the replacement string.
2485 */
cristyde58b412010-02-18 03:53:40 +00002486 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002487 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002488 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2489 sizeof(*p));
2490 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002491 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002492 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002493 }
cristy3ed852e2009-09-05 21:47:34 +00002494 /*
cristybc3392a2009-10-06 03:15:57 +00002495 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002496 */
cristybc3392a2009-10-06 03:15:57 +00002497 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002498 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2499 strlen(p+search_extent)+1);
2500 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002501 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002502 }
cristybc3392a2009-10-06 03:15:57 +00002503 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002504}