blob: dbbd2d3eb1615a32f740799322e3e6171d244d70 [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% %
cristy16af1cb2009-12-11 21:38:29 +000020% Copyright 1999-2010 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,
226 sizeof(*destination));
227 if (*destination == (char *) NULL)
228 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000229 if (length != 0)
230 (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,
445 sizeof(*destination));
446 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);
545 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
546 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
574 (void) MagickSeek(file,0,SEEK_SET);
575 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 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001020 count;
1021
cristybb503372010-05-27 20:51:26 +00001022 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001023 i,
1024 j;
1025
1026 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
1338% is determined by the sign of the difference between the values of the first< % pair of bytes that differ in the strings being compared.
1339%
1340% The format of the LocaleCompare method is:
1341%
cristyde58b412010-02-18 03:53:40 +00001342% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001343%
1344% A description of each parameter follows:
1345%
1346% o p: A pointer to a character string.
1347%
1348% o q: A pointer to a character string to compare to p.
1349%
1350*/
cristyde58b412010-02-18 03:53:40 +00001351MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001352{
1353 if ((p == (char *) NULL) && (q == (char *) NULL))
1354 return(0);
1355 if (p == (char *) NULL)
1356 return(-1);
1357 if (q == (char *) NULL)
1358 return(1);
1359#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001360 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001361#else
1362 {
cristyde58b412010-02-18 03:53:40 +00001363 register int
cristy3ed852e2009-09-05 21:47:34 +00001364 c,
cristya72c2d12010-02-18 01:20:28 +00001365 d;
cristy3ed852e2009-09-05 21:47:34 +00001366
cristya72c2d12010-02-18 01:20:28 +00001367 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001368 {
cristyde58b412010-02-18 03:53:40 +00001369 c=(int) *((unsigned char *) p);
1370 d=(int) *((unsigned char *) q);
1371 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001372 break;
cristya72c2d12010-02-18 01:20:28 +00001373 p++;
1374 q++;
cristy3ed852e2009-09-05 21:47:34 +00001375 }
cristyde58b412010-02-18 03:53:40 +00001376 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001377 }
1378#endif
1379}
1380
1381/*
1382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1383% %
1384% %
1385% %
1386% L o c a l e L o w e r %
1387% %
1388% %
1389% %
1390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1391%
1392% LocaleLower() transforms all of the characters in the supplied
1393% null-terminated string, changing all uppercase letters to lowercase.
1394%
1395% The format of the LocaleLower method is:
1396%
1397% void LocaleLower(char *string)
1398%
1399% A description of each parameter follows:
1400%
1401% o string: A pointer to the string to convert to lower-case Locale.
1402%
1403*/
1404MagickExport void LocaleLower(char *string)
1405{
1406 register char
1407 *q;
1408
1409 assert(string != (char *) NULL);
1410 for (q=string; *q != '\0'; q++)
1411 *q=(char) tolower((int) *q);
1412}
1413
1414/*
1415%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1416% %
1417% %
1418% %
1419% L o c a l e N C o m p a r e %
1420% %
1421% %
1422% %
1423%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1424%
1425% LocaleNCompare() performs a case-insensitive comparison of two
1426% strings byte-by-byte, according to the ordering of the current locale
1427% encoding. LocaleNCompare returns an integer greater than, equal to, or
1428% less than 0, if the string pointed to by p is greater than, equal to, or
1429% less than the string pointed to by q respectively. The sign of a non-zero
1430% return value is determined by the sign of the difference between the
1431% values of the first pair of bytes that differ in the strings being
1432% compared. The LocaleNCompare method makes the same comparison as
1433% LocaleCompare but looks at a maximum of n bytes. Bytes following a
1434% null byte are not compared.
1435%
1436% The format of the LocaleNCompare method is:
1437%
cristyde58b412010-02-18 03:53:40 +00001438% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001439%
1440% A description of each parameter follows:
1441%
1442% o p: A pointer to a character string.
1443%
1444% o q: A pointer to a character string to compare to p.
1445%
1446% o length: the number of characters to compare in strings p & q.
1447%
1448*/
cristyde58b412010-02-18 03:53:40 +00001449MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001450{
1451 if (p == (char *) NULL)
1452 return(-1);
1453 if (q == (char *) NULL)
1454 return(1);
1455#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001456 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001457#else
1458 {
cristyde58b412010-02-18 03:53:40 +00001459 register int
cristy3ed852e2009-09-05 21:47:34 +00001460 c,
1461 d;
1462
cristyb6af4a52009-10-06 13:56:23 +00001463 register size_t
cristyc4cded12010-02-18 14:40:57 +00001464 i;
cristyb6af4a52009-10-06 13:56:23 +00001465
cristyc4cded12010-02-18 14:40:57 +00001466 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001467 {
cristyde58b412010-02-18 03:53:40 +00001468 c=(int) *((unsigned char *) p);
1469 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001470 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001471 return(AsciiMap[c]-(int) AsciiMap[d]);
1472 if (c == 0)
1473 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001474 p++;
1475 q++;
1476 }
cristyde58b412010-02-18 03:53:40 +00001477 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001478 }
1479#endif
1480}
1481
1482/*
1483%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1484% %
1485% %
1486% %
1487% L o c a l e U p p e r %
1488% %
1489% %
1490% %
1491%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1492%
1493% LocaleUpper() transforms all of the characters in the supplied
1494% null-terminated string, changing all lowercase letters to uppercase.
1495%
1496% The format of the LocaleUpper method is:
1497%
1498% void LocaleUpper(char *string)
1499%
1500% A description of each parameter follows:
1501%
1502% o string: A pointer to the string to convert to upper-case Locale.
1503%
1504*/
1505MagickExport void LocaleUpper(char *string)
1506{
1507 register char
1508 *q;
1509
1510 assert(string != (char *) NULL);
1511 for (q=string; *q != '\0'; q++)
1512 *q=(char) toupper((int) *q);
1513}
1514
1515/*
1516%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1517% %
1518% %
1519% %
1520% P r i n t S t r i n g I n f o %
1521% %
1522% %
1523% %
1524%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1525%
1526% PrintStringInfo() prints the string.
1527%
1528% The format of the PrintStringInfo method is:
1529%
1530% void PrintStringInfo(FILE *file,const char *id,
1531% const StringInfo *string_info)
1532%
1533% A description of each parameter follows:
1534%
1535% o file: the file, typically stdout.
1536%
1537% o id: the string id.
1538%
1539% o string_info: the string info.
1540%
1541*/
1542MagickExport void PrintStringInfo(FILE *file,const char *id,
1543 const StringInfo *string_info)
1544{
1545 register const char
1546 *p;
1547
1548 register size_t
1549 i,
1550 j;
1551
1552 assert(id != (const char *) NULL);
1553 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1554 assert(string_info != (StringInfo *) NULL);
1555 assert(string_info->signature == MagickSignature);
1556 p=(char *) string_info->datum;
1557 for (i=0; i < string_info->length; i++)
1558 {
1559 if (((int) ((unsigned char) *p) < 32) &&
1560 (isspace((int) ((unsigned char) *p)) == 0))
1561 break;
1562 p++;
1563 }
1564 if (i == string_info->length)
1565 {
1566 (void) fputs((char *) string_info->datum,file);
1567 (void) fputc('\n',file);
1568 return;
1569 }
1570 /*
1571 Convert string to a HEX list.
1572 */
1573 p=(char *) string_info->datum;
1574 for (i=0; i < string_info->length; i+=0x14)
1575 {
cristyf1d91242010-05-28 02:23:19 +00001576 (void) fprintf(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001577 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1578 {
cristyf1d91242010-05-28 02:23:19 +00001579 (void) fprintf(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001580 if ((j % 0x04) == 0)
1581 (void) fputc(' ',file);
1582 }
1583 for ( ; j <= 0x14; j++)
1584 {
1585 (void) fputc(' ',file);
1586 (void) fputc(' ',file);
1587 if ((j % 0x04) == 0)
1588 (void) fputc(' ',file);
1589 }
1590 (void) fputc(' ',file);
1591 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1592 {
1593 if (isprint((int) ((unsigned char) *p)) != 0)
1594 (void) fputc(*p,file);
1595 else
1596 (void) fputc('-',file);
1597 p++;
1598 }
1599 (void) fputc('\n',file);
1600 }
1601}
1602
1603/*
1604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1605% %
1606% %
1607% %
1608% R e s e t S t r i n g I n f o %
1609% %
1610% %
1611% %
1612%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1613%
1614% ResetStringInfo() reset the string to all null bytes.
1615%
1616% The format of the ResetStringInfo method is:
1617%
1618% void ResetStringInfo(StringInfo *string_info)
1619%
1620% A description of each parameter follows:
1621%
1622% o string_info: the string info.
1623%
1624*/
1625MagickExport void ResetStringInfo(StringInfo *string_info)
1626{
1627 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1628 assert(string_info != (StringInfo *) NULL);
1629 assert(string_info->signature == MagickSignature);
1630 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1631}
1632
1633/*
1634%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1635% %
1636% %
1637% %
1638% S e t S t r i n g I n f o %
1639% %
1640% %
1641% %
1642%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1643%
1644% SetStringInfo() copies the source string to the destination string.
1645%
1646% The format of the SetStringInfo method is:
1647%
1648% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1649%
1650% A description of each parameter follows:
1651%
1652% o string_info: the string info.
1653%
1654% o source: the source string.
1655%
1656*/
1657MagickExport void SetStringInfo(StringInfo *string_info,
1658 const StringInfo *source)
1659{
1660 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1661 assert(string_info != (StringInfo *) NULL);
1662 assert(string_info->signature == MagickSignature);
1663 assert(source != (StringInfo *) NULL);
1664 assert(source->signature == MagickSignature);
1665 if (string_info->length == 0)
1666 return;
1667 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001668 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1669 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001670}
1671
1672/*
1673%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1674% %
1675% %
1676% %
1677% S e t S t r i n g I n f o D a t u m %
1678% %
1679% %
1680% %
1681%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1682%
1683% SetStringInfoDatum() copies bytes from the source string for the length of
1684% the destination string.
1685%
1686% The format of the SetStringInfoDatum method is:
1687%
1688% void SetStringInfoDatum(StringInfo *string_info,
1689% const unsigned char *source)
1690%
1691% A description of each parameter follows:
1692%
1693% o string_info: the string info.
1694%
1695% o source: the source string.
1696%
1697*/
1698MagickExport void SetStringInfoDatum(StringInfo *string_info,
1699 const unsigned char *source)
1700{
1701 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1702 assert(string_info != (StringInfo *) NULL);
1703 assert(string_info->signature == MagickSignature);
1704 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001705 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001706}
1707
1708/*
1709%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1710% %
1711% %
1712% %
1713% S e t S t r i n g I n f o L e n g t h %
1714% %
1715% %
1716% %
1717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1718%
1719% SetStringInfoLength() set the string length to the specified value.
1720%
1721% The format of the SetStringInfoLength method is:
1722%
1723% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1724%
1725% A description of each parameter follows:
1726%
1727% o string_info: the string info.
1728%
1729% o length: the string length.
1730%
1731*/
1732MagickExport void SetStringInfoLength(StringInfo *string_info,
1733 const size_t length)
1734{
1735 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1736 assert(string_info != (StringInfo *) NULL);
1737 assert(string_info->signature == MagickSignature);
1738 if (~length < MaxTextExtent)
1739 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1740 string_info->length=length;
1741 if (string_info->datum == (unsigned char *) NULL)
1742 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1743 MaxTextExtent,sizeof(*string_info->datum));
1744 else
1745 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1746 length+MaxTextExtent,sizeof(*string_info->datum));
1747 if (string_info->datum == (unsigned char *) NULL)
1748 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1749}
1750
1751/*
1752%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1753% %
1754% %
1755% %
1756% S e t S t r i n g I n f o D a t u m %
1757% %
1758% %
1759% %
1760%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1761%
1762% SetStringInfoPath() sets the path associated with the string.
1763%
1764% The format of the SetStringInfoPath method is:
1765%
1766% void SetStringInfoPath(StringInfo *string_info,const char *path)
1767%
1768% A description of each parameter follows:
1769%
1770% o string_info: the string info.
1771%
1772% o path: the path.
1773%
1774*/
1775MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1776{
1777 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1778 assert(string_info != (StringInfo *) NULL);
1779 assert(string_info->signature == MagickSignature);
1780 assert(path != (const char *) NULL);
1781 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1782}
1783
1784/*
1785%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1786% %
1787% %
1788% %
1789% S p l i t S t r i n g I n f o %
1790% %
1791% %
1792% %
1793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1794%
1795% SplitStringInfo() splits a string into two and returns it.
1796%
1797% The format of the SplitStringInfo method is:
1798%
1799% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1800%
1801% A description of each parameter follows:
1802%
1803% o string_info: the string info.
1804%
1805*/
1806MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1807 const size_t offset)
1808{
1809 StringInfo
1810 *split_info;
1811
1812 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1813 assert(string_info != (StringInfo *) NULL);
1814 assert(string_info->signature == MagickSignature);
1815 if (offset > string_info->length)
1816 return((StringInfo *) NULL);
1817 split_info=AcquireStringInfo(offset);
1818 SetStringInfo(split_info,string_info);
cristy54aad5e2010-09-03 16:02:04 +00001819 (void) memcpy(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00001820 string_info->length-offset+MaxTextExtent);
1821 SetStringInfoLength(string_info,string_info->length-offset);
1822 return(split_info);
1823}
1824
1825/*
1826%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1827% %
1828% %
1829% %
1830% S t r i n g I n f o T o S t r i n g %
1831% %
1832% %
1833% %
1834%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1835%
1836% StringInfoToString() converts a string info string to a C string.
1837%
1838% The format of the StringInfoToString method is:
1839%
1840% char *StringInfoToString(const StringInfo *string_info)
1841%
1842% A description of each parameter follows:
1843%
1844% o string_info: the string.
1845%
1846*/
1847MagickExport char *StringInfoToString(const StringInfo *string_info)
1848{
1849 char
1850 *string;
1851
1852 size_t
1853 length;
1854
1855 string=(char *) NULL;
1856 length=string_info->length;
1857 if (~length >= MaxTextExtent)
1858 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001859 if (string == (char *) NULL)
1860 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00001861 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001862 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001863 return(string);
1864}
1865
1866/*
1867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1868% %
1869% %
1870% %
1871% S t r i n g T o A r g v %
1872% %
1873% %
1874% %
1875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1876%
1877% StringToArgv() converts a text string into command line arguments.
1878%
1879% The format of the StringToArgv method is:
1880%
1881% char **StringToArgv(const char *text,int *argc)
1882%
1883% A description of each parameter follows:
1884%
1885% o argv: Method StringToArgv returns the string list unless an error
1886% occurs, otherwise NULL.
1887%
1888% o text: Specifies the string to segment into a list.
1889%
1890% o argc: This integer pointer returns the number of arguments in the
1891% list.
1892%
1893*/
1894MagickExport char **StringToArgv(const char *text,int *argc)
1895{
1896 char
1897 **argv;
1898
1899 register const char
1900 *p,
1901 *q;
1902
cristybb503372010-05-27 20:51:26 +00001903 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001904 i;
1905
1906 *argc=0;
1907 if (text == (char *) NULL)
1908 return((char **) NULL);
1909 /*
1910 Determine the number of arguments.
1911 */
1912 for (p=text; *p != '\0'; )
1913 {
1914 while (isspace((int) ((unsigned char) *p)) != 0)
1915 p++;
1916 (*argc)++;
1917 if (*p == '"')
1918 for (p++; (*p != '"') && (*p != '\0'); p++) ;
1919 if (*p == '\'')
1920 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
1921 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1922 p++;
1923 }
1924 (*argc)++;
1925 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
1926 if (argv == (char **) NULL)
1927 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
1928 /*
1929 Convert string to an ASCII list.
1930 */
1931 argv[0]=AcquireString("magick");
1932 p=text;
cristybb503372010-05-27 20:51:26 +00001933 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00001934 {
1935 while (isspace((int) ((unsigned char) *p)) != 0)
1936 p++;
1937 q=p;
1938 if (*q == '"')
1939 {
1940 p++;
1941 for (q++; (*q != '"') && (*q != '\0'); q++) ;
1942 }
1943 else
1944 if (*q == '\'')
1945 {
1946 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
1947 q++;
1948 }
1949 else
1950 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
1951 q++;
1952 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
1953 sizeof(**argv));
1954 if (argv[i] == (char *) NULL)
1955 {
1956 for (i--; i >= 0; i--)
1957 argv[i]=DestroyString(argv[i]);
1958 argv=(char **) RelinquishMagickMemory(argv);
1959 ThrowFatalException(ResourceLimitFatalError,
1960 "UnableToConvertStringToARGV");
1961 }
cristy54aad5e2010-09-03 16:02:04 +00001962 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00001963 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001964 p=q;
1965 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1966 p++;
1967 }
1968 argv[i]=(char *) NULL;
1969 return(argv);
1970}
1971
1972/*
1973%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1974% %
1975% %
1976% %
cristy3ed852e2009-09-05 21:47:34 +00001977% S t r i n g I n f o T o H e x S t r i n g %
1978% %
1979% %
1980% %
1981%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1982%
1983% StringInfoToHexString() converts a string info string to a C string.
1984%
1985% The format of the StringInfoToHexString method is:
1986%
1987% char *StringInfoToHexString(const StringInfo *string_info)
1988%
1989% A description of each parameter follows:
1990%
1991% o string_info: the string.
1992%
1993*/
1994MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1995{
1996 char
1997 *string;
1998
1999 register const unsigned char
2000 *p;
2001
cristybb503372010-05-27 20:51:26 +00002002 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002003 i;
2004
2005 register unsigned char
2006 *q;
2007
2008 size_t
2009 length;
2010
2011 unsigned char
2012 hex_digits[16];
2013
2014 length=string_info->length;
2015 if (~length < MaxTextExtent)
2016 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2017 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2018 if (string == (char *) NULL)
2019 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2020 hex_digits[0]='0';
2021 hex_digits[1]='1';
2022 hex_digits[2]='2';
2023 hex_digits[3]='3';
2024 hex_digits[4]='4';
2025 hex_digits[5]='5';
2026 hex_digits[6]='6';
2027 hex_digits[7]='7';
2028 hex_digits[8]='8';
2029 hex_digits[9]='9';
2030 hex_digits[10]='a';
2031 hex_digits[11]='b';
2032 hex_digits[12]='c';
2033 hex_digits[13]='d';
2034 hex_digits[14]='e';
2035 hex_digits[15]='f';
2036 p=string_info->datum;
2037 q=(unsigned char *) string;
cristybb503372010-05-27 20:51:26 +00002038 for (i=0; i < (ssize_t) string_info->length; i++)
cristy3ed852e2009-09-05 21:47:34 +00002039 {
2040 *q++=hex_digits[(*p >> 4) & 0x0f];
2041 *q++=hex_digits[*p & 0x0f];
2042 p++;
2043 }
2044 *q='\0';
2045 return(string);
2046}
2047
2048/*
2049%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2050% %
2051% %
2052% %
2053% S t r i n g T o k e n %
2054% %
2055% %
2056% %
2057%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2058%
2059% StringToken() extracts a token a from the string.
2060%
2061% The format of the StringToken method is:
2062%
2063% char *StringToken(const char *delimiters,char **string)
2064%
2065% A description of each parameter follows:
2066%
2067% o delimiters: one or more delimiters.
2068%
2069% o string: return the first token in the string. If none is found, return
2070% NULL.
2071%
2072*/
2073MagickExport char *StringToken(const char *delimiters,char **string)
2074{
2075 char
2076 *q;
2077
2078 register char
2079 *p;
2080
2081 register const char
2082 *r;
2083
2084 register int
2085 c,
2086 d;
2087
2088 p=(*string);
2089 if (p == (char *) NULL)
2090 return((char *) NULL);
2091 for (q=p; ; )
2092 {
2093 c=(*p++);
2094 r=delimiters;
2095 do
2096 {
2097 d=(*r++);
2098 if (c == d)
2099 {
2100 if (c == '\0')
2101 p=(char *) NULL;
2102 else
2103 p[-1]='\0';
2104 *string=p;
2105 return(q);
2106 }
2107 } while (d != '\0');
2108 }
2109}
2110
2111/*
2112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2113% %
2114% %
2115% %
2116% S t r i n g T o L i s t %
2117% %
2118% %
2119% %
2120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2121%
2122% StringToList() converts a text string into a list by segmenting the text
2123% string at each carriage return discovered. The list is converted to HEX
2124% characters if any control characters are discovered within the text string.
2125%
2126% The format of the StringToList method is:
2127%
2128% char **StringToList(const char *text)
2129%
2130% A description of each parameter follows:
2131%
cristy3ed852e2009-09-05 21:47:34 +00002132% o text: Specifies the string to segment into a list.
2133%
2134*/
2135MagickExport char **StringToList(const char *text)
2136{
2137 char
2138 **textlist;
2139
2140 register const char
2141 *p;
2142
cristybb503372010-05-27 20:51:26 +00002143 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002144 i;
2145
cristybb503372010-05-27 20:51:26 +00002146 size_t
cristy3ed852e2009-09-05 21:47:34 +00002147 lines;
2148
2149 if (text == (char *) NULL)
2150 return((char **) NULL);
2151 for (p=text; *p != '\0'; p++)
2152 if (((int) ((unsigned char) *p) < 32) &&
2153 (isspace((int) ((unsigned char) *p)) == 0))
2154 break;
2155 if (*p == '\0')
2156 {
2157 register const char
2158 *q;
2159
2160 /*
2161 Convert string to an ASCII list.
2162 */
2163 lines=1;
2164 for (p=text; *p != '\0'; p++)
2165 if (*p == '\n')
2166 lines++;
2167 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2168 sizeof(*textlist));
2169 if (textlist == (char **) NULL)
2170 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2171 p=text;
cristybb503372010-05-27 20:51:26 +00002172 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002173 {
2174 for (q=p; *q != '\0'; q++)
2175 if ((*q == '\r') || (*q == '\n'))
2176 break;
2177 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2178 sizeof(*textlist));
2179 if (textlist[i] == (char *) NULL)
2180 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002181 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002182 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002183 if (*q == '\r')
2184 q++;
2185 p=q+1;
2186 }
2187 }
2188 else
2189 {
2190 char
2191 hex_string[MaxTextExtent];
2192
2193 register char
2194 *q;
2195
cristybb503372010-05-27 20:51:26 +00002196 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002197 j;
2198
2199 /*
2200 Convert string to a HEX list.
2201 */
cristybb503372010-05-27 20:51:26 +00002202 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002203 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2204 sizeof(*textlist));
2205 if (textlist == (char **) NULL)
2206 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2207 p=text;
cristybb503372010-05-27 20:51:26 +00002208 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002209 {
2210 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
2211 sizeof(*textlist));
2212 if (textlist[i] == (char *) NULL)
2213 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyf1d91242010-05-28 02:23:19 +00002214 (void) FormatMagickString(textlist[i],MaxTextExtent,"0x%08lx: ",
2215 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002216 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002217 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002218 {
2219 (void) FormatMagickString(hex_string,MaxTextExtent,"%02x",*(p+j));
2220 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2221 q+=2;
2222 if ((j % 0x04) == 0)
2223 *q++=' ';
2224 }
2225 for ( ; j <= 0x14; j++)
2226 {
2227 *q++=' ';
2228 *q++=' ';
2229 if ((j % 0x04) == 0)
2230 *q++=' ';
2231 }
2232 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002233 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002234 {
2235 if (isprint((int) ((unsigned char) *p)) != 0)
2236 *q++=(*p);
2237 else
2238 *q++='-';
2239 p++;
2240 }
2241 *q='\0';
2242 }
2243 }
2244 textlist[i]=(char *) NULL;
2245 return(textlist);
2246}
2247
2248/*
2249%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2250% %
2251% %
2252% %
2253% S t r i n g T o S t r i n g I n f o %
2254% %
2255% %
2256% %
2257%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2258%
2259% StringToStringInfo() returns the contents of a file as a string.
2260%
2261% The format of the StringToStringInfo method is:
2262%
2263% StringInfo *StringToStringInfo(const char *string)
2264%
2265% A description of each parameter follows:
2266%
2267% o string: The string.
2268%
2269*/
2270MagickExport StringInfo *StringToStringInfo(const char *string)
2271{
2272 StringInfo
2273 *string_info;
2274
2275 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2276 assert(string != (const char *) NULL);
2277 string_info=AcquireStringInfo(strlen(string)+1);
2278 SetStringInfoDatum(string_info,(const unsigned char *) string);
2279 return(string_info);
2280}
2281
2282/*
2283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2284% %
2285% %
2286% %
2287% S t r i p S t r i n g %
2288% %
2289% %
2290% %
2291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2292%
2293% StripString() strips any whitespace or quotes from the beginning and end of
2294% a string of characters.
2295%
2296% The format of the StripString method is:
2297%
2298% void StripString(char *message)
2299%
2300% A description of each parameter follows:
2301%
2302% o message: Specifies an array of characters.
2303%
2304*/
2305MagickExport void StripString(char *message)
2306{
2307 register char
2308 *p,
2309 *q;
2310
2311 size_t
2312 length;
2313
2314 assert(message != (char *) NULL);
2315 if (*message == '\0')
2316 return;
2317 length=strlen(message);
2318 p=message;
2319 while (isspace((int) ((unsigned char) *p)) != 0)
2320 p++;
2321 if ((*p == '\'') || (*p == '"'))
2322 p++;
2323 q=message+length-1;
2324 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2325 q--;
2326 if (q > p)
2327 if ((*q == '\'') || (*q == '"'))
2328 q--;
cristy54aad5e2010-09-03 16:02:04 +00002329 (void) memcpy(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002330 message[q-p+1]='\0';
2331 for (p=message; *p != '\0'; p++)
2332 if (*p == '\n')
2333 *p=' ';
2334}
2335
2336/*
2337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2338% %
2339% %
2340% %
2341% S u b s t i t u t e S t r i n g %
2342% %
2343% %
2344% %
2345%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2346%
cristyf1b72c12009-10-06 13:25:21 +00002347% SubstituteString() performs string substitution on a string, replacing the
2348% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002349% If the string is matched and status, MagickTrue is returned otherwise
2350% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002351%
2352% The format of the SubstituteString method is:
2353%
cristyf1b72c12009-10-06 13:25:21 +00002354% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002355% const char *replace)
2356%
2357% A description of each parameter follows:
2358%
cristyf1b72c12009-10-06 13:25:21 +00002359% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002360% allocation if a replacement is made.
2361%
cristybc3392a2009-10-06 03:15:57 +00002362% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002363%
cristybc3392a2009-10-06 03:15:57 +00002364% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002365%
2366*/
cristyf1b72c12009-10-06 13:25:21 +00002367MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002368 const char *search,const char *replace)
2369{
cristybc3392a2009-10-06 03:15:57 +00002370 MagickBooleanType
2371 status;
cristy3ed852e2009-09-05 21:47:34 +00002372
cristybc3392a2009-10-06 03:15:57 +00002373 register char
2374 *p;
cristy3ed852e2009-09-05 21:47:34 +00002375
cristy3ed852e2009-09-05 21:47:34 +00002376 size_t
cristybc3392a2009-10-06 03:15:57 +00002377 extent,
2378 replace_extent,
2379 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002380
cristyf1b72c12009-10-06 13:25:21 +00002381 ssize_t
2382 offset;
2383
cristybc3392a2009-10-06 03:15:57 +00002384 status=MagickFalse;
2385 search_extent=0,
2386 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002387 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002388 {
cristyf1b72c12009-10-06 13:25:21 +00002389 if (search_extent == 0)
2390 search_extent=strlen(search);
2391 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002392 continue;
cristy3ed852e2009-09-05 21:47:34 +00002393 /*
cristybc3392a2009-10-06 03:15:57 +00002394 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002395 */
cristyf1b72c12009-10-06 13:25:21 +00002396 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002397 if (replace_extent == 0)
2398 replace_extent=strlen(replace);
2399 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002400 {
cristybc3392a2009-10-06 03:15:57 +00002401 /*
2402 Make room for the replacement string.
2403 */
cristyde58b412010-02-18 03:53:40 +00002404 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002405 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002406 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2407 sizeof(*p));
2408 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002409 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002410 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002411 }
cristy3ed852e2009-09-05 21:47:34 +00002412 /*
cristybc3392a2009-10-06 03:15:57 +00002413 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002414 */
cristybc3392a2009-10-06 03:15:57 +00002415 if (search_extent != replace_extent)
cristy54aad5e2010-09-03 16:02:04 +00002416 (void) memcpy(p+replace_extent,p+search_extent,strlen(p+search_extent)+1);
2417 (void) memcpy(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002418 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002419 }
cristybc3392a2009-10-06 03:15:57 +00002420 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002421}