blob: 73fdb6498e4f6b9d6ab60f04e6b4fb067ec48c2e [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% 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 %
11% %
12% %
13% MagickCore String Methods %
14% %
15% Software Design %
16% John Cristy %
17% August 2003 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% 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. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
42#include "magick/studio.h"
43#include "magick/blob.h"
44#include "magick/blob-private.h"
45#include "magick/exception.h"
46#include "magick/exception-private.h"
47#include "magick/list.h"
48#include "magick/log.h"
49#include "magick/memory_.h"
50#include "magick/property.h"
51#include "magick/resource_.h"
52#include "magick/signature-private.h"
53#include "magick/string_.h"
54
55/*
56 Static declarations.
57*/
58#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
59static const unsigned char
60 AsciiMap[] =
61 {
62 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
63 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
64 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
65 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
66 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
67 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
68 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
69 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
70 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
71 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
72 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
73 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
74 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
75 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
76 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
77 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
78 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
79 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
80 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
81 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
82 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
83 0xfc, 0xfd, 0xfe, 0xff,
84 };
85#endif
86
87/*
88%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89% %
90% %
91% %
92% A c q u i r e S t r i n g %
93% %
94% %
95% %
96%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
97%
98% AcquireString() allocates memory for a string and copies the source string
99% to that memory location (and returns it).
100%
101% The format of the AcquireString method is:
102%
103% char *AcquireString(const char *source)
104%
105% A description of each parameter follows:
106%
107% o source: A character string.
108%
109*/
110MagickExport char *AcquireString(const char *source)
111{
112 char
113 *destination;
114
115 size_t
116 length;
117
118 length=0;
119 if (source != (char *) NULL)
120 length+=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000121 if (~length < MaxTextExtent)
122 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
123 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
124 sizeof(*destination));
cristy3ed852e2009-09-05 21:47:34 +0000125 if (destination == (char *) NULL)
126 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
127 *destination='\0';
128 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000129 (void) memcpy(destination,source,length*sizeof(*destination));
130 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000131 return(destination);
132}
133
134/*
135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136% %
137% %
138% %
139% A c q u i r e S t r i n g I n f o %
140% %
141% %
142% %
143%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144%
145% AcquireStringInfo() allocates the StringInfo structure.
146%
147% The format of the AcquireStringInfo method is:
148%
149% StringInfo *AcquireStringInfo(const size_t length)
150%
151% A description of each parameter follows:
152%
153% o length: the string length.
154%
155*/
156MagickExport StringInfo *AcquireStringInfo(const size_t length)
157{
158 StringInfo
159 *string_info;
160
cristy73bd4a52010-10-05 11:24:23 +0000161 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000162 if (string_info == (StringInfo *) NULL)
163 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
164 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
165 string_info->signature=MagickSignature;
166 string_info->length=length;
167 if (string_info->length != 0)
168 {
169 string_info->datum=(unsigned char *) NULL;
170 if (~string_info->length >= MaxTextExtent)
171 string_info->datum=(unsigned char *) AcquireQuantumMemory(
172 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
173 if (string_info->datum == (unsigned char *) NULL)
174 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
175 }
176 return(string_info);
177}
178
179/*
180%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181% %
182% %
183% %
184% C l o n e S t r i n g %
185% %
186% %
187% %
188%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189%
190% CloneString() allocates memory for the destination string and copies
191% the source string to that memory location.
192%
193% The format of the CloneString method is:
194%
195% char *CloneString(char **destination,const char *source)
196%
197% A description of each parameter follows:
198%
199% o destination: A pointer to a character string.
200%
201% o source: A character string.
202%
203*/
204MagickExport char *CloneString(char **destination,const char *source)
205{
206 size_t
207 length;
208
209 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
210 assert(destination != (char **) NULL);
211 if (source == (const char *) NULL)
212 {
213 if (*destination != (char *) NULL)
214 *destination=DestroyString(*destination);
215 return(*destination);
216 }
217 if (*destination == (char *) NULL)
218 {
219 *destination=AcquireString(source);
220 return(*destination);
221 }
222 length=strlen(source);
223 if (~length < MaxTextExtent)
224 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
225 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000226 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000227 if (*destination == (char *) NULL)
228 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000229 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000230 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000231 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000232 return(*destination);
233}
234
235/*
236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237% %
238% %
239% %
240% C l o n e S t r i n g I n f o %
241% %
242% %
243% %
244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245%
246% CloneStringInfo() clones a copy of the StringInfo structure.
247%
248% The format of the CloneStringInfo method is:
249%
250% StringInfo *CloneStringInfo(const StringInfo *string_info)
251%
252% A description of each parameter follows:
253%
254% o string_info: the string info.
255%
256*/
257MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
258{
259 StringInfo
260 *clone_info;
261
262 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
263 assert(string_info != (StringInfo *) NULL);
264 assert(string_info->signature == MagickSignature);
265 clone_info=AcquireStringInfo(string_info->length);
266 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000267 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000268 return(clone_info);
269}
270
271/*
272%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273% %
274% %
275% %
276% C o m p a r e S t r i n g I n f o %
277% %
278% %
279% %
280%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
281%
282% CompareStringInfo() compares the two datums target and source. It returns
283% an integer less than, equal to, or greater than zero if target is found,
284% respectively, to be less than, to match, or be greater than source.
285%
286% The format of the CompareStringInfo method is:
287%
288% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
289%
290% A description of each parameter follows:
291%
292% o target: the target string.
293%
294% o source: the source string.
295%
296*/
297
298static inline size_t MagickMin(const size_t x,const size_t y)
299{
300 if (x < y)
301 return(x);
302 return(y);
303}
304
305MagickExport int CompareStringInfo(const StringInfo *target,
306 const StringInfo *source)
307{
308 int
309 status;
310
311 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
312 assert(target != (StringInfo *) NULL);
313 assert(target->signature == MagickSignature);
314 assert(source != (StringInfo *) NULL);
315 assert(source->signature == MagickSignature);
316 status=memcmp(target->datum,source->datum,MagickMin(target->length,
317 source->length));
318 if (status != 0)
319 return(status);
320 if (target->length == source->length)
321 return(0);
322 return(target->length < source->length ? -1 : 1);
323}
324
325/*
326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327% %
328% %
329% %
330% C o n c a t e n a t e M a g i c k S t r i n g %
331% %
332% %
333% %
334%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
335%
336% ConcatenateMagickString() concatenates the source string to the destination
337% string. The destination buffer is always null-terminated even if the
338% string must be truncated.
339%
340% The format of the ConcatenateMagickString method is:
341%
342% size_t ConcatenateMagickString(char *destination,const char *source,
343% const size_t length)
344%
345% A description of each parameter follows:
346%
347% o destination: the destination string.
348%
349% o source: the source string.
350%
351% o length: the length of the destination string.
352%
353*/
354MagickExport size_t ConcatenateMagickString(char *destination,
355 const char *source,const size_t length)
356{
357 register char
358 *q;
359
360 register const char
361 *p;
362
363 register size_t
364 i;
365
366 size_t
367 count;
368
369 assert(destination != (char *) NULL);
370 assert(source != (const char *) NULL);
371 assert(length >= 1);
372 p=source;
373 q=destination;
374 i=length;
375 while ((i-- != 0) && (*q != '\0'))
376 q++;
377 count=(size_t) (q-destination);
378 i=length-count;
379 if (i == 0)
380 return(count+strlen(p));
381 while (*p != '\0')
382 {
383 if (i != 1)
384 {
385 *q++=(*p);
386 i--;
387 }
388 p++;
389 }
390 *q='\0';
391 return(count+(p-source));
392}
393
394/*
395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396% %
397% %
398% %
399% C o n c a t e n a t e S t r i n g %
400% %
401% %
402% %
403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404%
405% ConcatenateString() appends a copy of string source, including the
406% terminating null character, to the end of string destination.
407%
408% The format of the ConcatenateString method is:
409%
410% MagickBooleanType ConcatenateString(char **destination,
411% const char *source)
412%
413% A description of each parameter follows:
414%
415% o destination: A pointer to a character string.
416%
417% o source: A character string.
418%
419*/
420MagickExport MagickBooleanType ConcatenateString(char **destination,
421 const char *source)
422{
423 size_t
cristy54aad5e2010-09-03 16:02:04 +0000424 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000425 length,
426 source_length;
427
428 assert(destination != (char **) NULL);
429 if (source == (const char *) NULL)
430 return(MagickTrue);
431 if (*destination == (char *) NULL)
432 {
433 *destination=AcquireString(source);
434 return(MagickTrue);
435 }
cristy54aad5e2010-09-03 16:02:04 +0000436 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000437 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000438 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000439 if (~length < source_length)
440 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
441 length+=source_length;
442 if (~length < MaxTextExtent)
443 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
444 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000445 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000446 if (*destination == (char *) NULL)
447 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000448 if (source_length != 0)
449 (void) memcpy((*destination)+destination_length,source,source_length);
450 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000451 return(MagickTrue);
452}
453
454/*
455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456% %
457% %
458% %
459% C o n c a t e n a t e S t r i n g I n f o %
460% %
461% %
462% %
463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464%
465% ConcatenateStringInfo() concatenates the source string to the destination
466% string.
467%
468% The format of the ConcatenateStringInfo method is:
469%
470% void ConcatenateStringInfo(StringInfo *string_info,
471% const StringInfo *source)
472%
473% A description of each parameter follows:
474%
475% o string_info: the string info.
476%
477% o source: the source string.
478%
479*/
480MagickExport void ConcatenateStringInfo(StringInfo *string_info,
481 const StringInfo *source)
482{
483 size_t
484 length;
485
486 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
487 assert(string_info != (StringInfo *) NULL);
488 assert(string_info->signature == MagickSignature);
489 assert(source != (const StringInfo *) NULL);
490 length=string_info->length;
491 if (~length < source->length)
492 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
493 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000494 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000495}
496
497/*
498%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499% %
500% %
501% %
502% 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 %
503% %
504% %
505% %
506%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
507%
508% ConfigureFileToStringInfo() returns the contents of a configure file as a
509% string.
510%
511% The format of the ConfigureFileToStringInfo method is:
512%
513% StringInfo *ConfigureFileToStringInfo(const char *filename)
514% ExceptionInfo *exception)
515%
516% A description of each parameter follows:
517%
518% o filename: the filename.
519%
520*/
521MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
522{
523 char
524 *string;
525
526 int
527 file;
528
529 MagickOffsetType
530 offset;
531
532 size_t
533 length;
534
535 StringInfo
536 *string_info;
537
538 void
539 *map;
540
541 assert(filename != (const char *) NULL);
542 file=open(filename,O_RDONLY | O_BINARY);
543 if (file == -1)
544 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000545 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000546 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
547 {
548 file=close(file)-1;
549 return((StringInfo *) NULL);
550 }
551 length=(size_t) offset;
552 string=(char *) NULL;
553 if (~length > MaxTextExtent)
554 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
555 if (string == (char *) NULL)
556 {
557 file=close(file)-1;
558 return((StringInfo *) NULL);
559 }
560 map=MapBlob(file,ReadMode,0,length);
561 if (map != (void *) NULL)
562 {
cristy54aad5e2010-09-03 16:02:04 +0000563 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000564 (void) UnmapBlob(map,length);
565 }
566 else
567 {
568 register size_t
569 i;
570
571 ssize_t
572 count;
573
cristy7f317702011-02-18 20:40:28 +0000574 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000575 for (i=0; i < length; i+=count)
576 {
577 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
578 SSIZE_MAX));
579 if (count <= 0)
580 {
581 count=0;
582 if (errno != EINTR)
583 break;
584 }
585 }
586 if (i < length)
587 {
588 file=close(file)-1;
589 string=DestroyString(string);
590 return((StringInfo *) NULL);
591 }
592 }
593 string[length]='\0';
594 file=close(file)-1;
595 string_info=AcquireStringInfo(0);
596 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
597 string_info->length=length;
598 string_info->datum=(unsigned char *) string;
599 return(string_info);
600}
601
602/*
603%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604% %
605% %
606% %
607% C o n s t a n t S t r i n g %
608% %
609% %
610% %
611%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
612%
613% ConstantString() allocates memory for a string and copies the source string
614% to that memory location (and returns it). Use it for strings that you do
615% do not expect to change over its lifetime.
616%
617% The format of the ConstantString method is:
618%
619% char *ConstantString(const char *source)
620%
621% A description of each parameter follows:
622%
623% o source: A character string.
624%
625*/
626MagickExport char *ConstantString(const char *source)
627{
628 char
629 *destination;
630
631 size_t
632 length;
633
634 length=0;
635 if (source != (char *) NULL)
636 length+=strlen(source);
637 destination=(char *) NULL;
638 if (~length >= 1UL)
639 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
640 if (destination == (char *) NULL)
641 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
642 *destination='\0';
643 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000644 (void) memcpy(destination,source,length*sizeof(*destination));
645 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000646 return(destination);
647}
648
649/*
650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651% %
652% %
653% %
654% C o p y M a g i c k S t r i n g %
655% %
656% %
657% %
658%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659%
660% CopyMagickString() copies the source string to the destination string. The
661% destination buffer is always null-terminated even if the string must be
662% truncated. The return value is the minimum of the source string length
663% or the length parameter.
664%
665% The format of the CopyMagickString method is:
666%
667% size_t CopyMagickString(const char *destination,char *source,
668% const size_t length)
669%
670% A description of each parameter follows:
671%
672% o destination: the destination string.
673%
674% o source: the source string.
675%
676% o length: the length of the destination string.
677%
678*/
679MagickExport size_t CopyMagickString(char *destination,const char *source,
680 const size_t length)
681{
682 register char
683 *q;
684
685 register const char
686 *p;
687
688 register size_t
689 n;
690
691 p=source;
692 q=destination;
693 for (n=length; n > 4; n-=4)
694 {
695 *q=(*p++);
696 if (*q == '\0')
697 return((size_t) (p-source-1));
698 q++;
699 *q=(*p++);
700 if (*q == '\0')
701 return((size_t) (p-source-1));
702 q++;
703 *q=(*p++);
704 if (*q == '\0')
705 return((size_t) (p-source-1));
706 q++;
707 *q=(*p++);
708 if (*q == '\0')
709 return((size_t) (p-source-1));
710 q++;
711 }
712 if (n != 0)
713 for (n--; n != 0; n--)
714 {
715 *q=(*p++);
716 if (*q == '\0')
717 return((size_t) (p-source-1));
718 q++;
719 }
720 if (length != 0)
721 *q='\0';
722 return((size_t) (p-source-1));
723}
724
725/*
726%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
727% %
728% %
729% %
730% D e s t r o y S t r i n g %
731% %
732% %
733% %
734%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735%
736% DestroyString() destroys memory associated with a string.
737%
738% The format of the DestroyString method is:
739%
740% char *DestroyString(char *string)
741%
742% A description of each parameter follows:
743%
744% o string: the string.
745%
746*/
747MagickExport char *DestroyString(char *string)
748{
749 return((char *) RelinquishMagickMemory(string));
750}
751
752/*
753%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
754% %
755% %
756% %
757% D e s t r o y S t r i n g I n f o %
758% %
759% %
760% %
761%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762%
763% DestroyStringInfo() destroys memory associated with the StringInfo structure.
764%
765% The format of the DestroyStringInfo method is:
766%
767% StringInfo *DestroyStringInfo(StringInfo *string_info)
768%
769% A description of each parameter follows:
770%
771% o string_info: the string info.
772%
773*/
774MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
775{
776 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
777 assert(string_info != (StringInfo *) NULL);
778 assert(string_info->signature == MagickSignature);
779 if (string_info->datum != (unsigned char *) NULL)
780 string_info->datum=(unsigned char *) RelinquishMagickMemory(
781 string_info->datum);
782 string_info->signature=(~MagickSignature);
783 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
784 return(string_info);
785}
786
787/*
788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789% %
790% %
791% %
792% D e s t r o y S t r i n g L i s t %
793% %
794% %
795% %
796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
797%
798% DestroyStringList() zeros memory associated with a string list.
799%
800% The format of the DestroyStringList method is:
801%
802% char **DestroyStringList(char **list)
803%
804% A description of each parameter follows:
805%
806% o list: the string list.
807%
808*/
809MagickExport char **DestroyStringList(char **list)
810{
cristybb503372010-05-27 20:51:26 +0000811 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000812 i;
813
814 assert(list != (char **) NULL);
815 for (i=0; list[i] != (char *) NULL; i++)
816 list[i]=DestroyString(list[i]);
817 list=(char **) RelinquishMagickMemory(list);
818 return(list);
819}
820
821/*
822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823% %
824% %
825% %
826% E s c a p e S t r i n g %
827% %
828% %
829% %
830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831%
832% EscapeString() allocates memory for a backslash-escaped version of a
833% source text string, copies the escaped version of the text to that
834% memory location while adding backslash characters, and returns the
835% escaped string.
836%
837% The format of the EscapeString method is:
838%
839% char *EscapeString(const char *source,const char escape)
840%
841% A description of each parameter follows:
842%
843% o allocate_string: Method EscapeString returns the escaped string.
844%
845% o source: A character string.
846%
847% o escape: the quoted string termination character to escape (e.g. '"').
848%
849*/
850MagickExport char *EscapeString(const char *source,const char escape)
851{
852 char
853 *destination;
854
855 register char
856 *q;
857
858 register const char
859 *p;
860
861 size_t
862 length;
863
864 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
865 assert(source != (const char *) NULL);
866 length=strlen(source);
867 for (p=source; *p != '\0'; p++)
868 if ((*p == '\\') || (*p == escape))
869 {
870 if (~length < 1)
871 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
872 length++;
873 }
874 destination=(char *) NULL;
875 if (~length >= MaxTextExtent)
876 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
877 sizeof(*destination));
878 if (destination == (char *) NULL)
879 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
880 *destination='\0';
881 if (source != (char *) NULL)
882 {
883 q=destination;
884 for (p=source; *p != '\0'; p++)
885 {
886 if ((*p == '\\') || (*p == escape))
887 *q++='\\';
888 *q++=(*p);
889 }
890 *q='\0';
891 }
892 return(destination);
893}
894
895/*
896%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
897% %
898% %
899% %
900% F i l e T o S t r i n g %
901% %
902% %
903% %
904%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
905%
906% FileToString() returns the contents of a file as a string.
907%
908% The format of the FileToString method is:
909%
910% char *FileToString(const char *filename,const size_t extent,
911% ExceptionInfo *exception)
912%
913% A description of each parameter follows:
914%
915% o filename: the filename.
916%
917% o extent: Maximum length of the string.
918%
919% o exception: return any errors or warnings in this structure.
920%
921*/
922MagickExport char *FileToString(const char *filename,const size_t extent,
923 ExceptionInfo *exception)
924{
925 size_t
926 length;
927
928 assert(filename != (const char *) NULL);
929 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
930 assert(exception != (ExceptionInfo *) NULL);
931 return((char *) FileToBlob(filename,extent,&length,exception));
932}
933
934/*
935%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
936% %
937% %
938% %
939% F i l e T o S t r i n g I n f o %
940% %
941% %
942% %
943%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
944%
945% FileToStringInfo() returns the contents of a file as a string.
946%
947% The format of the FileToStringInfo method is:
948%
949% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
950% ExceptionInfo *exception)
951%
952% A description of each parameter follows:
953%
954% o filename: the filename.
955%
956% o extent: Maximum length of the string.
957%
958% o exception: return any errors or warnings in this structure.
959%
960*/
961MagickExport StringInfo *FileToStringInfo(const char *filename,
962 const size_t extent,ExceptionInfo *exception)
963{
964 StringInfo
965 *string_info;
966
967 assert(filename != (const char *) NULL);
968 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
969 assert(exception != (ExceptionInfo *) NULL);
970 string_info=AcquireStringInfo(0);
971 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
972 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
973 if (string_info->datum == (unsigned char *) NULL)
974 {
975 string_info=DestroyStringInfo(string_info);
976 return((StringInfo *) NULL);
977 }
978 return(string_info);
979}
980
981/*
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983% %
984% %
985% %
986% F o r m a t M a g i c k S i z e %
987% %
988% %
989% %
990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991%
992% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +0000993% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +0000994% 1000.
cristy3ed852e2009-09-05 21:47:34 +0000995%
996% The format of the FormatMagickSize method is:
997%
cristybb503372010-05-27 20:51:26 +0000998% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +0000999%
1000% A description of each parameter follows:
1001%
1002% o size: convert this size to a human readable format.
1003%
cristyb9080c92009-12-01 20:13:26 +00001004% o bi: use power of two rather than power of ten.
1005%
cristy3ed852e2009-09-05 21:47:34 +00001006% o format: human readable format.
1007%
1008*/
cristybb503372010-05-27 20:51:26 +00001009MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001010 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001011{
cristyb9080c92009-12-01 20:13:26 +00001012 const char
1013 **units;
1014
cristy3ed852e2009-09-05 21:47:34 +00001015 double
cristyb9080c92009-12-01 20:13:26 +00001016 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001017 length;
1018
cristybb503372010-05-27 20:51:26 +00001019 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001020 i,
1021 j;
1022
cristy9d314ff2011-03-09 01:30:28 +00001023 ssize_t
1024 count;
1025
cristy3ed852e2009-09-05 21:47:34 +00001026 static const char
cristyb9080c92009-12-01 20:13:26 +00001027 *bi_units[] =
1028 {
cristy2ce15c92010-03-12 14:03:41 +00001029 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001030 },
1031 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001032 {
cristy2ce15c92010-03-12 14:03:41 +00001033 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001034 };
cristy3ed852e2009-09-05 21:47:34 +00001035
cristyb9080c92009-12-01 20:13:26 +00001036 bytes=1000.0;
1037 units=traditional_units;
1038 if (bi != MagickFalse)
1039 {
1040 bytes=1024.0;
1041 units=bi_units;
1042 }
cristy3ed852e2009-09-05 21:47:34 +00001043#if defined(_MSC_VER) && (_MSC_VER == 1200)
1044 length=(double) ((MagickOffsetType) size);
1045#else
1046 length=(double) size;
1047#endif
cristyb9080c92009-12-01 20:13:26 +00001048 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1049 length/=bytes;
cristy9bf9da32009-09-27 16:48:34 +00001050 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001051 {
cristy9bfdd582010-10-23 01:27:25 +00001052 count=FormatMagickString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001053 units[i]);
1054 if (strchr(format,'+') == (char *) NULL)
1055 break;
1056 }
1057 return(count);
1058}
1059
1060/*
1061%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1062% %
1063% %
1064% %
1065% F o r m a t M a g i c k S t r i n g %
1066% %
1067% %
1068% %
1069%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070%
1071% FormatMagickString() prints formatted output of a variable argument list.
1072%
1073% The format of the FormatMagickString method is:
1074%
cristybb503372010-05-27 20:51:26 +00001075% ssize_t FormatMagickString(char *string,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001076% const char *format,...)
1077%
1078% A description of each parameter follows.
1079%
1080% o string: FormatMagickString() returns the formatted string in this
1081% character buffer.
1082%
1083% o length: the maximum length of the string.
1084%
1085% o format: A string describing the format to use to write the remaining
1086% arguments.
1087%
1088*/
1089
cristybb503372010-05-27 20:51:26 +00001090MagickExport ssize_t FormatMagickStringList(char *string,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001091 const char *format,va_list operands)
1092{
1093 int
1094 n;
1095
1096#if defined(MAGICKCORE_HAVE_VSNPRINTF)
1097 n=vsnprintf(string,length,format,operands);
1098#else
1099 n=vsprintf(string,format,operands);
1100#endif
1101 if (n < 0)
1102 string[length-1]='\0';
cristybb503372010-05-27 20:51:26 +00001103 return((ssize_t) n);
cristy3ed852e2009-09-05 21:47:34 +00001104}
1105
cristybb503372010-05-27 20:51:26 +00001106MagickExport ssize_t FormatMagickString(char *string,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001107 const char *format,...)
1108{
cristybb503372010-05-27 20:51:26 +00001109 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001110 n;
1111
1112 va_list
1113 operands;
1114
1115 va_start(operands,format);
cristybb503372010-05-27 20:51:26 +00001116 n=(ssize_t) FormatMagickStringList(string,length,format,operands);
cristy3ed852e2009-09-05 21:47:34 +00001117 va_end(operands);
1118 return(n);
1119}
1120
1121/*
1122%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1123% %
1124% %
1125% %
1126% F o r m a t M a g i c k T i m e %
1127% %
1128% %
1129% %
1130%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1131%
1132% FormatMagickTime() returns the specified time in the Internet date/time
1133% format and the length of the timestamp.
1134%
1135% The format of the FormatMagickTime method is:
1136%
cristybb503372010-05-27 20:51:26 +00001137% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001138% char *timestamp)
1139%
1140% A description of each parameter follows.
1141%
1142% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1143% measured in seconds.
1144%
1145% o length: the maximum length of the string.
1146%
1147% o timestamp: Return the Internet date/time here.
1148%
1149*/
cristybb503372010-05-27 20:51:26 +00001150MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001151 char *timestamp)
1152{
cristybb503372010-05-27 20:51:26 +00001153 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001154 count;
1155
1156 struct tm
1157 gm_time,
1158 local_time;
1159
1160 time_t
1161 timezone;
1162
1163 assert(timestamp != (char *) NULL);
1164 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1165 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1166#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1167 (void) localtime_r(&time,&local_time);
1168#else
1169 {
cristybc3392a2009-10-06 03:15:57 +00001170 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001171 *my_time;
1172
1173 my_time=localtime(&time);
1174 if (my_time != (struct tm *) NULL)
1175 (void) memcpy(&local_time,my_time,sizeof(local_time));
1176 }
1177#endif
1178#if defined(MAGICKCORE_HAVE_GMTIME_R)
1179 (void) gmtime_r(&time,&gm_time);
1180#else
1181 {
cristybc3392a2009-10-06 03:15:57 +00001182 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001183 *my_time;
1184
1185 my_time=gmtime(&time);
1186 if (my_time != (struct tm *) NULL)
1187 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1188 }
1189#endif
1190 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1191 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1192 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1193 (local_time.tm_yday-gm_time.tm_yday)));
1194 count=FormatMagickString(timestamp,length,
1195 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1196 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001197 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001198 return(count);
1199}
1200
1201/*
1202%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1203% %
1204% %
1205% %
1206% G e t E n v i r o n m e n t V a l u e %
1207% %
1208% %
1209% %
1210%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1211%
1212% GetEnvironmentValue() returns the environment string that matches the
1213% specified name.
1214%
1215% The format of the GetEnvironmentValue method is:
1216%
1217% char *GetEnvironmentValue(const char *name)
1218%
1219% A description of each parameter follows:
1220%
1221% o name: the environment name.
1222%
1223*/
1224MagickExport char *GetEnvironmentValue(const char *name)
1225{
1226 const char
1227 *environment;
1228
1229 environment=getenv(name);
1230 if (environment == (const char *) NULL)
1231 return((char *) NULL);
1232 return(ConstantString(environment));
1233}
1234
1235/*
1236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1237% %
1238% %
1239% %
1240% G e t S t r i n g I n f o D a t u m %
1241% %
1242% %
1243% %
1244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1245%
1246% GetStringInfoDatum() returns the datum associated with the string.
1247%
1248% The format of the GetStringInfoDatum method is:
1249%
1250% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1251%
1252% A description of each parameter follows:
1253%
1254% o string_info: the string info.
1255%
1256*/
1257MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1258{
1259 assert(string_info != (StringInfo *) NULL);
1260 assert(string_info->signature == MagickSignature);
1261 return(string_info->datum);
1262}
1263
1264/*
1265%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1266% %
1267% %
1268% %
1269% G e t S t r i n g I n f o L e n g t h %
1270% %
1271% %
1272% %
1273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1274%
1275% GetStringInfoLength() returns the string length.
1276%
1277% The format of the GetStringInfoLength method is:
1278%
1279% size_t GetStringInfoLength(const StringInfo *string_info)
1280%
1281% A description of each parameter follows:
1282%
1283% o string_info: the string info.
1284%
1285*/
1286MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1287{
1288 assert(string_info != (StringInfo *) NULL);
1289 assert(string_info->signature == MagickSignature);
1290 return(string_info->length);
1291}
1292
1293/*
1294%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1295% %
1296% %
1297% %
1298% G e t S t r i n g I n f o P a t h %
1299% %
1300% %
1301% %
1302%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1303%
1304% GetStringInfoPath() returns the path associated with the string.
1305%
1306% The format of the GetStringInfoPath method is:
1307%
1308% const char *GetStringInfoPath(const StringInfo *string_info)
1309%
1310% A description of each parameter follows:
1311%
1312% o string_info: the string info.
1313%
1314*/
1315MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1316{
1317 assert(string_info != (StringInfo *) NULL);
1318 assert(string_info->signature == MagickSignature);
1319 return(string_info->path);
1320}
1321
1322/*
1323%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1324% %
1325% %
1326% %
1327% L o c a l e C o m p a r e %
1328% %
1329% %
1330% %
1331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332%
1333% LocaleCompare() performs a case-insensitive comparison of two strings
1334% byte-by-byte, according to the ordering of the current locale encoding.
1335% LocaleCompare returns an integer greater than, equal to, or less than 0,
1336% if the string pointed to by p is greater than, equal to, or less than the
1337% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001338% is determined by the sign of the difference between the values of the first
1339% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001340%
1341% The format of the LocaleCompare method is:
1342%
cristyde58b412010-02-18 03:53:40 +00001343% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001344%
1345% A description of each parameter follows:
1346%
1347% o p: A pointer to a character string.
1348%
1349% o q: A pointer to a character string to compare to p.
1350%
1351*/
cristyde58b412010-02-18 03:53:40 +00001352MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001353{
1354 if ((p == (char *) NULL) && (q == (char *) NULL))
1355 return(0);
1356 if (p == (char *) NULL)
1357 return(-1);
1358 if (q == (char *) NULL)
1359 return(1);
1360#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001361 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001362#else
1363 {
cristyde58b412010-02-18 03:53:40 +00001364 register int
cristy3ed852e2009-09-05 21:47:34 +00001365 c,
cristya72c2d12010-02-18 01:20:28 +00001366 d;
cristy3ed852e2009-09-05 21:47:34 +00001367
cristya72c2d12010-02-18 01:20:28 +00001368 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001369 {
cristyde58b412010-02-18 03:53:40 +00001370 c=(int) *((unsigned char *) p);
1371 d=(int) *((unsigned char *) q);
1372 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001373 break;
cristya72c2d12010-02-18 01:20:28 +00001374 p++;
1375 q++;
cristy3ed852e2009-09-05 21:47:34 +00001376 }
cristyde58b412010-02-18 03:53:40 +00001377 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001378 }
1379#endif
1380}
1381
1382/*
1383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1384% %
1385% %
1386% %
1387% L o c a l e L o w e r %
1388% %
1389% %
1390% %
1391%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1392%
1393% LocaleLower() transforms all of the characters in the supplied
1394% null-terminated string, changing all uppercase letters to lowercase.
1395%
1396% The format of the LocaleLower method is:
1397%
1398% void LocaleLower(char *string)
1399%
1400% A description of each parameter follows:
1401%
1402% o string: A pointer to the string to convert to lower-case Locale.
1403%
1404*/
1405MagickExport void LocaleLower(char *string)
1406{
1407 register char
1408 *q;
1409
1410 assert(string != (char *) NULL);
1411 for (q=string; *q != '\0'; q++)
1412 *q=(char) tolower((int) *q);
1413}
1414
1415/*
1416%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417% %
1418% %
1419% %
1420% L o c a l e N C o m p a r e %
1421% %
1422% %
1423% %
1424%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1425%
1426% LocaleNCompare() performs a case-insensitive comparison of two
1427% strings byte-by-byte, according to the ordering of the current locale
1428% encoding. LocaleNCompare returns an integer greater than, equal to, or
1429% less than 0, if the string pointed to by p is greater than, equal to, or
1430% less than the string pointed to by q respectively. The sign of a non-zero
1431% return value is determined by the sign of the difference between the
1432% values of the first pair of bytes that differ in the strings being
1433% compared. The LocaleNCompare method makes the same comparison as
1434% LocaleCompare but looks at a maximum of n bytes. Bytes following a
1435% null byte are not compared.
1436%
1437% The format of the LocaleNCompare method is:
1438%
cristyde58b412010-02-18 03:53:40 +00001439% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001440%
1441% A description of each parameter follows:
1442%
1443% o p: A pointer to a character string.
1444%
1445% o q: A pointer to a character string to compare to p.
1446%
cristy7a40ba82011-01-08 20:31:18 +00001447% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001448%
1449*/
cristyde58b412010-02-18 03:53:40 +00001450MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001451{
1452 if (p == (char *) NULL)
1453 return(-1);
1454 if (q == (char *) NULL)
1455 return(1);
1456#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001457 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001458#else
1459 {
cristyde58b412010-02-18 03:53:40 +00001460 register int
cristy3ed852e2009-09-05 21:47:34 +00001461 c,
1462 d;
1463
cristyb6af4a52009-10-06 13:56:23 +00001464 register size_t
cristyc4cded12010-02-18 14:40:57 +00001465 i;
cristyb6af4a52009-10-06 13:56:23 +00001466
cristyc4cded12010-02-18 14:40:57 +00001467 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001468 {
cristyde58b412010-02-18 03:53:40 +00001469 c=(int) *((unsigned char *) p);
1470 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001471 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001472 return(AsciiMap[c]-(int) AsciiMap[d]);
1473 if (c == 0)
1474 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001475 p++;
1476 q++;
1477 }
cristyde58b412010-02-18 03:53:40 +00001478 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001479 }
1480#endif
1481}
1482
1483/*
1484%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1485% %
1486% %
1487% %
1488% L o c a l e U p p e r %
1489% %
1490% %
1491% %
1492%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1493%
1494% LocaleUpper() transforms all of the characters in the supplied
1495% null-terminated string, changing all lowercase letters to uppercase.
1496%
1497% The format of the LocaleUpper method is:
1498%
1499% void LocaleUpper(char *string)
1500%
1501% A description of each parameter follows:
1502%
1503% o string: A pointer to the string to convert to upper-case Locale.
1504%
1505*/
1506MagickExport void LocaleUpper(char *string)
1507{
1508 register char
1509 *q;
1510
1511 assert(string != (char *) NULL);
1512 for (q=string; *q != '\0'; q++)
1513 *q=(char) toupper((int) *q);
1514}
1515
1516/*
1517%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1518% %
1519% %
1520% %
1521% P r i n t S t r i n g I n f o %
1522% %
1523% %
1524% %
1525%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1526%
1527% PrintStringInfo() prints the string.
1528%
1529% The format of the PrintStringInfo method is:
1530%
1531% void PrintStringInfo(FILE *file,const char *id,
1532% const StringInfo *string_info)
1533%
1534% A description of each parameter follows:
1535%
1536% o file: the file, typically stdout.
1537%
1538% o id: the string id.
1539%
1540% o string_info: the string info.
1541%
1542*/
1543MagickExport void PrintStringInfo(FILE *file,const char *id,
1544 const StringInfo *string_info)
1545{
1546 register const char
1547 *p;
1548
1549 register size_t
1550 i,
1551 j;
1552
1553 assert(id != (const char *) NULL);
1554 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1555 assert(string_info != (StringInfo *) NULL);
1556 assert(string_info->signature == MagickSignature);
1557 p=(char *) string_info->datum;
1558 for (i=0; i < string_info->length; i++)
1559 {
1560 if (((int) ((unsigned char) *p) < 32) &&
1561 (isspace((int) ((unsigned char) *p)) == 0))
1562 break;
1563 p++;
1564 }
1565 if (i == string_info->length)
1566 {
1567 (void) fputs((char *) string_info->datum,file);
1568 (void) fputc('\n',file);
1569 return;
1570 }
1571 /*
1572 Convert string to a HEX list.
1573 */
1574 p=(char *) string_info->datum;
1575 for (i=0; i < string_info->length; i+=0x14)
1576 {
cristyf1d91242010-05-28 02:23:19 +00001577 (void) fprintf(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001578 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1579 {
cristyf1d91242010-05-28 02:23:19 +00001580 (void) fprintf(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001581 if ((j % 0x04) == 0)
1582 (void) fputc(' ',file);
1583 }
1584 for ( ; j <= 0x14; j++)
1585 {
1586 (void) fputc(' ',file);
1587 (void) fputc(' ',file);
1588 if ((j % 0x04) == 0)
1589 (void) fputc(' ',file);
1590 }
1591 (void) fputc(' ',file);
1592 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1593 {
1594 if (isprint((int) ((unsigned char) *p)) != 0)
1595 (void) fputc(*p,file);
1596 else
1597 (void) fputc('-',file);
1598 p++;
1599 }
1600 (void) fputc('\n',file);
1601 }
1602}
1603
1604/*
1605%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1606% %
1607% %
1608% %
1609% R e s e t S t r i n g I n f o %
1610% %
1611% %
1612% %
1613%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1614%
1615% ResetStringInfo() reset the string to all null bytes.
1616%
1617% The format of the ResetStringInfo method is:
1618%
1619% void ResetStringInfo(StringInfo *string_info)
1620%
1621% A description of each parameter follows:
1622%
1623% o string_info: the string info.
1624%
1625*/
1626MagickExport void ResetStringInfo(StringInfo *string_info)
1627{
1628 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1629 assert(string_info != (StringInfo *) NULL);
1630 assert(string_info->signature == MagickSignature);
1631 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1632}
1633
1634/*
1635%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1636% %
1637% %
1638% %
1639% S e t S t r i n g I n f o %
1640% %
1641% %
1642% %
1643%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1644%
1645% SetStringInfo() copies the source string to the destination string.
1646%
1647% The format of the SetStringInfo method is:
1648%
1649% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1650%
1651% A description of each parameter follows:
1652%
1653% o string_info: the string info.
1654%
1655% o source: the source string.
1656%
1657*/
1658MagickExport void SetStringInfo(StringInfo *string_info,
1659 const StringInfo *source)
1660{
1661 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1662 assert(string_info != (StringInfo *) NULL);
1663 assert(string_info->signature == MagickSignature);
1664 assert(source != (StringInfo *) NULL);
1665 assert(source->signature == MagickSignature);
1666 if (string_info->length == 0)
1667 return;
1668 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001669 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1670 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001671}
1672
1673/*
1674%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1675% %
1676% %
1677% %
1678% S e t S t r i n g I n f o D a t u m %
1679% %
1680% %
1681% %
1682%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1683%
1684% SetStringInfoDatum() copies bytes from the source string for the length of
1685% the destination string.
1686%
1687% The format of the SetStringInfoDatum method is:
1688%
1689% void SetStringInfoDatum(StringInfo *string_info,
1690% const unsigned char *source)
1691%
1692% A description of each parameter follows:
1693%
1694% o string_info: the string info.
1695%
1696% o source: the source string.
1697%
1698*/
1699MagickExport void SetStringInfoDatum(StringInfo *string_info,
1700 const unsigned char *source)
1701{
1702 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1703 assert(string_info != (StringInfo *) NULL);
1704 assert(string_info->signature == MagickSignature);
1705 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001706 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001707}
1708
1709/*
1710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1711% %
1712% %
1713% %
1714% S e t S t r i n g I n f o L e n g t h %
1715% %
1716% %
1717% %
1718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1719%
1720% SetStringInfoLength() set the string length to the specified value.
1721%
1722% The format of the SetStringInfoLength method is:
1723%
1724% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1725%
1726% A description of each parameter follows:
1727%
1728% o string_info: the string info.
1729%
1730% o length: the string length.
1731%
1732*/
1733MagickExport void SetStringInfoLength(StringInfo *string_info,
1734 const size_t length)
1735{
1736 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1737 assert(string_info != (StringInfo *) NULL);
1738 assert(string_info->signature == MagickSignature);
1739 if (~length < MaxTextExtent)
1740 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1741 string_info->length=length;
1742 if (string_info->datum == (unsigned char *) NULL)
1743 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1744 MaxTextExtent,sizeof(*string_info->datum));
1745 else
1746 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1747 length+MaxTextExtent,sizeof(*string_info->datum));
1748 if (string_info->datum == (unsigned char *) NULL)
1749 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1750}
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% SetStringInfoPath() sets the path associated with the string.
1764%
1765% The format of the SetStringInfoPath method is:
1766%
1767% void SetStringInfoPath(StringInfo *string_info,const char *path)
1768%
1769% A description of each parameter follows:
1770%
1771% o string_info: the string info.
1772%
1773% o path: the path.
1774%
1775*/
1776MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1777{
1778 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1779 assert(string_info != (StringInfo *) NULL);
1780 assert(string_info->signature == MagickSignature);
1781 assert(path != (const char *) NULL);
1782 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1783}
1784
1785/*
1786%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1787% %
1788% %
1789% %
1790% S p l i t S t r i n g I n f o %
1791% %
1792% %
1793% %
1794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1795%
1796% SplitStringInfo() splits a string into two and returns it.
1797%
1798% The format of the SplitStringInfo method is:
1799%
1800% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1801%
1802% A description of each parameter follows:
1803%
1804% o string_info: the string info.
1805%
1806*/
1807MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1808 const size_t offset)
1809{
1810 StringInfo
1811 *split_info;
1812
1813 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1814 assert(string_info != (StringInfo *) NULL);
1815 assert(string_info->signature == MagickSignature);
1816 if (offset > string_info->length)
1817 return((StringInfo *) NULL);
1818 split_info=AcquireStringInfo(offset);
1819 SetStringInfo(split_info,string_info);
cristy54aad5e2010-09-03 16:02:04 +00001820 (void) memcpy(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00001821 string_info->length-offset+MaxTextExtent);
1822 SetStringInfoLength(string_info,string_info->length-offset);
1823 return(split_info);
1824}
1825
1826/*
1827%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1828% %
1829% %
1830% %
1831% S t r i n g I n f o T o S t r i n g %
1832% %
1833% %
1834% %
1835%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1836%
1837% StringInfoToString() converts a string info string to a C string.
1838%
1839% The format of the StringInfoToString method is:
1840%
1841% char *StringInfoToString(const StringInfo *string_info)
1842%
1843% A description of each parameter follows:
1844%
1845% o string_info: the string.
1846%
1847*/
1848MagickExport char *StringInfoToString(const StringInfo *string_info)
1849{
1850 char
1851 *string;
1852
1853 size_t
1854 length;
1855
1856 string=(char *) NULL;
1857 length=string_info->length;
1858 if (~length >= MaxTextExtent)
1859 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001860 if (string == (char *) NULL)
1861 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00001862 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001863 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001864 return(string);
1865}
1866
1867/*
1868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1869% %
1870% %
1871% %
1872% S t r i n g T o A r g v %
1873% %
1874% %
1875% %
1876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1877%
1878% StringToArgv() converts a text string into command line arguments.
1879%
1880% The format of the StringToArgv method is:
1881%
1882% char **StringToArgv(const char *text,int *argc)
1883%
1884% A description of each parameter follows:
1885%
1886% o argv: Method StringToArgv returns the string list unless an error
1887% occurs, otherwise NULL.
1888%
1889% o text: Specifies the string to segment into a list.
1890%
1891% o argc: This integer pointer returns the number of arguments in the
1892% list.
1893%
1894*/
1895MagickExport char **StringToArgv(const char *text,int *argc)
1896{
1897 char
1898 **argv;
1899
1900 register const char
1901 *p,
1902 *q;
1903
cristybb503372010-05-27 20:51:26 +00001904 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001905 i;
1906
1907 *argc=0;
1908 if (text == (char *) NULL)
1909 return((char **) NULL);
1910 /*
1911 Determine the number of arguments.
1912 */
1913 for (p=text; *p != '\0'; )
1914 {
1915 while (isspace((int) ((unsigned char) *p)) != 0)
1916 p++;
cristy74895d32011-01-22 21:30:47 +00001917 if (*p == '\0')
1918 break;
cristy3ed852e2009-09-05 21:47:34 +00001919 (*argc)++;
1920 if (*p == '"')
1921 for (p++; (*p != '"') && (*p != '\0'); p++) ;
1922 if (*p == '\'')
1923 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
1924 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1925 p++;
1926 }
1927 (*argc)++;
1928 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
1929 if (argv == (char **) NULL)
1930 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
1931 /*
1932 Convert string to an ASCII list.
1933 */
1934 argv[0]=AcquireString("magick");
1935 p=text;
cristybb503372010-05-27 20:51:26 +00001936 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00001937 {
1938 while (isspace((int) ((unsigned char) *p)) != 0)
1939 p++;
1940 q=p;
1941 if (*q == '"')
1942 {
1943 p++;
1944 for (q++; (*q != '"') && (*q != '\0'); q++) ;
1945 }
1946 else
1947 if (*q == '\'')
1948 {
cristy06b15f42011-01-22 21:36:24 +00001949 p++;
cristy3ed852e2009-09-05 21:47:34 +00001950 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00001951 }
1952 else
1953 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
1954 q++;
1955 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
1956 sizeof(**argv));
1957 if (argv[i] == (char *) NULL)
1958 {
1959 for (i--; i >= 0; i--)
1960 argv[i]=DestroyString(argv[i]);
1961 argv=(char **) RelinquishMagickMemory(argv);
1962 ThrowFatalException(ResourceLimitFatalError,
1963 "UnableToConvertStringToARGV");
1964 }
cristy54aad5e2010-09-03 16:02:04 +00001965 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00001966 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001967 p=q;
1968 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1969 p++;
1970 }
1971 argv[i]=(char *) NULL;
1972 return(argv);
1973}
1974
1975/*
1976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1977% %
1978% %
1979% %
cristy3ed852e2009-09-05 21:47:34 +00001980% S t r i n g I n f o T o H e x S t r i n g %
1981% %
1982% %
1983% %
1984%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1985%
1986% StringInfoToHexString() converts a string info string to a C string.
1987%
1988% The format of the StringInfoToHexString method is:
1989%
1990% char *StringInfoToHexString(const StringInfo *string_info)
1991%
1992% A description of each parameter follows:
1993%
1994% o string_info: the string.
1995%
1996*/
1997MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1998{
1999 char
2000 *string;
2001
2002 register const unsigned char
2003 *p;
2004
cristybb503372010-05-27 20:51:26 +00002005 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002006 i;
2007
2008 register unsigned char
2009 *q;
2010
2011 size_t
2012 length;
2013
2014 unsigned char
2015 hex_digits[16];
2016
2017 length=string_info->length;
2018 if (~length < MaxTextExtent)
2019 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2020 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2021 if (string == (char *) NULL)
2022 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2023 hex_digits[0]='0';
2024 hex_digits[1]='1';
2025 hex_digits[2]='2';
2026 hex_digits[3]='3';
2027 hex_digits[4]='4';
2028 hex_digits[5]='5';
2029 hex_digits[6]='6';
2030 hex_digits[7]='7';
2031 hex_digits[8]='8';
2032 hex_digits[9]='9';
2033 hex_digits[10]='a';
2034 hex_digits[11]='b';
2035 hex_digits[12]='c';
2036 hex_digits[13]='d';
2037 hex_digits[14]='e';
2038 hex_digits[15]='f';
2039 p=string_info->datum;
2040 q=(unsigned char *) string;
cristybb503372010-05-27 20:51:26 +00002041 for (i=0; i < (ssize_t) string_info->length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002042 {
2043 *q++=hex_digits[(*p >> 4) & 0x0f];
2044 *q++=hex_digits[*p & 0x0f];
2045 p++;
2046 }
2047 *q='\0';
2048 return(string);
2049}
2050
2051/*
2052%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2053% %
2054% %
2055% %
2056% S t r i n g T o k e n %
2057% %
2058% %
2059% %
2060%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2061%
2062% StringToken() extracts a token a from the string.
2063%
2064% The format of the StringToken method is:
2065%
2066% char *StringToken(const char *delimiters,char **string)
2067%
2068% A description of each parameter follows:
2069%
2070% o delimiters: one or more delimiters.
2071%
2072% o string: return the first token in the string. If none is found, return
2073% NULL.
2074%
2075*/
2076MagickExport char *StringToken(const char *delimiters,char **string)
2077{
2078 char
2079 *q;
2080
2081 register char
2082 *p;
2083
2084 register const char
2085 *r;
2086
2087 register int
2088 c,
2089 d;
2090
2091 p=(*string);
2092 if (p == (char *) NULL)
2093 return((char *) NULL);
2094 for (q=p; ; )
2095 {
2096 c=(*p++);
2097 r=delimiters;
2098 do
2099 {
2100 d=(*r++);
2101 if (c == d)
2102 {
2103 if (c == '\0')
2104 p=(char *) NULL;
2105 else
2106 p[-1]='\0';
2107 *string=p;
2108 return(q);
2109 }
2110 } while (d != '\0');
2111 }
2112}
2113
2114/*
2115%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2116% %
2117% %
2118% %
2119% S t r i n g T o L i s t %
2120% %
2121% %
2122% %
2123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2124%
2125% StringToList() converts a text string into a list by segmenting the text
2126% string at each carriage return discovered. The list is converted to HEX
2127% characters if any control characters are discovered within the text string.
2128%
2129% The format of the StringToList method is:
2130%
2131% char **StringToList(const char *text)
2132%
2133% A description of each parameter follows:
2134%
cristy3ed852e2009-09-05 21:47:34 +00002135% o text: Specifies the string to segment into a list.
2136%
2137*/
2138MagickExport char **StringToList(const char *text)
2139{
2140 char
2141 **textlist;
2142
2143 register const char
2144 *p;
2145
cristybb503372010-05-27 20:51:26 +00002146 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002147 i;
2148
cristybb503372010-05-27 20:51:26 +00002149 size_t
cristy3ed852e2009-09-05 21:47:34 +00002150 lines;
2151
2152 if (text == (char *) NULL)
2153 return((char **) NULL);
2154 for (p=text; *p != '\0'; p++)
2155 if (((int) ((unsigned char) *p) < 32) &&
2156 (isspace((int) ((unsigned char) *p)) == 0))
2157 break;
2158 if (*p == '\0')
2159 {
2160 register const char
2161 *q;
2162
2163 /*
2164 Convert string to an ASCII list.
2165 */
2166 lines=1;
2167 for (p=text; *p != '\0'; p++)
2168 if (*p == '\n')
2169 lines++;
2170 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2171 sizeof(*textlist));
2172 if (textlist == (char **) NULL)
2173 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2174 p=text;
cristybb503372010-05-27 20:51:26 +00002175 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002176 {
2177 for (q=p; *q != '\0'; q++)
2178 if ((*q == '\r') || (*q == '\n'))
2179 break;
2180 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2181 sizeof(*textlist));
2182 if (textlist[i] == (char *) NULL)
2183 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002184 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002185 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002186 if (*q == '\r')
2187 q++;
2188 p=q+1;
2189 }
2190 }
2191 else
2192 {
2193 char
2194 hex_string[MaxTextExtent];
2195
2196 register char
2197 *q;
2198
cristybb503372010-05-27 20:51:26 +00002199 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002200 j;
2201
2202 /*
2203 Convert string to a HEX list.
2204 */
cristybb503372010-05-27 20:51:26 +00002205 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002206 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2207 sizeof(*textlist));
2208 if (textlist == (char **) NULL)
2209 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2210 p=text;
cristybb503372010-05-27 20:51:26 +00002211 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002212 {
2213 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
2214 sizeof(*textlist));
2215 if (textlist[i] == (char *) NULL)
2216 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyf1d91242010-05-28 02:23:19 +00002217 (void) FormatMagickString(textlist[i],MaxTextExtent,"0x%08lx: ",
2218 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002219 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002220 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002221 {
2222 (void) FormatMagickString(hex_string,MaxTextExtent,"%02x",*(p+j));
2223 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2224 q+=2;
2225 if ((j % 0x04) == 0)
2226 *q++=' ';
2227 }
2228 for ( ; j <= 0x14; j++)
2229 {
2230 *q++=' ';
2231 *q++=' ';
2232 if ((j % 0x04) == 0)
2233 *q++=' ';
2234 }
2235 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002236 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002237 {
2238 if (isprint((int) ((unsigned char) *p)) != 0)
2239 *q++=(*p);
2240 else
2241 *q++='-';
2242 p++;
2243 }
2244 *q='\0';
2245 }
2246 }
2247 textlist[i]=(char *) NULL;
2248 return(textlist);
2249}
2250
2251/*
2252%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2253% %
2254% %
2255% %
2256% S t r i n g T o S t r i n g I n f o %
2257% %
2258% %
2259% %
2260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2261%
2262% StringToStringInfo() returns the contents of a file as a string.
2263%
2264% The format of the StringToStringInfo method is:
2265%
2266% StringInfo *StringToStringInfo(const char *string)
2267%
2268% A description of each parameter follows:
2269%
2270% o string: The string.
2271%
2272*/
2273MagickExport StringInfo *StringToStringInfo(const char *string)
2274{
2275 StringInfo
2276 *string_info;
2277
2278 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2279 assert(string != (const char *) NULL);
2280 string_info=AcquireStringInfo(strlen(string)+1);
2281 SetStringInfoDatum(string_info,(const unsigned char *) string);
2282 return(string_info);
2283}
2284
2285/*
2286%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2287% %
2288% %
2289% %
2290% S t r i p S t r i n g %
2291% %
2292% %
2293% %
2294%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2295%
2296% StripString() strips any whitespace or quotes from the beginning and end of
2297% a string of characters.
2298%
2299% The format of the StripString method is:
2300%
2301% void StripString(char *message)
2302%
2303% A description of each parameter follows:
2304%
2305% o message: Specifies an array of characters.
2306%
2307*/
2308MagickExport void StripString(char *message)
2309{
2310 register char
2311 *p,
2312 *q;
2313
2314 size_t
2315 length;
2316
2317 assert(message != (char *) NULL);
2318 if (*message == '\0')
2319 return;
2320 length=strlen(message);
2321 p=message;
2322 while (isspace((int) ((unsigned char) *p)) != 0)
2323 p++;
2324 if ((*p == '\'') || (*p == '"'))
2325 p++;
2326 q=message+length-1;
2327 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2328 q--;
2329 if (q > p)
2330 if ((*q == '\'') || (*q == '"'))
2331 q--;
cristy54aad5e2010-09-03 16:02:04 +00002332 (void) memcpy(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002333 message[q-p+1]='\0';
2334 for (p=message; *p != '\0'; p++)
2335 if (*p == '\n')
2336 *p=' ';
2337}
2338
2339/*
2340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2341% %
2342% %
2343% %
2344% S u b s t i t u t e S t r i n g %
2345% %
2346% %
2347% %
2348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2349%
cristyf1b72c12009-10-06 13:25:21 +00002350% SubstituteString() performs string substitution on a string, replacing the
2351% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002352% If the string is matched and status, MagickTrue is returned otherwise
2353% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002354%
2355% The format of the SubstituteString method is:
2356%
cristyf1b72c12009-10-06 13:25:21 +00002357% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002358% const char *replace)
2359%
2360% A description of each parameter follows:
2361%
cristyf1b72c12009-10-06 13:25:21 +00002362% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002363% allocation if a replacement is made.
2364%
cristybc3392a2009-10-06 03:15:57 +00002365% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002366%
cristybc3392a2009-10-06 03:15:57 +00002367% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002368%
2369*/
cristyf1b72c12009-10-06 13:25:21 +00002370MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002371 const char *search,const char *replace)
2372{
cristybc3392a2009-10-06 03:15:57 +00002373 MagickBooleanType
2374 status;
cristy3ed852e2009-09-05 21:47:34 +00002375
cristybc3392a2009-10-06 03:15:57 +00002376 register char
2377 *p;
cristy3ed852e2009-09-05 21:47:34 +00002378
cristy3ed852e2009-09-05 21:47:34 +00002379 size_t
cristybc3392a2009-10-06 03:15:57 +00002380 extent,
2381 replace_extent,
2382 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002383
cristyf1b72c12009-10-06 13:25:21 +00002384 ssize_t
2385 offset;
2386
cristybc3392a2009-10-06 03:15:57 +00002387 status=MagickFalse;
2388 search_extent=0,
2389 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002390 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002391 {
cristyf1b72c12009-10-06 13:25:21 +00002392 if (search_extent == 0)
2393 search_extent=strlen(search);
2394 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002395 continue;
cristy3ed852e2009-09-05 21:47:34 +00002396 /*
cristybc3392a2009-10-06 03:15:57 +00002397 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002398 */
cristyf1b72c12009-10-06 13:25:21 +00002399 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002400 if (replace_extent == 0)
2401 replace_extent=strlen(replace);
2402 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002403 {
cristybc3392a2009-10-06 03:15:57 +00002404 /*
2405 Make room for the replacement string.
2406 */
cristyde58b412010-02-18 03:53:40 +00002407 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002408 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002409 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2410 sizeof(*p));
2411 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002412 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002413 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002414 }
cristy3ed852e2009-09-05 21:47:34 +00002415 /*
cristybc3392a2009-10-06 03:15:57 +00002416 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002417 */
cristybc3392a2009-10-06 03:15:57 +00002418 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002419 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2420 strlen(p+search_extent)+1);
2421 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002422 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002423 }
cristybc3392a2009-10-06 03:15:57 +00002424 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002425}