blob: 09a5486ab1430d9ecf6799afe6d8db6232e1035e [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);
121 destination=(char *) NULL;
122 if (~length >= MaxTextExtent)
123 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
124 sizeof(*destination));
125 if (destination == (char *) NULL)
126 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
127 *destination='\0';
128 if (source != (char *) NULL)
129 (void) CopyMagickString(destination,source,(length+1)*sizeof(*destination));
130 return(destination);
131}
132
133/*
134%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135% %
136% %
137% %
138% A c q u i r e S t r i n g I n f o %
139% %
140% %
141% %
142%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143%
144% AcquireStringInfo() allocates the StringInfo structure.
145%
146% The format of the AcquireStringInfo method is:
147%
148% StringInfo *AcquireStringInfo(const size_t length)
149%
150% A description of each parameter follows:
151%
152% o length: the string length.
153%
154*/
155MagickExport StringInfo *AcquireStringInfo(const size_t length)
156{
157 StringInfo
158 *string_info;
159
cristy90823212009-12-12 20:48:33 +0000160 string_info=(StringInfo *) AcquireAlignedMemory(1,sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000161 if (string_info == (StringInfo *) NULL)
162 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
163 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
164 string_info->signature=MagickSignature;
165 string_info->length=length;
166 if (string_info->length != 0)
167 {
168 string_info->datum=(unsigned char *) NULL;
169 if (~string_info->length >= MaxTextExtent)
170 string_info->datum=(unsigned char *) AcquireQuantumMemory(
171 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
172 if (string_info->datum == (unsigned char *) NULL)
173 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
174 }
175 return(string_info);
176}
177
178/*
179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180% %
181% %
182% %
183% C l o n e S t r i n g %
184% %
185% %
186% %
187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188%
189% CloneString() allocates memory for the destination string and copies
190% the source string to that memory location.
191%
192% The format of the CloneString method is:
193%
194% char *CloneString(char **destination,const char *source)
195%
196% A description of each parameter follows:
197%
198% o destination: A pointer to a character string.
199%
200% o source: A character string.
201%
202*/
203MagickExport char *CloneString(char **destination,const char *source)
204{
205 size_t
206 length;
207
208 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
209 assert(destination != (char **) NULL);
210 if (source == (const char *) NULL)
211 {
212 if (*destination != (char *) NULL)
213 *destination=DestroyString(*destination);
214 return(*destination);
215 }
216 if (*destination == (char *) NULL)
217 {
218 *destination=AcquireString(source);
219 return(*destination);
220 }
221 length=strlen(source);
222 if (~length < MaxTextExtent)
223 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
224 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
225 sizeof(*destination));
226 if (*destination == (char *) NULL)
227 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
228 (void) CopyMagickString(*destination,source,(length+1)*sizeof(*destination));
229 return(*destination);
230}
231
232/*
233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234% %
235% %
236% %
237% C l o n e S t r i n g I n f o %
238% %
239% %
240% %
241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242%
243% CloneStringInfo() clones a copy of the StringInfo structure.
244%
245% The format of the CloneStringInfo method is:
246%
247% StringInfo *CloneStringInfo(const StringInfo *string_info)
248%
249% A description of each parameter follows:
250%
251% o string_info: the string info.
252%
253*/
254MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
255{
256 StringInfo
257 *clone_info;
258
259 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
260 assert(string_info != (StringInfo *) NULL);
261 assert(string_info->signature == MagickSignature);
262 clone_info=AcquireStringInfo(string_info->length);
263 if (string_info->length != 0)
264 (void) CopyMagickMemory(clone_info->datum,string_info->datum,
265 string_info->length+1);
266 return(clone_info);
267}
268
269/*
270%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271% %
272% %
273% %
274% C o m p a r e S t r i n g I n f o %
275% %
276% %
277% %
278%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
279%
280% CompareStringInfo() compares the two datums target and source. It returns
281% an integer less than, equal to, or greater than zero if target is found,
282% respectively, to be less than, to match, or be greater than source.
283%
284% The format of the CompareStringInfo method is:
285%
286% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
287%
288% A description of each parameter follows:
289%
290% o target: the target string.
291%
292% o source: the source string.
293%
294*/
295
296static inline size_t MagickMin(const size_t x,const size_t y)
297{
298 if (x < y)
299 return(x);
300 return(y);
301}
302
303MagickExport int CompareStringInfo(const StringInfo *target,
304 const StringInfo *source)
305{
306 int
307 status;
308
309 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
310 assert(target != (StringInfo *) NULL);
311 assert(target->signature == MagickSignature);
312 assert(source != (StringInfo *) NULL);
313 assert(source->signature == MagickSignature);
314 status=memcmp(target->datum,source->datum,MagickMin(target->length,
315 source->length));
316 if (status != 0)
317 return(status);
318 if (target->length == source->length)
319 return(0);
320 return(target->length < source->length ? -1 : 1);
321}
322
323/*
324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325% %
326% %
327% %
328% C o n c a t e n a t e M a g i c k S t r i n g %
329% %
330% %
331% %
332%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333%
334% ConcatenateMagickString() concatenates the source string to the destination
335% string. The destination buffer is always null-terminated even if the
336% string must be truncated.
337%
338% The format of the ConcatenateMagickString method is:
339%
340% size_t ConcatenateMagickString(char *destination,const char *source,
341% const size_t length)
342%
343% A description of each parameter follows:
344%
345% o destination: the destination string.
346%
347% o source: the source string.
348%
349% o length: the length of the destination string.
350%
351*/
352MagickExport size_t ConcatenateMagickString(char *destination,
353 const char *source,const size_t length)
354{
355 register char
356 *q;
357
358 register const char
359 *p;
360
361 register size_t
362 i;
363
364 size_t
365 count;
366
367 assert(destination != (char *) NULL);
368 assert(source != (const char *) NULL);
369 assert(length >= 1);
370 p=source;
371 q=destination;
372 i=length;
373 while ((i-- != 0) && (*q != '\0'))
374 q++;
375 count=(size_t) (q-destination);
376 i=length-count;
377 if (i == 0)
378 return(count+strlen(p));
379 while (*p != '\0')
380 {
381 if (i != 1)
382 {
383 *q++=(*p);
384 i--;
385 }
386 p++;
387 }
388 *q='\0';
389 return(count+(p-source));
390}
391
392/*
393%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394% %
395% %
396% %
397% C o n c a t e n a t e S t r i n g %
398% %
399% %
400% %
401%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402%
403% ConcatenateString() appends a copy of string source, including the
404% terminating null character, to the end of string destination.
405%
406% The format of the ConcatenateString method is:
407%
408% MagickBooleanType ConcatenateString(char **destination,
409% const char *source)
410%
411% A description of each parameter follows:
412%
413% o destination: A pointer to a character string.
414%
415% o source: A character string.
416%
417*/
418MagickExport MagickBooleanType ConcatenateString(char **destination,
419 const char *source)
420{
421 size_t
422 length,
423 source_length;
424
425 assert(destination != (char **) NULL);
426 if (source == (const char *) NULL)
427 return(MagickTrue);
428 if (*destination == (char *) NULL)
429 {
430 *destination=AcquireString(source);
431 return(MagickTrue);
432 }
433 length=strlen(*destination);
434 source_length=strlen(source);
435 if (~length < source_length)
436 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
437 length+=source_length;
438 if (~length < MaxTextExtent)
439 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
440 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
441 sizeof(*destination));
442 if (*destination == (char *) NULL)
443 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
444 (void) ConcatenateMagickString(*destination,source,(length+1)*
445 sizeof(*destination));
446 return(MagickTrue);
447}
448
449/*
450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451% %
452% %
453% %
454% C o n c a t e n a t e S t r i n g I n f o %
455% %
456% %
457% %
458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459%
460% ConcatenateStringInfo() concatenates the source string to the destination
461% string.
462%
463% The format of the ConcatenateStringInfo method is:
464%
465% void ConcatenateStringInfo(StringInfo *string_info,
466% const StringInfo *source)
467%
468% A description of each parameter follows:
469%
470% o string_info: the string info.
471%
472% o source: the source string.
473%
474*/
475MagickExport void ConcatenateStringInfo(StringInfo *string_info,
476 const StringInfo *source)
477{
478 size_t
479 length;
480
481 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
482 assert(string_info != (StringInfo *) NULL);
483 assert(string_info->signature == MagickSignature);
484 assert(source != (const StringInfo *) NULL);
485 length=string_info->length;
486 if (~length < source->length)
487 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
488 SetStringInfoLength(string_info,length+source->length);
489 (void) CopyMagickMemory(string_info->datum+length,source->datum,
490 source->length);
491}
492
493/*
494%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
495% %
496% %
497% %
498% 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 %
499% %
500% %
501% %
502%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503%
504% ConfigureFileToStringInfo() returns the contents of a configure file as a
505% string.
506%
507% The format of the ConfigureFileToStringInfo method is:
508%
509% StringInfo *ConfigureFileToStringInfo(const char *filename)
510% ExceptionInfo *exception)
511%
512% A description of each parameter follows:
513%
514% o filename: the filename.
515%
516*/
517MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
518{
519 char
520 *string;
521
522 int
523 file;
524
525 MagickOffsetType
526 offset;
527
528 size_t
529 length;
530
531 StringInfo
532 *string_info;
533
534 void
535 *map;
536
537 assert(filename != (const char *) NULL);
538 file=open(filename,O_RDONLY | O_BINARY);
539 if (file == -1)
540 return((StringInfo *) NULL);
541 offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
542 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
543 {
544 file=close(file)-1;
545 return((StringInfo *) NULL);
546 }
547 length=(size_t) offset;
548 string=(char *) NULL;
549 if (~length > MaxTextExtent)
550 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
551 if (string == (char *) NULL)
552 {
553 file=close(file)-1;
554 return((StringInfo *) NULL);
555 }
556 map=MapBlob(file,ReadMode,0,length);
557 if (map != (void *) NULL)
558 {
559 (void) CopyMagickMemory(string,map,length);
560 (void) UnmapBlob(map,length);
561 }
562 else
563 {
564 register size_t
565 i;
566
567 ssize_t
568 count;
569
570 (void) MagickSeek(file,0,SEEK_SET);
571 for (i=0; i < length; i+=count)
572 {
573 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
574 SSIZE_MAX));
575 if (count <= 0)
576 {
577 count=0;
578 if (errno != EINTR)
579 break;
580 }
581 }
582 if (i < length)
583 {
584 file=close(file)-1;
585 string=DestroyString(string);
586 return((StringInfo *) NULL);
587 }
588 }
589 string[length]='\0';
590 file=close(file)-1;
591 string_info=AcquireStringInfo(0);
592 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
593 string_info->length=length;
594 string_info->datum=(unsigned char *) string;
595 return(string_info);
596}
597
598/*
599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
600% %
601% %
602% %
603% C o n s t a n t S t r i n g %
604% %
605% %
606% %
607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
608%
609% ConstantString() allocates memory for a string and copies the source string
610% to that memory location (and returns it). Use it for strings that you do
611% do not expect to change over its lifetime.
612%
613% The format of the ConstantString method is:
614%
615% char *ConstantString(const char *source)
616%
617% A description of each parameter follows:
618%
619% o source: A character string.
620%
621*/
622MagickExport char *ConstantString(const char *source)
623{
624 char
625 *destination;
626
627 size_t
628 length;
629
630 length=0;
631 if (source != (char *) NULL)
632 length+=strlen(source);
633 destination=(char *) NULL;
634 if (~length >= 1UL)
635 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
636 if (destination == (char *) NULL)
637 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
638 *destination='\0';
639 if (source != (char *) NULL)
640 (void) CopyMagickString(destination,source,(length+1)*sizeof(*destination));
641 return(destination);
642}
643
644/*
645%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
646% %
647% %
648% %
649% C o p y M a g i c k S t r i n g %
650% %
651% %
652% %
653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654%
655% CopyMagickString() copies the source string to the destination string. The
656% destination buffer is always null-terminated even if the string must be
657% truncated. The return value is the minimum of the source string length
658% or the length parameter.
659%
660% The format of the CopyMagickString method is:
661%
662% size_t CopyMagickString(const char *destination,char *source,
663% const size_t length)
664%
665% A description of each parameter follows:
666%
667% o destination: the destination string.
668%
669% o source: the source string.
670%
671% o length: the length of the destination string.
672%
673*/
674MagickExport size_t CopyMagickString(char *destination,const char *source,
675 const size_t length)
676{
677 register char
678 *q;
679
680 register const char
681 *p;
682
683 register size_t
684 n;
685
686 p=source;
687 q=destination;
688 for (n=length; n > 4; n-=4)
689 {
690 *q=(*p++);
691 if (*q == '\0')
692 return((size_t) (p-source-1));
693 q++;
694 *q=(*p++);
695 if (*q == '\0')
696 return((size_t) (p-source-1));
697 q++;
698 *q=(*p++);
699 if (*q == '\0')
700 return((size_t) (p-source-1));
701 q++;
702 *q=(*p++);
703 if (*q == '\0')
704 return((size_t) (p-source-1));
705 q++;
706 }
707 if (n != 0)
708 for (n--; n != 0; n--)
709 {
710 *q=(*p++);
711 if (*q == '\0')
712 return((size_t) (p-source-1));
713 q++;
714 }
715 if (length != 0)
716 *q='\0';
717 return((size_t) (p-source-1));
718}
719
720/*
721%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722% %
723% %
724% %
725% D e s t r o y S t r i n g %
726% %
727% %
728% %
729%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
730%
731% DestroyString() destroys memory associated with a string.
732%
733% The format of the DestroyString method is:
734%
735% char *DestroyString(char *string)
736%
737% A description of each parameter follows:
738%
739% o string: the string.
740%
741*/
742MagickExport char *DestroyString(char *string)
743{
744 return((char *) RelinquishMagickMemory(string));
745}
746
747/*
748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749% %
750% %
751% %
752% D e s t r o y S t r i n g I n f o %
753% %
754% %
755% %
756%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
757%
758% DestroyStringInfo() destroys memory associated with the StringInfo structure.
759%
760% The format of the DestroyStringInfo method is:
761%
762% StringInfo *DestroyStringInfo(StringInfo *string_info)
763%
764% A description of each parameter follows:
765%
766% o string_info: the string info.
767%
768*/
769MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
770{
771 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
772 assert(string_info != (StringInfo *) NULL);
773 assert(string_info->signature == MagickSignature);
774 if (string_info->datum != (unsigned char *) NULL)
775 string_info->datum=(unsigned char *) RelinquishMagickMemory(
776 string_info->datum);
777 string_info->signature=(~MagickSignature);
778 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
779 return(string_info);
780}
781
782/*
783%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784% %
785% %
786% %
787% D e s t r o y S t r i n g L i s t %
788% %
789% %
790% %
791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792%
793% DestroyStringList() zeros memory associated with a string list.
794%
795% The format of the DestroyStringList method is:
796%
797% char **DestroyStringList(char **list)
798%
799% A description of each parameter follows:
800%
801% o list: the string list.
802%
803*/
804MagickExport char **DestroyStringList(char **list)
805{
806 register long
807 i;
808
809 assert(list != (char **) NULL);
810 for (i=0; list[i] != (char *) NULL; i++)
811 list[i]=DestroyString(list[i]);
812 list=(char **) RelinquishMagickMemory(list);
813 return(list);
814}
815
816/*
817%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
818% %
819% %
820% %
821% E s c a p e S t r i n g %
822% %
823% %
824% %
825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
826%
827% EscapeString() allocates memory for a backslash-escaped version of a
828% source text string, copies the escaped version of the text to that
829% memory location while adding backslash characters, and returns the
830% escaped string.
831%
832% The format of the EscapeString method is:
833%
834% char *EscapeString(const char *source,const char escape)
835%
836% A description of each parameter follows:
837%
838% o allocate_string: Method EscapeString returns the escaped string.
839%
840% o source: A character string.
841%
842% o escape: the quoted string termination character to escape (e.g. '"').
843%
844*/
845MagickExport char *EscapeString(const char *source,const char escape)
846{
847 char
848 *destination;
849
850 register char
851 *q;
852
853 register const char
854 *p;
855
856 size_t
857 length;
858
859 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
860 assert(source != (const char *) NULL);
861 length=strlen(source);
862 for (p=source; *p != '\0'; p++)
863 if ((*p == '\\') || (*p == escape))
864 {
865 if (~length < 1)
866 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
867 length++;
868 }
869 destination=(char *) NULL;
870 if (~length >= MaxTextExtent)
871 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
872 sizeof(*destination));
873 if (destination == (char *) NULL)
874 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
875 *destination='\0';
876 if (source != (char *) NULL)
877 {
878 q=destination;
879 for (p=source; *p != '\0'; p++)
880 {
881 if ((*p == '\\') || (*p == escape))
882 *q++='\\';
883 *q++=(*p);
884 }
885 *q='\0';
886 }
887 return(destination);
888}
889
890/*
891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892% %
893% %
894% %
895% F i l e T o S t r i n g %
896% %
897% %
898% %
899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900%
901% FileToString() returns the contents of a file as a string.
902%
903% The format of the FileToString method is:
904%
905% char *FileToString(const char *filename,const size_t extent,
906% ExceptionInfo *exception)
907%
908% A description of each parameter follows:
909%
910% o filename: the filename.
911%
912% o extent: Maximum length of the string.
913%
914% o exception: return any errors or warnings in this structure.
915%
916*/
917MagickExport char *FileToString(const char *filename,const size_t extent,
918 ExceptionInfo *exception)
919{
920 size_t
921 length;
922
923 assert(filename != (const char *) NULL);
924 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
925 assert(exception != (ExceptionInfo *) NULL);
926 return((char *) FileToBlob(filename,extent,&length,exception));
927}
928
929/*
930%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
931% %
932% %
933% %
934% F i l e T o S t r i n g I n f o %
935% %
936% %
937% %
938%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939%
940% FileToStringInfo() returns the contents of a file as a string.
941%
942% The format of the FileToStringInfo method is:
943%
944% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
945% ExceptionInfo *exception)
946%
947% A description of each parameter follows:
948%
949% o filename: the filename.
950%
951% o extent: Maximum length of the string.
952%
953% o exception: return any errors or warnings in this structure.
954%
955*/
956MagickExport StringInfo *FileToStringInfo(const char *filename,
957 const size_t extent,ExceptionInfo *exception)
958{
959 StringInfo
960 *string_info;
961
962 assert(filename != (const char *) NULL);
963 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
964 assert(exception != (ExceptionInfo *) NULL);
965 string_info=AcquireStringInfo(0);
966 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
967 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
968 if (string_info->datum == (unsigned char *) NULL)
969 {
970 string_info=DestroyStringInfo(string_info);
971 return((StringInfo *) NULL);
972 }
973 return(string_info);
974}
975
976/*
977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978% %
979% %
980% %
981% F o r m a t M a g i c k S i z e %
982% %
983% %
984% %
985%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986%
987% FormatMagickSize() converts a size to a human readable format, for example,
988% 14kb, 234mb, 2.7gb, or 3.0tb. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +0000989% 1000.
cristy3ed852e2009-09-05 21:47:34 +0000990%
991% The format of the FormatMagickSize method is:
992%
993% long FormatMagickSize(const MagickSizeType size,char *format)
994%
995% A description of each parameter follows:
996%
997% o size: convert this size to a human readable format.
998%
cristyb9080c92009-12-01 20:13:26 +0000999% o bi: use power of two rather than power of ten.
1000%
cristy3ed852e2009-09-05 21:47:34 +00001001% o format: human readable format.
1002%
1003*/
cristyb9080c92009-12-01 20:13:26 +00001004MagickExport long FormatMagickSize(const MagickSizeType size,
1005 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001006{
cristyb9080c92009-12-01 20:13:26 +00001007 const char
1008 **units;
1009
cristy3ed852e2009-09-05 21:47:34 +00001010 double
cristyb9080c92009-12-01 20:13:26 +00001011 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001012 length;
1013
1014 long
1015 count;
1016
1017 register long
1018 i,
1019 j;
1020
1021 static const char
cristyb9080c92009-12-01 20:13:26 +00001022 *bi_units[] =
1023 {
1024 "b", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", (char *) NULL
1025 },
1026 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001027 {
cristy67341682009-12-01 19:27:48 +00001028 "b", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001029 };
cristy3ed852e2009-09-05 21:47:34 +00001030
cristyb9080c92009-12-01 20:13:26 +00001031 bytes=1000.0;
1032 units=traditional_units;
1033 if (bi != MagickFalse)
1034 {
1035 bytes=1024.0;
1036 units=bi_units;
1037 }
cristy3ed852e2009-09-05 21:47:34 +00001038#if defined(_MSC_VER) && (_MSC_VER == 1200)
1039 length=(double) ((MagickOffsetType) size);
1040#else
1041 length=(double) size;
1042#endif
cristyb9080c92009-12-01 20:13:26 +00001043 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1044 length/=bytes;
cristy9bf9da32009-09-27 16:48:34 +00001045 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001046 {
1047 count=FormatMagickString(format,MaxTextExtent,"%.*g%s",(int) (i+j),length,
1048 units[i]);
1049 if (strchr(format,'+') == (char *) NULL)
1050 break;
1051 }
1052 return(count);
1053}
1054
1055/*
1056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057% %
1058% %
1059% %
1060% F o r m a t M a g i c k S t r i n g %
1061% %
1062% %
1063% %
1064%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1065%
1066% FormatMagickString() prints formatted output of a variable argument list.
1067%
1068% The format of the FormatMagickString method is:
1069%
1070% long FormatMagickString(char *string,const size_t length,
1071% const char *format,...)
1072%
1073% A description of each parameter follows.
1074%
1075% o string: FormatMagickString() returns the formatted string in this
1076% character buffer.
1077%
1078% o length: the maximum length of the string.
1079%
1080% o format: A string describing the format to use to write the remaining
1081% arguments.
1082%
1083*/
1084
1085MagickExport long FormatMagickStringList(char *string,const size_t length,
1086 const char *format,va_list operands)
1087{
1088 int
1089 n;
1090
1091#if defined(MAGICKCORE_HAVE_VSNPRINTF)
1092 n=vsnprintf(string,length,format,operands);
1093#else
1094 n=vsprintf(string,format,operands);
1095#endif
1096 if (n < 0)
1097 string[length-1]='\0';
1098 return((long) n);
1099}
1100
1101MagickExport long FormatMagickString(char *string,const size_t length,
1102 const char *format,...)
1103{
1104 long
1105 n;
1106
1107 va_list
1108 operands;
1109
1110 va_start(operands,format);
1111 n=(long) FormatMagickStringList(string,length,format,operands);
1112 va_end(operands);
1113 return(n);
1114}
1115
1116/*
1117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1118% %
1119% %
1120% %
1121% F o r m a t M a g i c k T i m e %
1122% %
1123% %
1124% %
1125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1126%
1127% FormatMagickTime() returns the specified time in the Internet date/time
1128% format and the length of the timestamp.
1129%
1130% The format of the FormatMagickTime method is:
1131%
1132% long FormatMagickTime(const time_t time,const size_t length,
1133% char *timestamp)
1134%
1135% A description of each parameter follows.
1136%
1137% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1138% measured in seconds.
1139%
1140% o length: the maximum length of the string.
1141%
1142% o timestamp: Return the Internet date/time here.
1143%
1144*/
1145MagickExport long FormatMagickTime(const time_t time,const size_t length,
1146 char *timestamp)
1147{
1148 long
1149 count;
1150
1151 struct tm
1152 gm_time,
1153 local_time;
1154
1155 time_t
1156 timezone;
1157
1158 assert(timestamp != (char *) NULL);
1159 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1160 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1161#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1162 (void) localtime_r(&time,&local_time);
1163#else
1164 {
cristybc3392a2009-10-06 03:15:57 +00001165 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001166 *my_time;
1167
1168 my_time=localtime(&time);
1169 if (my_time != (struct tm *) NULL)
1170 (void) memcpy(&local_time,my_time,sizeof(local_time));
1171 }
1172#endif
1173#if defined(MAGICKCORE_HAVE_GMTIME_R)
1174 (void) gmtime_r(&time,&gm_time);
1175#else
1176 {
cristybc3392a2009-10-06 03:15:57 +00001177 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001178 *my_time;
1179
1180 my_time=gmtime(&time);
1181 if (my_time != (struct tm *) NULL)
1182 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1183 }
1184#endif
1185 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1186 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1187 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1188 (local_time.tm_yday-gm_time.tm_yday)));
1189 count=FormatMagickString(timestamp,length,
1190 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1191 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
1192 local_time.tm_min,local_time.tm_sec,(long) timezone);
1193 return(count);
1194}
1195
1196/*
1197%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1198% %
1199% %
1200% %
1201% G e t E n v i r o n m e n t V a l u e %
1202% %
1203% %
1204% %
1205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1206%
1207% GetEnvironmentValue() returns the environment string that matches the
1208% specified name.
1209%
1210% The format of the GetEnvironmentValue method is:
1211%
1212% char *GetEnvironmentValue(const char *name)
1213%
1214% A description of each parameter follows:
1215%
1216% o name: the environment name.
1217%
1218*/
1219MagickExport char *GetEnvironmentValue(const char *name)
1220{
1221 const char
1222 *environment;
1223
1224 environment=getenv(name);
1225 if (environment == (const char *) NULL)
1226 return((char *) NULL);
1227 return(ConstantString(environment));
1228}
1229
1230/*
1231%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1232% %
1233% %
1234% %
1235% G e t S t r i n g I n f o D a t u m %
1236% %
1237% %
1238% %
1239%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1240%
1241% GetStringInfoDatum() returns the datum associated with the string.
1242%
1243% The format of the GetStringInfoDatum method is:
1244%
1245% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1246%
1247% A description of each parameter follows:
1248%
1249% o string_info: the string info.
1250%
1251*/
1252MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1253{
1254 assert(string_info != (StringInfo *) NULL);
1255 assert(string_info->signature == MagickSignature);
1256 return(string_info->datum);
1257}
1258
1259/*
1260%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1261% %
1262% %
1263% %
1264% G e t S t r i n g I n f o L e n g t h %
1265% %
1266% %
1267% %
1268%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1269%
1270% GetStringInfoLength() returns the string length.
1271%
1272% The format of the GetStringInfoLength method is:
1273%
1274% size_t GetStringInfoLength(const StringInfo *string_info)
1275%
1276% A description of each parameter follows:
1277%
1278% o string_info: the string info.
1279%
1280*/
1281MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1282{
1283 assert(string_info != (StringInfo *) NULL);
1284 assert(string_info->signature == MagickSignature);
1285 return(string_info->length);
1286}
1287
1288/*
1289%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290% %
1291% %
1292% %
1293% G e t S t r i n g I n f o P a t h %
1294% %
1295% %
1296% %
1297%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1298%
1299% GetStringInfoPath() returns the path associated with the string.
1300%
1301% The format of the GetStringInfoPath method is:
1302%
1303% const char *GetStringInfoPath(const StringInfo *string_info)
1304%
1305% A description of each parameter follows:
1306%
1307% o string_info: the string info.
1308%
1309*/
1310MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1311{
1312 assert(string_info != (StringInfo *) NULL);
1313 assert(string_info->signature == MagickSignature);
1314 return(string_info->path);
1315}
1316
1317/*
1318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319% %
1320% %
1321% %
1322% L o c a l e C o m p a r e %
1323% %
1324% %
1325% %
1326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1327%
1328% LocaleCompare() performs a case-insensitive comparison of two strings
1329% byte-by-byte, according to the ordering of the current locale encoding.
1330% LocaleCompare returns an integer greater than, equal to, or less than 0,
1331% if the string pointed to by p is greater than, equal to, or less than the
1332% string pointed to by q respectively. The sign of a non-zero return value
1333% is determined by the sign of the difference between the values of the first< % pair of bytes that differ in the strings being compared.
1334%
1335% The format of the LocaleCompare method is:
1336%
cristyde58b412010-02-18 03:53:40 +00001337% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001338%
1339% A description of each parameter follows:
1340%
1341% o p: A pointer to a character string.
1342%
1343% o q: A pointer to a character string to compare to p.
1344%
1345*/
cristyde58b412010-02-18 03:53:40 +00001346MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001347{
1348 if ((p == (char *) NULL) && (q == (char *) NULL))
1349 return(0);
1350 if (p == (char *) NULL)
1351 return(-1);
1352 if (q == (char *) NULL)
1353 return(1);
1354#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001355 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001356#else
1357 {
cristyde58b412010-02-18 03:53:40 +00001358 register int
cristy3ed852e2009-09-05 21:47:34 +00001359 c,
cristya72c2d12010-02-18 01:20:28 +00001360 d;
cristy3ed852e2009-09-05 21:47:34 +00001361
cristya72c2d12010-02-18 01:20:28 +00001362 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001363 {
cristyde58b412010-02-18 03:53:40 +00001364 c=(int) *((unsigned char *) p);
1365 d=(int) *((unsigned char *) q);
1366 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001367 break;
cristya72c2d12010-02-18 01:20:28 +00001368 p++;
1369 q++;
cristy3ed852e2009-09-05 21:47:34 +00001370 }
cristyde58b412010-02-18 03:53:40 +00001371 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001372 }
1373#endif
1374}
1375
1376/*
1377%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1378% %
1379% %
1380% %
1381% L o c a l e L o w e r %
1382% %
1383% %
1384% %
1385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1386%
1387% LocaleLower() transforms all of the characters in the supplied
1388% null-terminated string, changing all uppercase letters to lowercase.
1389%
1390% The format of the LocaleLower method is:
1391%
1392% void LocaleLower(char *string)
1393%
1394% A description of each parameter follows:
1395%
1396% o string: A pointer to the string to convert to lower-case Locale.
1397%
1398*/
1399MagickExport void LocaleLower(char *string)
1400{
1401 register char
1402 *q;
1403
1404 assert(string != (char *) NULL);
1405 for (q=string; *q != '\0'; q++)
1406 *q=(char) tolower((int) *q);
1407}
1408
1409/*
1410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1411% %
1412% %
1413% %
1414% L o c a l e N C o m p a r e %
1415% %
1416% %
1417% %
1418%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1419%
1420% LocaleNCompare() performs a case-insensitive comparison of two
1421% strings byte-by-byte, according to the ordering of the current locale
1422% encoding. LocaleNCompare returns an integer greater than, equal to, or
1423% less than 0, if the string pointed to by p is greater than, equal to, or
1424% less than the string pointed to by q respectively. The sign of a non-zero
1425% return value is determined by the sign of the difference between the
1426% values of the first pair of bytes that differ in the strings being
1427% compared. The LocaleNCompare method makes the same comparison as
1428% LocaleCompare but looks at a maximum of n bytes. Bytes following a
1429% null byte are not compared.
1430%
1431% The format of the LocaleNCompare method is:
1432%
cristyde58b412010-02-18 03:53:40 +00001433% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001434%
1435% A description of each parameter follows:
1436%
1437% o p: A pointer to a character string.
1438%
1439% o q: A pointer to a character string to compare to p.
1440%
1441% o length: the number of characters to compare in strings p & q.
1442%
1443*/
cristyde58b412010-02-18 03:53:40 +00001444MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001445{
1446 if (p == (char *) NULL)
1447 return(-1);
1448 if (q == (char *) NULL)
1449 return(1);
1450#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001451 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001452#else
1453 {
cristyde58b412010-02-18 03:53:40 +00001454 register int
cristy3ed852e2009-09-05 21:47:34 +00001455 c,
1456 d;
1457
cristyb6af4a52009-10-06 13:56:23 +00001458 register size_t
cristyc4cded12010-02-18 14:40:57 +00001459 i;
cristyb6af4a52009-10-06 13:56:23 +00001460
cristyc4cded12010-02-18 14:40:57 +00001461 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001462 {
cristyde58b412010-02-18 03:53:40 +00001463 c=(int) *((unsigned char *) p);
1464 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001465 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001466 return(AsciiMap[c]-(int) AsciiMap[d]);
1467 if (c == 0)
1468 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001469 p++;
1470 q++;
1471 }
cristyde58b412010-02-18 03:53:40 +00001472 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001473 }
1474#endif
1475}
1476
1477/*
1478%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1479% %
1480% %
1481% %
1482% L o c a l e U p p e r %
1483% %
1484% %
1485% %
1486%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1487%
1488% LocaleUpper() transforms all of the characters in the supplied
1489% null-terminated string, changing all lowercase letters to uppercase.
1490%
1491% The format of the LocaleUpper method is:
1492%
1493% void LocaleUpper(char *string)
1494%
1495% A description of each parameter follows:
1496%
1497% o string: A pointer to the string to convert to upper-case Locale.
1498%
1499*/
1500MagickExport void LocaleUpper(char *string)
1501{
1502 register char
1503 *q;
1504
1505 assert(string != (char *) NULL);
1506 for (q=string; *q != '\0'; q++)
1507 *q=(char) toupper((int) *q);
1508}
1509
1510/*
1511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1512% %
1513% %
1514% %
1515% P r i n t S t r i n g I n f o %
1516% %
1517% %
1518% %
1519%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1520%
1521% PrintStringInfo() prints the string.
1522%
1523% The format of the PrintStringInfo method is:
1524%
1525% void PrintStringInfo(FILE *file,const char *id,
1526% const StringInfo *string_info)
1527%
1528% A description of each parameter follows:
1529%
1530% o file: the file, typically stdout.
1531%
1532% o id: the string id.
1533%
1534% o string_info: the string info.
1535%
1536*/
1537MagickExport void PrintStringInfo(FILE *file,const char *id,
1538 const StringInfo *string_info)
1539{
1540 register const char
1541 *p;
1542
1543 register size_t
1544 i,
1545 j;
1546
1547 assert(id != (const char *) NULL);
1548 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1549 assert(string_info != (StringInfo *) NULL);
1550 assert(string_info->signature == MagickSignature);
1551 p=(char *) string_info->datum;
1552 for (i=0; i < string_info->length; i++)
1553 {
1554 if (((int) ((unsigned char) *p) < 32) &&
1555 (isspace((int) ((unsigned char) *p)) == 0))
1556 break;
1557 p++;
1558 }
1559 if (i == string_info->length)
1560 {
1561 (void) fputs((char *) string_info->datum,file);
1562 (void) fputc('\n',file);
1563 return;
1564 }
1565 /*
1566 Convert string to a HEX list.
1567 */
1568 p=(char *) string_info->datum;
1569 for (i=0; i < string_info->length; i+=0x14)
1570 {
1571 (void) fprintf(file,"0x%08lx: ",(unsigned long) (0x14*i));
1572 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1573 {
1574 (void) fprintf(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
1575 if ((j % 0x04) == 0)
1576 (void) fputc(' ',file);
1577 }
1578 for ( ; j <= 0x14; j++)
1579 {
1580 (void) fputc(' ',file);
1581 (void) fputc(' ',file);
1582 if ((j % 0x04) == 0)
1583 (void) fputc(' ',file);
1584 }
1585 (void) fputc(' ',file);
1586 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1587 {
1588 if (isprint((int) ((unsigned char) *p)) != 0)
1589 (void) fputc(*p,file);
1590 else
1591 (void) fputc('-',file);
1592 p++;
1593 }
1594 (void) fputc('\n',file);
1595 }
1596}
1597
1598/*
1599%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1600% %
1601% %
1602% %
1603% R e s e t S t r i n g I n f o %
1604% %
1605% %
1606% %
1607%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1608%
1609% ResetStringInfo() reset the string to all null bytes.
1610%
1611% The format of the ResetStringInfo method is:
1612%
1613% void ResetStringInfo(StringInfo *string_info)
1614%
1615% A description of each parameter follows:
1616%
1617% o string_info: the string info.
1618%
1619*/
1620MagickExport void ResetStringInfo(StringInfo *string_info)
1621{
1622 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1623 assert(string_info != (StringInfo *) NULL);
1624 assert(string_info->signature == MagickSignature);
1625 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1626}
1627
1628/*
1629%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1630% %
1631% %
1632% %
1633% S e t S t r i n g I n f o %
1634% %
1635% %
1636% %
1637%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1638%
1639% SetStringInfo() copies the source string to the destination string.
1640%
1641% The format of the SetStringInfo method is:
1642%
1643% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1644%
1645% A description of each parameter follows:
1646%
1647% o string_info: the string info.
1648%
1649% o source: the source string.
1650%
1651*/
1652MagickExport void SetStringInfo(StringInfo *string_info,
1653 const StringInfo *source)
1654{
1655 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1656 assert(string_info != (StringInfo *) NULL);
1657 assert(string_info->signature == MagickSignature);
1658 assert(source != (StringInfo *) NULL);
1659 assert(source->signature == MagickSignature);
1660 if (string_info->length == 0)
1661 return;
1662 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1663 (void) CopyMagickMemory(string_info->datum,source->datum,MagickMin(
1664 string_info->length,source->length));
1665}
1666
1667/*
1668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1669% %
1670% %
1671% %
1672% S e t S t r i n g I n f o D a t u m %
1673% %
1674% %
1675% %
1676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1677%
1678% SetStringInfoDatum() copies bytes from the source string for the length of
1679% the destination string.
1680%
1681% The format of the SetStringInfoDatum method is:
1682%
1683% void SetStringInfoDatum(StringInfo *string_info,
1684% const unsigned char *source)
1685%
1686% A description of each parameter follows:
1687%
1688% o string_info: the string info.
1689%
1690% o source: the source string.
1691%
1692*/
1693MagickExport void SetStringInfoDatum(StringInfo *string_info,
1694 const unsigned char *source)
1695{
1696 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1697 assert(string_info != (StringInfo *) NULL);
1698 assert(string_info->signature == MagickSignature);
1699 if (string_info->length != 0)
1700 (void) CopyMagickMemory(string_info->datum,source,string_info->length);
1701}
1702
1703/*
1704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1705% %
1706% %
1707% %
1708% S e t S t r i n g I n f o L e n g t h %
1709% %
1710% %
1711% %
1712%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1713%
1714% SetStringInfoLength() set the string length to the specified value.
1715%
1716% The format of the SetStringInfoLength method is:
1717%
1718% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1719%
1720% A description of each parameter follows:
1721%
1722% o string_info: the string info.
1723%
1724% o length: the string length.
1725%
1726*/
1727MagickExport void SetStringInfoLength(StringInfo *string_info,
1728 const size_t length)
1729{
1730 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1731 assert(string_info != (StringInfo *) NULL);
1732 assert(string_info->signature == MagickSignature);
1733 if (~length < MaxTextExtent)
1734 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1735 string_info->length=length;
1736 if (string_info->datum == (unsigned char *) NULL)
1737 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1738 MaxTextExtent,sizeof(*string_info->datum));
1739 else
1740 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1741 length+MaxTextExtent,sizeof(*string_info->datum));
1742 if (string_info->datum == (unsigned char *) NULL)
1743 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1744}
1745
1746/*
1747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1748% %
1749% %
1750% %
1751% S e t S t r i n g I n f o D a t u m %
1752% %
1753% %
1754% %
1755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1756%
1757% SetStringInfoPath() sets the path associated with the string.
1758%
1759% The format of the SetStringInfoPath method is:
1760%
1761% void SetStringInfoPath(StringInfo *string_info,const char *path)
1762%
1763% A description of each parameter follows:
1764%
1765% o string_info: the string info.
1766%
1767% o path: the path.
1768%
1769*/
1770MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1771{
1772 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1773 assert(string_info != (StringInfo *) NULL);
1774 assert(string_info->signature == MagickSignature);
1775 assert(path != (const char *) NULL);
1776 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1777}
1778
1779/*
1780%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1781% %
1782% %
1783% %
1784% S p l i t S t r i n g I n f o %
1785% %
1786% %
1787% %
1788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1789%
1790% SplitStringInfo() splits a string into two and returns it.
1791%
1792% The format of the SplitStringInfo method is:
1793%
1794% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1795%
1796% A description of each parameter follows:
1797%
1798% o string_info: the string info.
1799%
1800*/
1801MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1802 const size_t offset)
1803{
1804 StringInfo
1805 *split_info;
1806
1807 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1808 assert(string_info != (StringInfo *) NULL);
1809 assert(string_info->signature == MagickSignature);
1810 if (offset > string_info->length)
1811 return((StringInfo *) NULL);
1812 split_info=AcquireStringInfo(offset);
1813 SetStringInfo(split_info,string_info);
1814 (void) CopyMagickMemory(string_info->datum,string_info->datum+offset,
1815 string_info->length-offset+MaxTextExtent);
1816 SetStringInfoLength(string_info,string_info->length-offset);
1817 return(split_info);
1818}
1819
1820/*
1821%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1822% %
1823% %
1824% %
1825% S t r i n g I n f o T o S t r i n g %
1826% %
1827% %
1828% %
1829%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1830%
1831% StringInfoToString() converts a string info string to a C string.
1832%
1833% The format of the StringInfoToString method is:
1834%
1835% char *StringInfoToString(const StringInfo *string_info)
1836%
1837% A description of each parameter follows:
1838%
1839% o string_info: the string.
1840%
1841*/
1842MagickExport char *StringInfoToString(const StringInfo *string_info)
1843{
1844 char
1845 *string;
1846
1847 size_t
1848 length;
1849
1850 string=(char *) NULL;
1851 length=string_info->length;
1852 if (~length >= MaxTextExtent)
1853 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
1854 if (string != (char *) NULL)
1855 (void) CopyMagickString(string,(char *) string_info->datum,
1856 (length+1)*sizeof(*string));
1857 return(string);
1858}
1859
1860/*
1861%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1862% %
1863% %
1864% %
1865% S t r i n g T o A r g v %
1866% %
1867% %
1868% %
1869%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1870%
1871% StringToArgv() converts a text string into command line arguments.
1872%
1873% The format of the StringToArgv method is:
1874%
1875% char **StringToArgv(const char *text,int *argc)
1876%
1877% A description of each parameter follows:
1878%
1879% o argv: Method StringToArgv returns the string list unless an error
1880% occurs, otherwise NULL.
1881%
1882% o text: Specifies the string to segment into a list.
1883%
1884% o argc: This integer pointer returns the number of arguments in the
1885% list.
1886%
1887*/
1888MagickExport char **StringToArgv(const char *text,int *argc)
1889{
1890 char
1891 **argv;
1892
1893 register const char
1894 *p,
1895 *q;
1896
1897 register long
1898 i;
1899
1900 *argc=0;
1901 if (text == (char *) NULL)
1902 return((char **) NULL);
1903 /*
1904 Determine the number of arguments.
1905 */
1906 for (p=text; *p != '\0'; )
1907 {
1908 while (isspace((int) ((unsigned char) *p)) != 0)
1909 p++;
1910 (*argc)++;
1911 if (*p == '"')
1912 for (p++; (*p != '"') && (*p != '\0'); p++) ;
1913 if (*p == '\'')
1914 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
1915 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1916 p++;
1917 }
1918 (*argc)++;
1919 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
1920 if (argv == (char **) NULL)
1921 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
1922 /*
1923 Convert string to an ASCII list.
1924 */
1925 argv[0]=AcquireString("magick");
1926 p=text;
1927 for (i=1; i < (long) *argc; i++)
1928 {
1929 while (isspace((int) ((unsigned char) *p)) != 0)
1930 p++;
1931 q=p;
1932 if (*q == '"')
1933 {
1934 p++;
1935 for (q++; (*q != '"') && (*q != '\0'); q++) ;
1936 }
1937 else
1938 if (*q == '\'')
1939 {
1940 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
1941 q++;
1942 }
1943 else
1944 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
1945 q++;
1946 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
1947 sizeof(**argv));
1948 if (argv[i] == (char *) NULL)
1949 {
1950 for (i--; i >= 0; i--)
1951 argv[i]=DestroyString(argv[i]);
1952 argv=(char **) RelinquishMagickMemory(argv);
1953 ThrowFatalException(ResourceLimitFatalError,
1954 "UnableToConvertStringToARGV");
1955 }
1956 (void) CopyMagickString(argv[i],p,(size_t) (q-p+1));
1957 p=q;
1958 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1959 p++;
1960 }
1961 argv[i]=(char *) NULL;
1962 return(argv);
1963}
1964
1965/*
1966%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1967% %
1968% %
1969% %
cristy3ed852e2009-09-05 21:47:34 +00001970% S t r i n g I n f o T o H e x S t r i n g %
1971% %
1972% %
1973% %
1974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1975%
1976% StringInfoToHexString() converts a string info string to a C string.
1977%
1978% The format of the StringInfoToHexString method is:
1979%
1980% char *StringInfoToHexString(const StringInfo *string_info)
1981%
1982% A description of each parameter follows:
1983%
1984% o string_info: the string.
1985%
1986*/
1987MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1988{
1989 char
1990 *string;
1991
1992 register const unsigned char
1993 *p;
1994
1995 register long
1996 i;
1997
1998 register unsigned char
1999 *q;
2000
2001 size_t
2002 length;
2003
2004 unsigned char
2005 hex_digits[16];
2006
2007 length=string_info->length;
2008 if (~length < MaxTextExtent)
2009 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2010 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2011 if (string == (char *) NULL)
2012 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2013 hex_digits[0]='0';
2014 hex_digits[1]='1';
2015 hex_digits[2]='2';
2016 hex_digits[3]='3';
2017 hex_digits[4]='4';
2018 hex_digits[5]='5';
2019 hex_digits[6]='6';
2020 hex_digits[7]='7';
2021 hex_digits[8]='8';
2022 hex_digits[9]='9';
2023 hex_digits[10]='a';
2024 hex_digits[11]='b';
2025 hex_digits[12]='c';
2026 hex_digits[13]='d';
2027 hex_digits[14]='e';
2028 hex_digits[15]='f';
2029 p=string_info->datum;
2030 q=(unsigned char *) string;
2031 for (i=0; i < (long) string_info->length; i++)
2032 {
2033 *q++=hex_digits[(*p >> 4) & 0x0f];
2034 *q++=hex_digits[*p & 0x0f];
2035 p++;
2036 }
2037 *q='\0';
2038 return(string);
2039}
2040
2041/*
2042%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2043% %
2044% %
2045% %
2046% S t r i n g T o k e n %
2047% %
2048% %
2049% %
2050%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2051%
2052% StringToken() extracts a token a from the string.
2053%
2054% The format of the StringToken method is:
2055%
2056% char *StringToken(const char *delimiters,char **string)
2057%
2058% A description of each parameter follows:
2059%
2060% o delimiters: one or more delimiters.
2061%
2062% o string: return the first token in the string. If none is found, return
2063% NULL.
2064%
2065*/
2066MagickExport char *StringToken(const char *delimiters,char **string)
2067{
2068 char
2069 *q;
2070
2071 register char
2072 *p;
2073
2074 register const char
2075 *r;
2076
2077 register int
2078 c,
2079 d;
2080
2081 p=(*string);
2082 if (p == (char *) NULL)
2083 return((char *) NULL);
2084 for (q=p; ; )
2085 {
2086 c=(*p++);
2087 r=delimiters;
2088 do
2089 {
2090 d=(*r++);
2091 if (c == d)
2092 {
2093 if (c == '\0')
2094 p=(char *) NULL;
2095 else
2096 p[-1]='\0';
2097 *string=p;
2098 return(q);
2099 }
2100 } while (d != '\0');
2101 }
2102}
2103
2104/*
2105%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2106% %
2107% %
2108% %
2109% S t r i n g T o L i s t %
2110% %
2111% %
2112% %
2113%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2114%
2115% StringToList() converts a text string into a list by segmenting the text
2116% string at each carriage return discovered. The list is converted to HEX
2117% characters if any control characters are discovered within the text string.
2118%
2119% The format of the StringToList method is:
2120%
2121% char **StringToList(const char *text)
2122%
2123% A description of each parameter follows:
2124%
2125% o list: Method StringToList returns the string list unless an error
2126% occurs, otherwise NULL.
2127%
2128% o text: Specifies the string to segment into a list.
2129%
2130*/
2131MagickExport char **StringToList(const char *text)
2132{
2133 char
2134 **textlist;
2135
2136 register const char
2137 *p;
2138
2139 register long
2140 i;
2141
2142 unsigned long
2143 lines;
2144
2145 if (text == (char *) NULL)
2146 return((char **) NULL);
2147 for (p=text; *p != '\0'; p++)
2148 if (((int) ((unsigned char) *p) < 32) &&
2149 (isspace((int) ((unsigned char) *p)) == 0))
2150 break;
2151 if (*p == '\0')
2152 {
2153 register const char
2154 *q;
2155
2156 /*
2157 Convert string to an ASCII list.
2158 */
2159 lines=1;
2160 for (p=text; *p != '\0'; p++)
2161 if (*p == '\n')
2162 lines++;
2163 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2164 sizeof(*textlist));
2165 if (textlist == (char **) NULL)
2166 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2167 p=text;
2168 for (i=0; i < (long) lines; i++)
2169 {
2170 for (q=p; *q != '\0'; q++)
2171 if ((*q == '\r') || (*q == '\n'))
2172 break;
2173 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2174 sizeof(*textlist));
2175 if (textlist[i] == (char *) NULL)
2176 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2177 (void) CopyMagickString(textlist[i],p,(size_t) (q-p+1));
2178 if (*q == '\r')
2179 q++;
2180 p=q+1;
2181 }
2182 }
2183 else
2184 {
2185 char
2186 hex_string[MaxTextExtent];
2187
2188 register char
2189 *q;
2190
2191 register long
2192 j;
2193
2194 /*
2195 Convert string to a HEX list.
2196 */
2197 lines=(unsigned long) (strlen(text)/0x14)+1;
2198 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2199 sizeof(*textlist));
2200 if (textlist == (char **) NULL)
2201 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2202 p=text;
2203 for (i=0; i < (long) lines; i++)
2204 {
2205 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
2206 sizeof(*textlist));
2207 if (textlist[i] == (char *) NULL)
2208 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2209 (void) FormatMagickString(textlist[i],MaxTextExtent,"0x%08lx: ",0x14*i);
2210 q=textlist[i]+strlen(textlist[i]);
2211 for (j=1; j <= (long) MagickMin(strlen(p),0x14); j++)
2212 {
2213 (void) FormatMagickString(hex_string,MaxTextExtent,"%02x",*(p+j));
2214 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2215 q+=2;
2216 if ((j % 0x04) == 0)
2217 *q++=' ';
2218 }
2219 for ( ; j <= 0x14; j++)
2220 {
2221 *q++=' ';
2222 *q++=' ';
2223 if ((j % 0x04) == 0)
2224 *q++=' ';
2225 }
2226 *q++=' ';
2227 for (j=1; j <= (long) MagickMin(strlen(p),0x14); j++)
2228 {
2229 if (isprint((int) ((unsigned char) *p)) != 0)
2230 *q++=(*p);
2231 else
2232 *q++='-';
2233 p++;
2234 }
2235 *q='\0';
2236 }
2237 }
2238 textlist[i]=(char *) NULL;
2239 return(textlist);
2240}
2241
2242/*
2243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2244% %
2245% %
2246% %
2247% S t r i n g T o S t r i n g I n f o %
2248% %
2249% %
2250% %
2251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2252%
2253% StringToStringInfo() returns the contents of a file as a string.
2254%
2255% The format of the StringToStringInfo method is:
2256%
2257% StringInfo *StringToStringInfo(const char *string)
2258%
2259% A description of each parameter follows:
2260%
2261% o string: The string.
2262%
2263*/
2264MagickExport StringInfo *StringToStringInfo(const char *string)
2265{
2266 StringInfo
2267 *string_info;
2268
2269 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2270 assert(string != (const char *) NULL);
2271 string_info=AcquireStringInfo(strlen(string)+1);
2272 SetStringInfoDatum(string_info,(const unsigned char *) string);
2273 return(string_info);
2274}
2275
2276/*
2277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2278% %
2279% %
2280% %
2281% S t r i p S t r i n g %
2282% %
2283% %
2284% %
2285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2286%
2287% StripString() strips any whitespace or quotes from the beginning and end of
2288% a string of characters.
2289%
2290% The format of the StripString method is:
2291%
2292% void StripString(char *message)
2293%
2294% A description of each parameter follows:
2295%
2296% o message: Specifies an array of characters.
2297%
2298*/
2299MagickExport void StripString(char *message)
2300{
2301 register char
2302 *p,
2303 *q;
2304
2305 size_t
2306 length;
2307
2308 assert(message != (char *) NULL);
2309 if (*message == '\0')
2310 return;
2311 length=strlen(message);
2312 p=message;
2313 while (isspace((int) ((unsigned char) *p)) != 0)
2314 p++;
2315 if ((*p == '\'') || (*p == '"'))
2316 p++;
2317 q=message+length-1;
2318 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2319 q--;
2320 if (q > p)
2321 if ((*q == '\'') || (*q == '"'))
2322 q--;
2323 (void) CopyMagickMemory(message,p,(size_t) (q-p+1));
2324 message[q-p+1]='\0';
2325 for (p=message; *p != '\0'; p++)
2326 if (*p == '\n')
2327 *p=' ';
2328}
2329
2330/*
2331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2332% %
2333% %
2334% %
2335% S u b s t i t u t e S t r i n g %
2336% %
2337% %
2338% %
2339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2340%
cristyf1b72c12009-10-06 13:25:21 +00002341% SubstituteString() performs string substitution on a string, replacing the
2342% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002343% If the string is matched and status, MagickTrue is returned otherwise
2344% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002345%
2346% The format of the SubstituteString method is:
2347%
cristyf1b72c12009-10-06 13:25:21 +00002348% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002349% const char *replace)
2350%
2351% A description of each parameter follows:
2352%
cristyf1b72c12009-10-06 13:25:21 +00002353% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002354% allocation if a replacement is made.
2355%
cristybc3392a2009-10-06 03:15:57 +00002356% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002357%
cristybc3392a2009-10-06 03:15:57 +00002358% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002359%
2360*/
cristyf1b72c12009-10-06 13:25:21 +00002361MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002362 const char *search,const char *replace)
2363{
cristybc3392a2009-10-06 03:15:57 +00002364 MagickBooleanType
2365 status;
cristy3ed852e2009-09-05 21:47:34 +00002366
cristybc3392a2009-10-06 03:15:57 +00002367 register char
2368 *p;
cristy3ed852e2009-09-05 21:47:34 +00002369
cristy3ed852e2009-09-05 21:47:34 +00002370 size_t
cristybc3392a2009-10-06 03:15:57 +00002371 extent,
2372 replace_extent,
2373 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002374
cristyf1b72c12009-10-06 13:25:21 +00002375 ssize_t
2376 offset;
2377
cristybc3392a2009-10-06 03:15:57 +00002378 status=MagickFalse;
2379 search_extent=0,
2380 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002381 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002382 {
cristyf1b72c12009-10-06 13:25:21 +00002383 if (search_extent == 0)
2384 search_extent=strlen(search);
2385 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002386 continue;
cristy3ed852e2009-09-05 21:47:34 +00002387 /*
cristybc3392a2009-10-06 03:15:57 +00002388 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002389 */
cristyf1b72c12009-10-06 13:25:21 +00002390 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002391 if (replace_extent == 0)
2392 replace_extent=strlen(replace);
2393 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002394 {
cristybc3392a2009-10-06 03:15:57 +00002395 /*
2396 Make room for the replacement string.
2397 */
cristyde58b412010-02-18 03:53:40 +00002398 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002399 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002400 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2401 sizeof(*p));
2402 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002403 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002404 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002405 }
cristy3ed852e2009-09-05 21:47:34 +00002406 /*
cristybc3392a2009-10-06 03:15:57 +00002407 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002408 */
cristybc3392a2009-10-06 03:15:57 +00002409 if (search_extent != replace_extent)
cristyf1b72c12009-10-06 13:25:21 +00002410 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2411 strlen(p+search_extent)+1);
2412 (void) CopyMagickMemory(p,replace,replace_extent);
2413 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002414 }
cristybc3392a2009-10-06 03:15:57 +00002415 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002416}