blob: 4e1504fd8988c40e954f656624382eff379c3c71 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% SSSSS TTTTT RRRR IIIII N N GGGG %
7% SS T R R I NN N G %
8% SSS T RRRR I N N N G GGG %
9% SS T R R I N NN G G %
10% SSSSS T R R IIIII N N GGGG %
11% %
12% %
13% MagickCore String Methods %
14% %
15% Software Design %
16% John Cristy %
17% August 2003 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
cristy4c08aed2011-07-01 19:47:50 +000042#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/exception.h"
46#include "MagickCore/exception-private.h"
47#include "MagickCore/list.h"
48#include "MagickCore/locale_.h"
49#include "MagickCore/log.h"
50#include "MagickCore/memory_.h"
51#include "MagickCore/property.h"
52#include "MagickCore/resource_.h"
53#include "MagickCore/signature-private.h"
54#include "MagickCore/string_.h"
cristy3ed852e2009-09-05 21:47:34 +000055
56/*
57 Static declarations.
58*/
59#if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
60static const unsigned char
61 AsciiMap[] =
62 {
63 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
64 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
65 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
66 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
67 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
68 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
69 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
70 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
71 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
72 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
73 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
74 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
75 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
76 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
77 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
78 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
79 0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
80 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
81 0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
82 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
83 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
84 0xfc, 0xfd, 0xfe, 0xff,
85 };
86#endif
87
88/*
89%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90% %
91% %
92% %
93% A c q u i r e S t r i n g %
94% %
95% %
96% %
97%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
98%
99% AcquireString() allocates memory for a string and copies the source string
100% to that memory location (and returns it).
101%
102% The format of the AcquireString method is:
103%
104% char *AcquireString(const char *source)
105%
106% A description of each parameter follows:
107%
108% o source: A character string.
109%
110*/
111MagickExport char *AcquireString(const char *source)
112{
113 char
114 *destination;
115
116 size_t
117 length;
118
119 length=0;
120 if (source != (char *) NULL)
121 length+=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000122 if (~length < MaxTextExtent)
123 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
124 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
125 sizeof(*destination));
cristy3ed852e2009-09-05 21:47:34 +0000126 if (destination == (char *) NULL)
127 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
128 *destination='\0';
129 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000130 (void) memcpy(destination,source,length*sizeof(*destination));
131 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000132 return(destination);
133}
134
135/*
136%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137% %
138% %
139% %
140% A c q u i r e S t r i n g I n f o %
141% %
142% %
143% %
144%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145%
146% AcquireStringInfo() allocates the StringInfo structure.
147%
148% The format of the AcquireStringInfo method is:
149%
150% StringInfo *AcquireStringInfo(const size_t length)
151%
152% A description of each parameter follows:
153%
154% o length: the string length.
155%
156*/
157MagickExport StringInfo *AcquireStringInfo(const size_t length)
158{
159 StringInfo
160 *string_info;
161
cristy73bd4a52010-10-05 11:24:23 +0000162 string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
cristy3ed852e2009-09-05 21:47:34 +0000163 if (string_info == (StringInfo *) NULL)
164 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
165 (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
166 string_info->signature=MagickSignature;
167 string_info->length=length;
168 if (string_info->length != 0)
169 {
170 string_info->datum=(unsigned char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000171 if (~string_info->length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000172 string_info->datum=(unsigned char *) AcquireQuantumMemory(
173 string_info->length+MaxTextExtent,sizeof(*string_info->datum));
174 if (string_info->datum == (unsigned char *) NULL)
175 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
176 }
177 return(string_info);
178}
179
180/*
181%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182% %
183% %
184% %
185% C l o n e S t r i n g %
186% %
187% %
188% %
189%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190%
191% CloneString() allocates memory for the destination string and copies
192% the source string to that memory location.
193%
194% The format of the CloneString method is:
195%
196% char *CloneString(char **destination,const char *source)
197%
198% A description of each parameter follows:
199%
200% o destination: A pointer to a character string.
201%
202% o source: A character string.
203%
204*/
205MagickExport char *CloneString(char **destination,const char *source)
206{
207 size_t
208 length;
209
210 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
211 assert(destination != (char **) NULL);
212 if (source == (const char *) NULL)
213 {
214 if (*destination != (char *) NULL)
215 *destination=DestroyString(*destination);
216 return(*destination);
217 }
218 if (*destination == (char *) NULL)
219 {
220 *destination=AcquireString(source);
221 return(*destination);
222 }
223 length=strlen(source);
224 if (~length < MaxTextExtent)
225 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
226 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristyb936f702011-03-25 15:33:43 +0000227 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000228 if (*destination == (char *) NULL)
229 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristy54aad5e2010-09-03 16:02:04 +0000230 if (length != 0)
cristyf7e6ab42011-03-25 12:32:09 +0000231 (void) memcpy(*destination,source,length*sizeof(**destination));
cristy208cacf2010-09-03 02:24:42 +0000232 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000233 return(*destination);
234}
235
236/*
237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238% %
239% %
240% %
241% C l o n e S t r i n g I n f o %
242% %
243% %
244% %
245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246%
247% CloneStringInfo() clones a copy of the StringInfo structure.
248%
249% The format of the CloneStringInfo method is:
250%
251% StringInfo *CloneStringInfo(const StringInfo *string_info)
252%
253% A description of each parameter follows:
254%
255% o string_info: the string info.
256%
257*/
258MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
259{
260 StringInfo
261 *clone_info;
262
263 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
264 assert(string_info != (StringInfo *) NULL);
265 assert(string_info->signature == MagickSignature);
266 clone_info=AcquireStringInfo(string_info->length);
267 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +0000268 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
cristy3ed852e2009-09-05 21:47:34 +0000269 return(clone_info);
270}
271
272/*
273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274% %
275% %
276% %
277% C o m p a r e S t r i n g I n f o %
278% %
279% %
280% %
281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282%
283% CompareStringInfo() compares the two datums target and source. It returns
284% an integer less than, equal to, or greater than zero if target is found,
285% respectively, to be less than, to match, or be greater than source.
286%
287% The format of the CompareStringInfo method is:
288%
289% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
290%
291% A description of each parameter follows:
292%
293% o target: the target string.
294%
295% o source: the source string.
296%
297*/
298
299static inline size_t MagickMin(const size_t x,const size_t y)
300{
301 if (x < y)
302 return(x);
303 return(y);
304}
305
306MagickExport int CompareStringInfo(const StringInfo *target,
307 const StringInfo *source)
308{
309 int
310 status;
311
312 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
313 assert(target != (StringInfo *) NULL);
314 assert(target->signature == MagickSignature);
315 assert(source != (StringInfo *) NULL);
316 assert(source->signature == MagickSignature);
317 status=memcmp(target->datum,source->datum,MagickMin(target->length,
318 source->length));
319 if (status != 0)
320 return(status);
321 if (target->length == source->length)
322 return(0);
323 return(target->length < source->length ? -1 : 1);
324}
325
326/*
327%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
328% %
329% %
330% %
331% C o n c a t e n a t e M a g i c k S t r i n g %
332% %
333% %
334% %
335%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
336%
337% ConcatenateMagickString() concatenates the source string to the destination
338% string. The destination buffer is always null-terminated even if the
339% string must be truncated.
340%
341% The format of the ConcatenateMagickString method is:
342%
343% size_t ConcatenateMagickString(char *destination,const char *source,
344% const size_t length)
345%
346% A description of each parameter follows:
347%
348% o destination: the destination string.
349%
350% o source: the source string.
351%
352% o length: the length of the destination string.
353%
354*/
355MagickExport size_t ConcatenateMagickString(char *destination,
356 const char *source,const size_t length)
357{
358 register char
359 *q;
360
361 register const char
362 *p;
363
364 register size_t
365 i;
366
367 size_t
368 count;
369
370 assert(destination != (char *) NULL);
371 assert(source != (const char *) NULL);
372 assert(length >= 1);
373 p=source;
374 q=destination;
375 i=length;
376 while ((i-- != 0) && (*q != '\0'))
377 q++;
378 count=(size_t) (q-destination);
379 i=length-count;
380 if (i == 0)
381 return(count+strlen(p));
382 while (*p != '\0')
383 {
384 if (i != 1)
385 {
386 *q++=(*p);
387 i--;
388 }
389 p++;
390 }
391 *q='\0';
392 return(count+(p-source));
393}
394
395/*
396%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397% %
398% %
399% %
400% C o n c a t e n a t e S t r i n g %
401% %
402% %
403% %
404%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405%
406% ConcatenateString() appends a copy of string source, including the
407% terminating null character, to the end of string destination.
408%
409% The format of the ConcatenateString method is:
410%
411% MagickBooleanType ConcatenateString(char **destination,
412% const char *source)
413%
414% A description of each parameter follows:
415%
416% o destination: A pointer to a character string.
417%
418% o source: A character string.
419%
420*/
421MagickExport MagickBooleanType ConcatenateString(char **destination,
422 const char *source)
423{
424 size_t
cristy54aad5e2010-09-03 16:02:04 +0000425 destination_length,
cristy3ed852e2009-09-05 21:47:34 +0000426 length,
427 source_length;
428
429 assert(destination != (char **) NULL);
430 if (source == (const char *) NULL)
431 return(MagickTrue);
432 if (*destination == (char *) NULL)
433 {
434 *destination=AcquireString(source);
435 return(MagickTrue);
436 }
cristy54aad5e2010-09-03 16:02:04 +0000437 destination_length=strlen(*destination);
cristy3ed852e2009-09-05 21:47:34 +0000438 source_length=strlen(source);
cristy54aad5e2010-09-03 16:02:04 +0000439 length=destination_length;
cristy3ed852e2009-09-05 21:47:34 +0000440 if (~length < source_length)
441 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
442 length+=source_length;
443 if (~length < MaxTextExtent)
444 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
445 *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
cristycf1667c2011-03-25 15:35:41 +0000446 sizeof(**destination));
cristy3ed852e2009-09-05 21:47:34 +0000447 if (*destination == (char *) NULL)
448 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
cristy54aad5e2010-09-03 16:02:04 +0000449 if (source_length != 0)
450 (void) memcpy((*destination)+destination_length,source,source_length);
451 (*destination)[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000452 return(MagickTrue);
453}
454
455/*
456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457% %
458% %
459% %
460% C o n c a t e n a t e S t r i n g I n f o %
461% %
462% %
463% %
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465%
466% ConcatenateStringInfo() concatenates the source string to the destination
467% string.
468%
469% The format of the ConcatenateStringInfo method is:
470%
471% void ConcatenateStringInfo(StringInfo *string_info,
472% const StringInfo *source)
473%
474% A description of each parameter follows:
475%
476% o string_info: the string info.
477%
478% o source: the source string.
479%
480*/
481MagickExport void ConcatenateStringInfo(StringInfo *string_info,
482 const StringInfo *source)
483{
484 size_t
485 length;
486
487 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
488 assert(string_info != (StringInfo *) NULL);
489 assert(string_info->signature == MagickSignature);
490 assert(source != (const StringInfo *) NULL);
491 length=string_info->length;
492 if (~length < source->length)
493 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
494 SetStringInfoLength(string_info,length+source->length);
cristy54aad5e2010-09-03 16:02:04 +0000495 (void) memcpy(string_info->datum+length,source->datum,source->length);
cristy3ed852e2009-09-05 21:47:34 +0000496}
497
498/*
499%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
500% %
501% %
502% %
503% 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 %
504% %
505% %
506% %
507%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
508%
509% ConfigureFileToStringInfo() returns the contents of a configure file as a
510% string.
511%
512% The format of the ConfigureFileToStringInfo method is:
513%
514% StringInfo *ConfigureFileToStringInfo(const char *filename)
515% ExceptionInfo *exception)
516%
517% A description of each parameter follows:
518%
519% o filename: the filename.
520%
521*/
522MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
523{
524 char
525 *string;
526
527 int
528 file;
529
530 MagickOffsetType
531 offset;
532
533 size_t
534 length;
535
536 StringInfo
537 *string_info;
538
539 void
540 *map;
541
542 assert(filename != (const char *) NULL);
543 file=open(filename,O_RDONLY | O_BINARY);
544 if (file == -1)
545 return((StringInfo *) NULL);
cristy7f317702011-02-18 20:40:28 +0000546 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
cristy3ed852e2009-09-05 21:47:34 +0000547 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
548 {
549 file=close(file)-1;
550 return((StringInfo *) NULL);
551 }
552 length=(size_t) offset;
553 string=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000554 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000555 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
556 if (string == (char *) NULL)
557 {
558 file=close(file)-1;
559 return((StringInfo *) NULL);
560 }
561 map=MapBlob(file,ReadMode,0,length);
562 if (map != (void *) NULL)
563 {
cristy54aad5e2010-09-03 16:02:04 +0000564 (void) memcpy(string,map,length);
cristy3ed852e2009-09-05 21:47:34 +0000565 (void) UnmapBlob(map,length);
566 }
567 else
568 {
569 register size_t
570 i;
571
572 ssize_t
573 count;
574
cristy7f317702011-02-18 20:40:28 +0000575 (void) lseek(file,0,SEEK_SET);
cristy3ed852e2009-09-05 21:47:34 +0000576 for (i=0; i < length; i+=count)
577 {
578 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
579 SSIZE_MAX));
580 if (count <= 0)
581 {
582 count=0;
583 if (errno != EINTR)
584 break;
585 }
586 }
587 if (i < length)
588 {
589 file=close(file)-1;
590 string=DestroyString(string);
591 return((StringInfo *) NULL);
592 }
593 }
594 string[length]='\0';
595 file=close(file)-1;
596 string_info=AcquireStringInfo(0);
597 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
598 string_info->length=length;
599 string_info->datum=(unsigned char *) string;
600 return(string_info);
601}
602
603/*
604%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
605% %
606% %
607% %
608% C o n s t a n t S t r i n g %
609% %
610% %
611% %
612%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
613%
614% ConstantString() allocates memory for a string and copies the source string
615% to that memory location (and returns it). Use it for strings that you do
616% do not expect to change over its lifetime.
617%
618% The format of the ConstantString method is:
619%
620% char *ConstantString(const char *source)
621%
622% A description of each parameter follows:
623%
624% o source: A character string.
625%
626*/
627MagickExport char *ConstantString(const char *source)
628{
629 char
630 *destination;
631
632 size_t
633 length;
634
635 length=0;
636 if (source != (char *) NULL)
637 length+=strlen(source);
638 destination=(char *) NULL;
639 if (~length >= 1UL)
640 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
641 if (destination == (char *) NULL)
642 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
643 *destination='\0';
644 if (source != (char *) NULL)
cristy54aad5e2010-09-03 16:02:04 +0000645 (void) memcpy(destination,source,length*sizeof(*destination));
646 destination[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +0000647 return(destination);
648}
649
650/*
651%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652% %
653% %
654% %
655% C o p y M a g i c k S t r i n g %
656% %
657% %
658% %
659%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660%
661% CopyMagickString() copies the source string to the destination string. The
662% destination buffer is always null-terminated even if the string must be
663% truncated. The return value is the minimum of the source string length
664% or the length parameter.
665%
666% The format of the CopyMagickString method is:
667%
668% size_t CopyMagickString(const char *destination,char *source,
669% const size_t length)
670%
671% A description of each parameter follows:
672%
673% o destination: the destination string.
674%
675% o source: the source string.
676%
677% o length: the length of the destination string.
678%
679*/
680MagickExport size_t CopyMagickString(char *destination,const char *source,
681 const size_t length)
682{
683 register char
684 *q;
685
686 register const char
687 *p;
688
689 register size_t
690 n;
691
692 p=source;
693 q=destination;
694 for (n=length; n > 4; n-=4)
695 {
696 *q=(*p++);
697 if (*q == '\0')
698 return((size_t) (p-source-1));
699 q++;
700 *q=(*p++);
701 if (*q == '\0')
702 return((size_t) (p-source-1));
703 q++;
704 *q=(*p++);
705 if (*q == '\0')
706 return((size_t) (p-source-1));
707 q++;
708 *q=(*p++);
709 if (*q == '\0')
710 return((size_t) (p-source-1));
711 q++;
712 }
713 if (n != 0)
714 for (n--; n != 0; n--)
715 {
716 *q=(*p++);
717 if (*q == '\0')
718 return((size_t) (p-source-1));
719 q++;
720 }
721 if (length != 0)
722 *q='\0';
723 return((size_t) (p-source-1));
724}
725
726/*
727%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
728% %
729% %
730% %
731% D e s t r o y S t r i n g %
732% %
733% %
734% %
735%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736%
737% DestroyString() destroys memory associated with a string.
738%
739% The format of the DestroyString method is:
740%
741% char *DestroyString(char *string)
742%
743% A description of each parameter follows:
744%
745% o string: the string.
746%
747*/
748MagickExport char *DestroyString(char *string)
749{
750 return((char *) RelinquishMagickMemory(string));
751}
752
753/*
754%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
755% %
756% %
757% %
758% D e s t r o y S t r i n g I n f o %
759% %
760% %
761% %
762%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
763%
764% DestroyStringInfo() destroys memory associated with the StringInfo structure.
765%
766% The format of the DestroyStringInfo method is:
767%
768% StringInfo *DestroyStringInfo(StringInfo *string_info)
769%
770% A description of each parameter follows:
771%
772% o string_info: the string info.
773%
774*/
775MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
776{
777 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
778 assert(string_info != (StringInfo *) NULL);
779 assert(string_info->signature == MagickSignature);
780 if (string_info->datum != (unsigned char *) NULL)
781 string_info->datum=(unsigned char *) RelinquishMagickMemory(
782 string_info->datum);
783 string_info->signature=(~MagickSignature);
784 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
785 return(string_info);
786}
787
788/*
789%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
790% %
791% %
792% %
793% D e s t r o y S t r i n g L i s t %
794% %
795% %
796% %
797%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798%
799% DestroyStringList() zeros memory associated with a string list.
800%
801% The format of the DestroyStringList method is:
802%
803% char **DestroyStringList(char **list)
804%
805% A description of each parameter follows:
806%
807% o list: the string list.
808%
809*/
810MagickExport char **DestroyStringList(char **list)
811{
cristybb503372010-05-27 20:51:26 +0000812 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000813 i;
814
815 assert(list != (char **) NULL);
816 for (i=0; list[i] != (char *) NULL; i++)
817 list[i]=DestroyString(list[i]);
818 list=(char **) RelinquishMagickMemory(list);
819 return(list);
820}
821
822/*
823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824% %
825% %
826% %
827% E s c a p e S t r i n g %
828% %
829% %
830% %
831%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832%
833% EscapeString() allocates memory for a backslash-escaped version of a
834% source text string, copies the escaped version of the text to that
835% memory location while adding backslash characters, and returns the
836% escaped string.
837%
838% The format of the EscapeString method is:
839%
840% char *EscapeString(const char *source,const char escape)
841%
842% A description of each parameter follows:
843%
844% o allocate_string: Method EscapeString returns the escaped string.
845%
846% o source: A character string.
847%
848% o escape: the quoted string termination character to escape (e.g. '"').
849%
850*/
851MagickExport char *EscapeString(const char *source,const char escape)
852{
853 char
854 *destination;
855
856 register char
857 *q;
858
859 register const char
860 *p;
861
862 size_t
863 length;
864
865 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
866 assert(source != (const char *) NULL);
867 length=strlen(source);
868 for (p=source; *p != '\0'; p++)
869 if ((*p == '\\') || (*p == escape))
870 {
871 if (~length < 1)
872 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
873 length++;
874 }
875 destination=(char *) NULL;
cristy37e0b382011-06-07 13:31:21 +0000876 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +0000877 destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
878 sizeof(*destination));
879 if (destination == (char *) NULL)
880 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
881 *destination='\0';
882 if (source != (char *) NULL)
883 {
884 q=destination;
885 for (p=source; *p != '\0'; p++)
886 {
887 if ((*p == '\\') || (*p == escape))
888 *q++='\\';
889 *q++=(*p);
890 }
891 *q='\0';
892 }
893 return(destination);
894}
895
896/*
897%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898% %
899% %
900% %
901% F i l e T o S t r i n g %
902% %
903% %
904% %
905%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
906%
907% FileToString() returns the contents of a file as a string.
908%
909% The format of the FileToString method is:
910%
911% char *FileToString(const char *filename,const size_t extent,
912% ExceptionInfo *exception)
913%
914% A description of each parameter follows:
915%
916% o filename: the filename.
917%
918% o extent: Maximum length of the string.
919%
920% o exception: return any errors or warnings in this structure.
921%
922*/
923MagickExport char *FileToString(const char *filename,const size_t extent,
924 ExceptionInfo *exception)
925{
926 size_t
927 length;
928
929 assert(filename != (const char *) NULL);
930 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
931 assert(exception != (ExceptionInfo *) NULL);
932 return((char *) FileToBlob(filename,extent,&length,exception));
933}
934
935/*
936%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
937% %
938% %
939% %
940% F i l e T o S t r i n g I n f o %
941% %
942% %
943% %
944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945%
946% FileToStringInfo() returns the contents of a file as a string.
947%
948% The format of the FileToStringInfo method is:
949%
950% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
951% ExceptionInfo *exception)
952%
953% A description of each parameter follows:
954%
955% o filename: the filename.
956%
957% o extent: Maximum length of the string.
958%
959% o exception: return any errors or warnings in this structure.
960%
961*/
962MagickExport StringInfo *FileToStringInfo(const char *filename,
963 const size_t extent,ExceptionInfo *exception)
964{
965 StringInfo
966 *string_info;
967
968 assert(filename != (const char *) NULL);
969 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
970 assert(exception != (ExceptionInfo *) NULL);
971 string_info=AcquireStringInfo(0);
972 (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
973 string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
974 if (string_info->datum == (unsigned char *) NULL)
975 {
976 string_info=DestroyStringInfo(string_info);
977 return((StringInfo *) NULL);
978 }
979 return(string_info);
980}
981
982/*
983%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
984% %
985% %
986% %
987% F o r m a t M a g i c k S i z e %
988% %
989% %
990% %
991%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992%
993% FormatMagickSize() converts a size to a human readable format, for example,
cristy2ce15c92010-03-12 14:03:41 +0000994% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
cristyc15ce492009-12-01 19:18:23 +0000995% 1000.
cristy3ed852e2009-09-05 21:47:34 +0000996%
997% The format of the FormatMagickSize method is:
998%
cristybb503372010-05-27 20:51:26 +0000999% ssize_t FormatMagickSize(const MagickSizeType size,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001000%
1001% A description of each parameter follows:
1002%
1003% o size: convert this size to a human readable format.
1004%
cristyb9080c92009-12-01 20:13:26 +00001005% o bi: use power of two rather than power of ten.
1006%
cristy3ed852e2009-09-05 21:47:34 +00001007% o format: human readable format.
1008%
1009*/
cristybb503372010-05-27 20:51:26 +00001010MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
cristyb9080c92009-12-01 20:13:26 +00001011 const MagickBooleanType bi,char *format)
cristy3ed852e2009-09-05 21:47:34 +00001012{
cristyb9080c92009-12-01 20:13:26 +00001013 const char
1014 **units;
1015
cristy3ed852e2009-09-05 21:47:34 +00001016 double
cristyb9080c92009-12-01 20:13:26 +00001017 bytes,
cristy3ed852e2009-09-05 21:47:34 +00001018 length;
1019
cristybb503372010-05-27 20:51:26 +00001020 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001021 i,
1022 j;
1023
cristy9d314ff2011-03-09 01:30:28 +00001024 ssize_t
1025 count;
1026
cristy3ed852e2009-09-05 21:47:34 +00001027 static const char
cristyb9080c92009-12-01 20:13:26 +00001028 *bi_units[] =
1029 {
cristy2ce15c92010-03-12 14:03:41 +00001030 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
cristyb9080c92009-12-01 20:13:26 +00001031 },
1032 *traditional_units[] =
cristy9bf9da32009-09-27 16:48:34 +00001033 {
cristy2ce15c92010-03-12 14:03:41 +00001034 "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
cristy9bf9da32009-09-27 16:48:34 +00001035 };
cristy3ed852e2009-09-05 21:47:34 +00001036
cristyb9080c92009-12-01 20:13:26 +00001037 bytes=1000.0;
1038 units=traditional_units;
1039 if (bi != MagickFalse)
1040 {
1041 bytes=1024.0;
1042 units=bi_units;
1043 }
cristy3ed852e2009-09-05 21:47:34 +00001044#if defined(_MSC_VER) && (_MSC_VER == 1200)
1045 length=(double) ((MagickOffsetType) size);
1046#else
1047 length=(double) size;
1048#endif
cristyb9080c92009-12-01 20:13:26 +00001049 for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1050 length/=bytes;
cristy9bf9da32009-09-27 16:48:34 +00001051 for (j=2; j < 12; j++)
cristy3ed852e2009-09-05 21:47:34 +00001052 {
cristyb51dff52011-05-19 16:55:47 +00001053 count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
cristy3ed852e2009-09-05 21:47:34 +00001054 units[i]);
1055 if (strchr(format,'+') == (char *) NULL)
1056 break;
1057 }
1058 return(count);
1059}
1060
1061/*
1062%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1063% %
1064% %
1065% %
cristy3ed852e2009-09-05 21:47:34 +00001066% F o r m a t M a g i c k T i m e %
1067% %
1068% %
1069% %
1070%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071%
1072% FormatMagickTime() returns the specified time in the Internet date/time
1073% format and the length of the timestamp.
1074%
1075% The format of the FormatMagickTime method is:
1076%
cristybb503372010-05-27 20:51:26 +00001077% ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001078% char *timestamp)
1079%
1080% A description of each parameter follows.
1081%
1082% o time: the time since the Epoch (00:00:00 UTC, January 1, 1970),
1083% measured in seconds.
1084%
1085% o length: the maximum length of the string.
1086%
1087% o timestamp: Return the Internet date/time here.
1088%
1089*/
cristybb503372010-05-27 20:51:26 +00001090MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
cristy3ed852e2009-09-05 21:47:34 +00001091 char *timestamp)
1092{
cristybb503372010-05-27 20:51:26 +00001093 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001094 count;
1095
1096 struct tm
1097 gm_time,
1098 local_time;
1099
1100 time_t
1101 timezone;
1102
1103 assert(timestamp != (char *) NULL);
1104 (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1105 (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1106#if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1107 (void) localtime_r(&time,&local_time);
1108#else
1109 {
cristybc3392a2009-10-06 03:15:57 +00001110 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001111 *my_time;
1112
1113 my_time=localtime(&time);
1114 if (my_time != (struct tm *) NULL)
1115 (void) memcpy(&local_time,my_time,sizeof(local_time));
1116 }
1117#endif
1118#if defined(MAGICKCORE_HAVE_GMTIME_R)
1119 (void) gmtime_r(&time,&gm_time);
1120#else
1121 {
cristybc3392a2009-10-06 03:15:57 +00001122 struct tm
cristy3ed852e2009-09-05 21:47:34 +00001123 *my_time;
1124
1125 my_time=gmtime(&time);
1126 if (my_time != (struct tm *) NULL)
1127 (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1128 }
1129#endif
1130 timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1131 local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1132 gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1133 (local_time.tm_yday-gm_time.tm_yday)));
cristyb51dff52011-05-19 16:55:47 +00001134 count=FormatLocaleString(timestamp,length,
cristy3ed852e2009-09-05 21:47:34 +00001135 "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1136 local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
cristyf1d91242010-05-28 02:23:19 +00001137 local_time.tm_min,local_time.tm_sec,(long) timezone);
cristy3ed852e2009-09-05 21:47:34 +00001138 return(count);
1139}
1140
1141/*
1142%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1143% %
1144% %
1145% %
1146% G e t E n v i r o n m e n t V a l u e %
1147% %
1148% %
1149% %
1150%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1151%
1152% GetEnvironmentValue() returns the environment string that matches the
1153% specified name.
1154%
1155% The format of the GetEnvironmentValue method is:
1156%
1157% char *GetEnvironmentValue(const char *name)
1158%
1159% A description of each parameter follows:
1160%
1161% o name: the environment name.
1162%
1163*/
1164MagickExport char *GetEnvironmentValue(const char *name)
1165{
1166 const char
1167 *environment;
1168
1169 environment=getenv(name);
1170 if (environment == (const char *) NULL)
1171 return((char *) NULL);
1172 return(ConstantString(environment));
1173}
1174
1175/*
1176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177% %
1178% %
1179% %
1180% G e t S t r i n g I n f o D a t u m %
1181% %
1182% %
1183% %
1184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185%
1186% GetStringInfoDatum() returns the datum associated with the string.
1187%
1188% The format of the GetStringInfoDatum method is:
1189%
1190% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1191%
1192% A description of each parameter follows:
1193%
1194% o string_info: the string info.
1195%
1196*/
1197MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1198{
1199 assert(string_info != (StringInfo *) NULL);
1200 assert(string_info->signature == MagickSignature);
1201 return(string_info->datum);
1202}
1203
1204/*
1205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1206% %
1207% %
1208% %
1209% G e t S t r i n g I n f o L e n g t h %
1210% %
1211% %
1212% %
1213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1214%
1215% GetStringInfoLength() returns the string length.
1216%
1217% The format of the GetStringInfoLength method is:
1218%
1219% size_t GetStringInfoLength(const StringInfo *string_info)
1220%
1221% A description of each parameter follows:
1222%
1223% o string_info: the string info.
1224%
1225*/
1226MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1227{
1228 assert(string_info != (StringInfo *) NULL);
1229 assert(string_info->signature == MagickSignature);
1230 return(string_info->length);
1231}
1232
1233/*
1234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1235% %
1236% %
1237% %
1238% G e t S t r i n g I n f o P a t h %
1239% %
1240% %
1241% %
1242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1243%
1244% GetStringInfoPath() returns the path associated with the string.
1245%
1246% The format of the GetStringInfoPath method is:
1247%
1248% const char *GetStringInfoPath(const StringInfo *string_info)
1249%
1250% A description of each parameter follows:
1251%
1252% o string_info: the string info.
1253%
1254*/
1255MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1256{
1257 assert(string_info != (StringInfo *) NULL);
1258 assert(string_info->signature == MagickSignature);
1259 return(string_info->path);
1260}
1261
1262/*
1263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264% %
1265% %
1266% %
1267% L o c a l e C o m p a r e %
1268% %
1269% %
1270% %
1271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272%
1273% LocaleCompare() performs a case-insensitive comparison of two strings
1274% byte-by-byte, according to the ordering of the current locale encoding.
1275% LocaleCompare returns an integer greater than, equal to, or less than 0,
1276% if the string pointed to by p is greater than, equal to, or less than the
1277% string pointed to by q respectively. The sign of a non-zero return value
cristy7a40ba82011-01-08 20:31:18 +00001278% is determined by the sign of the difference between the values of the first
1279% pair of bytes that differ in the strings being compared.
cristy3ed852e2009-09-05 21:47:34 +00001280%
1281% The format of the LocaleCompare method is:
1282%
cristyde58b412010-02-18 03:53:40 +00001283% int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001284%
1285% A description of each parameter follows:
1286%
1287% o p: A pointer to a character string.
1288%
1289% o q: A pointer to a character string to compare to p.
1290%
1291*/
cristyde58b412010-02-18 03:53:40 +00001292MagickExport int LocaleCompare(const char *p,const char *q)
cristy3ed852e2009-09-05 21:47:34 +00001293{
1294 if ((p == (char *) NULL) && (q == (char *) NULL))
1295 return(0);
1296 if (p == (char *) NULL)
1297 return(-1);
1298 if (q == (char *) NULL)
1299 return(1);
1300#if defined(MAGICKCORE_HAVE_STRCASECMP)
cristy27397b22010-02-18 17:30:43 +00001301 return(strcasecmp(p,q));
cristy3ed852e2009-09-05 21:47:34 +00001302#else
1303 {
cristyde58b412010-02-18 03:53:40 +00001304 register int
cristy3ed852e2009-09-05 21:47:34 +00001305 c,
cristya72c2d12010-02-18 01:20:28 +00001306 d;
cristy3ed852e2009-09-05 21:47:34 +00001307
cristya72c2d12010-02-18 01:20:28 +00001308 for ( ; ; )
cristy3ed852e2009-09-05 21:47:34 +00001309 {
cristyde58b412010-02-18 03:53:40 +00001310 c=(int) *((unsigned char *) p);
1311 d=(int) *((unsigned char *) q);
1312 if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
cristy3ed852e2009-09-05 21:47:34 +00001313 break;
cristya72c2d12010-02-18 01:20:28 +00001314 p++;
1315 q++;
cristy3ed852e2009-09-05 21:47:34 +00001316 }
cristyde58b412010-02-18 03:53:40 +00001317 return(AsciiMap[c]-(int) AsciiMap[d]);
cristy3ed852e2009-09-05 21:47:34 +00001318 }
1319#endif
1320}
1321
1322/*
1323%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1324% %
1325% %
1326% %
1327% L o c a l e L o w e r %
1328% %
1329% %
1330% %
1331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332%
1333% LocaleLower() transforms all of the characters in the supplied
1334% null-terminated string, changing all uppercase letters to lowercase.
1335%
1336% The format of the LocaleLower method is:
1337%
1338% void LocaleLower(char *string)
1339%
1340% A description of each parameter follows:
1341%
1342% o string: A pointer to the string to convert to lower-case Locale.
1343%
1344*/
1345MagickExport void LocaleLower(char *string)
1346{
1347 register char
1348 *q;
1349
1350 assert(string != (char *) NULL);
1351 for (q=string; *q != '\0'; q++)
1352 *q=(char) tolower((int) *q);
1353}
1354
1355/*
1356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357% %
1358% %
1359% %
1360% L o c a l e N C o m p a r e %
1361% %
1362% %
1363% %
1364%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1365%
1366% LocaleNCompare() performs a case-insensitive comparison of two
1367% strings byte-by-byte, according to the ordering of the current locale
1368% encoding. LocaleNCompare returns an integer greater than, equal to, or
1369% less than 0, if the string pointed to by p is greater than, equal to, or
1370% less than the string pointed to by q respectively. The sign of a non-zero
1371% return value is determined by the sign of the difference between the
1372% values of the first pair of bytes that differ in the strings being
1373% compared. The LocaleNCompare method makes the same comparison as
1374% LocaleCompare but looks at a maximum of n bytes. Bytes following a
1375% null byte are not compared.
1376%
1377% The format of the LocaleNCompare method is:
1378%
cristyde58b412010-02-18 03:53:40 +00001379% int LocaleNCompare(const char *p,const char *q,const size_t n)
cristy3ed852e2009-09-05 21:47:34 +00001380%
1381% A description of each parameter follows:
1382%
1383% o p: A pointer to a character string.
1384%
1385% o q: A pointer to a character string to compare to p.
1386%
cristy7a40ba82011-01-08 20:31:18 +00001387% o length: the number of characters to compare in strings p and q.
cristy3ed852e2009-09-05 21:47:34 +00001388%
1389*/
cristyde58b412010-02-18 03:53:40 +00001390MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
cristy3ed852e2009-09-05 21:47:34 +00001391{
1392 if (p == (char *) NULL)
1393 return(-1);
1394 if (q == (char *) NULL)
1395 return(1);
1396#if defined(MAGICKCORE_HAVE_STRNCASECMP)
cristy27397b22010-02-18 17:30:43 +00001397 return(strncasecmp(p,q,length));
cristy3ed852e2009-09-05 21:47:34 +00001398#else
1399 {
cristyde58b412010-02-18 03:53:40 +00001400 register int
cristy3ed852e2009-09-05 21:47:34 +00001401 c,
1402 d;
1403
cristyb6af4a52009-10-06 13:56:23 +00001404 register size_t
cristyc4cded12010-02-18 14:40:57 +00001405 i;
cristyb6af4a52009-10-06 13:56:23 +00001406
cristyc4cded12010-02-18 14:40:57 +00001407 for (i=length; i != 0; i--)
cristy3ed852e2009-09-05 21:47:34 +00001408 {
cristyde58b412010-02-18 03:53:40 +00001409 c=(int) *((unsigned char *) p);
1410 d=(int) *((unsigned char *) q);
cristy3ed852e2009-09-05 21:47:34 +00001411 if (AsciiMap[c] != AsciiMap[d])
cristyde58b412010-02-18 03:53:40 +00001412 return(AsciiMap[c]-(int) AsciiMap[d]);
1413 if (c == 0)
1414 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001415 p++;
1416 q++;
1417 }
cristyde58b412010-02-18 03:53:40 +00001418 return(0);
cristy3ed852e2009-09-05 21:47:34 +00001419 }
1420#endif
1421}
1422
1423/*
1424%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1425% %
1426% %
1427% %
1428% L o c a l e U p p e r %
1429% %
1430% %
1431% %
1432%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1433%
1434% LocaleUpper() transforms all of the characters in the supplied
1435% null-terminated string, changing all lowercase letters to uppercase.
1436%
1437% The format of the LocaleUpper method is:
1438%
1439% void LocaleUpper(char *string)
1440%
1441% A description of each parameter follows:
1442%
1443% o string: A pointer to the string to convert to upper-case Locale.
1444%
1445*/
1446MagickExport void LocaleUpper(char *string)
1447{
1448 register char
1449 *q;
1450
1451 assert(string != (char *) NULL);
1452 for (q=string; *q != '\0'; q++)
1453 *q=(char) toupper((int) *q);
1454}
1455
1456/*
1457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1458% %
1459% %
1460% %
1461% P r i n t S t r i n g I n f o %
1462% %
1463% %
1464% %
1465%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1466%
1467% PrintStringInfo() prints the string.
1468%
1469% The format of the PrintStringInfo method is:
1470%
1471% void PrintStringInfo(FILE *file,const char *id,
1472% const StringInfo *string_info)
1473%
1474% A description of each parameter follows:
1475%
1476% o file: the file, typically stdout.
1477%
1478% o id: the string id.
1479%
1480% o string_info: the string info.
1481%
1482*/
1483MagickExport void PrintStringInfo(FILE *file,const char *id,
1484 const StringInfo *string_info)
1485{
1486 register const char
1487 *p;
1488
1489 register size_t
1490 i,
1491 j;
1492
1493 assert(id != (const char *) NULL);
1494 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1495 assert(string_info != (StringInfo *) NULL);
1496 assert(string_info->signature == MagickSignature);
1497 p=(char *) string_info->datum;
1498 for (i=0; i < string_info->length; i++)
1499 {
1500 if (((int) ((unsigned char) *p) < 32) &&
1501 (isspace((int) ((unsigned char) *p)) == 0))
1502 break;
1503 p++;
1504 }
1505 if (i == string_info->length)
1506 {
1507 (void) fputs((char *) string_info->datum,file);
1508 (void) fputc('\n',file);
1509 return;
1510 }
1511 /*
1512 Convert string to a HEX list.
1513 */
1514 p=(char *) string_info->datum;
1515 for (i=0; i < string_info->length; i+=0x14)
1516 {
cristyb51dff52011-05-19 16:55:47 +00001517 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00001518 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1519 {
cristyb51dff52011-05-19 16:55:47 +00001520 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
cristy3ed852e2009-09-05 21:47:34 +00001521 if ((j % 0x04) == 0)
1522 (void) fputc(' ',file);
1523 }
1524 for ( ; j <= 0x14; j++)
1525 {
1526 (void) fputc(' ',file);
1527 (void) fputc(' ',file);
1528 if ((j % 0x04) == 0)
1529 (void) fputc(' ',file);
1530 }
1531 (void) fputc(' ',file);
1532 for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1533 {
1534 if (isprint((int) ((unsigned char) *p)) != 0)
1535 (void) fputc(*p,file);
1536 else
1537 (void) fputc('-',file);
1538 p++;
1539 }
1540 (void) fputc('\n',file);
1541 }
1542}
1543
1544/*
1545%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1546% %
1547% %
1548% %
1549% R e s e t S t r i n g I n f o %
1550% %
1551% %
1552% %
1553%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1554%
1555% ResetStringInfo() reset the string to all null bytes.
1556%
1557% The format of the ResetStringInfo method is:
1558%
1559% void ResetStringInfo(StringInfo *string_info)
1560%
1561% A description of each parameter follows:
1562%
1563% o string_info: the string info.
1564%
1565*/
1566MagickExport void ResetStringInfo(StringInfo *string_info)
1567{
1568 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1569 assert(string_info != (StringInfo *) NULL);
1570 assert(string_info->signature == MagickSignature);
1571 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1572}
1573
1574/*
1575%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1576% %
1577% %
1578% %
1579% S e t S t r i n g I n f o %
1580% %
1581% %
1582% %
1583%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1584%
1585% SetStringInfo() copies the source string to the destination string.
1586%
1587% The format of the SetStringInfo method is:
1588%
1589% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1590%
1591% A description of each parameter follows:
1592%
1593% o string_info: the string info.
1594%
1595% o source: the source string.
1596%
1597*/
1598MagickExport void SetStringInfo(StringInfo *string_info,
1599 const StringInfo *source)
1600{
1601 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1602 assert(string_info != (StringInfo *) NULL);
1603 assert(string_info->signature == MagickSignature);
1604 assert(source != (StringInfo *) NULL);
1605 assert(source->signature == MagickSignature);
1606 if (string_info->length == 0)
1607 return;
1608 (void) ResetMagickMemory(string_info->datum,0,string_info->length);
cristy54aad5e2010-09-03 16:02:04 +00001609 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1610 source->length));
cristy3ed852e2009-09-05 21:47:34 +00001611}
1612
1613/*
1614%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1615% %
1616% %
1617% %
1618% S e t S t r i n g I n f o D a t u m %
1619% %
1620% %
1621% %
1622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1623%
1624% SetStringInfoDatum() copies bytes from the source string for the length of
1625% the destination string.
1626%
1627% The format of the SetStringInfoDatum method is:
1628%
1629% void SetStringInfoDatum(StringInfo *string_info,
1630% const unsigned char *source)
1631%
1632% A description of each parameter follows:
1633%
1634% o string_info: the string info.
1635%
1636% o source: the source string.
1637%
1638*/
1639MagickExport void SetStringInfoDatum(StringInfo *string_info,
1640 const unsigned char *source)
1641{
1642 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1643 assert(string_info != (StringInfo *) NULL);
1644 assert(string_info->signature == MagickSignature);
1645 if (string_info->length != 0)
cristy54aad5e2010-09-03 16:02:04 +00001646 (void) memcpy(string_info->datum,source,string_info->length);
cristy3ed852e2009-09-05 21:47:34 +00001647}
1648
1649/*
1650%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1651% %
1652% %
1653% %
1654% S e t S t r i n g I n f o L e n g t h %
1655% %
1656% %
1657% %
1658%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1659%
1660% SetStringInfoLength() set the string length to the specified value.
1661%
1662% The format of the SetStringInfoLength method is:
1663%
1664% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1665%
1666% A description of each parameter follows:
1667%
1668% o string_info: the string info.
1669%
1670% o length: the string length.
1671%
1672*/
1673MagickExport void SetStringInfoLength(StringInfo *string_info,
1674 const size_t length)
1675{
1676 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1677 assert(string_info != (StringInfo *) NULL);
1678 assert(string_info->signature == MagickSignature);
1679 if (~length < MaxTextExtent)
1680 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1681 string_info->length=length;
1682 if (string_info->datum == (unsigned char *) NULL)
1683 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1684 MaxTextExtent,sizeof(*string_info->datum));
1685 else
1686 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1687 length+MaxTextExtent,sizeof(*string_info->datum));
1688 if (string_info->datum == (unsigned char *) NULL)
1689 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1690}
1691
1692/*
1693%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1694% %
1695% %
1696% %
1697% S e t S t r i n g I n f o D a t u m %
1698% %
1699% %
1700% %
1701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1702%
1703% SetStringInfoPath() sets the path associated with the string.
1704%
1705% The format of the SetStringInfoPath method is:
1706%
1707% void SetStringInfoPath(StringInfo *string_info,const char *path)
1708%
1709% A description of each parameter follows:
1710%
1711% o string_info: the string info.
1712%
1713% o path: the path.
1714%
1715*/
1716MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1717{
1718 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1719 assert(string_info != (StringInfo *) NULL);
1720 assert(string_info->signature == MagickSignature);
1721 assert(path != (const char *) NULL);
1722 (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1723}
1724
1725/*
1726%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1727% %
1728% %
1729% %
1730% S p l i t S t r i n g I n f o %
1731% %
1732% %
1733% %
1734%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1735%
1736% SplitStringInfo() splits a string into two and returns it.
1737%
1738% The format of the SplitStringInfo method is:
1739%
1740% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1741%
1742% A description of each parameter follows:
1743%
1744% o string_info: the string info.
1745%
1746*/
1747MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1748 const size_t offset)
1749{
1750 StringInfo
1751 *split_info;
1752
1753 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1754 assert(string_info != (StringInfo *) NULL);
1755 assert(string_info->signature == MagickSignature);
1756 if (offset > string_info->length)
1757 return((StringInfo *) NULL);
1758 split_info=AcquireStringInfo(offset);
1759 SetStringInfo(split_info,string_info);
cristy1bd862c2011-05-21 13:44:38 +00001760 (void) memmove(string_info->datum,string_info->datum+offset,
cristy3ed852e2009-09-05 21:47:34 +00001761 string_info->length-offset+MaxTextExtent);
1762 SetStringInfoLength(string_info,string_info->length-offset);
1763 return(split_info);
1764}
1765
1766/*
1767%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1768% %
1769% %
1770% %
1771% S t r i n g I n f o T o S t r i n g %
1772% %
1773% %
1774% %
1775%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1776%
1777% StringInfoToString() converts a string info string to a C string.
1778%
1779% The format of the StringInfoToString method is:
1780%
1781% char *StringInfoToString(const StringInfo *string_info)
1782%
1783% A description of each parameter follows:
1784%
1785% o string_info: the string.
1786%
1787*/
1788MagickExport char *StringInfoToString(const StringInfo *string_info)
1789{
1790 char
1791 *string;
1792
1793 size_t
1794 length;
1795
1796 string=(char *) NULL;
1797 length=string_info->length;
cristy37e0b382011-06-07 13:31:21 +00001798 if (~length >= (MaxTextExtent-1))
cristy3ed852e2009-09-05 21:47:34 +00001799 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001800 if (string == (char *) NULL)
1801 return((char *) NULL);
cristy54aad5e2010-09-03 16:02:04 +00001802 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
cristy208cacf2010-09-03 02:24:42 +00001803 string[length]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001804 return(string);
1805}
1806
1807/*
1808%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1809% %
1810% %
1811% %
1812% S t r i n g T o A r g v %
1813% %
1814% %
1815% %
1816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1817%
1818% StringToArgv() converts a text string into command line arguments.
1819%
1820% The format of the StringToArgv method is:
1821%
1822% char **StringToArgv(const char *text,int *argc)
1823%
1824% A description of each parameter follows:
1825%
1826% o argv: Method StringToArgv returns the string list unless an error
1827% occurs, otherwise NULL.
1828%
1829% o text: Specifies the string to segment into a list.
1830%
1831% o argc: This integer pointer returns the number of arguments in the
1832% list.
1833%
1834*/
1835MagickExport char **StringToArgv(const char *text,int *argc)
1836{
1837 char
1838 **argv;
1839
1840 register const char
1841 *p,
1842 *q;
1843
cristybb503372010-05-27 20:51:26 +00001844 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001845 i;
1846
1847 *argc=0;
1848 if (text == (char *) NULL)
1849 return((char **) NULL);
1850 /*
1851 Determine the number of arguments.
1852 */
1853 for (p=text; *p != '\0'; )
1854 {
1855 while (isspace((int) ((unsigned char) *p)) != 0)
1856 p++;
cristya20c9042011-05-19 13:22:18 +00001857 if (*p == '\0')
cristy74895d32011-01-22 21:30:47 +00001858 break;
cristy3ed852e2009-09-05 21:47:34 +00001859 (*argc)++;
1860 if (*p == '"')
1861 for (p++; (*p != '"') && (*p != '\0'); p++) ;
1862 if (*p == '\'')
1863 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
1864 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1865 p++;
1866 }
1867 (*argc)++;
cristy1b26e1f2011-03-25 15:40:56 +00001868 argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
cristy3ed852e2009-09-05 21:47:34 +00001869 if (argv == (char **) NULL)
1870 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
1871 /*
1872 Convert string to an ASCII list.
1873 */
1874 argv[0]=AcquireString("magick");
1875 p=text;
cristybb503372010-05-27 20:51:26 +00001876 for (i=1; i < (ssize_t) *argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00001877 {
1878 while (isspace((int) ((unsigned char) *p)) != 0)
1879 p++;
1880 q=p;
1881 if (*q == '"')
1882 {
1883 p++;
1884 for (q++; (*q != '"') && (*q != '\0'); q++) ;
1885 }
1886 else
1887 if (*q == '\'')
1888 {
cristy06b15f42011-01-22 21:36:24 +00001889 p++;
cristy3ed852e2009-09-05 21:47:34 +00001890 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
cristy3ed852e2009-09-05 21:47:34 +00001891 }
1892 else
1893 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
1894 q++;
1895 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
1896 sizeof(**argv));
1897 if (argv[i] == (char *) NULL)
1898 {
1899 for (i--; i >= 0; i--)
1900 argv[i]=DestroyString(argv[i]);
1901 argv=(char **) RelinquishMagickMemory(argv);
1902 ThrowFatalException(ResourceLimitFatalError,
1903 "UnableToConvertStringToARGV");
1904 }
cristy54aad5e2010-09-03 16:02:04 +00001905 (void) memcpy(argv[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00001906 argv[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00001907 p=q;
1908 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
1909 p++;
1910 }
1911 argv[i]=(char *) NULL;
1912 return(argv);
1913}
1914
1915/*
1916%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1917% %
1918% %
1919% %
cristy3ed852e2009-09-05 21:47:34 +00001920% S t r i n g I n f o T o H e x S t r i n g %
1921% %
1922% %
1923% %
1924%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1925%
1926% StringInfoToHexString() converts a string info string to a C string.
1927%
1928% The format of the StringInfoToHexString method is:
1929%
1930% char *StringInfoToHexString(const StringInfo *string_info)
1931%
1932% A description of each parameter follows:
1933%
1934% o string_info: the string.
1935%
1936*/
1937MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1938{
1939 char
1940 *string;
1941
1942 register const unsigned char
1943 *p;
1944
cristybb503372010-05-27 20:51:26 +00001945 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001946 i;
1947
1948 register unsigned char
1949 *q;
1950
1951 size_t
1952 length;
1953
1954 unsigned char
1955 hex_digits[16];
1956
1957 length=string_info->length;
1958 if (~length < MaxTextExtent)
1959 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1960 string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
1961 if (string == (char *) NULL)
1962 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1963 hex_digits[0]='0';
1964 hex_digits[1]='1';
1965 hex_digits[2]='2';
1966 hex_digits[3]='3';
1967 hex_digits[4]='4';
1968 hex_digits[5]='5';
1969 hex_digits[6]='6';
1970 hex_digits[7]='7';
1971 hex_digits[8]='8';
1972 hex_digits[9]='9';
1973 hex_digits[10]='a';
1974 hex_digits[11]='b';
1975 hex_digits[12]='c';
1976 hex_digits[13]='d';
1977 hex_digits[14]='e';
1978 hex_digits[15]='f';
1979 p=string_info->datum;
1980 q=(unsigned char *) string;
cristybb503372010-05-27 20:51:26 +00001981 for (i=0; i < (ssize_t) string_info->length; i++)
cristy3ed852e2009-09-05 21:47:34 +00001982 {
1983 *q++=hex_digits[(*p >> 4) & 0x0f];
1984 *q++=hex_digits[*p & 0x0f];
1985 p++;
1986 }
1987 *q='\0';
1988 return(string);
1989}
1990
1991/*
1992%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1993% %
1994% %
1995% %
1996% S t r i n g T o k e n %
1997% %
1998% %
1999% %
2000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001%
2002% StringToken() extracts a token a from the string.
2003%
2004% The format of the StringToken method is:
2005%
2006% char *StringToken(const char *delimiters,char **string)
2007%
2008% A description of each parameter follows:
2009%
2010% o delimiters: one or more delimiters.
2011%
2012% o string: return the first token in the string. If none is found, return
2013% NULL.
2014%
2015*/
2016MagickExport char *StringToken(const char *delimiters,char **string)
2017{
2018 char
2019 *q;
2020
2021 register char
2022 *p;
2023
2024 register const char
2025 *r;
2026
2027 register int
2028 c,
2029 d;
2030
2031 p=(*string);
2032 if (p == (char *) NULL)
2033 return((char *) NULL);
2034 for (q=p; ; )
2035 {
2036 c=(*p++);
2037 r=delimiters;
2038 do
2039 {
2040 d=(*r++);
2041 if (c == d)
2042 {
2043 if (c == '\0')
2044 p=(char *) NULL;
2045 else
2046 p[-1]='\0';
2047 *string=p;
2048 return(q);
2049 }
2050 } while (d != '\0');
2051 }
2052}
2053
2054/*
2055%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2056% %
2057% %
2058% %
2059% S t r i n g T o L i s t %
2060% %
2061% %
2062% %
2063%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2064%
2065% StringToList() converts a text string into a list by segmenting the text
2066% string at each carriage return discovered. The list is converted to HEX
2067% characters if any control characters are discovered within the text string.
2068%
2069% The format of the StringToList method is:
2070%
2071% char **StringToList(const char *text)
2072%
2073% A description of each parameter follows:
2074%
cristy3ed852e2009-09-05 21:47:34 +00002075% o text: Specifies the string to segment into a list.
2076%
2077*/
2078MagickExport char **StringToList(const char *text)
2079{
2080 char
2081 **textlist;
2082
2083 register const char
2084 *p;
2085
cristybb503372010-05-27 20:51:26 +00002086 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002087 i;
2088
cristybb503372010-05-27 20:51:26 +00002089 size_t
cristy3ed852e2009-09-05 21:47:34 +00002090 lines;
2091
2092 if (text == (char *) NULL)
2093 return((char **) NULL);
2094 for (p=text; *p != '\0'; p++)
2095 if (((int) ((unsigned char) *p) < 32) &&
2096 (isspace((int) ((unsigned char) *p)) == 0))
2097 break;
2098 if (*p == '\0')
2099 {
2100 register const char
2101 *q;
2102
2103 /*
2104 Convert string to an ASCII list.
2105 */
2106 lines=1;
2107 for (p=text; *p != '\0'; p++)
2108 if (*p == '\n')
2109 lines++;
2110 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2111 sizeof(*textlist));
2112 if (textlist == (char **) NULL)
2113 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2114 p=text;
cristybb503372010-05-27 20:51:26 +00002115 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002116 {
2117 for (q=p; *q != '\0'; q++)
2118 if ((*q == '\r') || (*q == '\n'))
2119 break;
2120 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002121 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002122 if (textlist[i] == (char *) NULL)
2123 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristy54aad5e2010-09-03 16:02:04 +00002124 (void) memcpy(textlist[i],p,(size_t) (q-p));
cristy208cacf2010-09-03 02:24:42 +00002125 textlist[i][q-p]='\0';
cristy3ed852e2009-09-05 21:47:34 +00002126 if (*q == '\r')
2127 q++;
2128 p=q+1;
2129 }
2130 }
2131 else
2132 {
2133 char
2134 hex_string[MaxTextExtent];
2135
2136 register char
2137 *q;
2138
cristybb503372010-05-27 20:51:26 +00002139 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002140 j;
2141
2142 /*
2143 Convert string to a HEX list.
2144 */
cristybb503372010-05-27 20:51:26 +00002145 lines=(size_t) (strlen(text)/0x14)+1;
cristy3ed852e2009-09-05 21:47:34 +00002146 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2147 sizeof(*textlist));
2148 if (textlist == (char **) NULL)
2149 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2150 p=text;
cristybb503372010-05-27 20:51:26 +00002151 for (i=0; i < (ssize_t) lines; i++)
cristy3ed852e2009-09-05 21:47:34 +00002152 {
2153 textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
cristy2e25ee62011-03-25 15:43:12 +00002154 sizeof(**textlist));
cristy3ed852e2009-09-05 21:47:34 +00002155 if (textlist[i] == (char *) NULL)
2156 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
cristyb51dff52011-05-19 16:55:47 +00002157 (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
cristyf1d91242010-05-28 02:23:19 +00002158 (long) (0x14*i));
cristy3ed852e2009-09-05 21:47:34 +00002159 q=textlist[i]+strlen(textlist[i]);
cristybb503372010-05-27 20:51:26 +00002160 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002161 {
cristyb51dff52011-05-19 16:55:47 +00002162 (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
cristy3ed852e2009-09-05 21:47:34 +00002163 (void) CopyMagickString(q,hex_string,MaxTextExtent);
2164 q+=2;
2165 if ((j % 0x04) == 0)
2166 *q++=' ';
2167 }
2168 for ( ; j <= 0x14; j++)
2169 {
2170 *q++=' ';
2171 *q++=' ';
2172 if ((j % 0x04) == 0)
2173 *q++=' ';
2174 }
2175 *q++=' ';
cristybb503372010-05-27 20:51:26 +00002176 for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
cristy3ed852e2009-09-05 21:47:34 +00002177 {
2178 if (isprint((int) ((unsigned char) *p)) != 0)
2179 *q++=(*p);
2180 else
2181 *q++='-';
2182 p++;
2183 }
2184 *q='\0';
2185 }
2186 }
2187 textlist[i]=(char *) NULL;
2188 return(textlist);
2189}
2190
2191/*
2192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2193% %
2194% %
2195% %
2196% S t r i n g T o S t r i n g I n f o %
2197% %
2198% %
2199% %
2200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2201%
cristybca58f32011-08-21 14:48:50 +00002202% StringToStringInfo() converts a string to a StringInfo type.
cristy3ed852e2009-09-05 21:47:34 +00002203%
2204% The format of the StringToStringInfo method is:
2205%
2206% StringInfo *StringToStringInfo(const char *string)
2207%
2208% A description of each parameter follows:
2209%
2210% o string: The string.
2211%
2212*/
2213MagickExport StringInfo *StringToStringInfo(const char *string)
2214{
2215 StringInfo
2216 *string_info;
2217
2218 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2219 assert(string != (const char *) NULL);
cristybca58f32011-08-21 14:48:50 +00002220 string_info=AcquireStringInfo(strlen(string));
cristy3ed852e2009-09-05 21:47:34 +00002221 SetStringInfoDatum(string_info,(const unsigned char *) string);
2222 return(string_info);
2223}
2224
2225/*
2226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2227% %
2228% %
2229% %
2230% S t r i p S t r i n g %
2231% %
2232% %
2233% %
2234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2235%
2236% StripString() strips any whitespace or quotes from the beginning and end of
2237% a string of characters.
2238%
2239% The format of the StripString method is:
2240%
2241% void StripString(char *message)
2242%
2243% A description of each parameter follows:
2244%
2245% o message: Specifies an array of characters.
2246%
2247*/
2248MagickExport void StripString(char *message)
2249{
2250 register char
2251 *p,
2252 *q;
2253
2254 size_t
2255 length;
2256
2257 assert(message != (char *) NULL);
2258 if (*message == '\0')
2259 return;
2260 length=strlen(message);
2261 p=message;
2262 while (isspace((int) ((unsigned char) *p)) != 0)
2263 p++;
2264 if ((*p == '\'') || (*p == '"'))
2265 p++;
2266 q=message+length-1;
2267 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2268 q--;
2269 if (q > p)
2270 if ((*q == '\'') || (*q == '"'))
2271 q--;
cristya63c1ba2011-06-02 20:33:43 +00002272 (void) memmove(message,p,(size_t) (q-p+1));
cristy3ed852e2009-09-05 21:47:34 +00002273 message[q-p+1]='\0';
2274 for (p=message; *p != '\0'; p++)
2275 if (*p == '\n')
2276 *p=' ';
2277}
2278
2279/*
2280%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2281% %
2282% %
2283% %
2284% S u b s t i t u t e S t r i n g %
2285% %
2286% %
2287% %
2288%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2289%
cristyf1b72c12009-10-06 13:25:21 +00002290% SubstituteString() performs string substitution on a string, replacing the
2291% string with the substituted version. Buffer must be allocated from the heap.
cristybc3392a2009-10-06 03:15:57 +00002292% If the string is matched and status, MagickTrue is returned otherwise
2293% MagickFalse.
cristy3ed852e2009-09-05 21:47:34 +00002294%
2295% The format of the SubstituteString method is:
2296%
cristyf1b72c12009-10-06 13:25:21 +00002297% MagickBooleanType SubstituteString(char **string,const char *search,
cristy3ed852e2009-09-05 21:47:34 +00002298% const char *replace)
2299%
2300% A description of each parameter follows:
2301%
cristyf1b72c12009-10-06 13:25:21 +00002302% o string: the string to perform replacements on; replaced with new
cristy3ed852e2009-09-05 21:47:34 +00002303% allocation if a replacement is made.
2304%
cristybc3392a2009-10-06 03:15:57 +00002305% o search: search for this string.
cristy3ed852e2009-09-05 21:47:34 +00002306%
cristybc3392a2009-10-06 03:15:57 +00002307% o replace: replace any matches with this string.
cristy3ed852e2009-09-05 21:47:34 +00002308%
2309*/
cristyf1b72c12009-10-06 13:25:21 +00002310MagickExport MagickBooleanType SubstituteString(char **string,
cristy3ed852e2009-09-05 21:47:34 +00002311 const char *search,const char *replace)
2312{
cristybc3392a2009-10-06 03:15:57 +00002313 MagickBooleanType
2314 status;
cristy3ed852e2009-09-05 21:47:34 +00002315
cristybc3392a2009-10-06 03:15:57 +00002316 register char
2317 *p;
cristy3ed852e2009-09-05 21:47:34 +00002318
cristy3ed852e2009-09-05 21:47:34 +00002319 size_t
cristybc3392a2009-10-06 03:15:57 +00002320 extent,
2321 replace_extent,
2322 search_extent;
cristy3ed852e2009-09-05 21:47:34 +00002323
cristyf1b72c12009-10-06 13:25:21 +00002324 ssize_t
2325 offset;
2326
cristybc3392a2009-10-06 03:15:57 +00002327 status=MagickFalse;
2328 search_extent=0,
2329 replace_extent=0;
cristyf1b72c12009-10-06 13:25:21 +00002330 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
cristy3ed852e2009-09-05 21:47:34 +00002331 {
cristyf1b72c12009-10-06 13:25:21 +00002332 if (search_extent == 0)
2333 search_extent=strlen(search);
2334 if (strncmp(p,search,search_extent) != 0)
cristybc3392a2009-10-06 03:15:57 +00002335 continue;
cristy3ed852e2009-09-05 21:47:34 +00002336 /*
cristybc3392a2009-10-06 03:15:57 +00002337 We found a match.
cristy3ed852e2009-09-05 21:47:34 +00002338 */
cristyf1b72c12009-10-06 13:25:21 +00002339 status=MagickTrue;
cristybc3392a2009-10-06 03:15:57 +00002340 if (replace_extent == 0)
2341 replace_extent=strlen(replace);
2342 if (replace_extent > search_extent)
cristy3ed852e2009-09-05 21:47:34 +00002343 {
cristybc3392a2009-10-06 03:15:57 +00002344 /*
2345 Make room for the replacement string.
2346 */
cristyde58b412010-02-18 03:53:40 +00002347 offset=(ssize_t) (p-(*string));
cristye08c3b82009-10-06 14:58:14 +00002348 extent=strlen(*string)+replace_extent-search_extent+1;
cristyf1b72c12009-10-06 13:25:21 +00002349 *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2350 sizeof(*p));
2351 if (*string == (char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +00002352 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
cristyf1b72c12009-10-06 13:25:21 +00002353 p=(*string)+offset;
cristy3ed852e2009-09-05 21:47:34 +00002354 }
cristy3ed852e2009-09-05 21:47:34 +00002355 /*
cristybc3392a2009-10-06 03:15:57 +00002356 Replace string.
cristy3ed852e2009-09-05 21:47:34 +00002357 */
cristybc3392a2009-10-06 03:15:57 +00002358 if (search_extent != replace_extent)
cristy0a9b3722010-10-23 18:45:49 +00002359 (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2360 strlen(p+search_extent)+1);
2361 (void) CopyMagickMemory(p,replace,replace_extent);
cristyf1b72c12009-10-06 13:25:21 +00002362 p+=replace_extent-1;
cristy3ed852e2009-09-05 21:47:34 +00002363 }
cristybc3392a2009-10-06 03:15:57 +00002364 return(status);
cristy3ed852e2009-09-05 21:47:34 +00002365}