]> granicus.if.org Git - imagemagick/blob - MagickCore/string.c
(no commit message)
[imagemagick] / MagickCore / string.c
1 /*
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 %                                                                             %
20 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
21 %  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 \f
39 /*
40   include declarations.
41 */
42 #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/nt-base-private.h"
52 #include "MagickCore/property.h"
53 #include "MagickCore/resource_.h"
54 #include "MagickCore/signature-private.h"
55 #include "MagickCore/string_.h"
56 #include "MagickCore/string-private.h"
57 #include "MagickCore/utility-private.h"
58 \f
59 /*
60   static declarations.
61 */
62 #if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
63 static const unsigned char
64   asciimap[] =
65   {
66     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
67     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
68     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
69     0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
70     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
71     0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
72     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
73     0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
74     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
75     0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
76     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
77     0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
78     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
79     0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
80     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
81     0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
82     0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
83     0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
84     0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
85     0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
86     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
87     0xfc, 0xfd, 0xfe, 0xff,
88   };
89 #endif
90 \f
91 /*
92 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93 %                                                                             %
94 %                                                                             %
95 %                                                                             %
96 %   A c q u i r e S t r i n g                                                 %
97 %                                                                             %
98 %                                                                             %
99 %                                                                             %
100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101 %
102 %  AcquireString() allocates memory for a string and copies the source string
103 %  to that memory location (and returns it).
104 %
105 %  The returned string shoud be freed using DestoryString() or
106 %  RelinquishMagickMemory() when finished.
107 %
108 %  The format of the AcquireString method is:
109 %
110 %      char *AcquireString(const char *source)
111 %
112 %  A description of each parameter follows:
113 %
114 %    o source: A character string.
115 %
116 */
117 MagickExport char *AcquireString(const char *source)
118 {
119   char
120     *destination;
121
122   size_t
123     length;
124
125   length=0;
126   if (source != (char *) NULL)
127     length+=strlen(source);
128   if (~length < MaxTextExtent)
129     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
130   destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
131     sizeof(*destination));
132   if (destination == (char *) NULL)
133     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
134   *destination='\0';
135   if (source != (char *) NULL)
136     (void) memcpy(destination,source,length*sizeof(*destination));
137   destination[length]='\0';
138   return(destination);
139 }
140 \f
141 /*
142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143 %                                                                             %
144 %                                                                             %
145 %                                                                             %
146 %   A c q u i r e S t r i n g I n f o                                         %
147 %                                                                             %
148 %                                                                             %
149 %                                                                             %
150 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151 %
152 %  AcquireStringInfo() allocates the StringInfo structure.
153 %
154 %  The format of the AcquireStringInfo method is:
155 %
156 %      StringInfo *AcquireStringInfo(const size_t length)
157 %
158 %  A description of each parameter follows:
159 %
160 %    o length: the string length.
161 %
162 */
163 MagickExport StringInfo *AcquireStringInfo(const size_t length)
164 {
165   StringInfo
166     *string_info;
167
168   string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
169   if (string_info == (StringInfo *) NULL)
170     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
171   (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
172   string_info->signature=MagickSignature;
173   string_info->length=length;
174   if (string_info->length != 0)
175     {
176       string_info->datum=(unsigned char *) NULL;
177       if (~string_info->length >= (MaxTextExtent-1))
178         string_info->datum=(unsigned char *) AcquireQuantumMemory(
179           string_info->length+MaxTextExtent,sizeof(*string_info->datum));
180       if (string_info->datum == (unsigned char *) NULL)
181         ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
182     }
183   return(string_info);
184 }
185 \f
186 /*
187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
188 %                                                                             %
189 %                                                                             %
190 %                                                                             %
191 %   B l o b T o S t r i n g I n f o                                           %
192 %                                                                             %
193 %                                                                             %
194 %                                                                             %
195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196 %
197 %  BlobToStringInfo() returns the contents of a blob as a string.
198 %
199 %  The format of the BlobToStringInfo method is:
200 %
201 %      StringInfo *BlobToStringInfo(const void *blob,const size_t length)
202 %
203 %  A description of each parameter follows:
204 %
205 %    o blob: the blob.
206 %
207 %    o length: the length of the blob.
208 %
209 */
210 MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
211 {
212   StringInfo
213     *string_info;
214
215   string_info=AcquireStringInfo(0);
216   string_info->length=length;
217   if (~string_info->length >= (MaxTextExtent-1))
218     string_info->datum=(unsigned char *) AcquireQuantumMemory(
219       string_info->length+MaxTextExtent,sizeof(*string_info->datum));
220   if (string_info->datum == (unsigned char *) NULL)
221     {
222       string_info=DestroyStringInfo(string_info);
223       return((StringInfo *) NULL);
224     }
225   if (blob != (const void *) NULL)
226     (void) memcpy(string_info->datum,blob,length);
227   return(string_info);
228 }
229 \f
230 /*
231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
232 %                                                                             %
233 %                                                                             %
234 %                                                                             %
235 %   C l o n e S t r i n g                                                     %
236 %                                                                             %
237 %                                                                             %
238 %                                                                             %
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 %
241 %  CloneString() allocates memory for the destination string and copies
242 %  the source string to that memory location.
243 %
244 %  If source is a NULL pointer the destination will also be set to a NULL
245 %  point (any existing string is freed).  Otherwise the memory is allocated
246 %  (or resized) and the source string copied into it.
247 %
248 %  A pointer to the copy of the source string, or NULL is returned.
249 %
250 %  The format of the CloneString method is:
251 %
252 %      char *CloneString(char **destination,const char *source)
253 %
254 %  A description of each parameter follows:
255 %
256 %    o destination:  A pointer to a character string.
257 %
258 %    o source: A character string.
259 %
260 */
261 MagickExport char *CloneString(char **destination,const char *source)
262 {
263   size_t
264     length;
265
266   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
267   assert(destination != (char **) NULL);
268   if (source == (const char *) NULL)
269     {
270       if (*destination != (char *) NULL)
271         *destination=DestroyString(*destination);
272       return(*destination);
273     }
274   if (*destination == (char *) NULL)
275     {
276       *destination=AcquireString(source);
277       return(*destination);
278     }
279   length=strlen(source);
280   if (~length < MaxTextExtent)
281     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
282   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
283     sizeof(**destination));
284   if (*destination == (char *) NULL)
285     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
286   if (length != 0)
287     (void) memcpy(*destination,source,length*sizeof(**destination));
288   (*destination)[length]='\0';
289   return(*destination);
290 }
291 \f
292 /*
293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294 %                                                                             %
295 %                                                                             %
296 %                                                                             %
297 %   C l o n e S t r i n g I n f o                                             %
298 %                                                                             %
299 %                                                                             %
300 %                                                                             %
301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302 %
303 %  CloneStringInfo() clones a copy of the StringInfo structure.
304 %
305 %  The format of the CloneStringInfo method is:
306 %
307 %      StringInfo *CloneStringInfo(const StringInfo *string_info)
308 %
309 %  A description of each parameter follows:
310 %
311 %    o string_info: the string info.
312 %
313 */
314 MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
315 {
316   StringInfo
317     *clone_info;
318
319   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
320   assert(string_info != (StringInfo *) NULL);
321   assert(string_info->signature == MagickSignature);
322   clone_info=AcquireStringInfo(string_info->length);
323   if (string_info->length != 0)
324     (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
325   return(clone_info);
326 }
327 \f
328 /*
329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330 %                                                                             %
331 %                                                                             %
332 %                                                                             %
333 %   C o m p a r e S t r i n g I n f o                                         %
334 %                                                                             %
335 %                                                                             %
336 %                                                                             %
337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 %
339 %  CompareStringInfo() compares the two datums target and source.  It returns
340 %  an integer less than, equal to, or greater than zero if target is found,
341 %  respectively, to be less than, to match, or be greater than source.
342 %
343 %  The format of the CompareStringInfo method is:
344 %
345 %      int CompareStringInfo(const StringInfo *target,const StringInfo *source)
346 %
347 %  A description of each parameter follows:
348 %
349 %    o target: the target string.
350 %
351 %    o source: the source string.
352 %
353 */
354
355 static inline size_t MagickMin(const size_t x,const size_t y)
356 {
357   if (x < y)
358     return(x);
359   return(y);
360 }
361
362 MagickExport int CompareStringInfo(const StringInfo *target,
363   const StringInfo *source)
364 {
365   int
366     status;
367
368   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
369   assert(target != (StringInfo *) NULL);
370   assert(target->signature == MagickSignature);
371   assert(source != (StringInfo *) NULL);
372   assert(source->signature == MagickSignature);
373   status=memcmp(target->datum,source->datum,MagickMin(target->length,
374     source->length));
375   if (status != 0)
376     return(status);
377   if (target->length == source->length)
378     return(0);
379   return(target->length < source->length ? -1 : 1);
380 }
381 \f
382 /*
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384 %                                                                             %
385 %                                                                             %
386 %                                                                             %
387 %   C o n c a t e n a t e M a g i c k S t r i n g                             %
388 %                                                                             %
389 %                                                                             %
390 %                                                                             %
391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392 %
393 %  ConcatenateMagickString() concatenates the source string to the destination
394 %  string.  The destination buffer is always null-terminated even if the
395 %  string must be truncated.
396 %
397 %  The format of the ConcatenateMagickString method is:
398 %
399 %      size_t ConcatenateMagickString(char *destination,const char *source,
400 %        const size_t length)
401 %
402 %  A description of each parameter follows:
403 %
404 %    o destination: the destination string.
405 %
406 %    o source: the source string.
407 %
408 %    o length: the length of the destination string.
409 %
410 */
411 MagickExport size_t ConcatenateMagickString(char *destination,
412   const char *source,const size_t length)
413 {
414   register char
415     *q;
416
417   register const char
418     *p;
419
420   register size_t
421     i;
422
423   size_t
424     count;
425
426   assert(destination != (char *) NULL);
427   assert(source != (const char *) NULL);
428   assert(length >= 1);
429   p=source;
430   q=destination;
431   i=length;
432   while ((i-- != 0) && (*q != '\0'))
433     q++;
434   count=(size_t) (q-destination);
435   i=length-count;
436   if (i == 0)
437     return(count+strlen(p));
438   while (*p != '\0')
439   {
440     if (i != 1)
441       {
442         *q++=(*p);
443         i--;
444       }
445     p++;
446   }
447   *q='\0';
448   return(count+(p-source));
449 }
450 \f
451 /*
452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453 %                                                                             %
454 %                                                                             %
455 %                                                                             %
456 %   C o n c a t e n a t e S t r i n g                                         %
457 %                                                                             %
458 %                                                                             %
459 %                                                                             %
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461 %
462 %  ConcatenateString() appends a copy of string source, including the
463 %  terminating null character, to the end of string destination.
464 %
465 %  The format of the ConcatenateString method is:
466 %
467 %      MagickBooleanType ConcatenateString(char **destination,
468 %        const char *source)
469 %
470 %  A description of each parameter follows:
471 %
472 %    o destination:  A pointer to a character string.
473 %
474 %    o source: A character string.
475 %
476 */
477 MagickExport MagickBooleanType ConcatenateString(char **destination,
478   const char *source)
479 {
480   size_t
481     destination_length,
482     length,
483     source_length;
484
485   assert(destination != (char **) NULL);
486   if (source == (const char *) NULL)
487     return(MagickTrue);
488   if (*destination == (char *) NULL)
489     {
490       *destination=AcquireString(source);
491       return(MagickTrue);
492     }
493   destination_length=strlen(*destination);
494   source_length=strlen(source);
495   length=destination_length;
496   if (~length < source_length)
497     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
498   length+=source_length;
499   if (~length < MaxTextExtent)
500     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
501   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
502     sizeof(**destination));
503   if (*destination == (char *) NULL)
504     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
505   if (source_length != 0)
506     (void) memcpy((*destination)+destination_length,source,source_length);
507   (*destination)[length]='\0';
508   return(MagickTrue);
509 }
510 \f
511 /*
512 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
513 %                                                                             %
514 %                                                                             %
515 %                                                                             %
516 %   C o n c a t e n a t e S t r i n g I n f o                                 %
517 %                                                                             %
518 %                                                                             %
519 %                                                                             %
520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
521 %
522 %  ConcatenateStringInfo() concatenates the source string to the destination
523 %  string.
524 %
525 %  The format of the ConcatenateStringInfo method is:
526 %
527 %      void ConcatenateStringInfo(StringInfo *string_info,
528 %        const StringInfo *source)
529 %
530 %  A description of each parameter follows:
531 %
532 %    o string_info: the string info.
533 %
534 %    o source: the source string.
535 %
536 */
537 MagickExport void ConcatenateStringInfo(StringInfo *string_info,
538   const StringInfo *source)
539 {
540   size_t
541     length;
542
543   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
544   assert(string_info != (StringInfo *) NULL);
545   assert(string_info->signature == MagickSignature);
546   assert(source != (const StringInfo *) NULL);
547   length=string_info->length;
548   if (~length < source->length)
549     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
550   SetStringInfoLength(string_info,length+source->length);
551   (void) memcpy(string_info->datum+length,source->datum,source->length);
552 }
553 \f
554 /*
555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556 %                                                                             %
557 %                                                                             %
558 %                                                                             %
559 %   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                         %
560 %                                                                             %
561 %                                                                             %
562 %                                                                             %
563 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564 %
565 %  ConfigureFileToStringInfo() returns the contents of a configure file as a
566 %  string.
567 %
568 %  The format of the ConfigureFileToStringInfo method is:
569 %
570 %      StringInfo *ConfigureFileToStringInfo(const char *filename)
571 %        ExceptionInfo *exception)
572 %
573 %  A description of each parameter follows:
574 %
575 %    o filename: the filename.
576 %
577 */
578 MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
579 {
580   char
581     *string;
582
583   int
584     file;
585
586   MagickOffsetType
587     offset;
588
589   size_t
590     length;
591
592   StringInfo
593     *string_info;
594
595   void
596     *map;
597
598   assert(filename != (const char *) NULL);
599   file=open_utf8(filename,O_RDONLY | O_BINARY,0);
600   if (file == -1)
601     return((StringInfo *) NULL);
602   offset=(MagickOffsetType) lseek(file,0,SEEK_END);
603   if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
604     {
605       file=close(file)-1;
606       return((StringInfo *) NULL);
607     }
608   length=(size_t) offset;
609   string=(char *) NULL;
610   if (~length >= (MaxTextExtent-1))
611     string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
612   if (string == (char *) NULL)
613     {
614       file=close(file)-1;
615       return((StringInfo *) NULL);
616     }
617   map=MapBlob(file,ReadMode,0,length);
618   if (map != (void *) NULL)
619     {
620       (void) memcpy(string,map,length);
621       (void) UnmapBlob(map,length);
622     }
623   else
624     {
625       register size_t
626         i;
627
628       ssize_t
629         count;
630
631       (void) lseek(file,0,SEEK_SET);
632       for (i=0; i < length; i+=count)
633       {
634         count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
635           SSIZE_MAX));
636         if (count <= 0)
637           {
638             count=0;
639             if (errno != EINTR)
640               break;
641           }
642       }
643       if (i < length)
644         {
645           file=close(file)-1;
646           string=DestroyString(string);
647           return((StringInfo *) NULL);
648         }
649     }
650   string[length]='\0';
651   file=close(file)-1;
652   string_info=AcquireStringInfo(0);
653   (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
654   string_info->length=length;
655   string_info->datum=(unsigned char *) string;
656   return(string_info);
657 }
658 \f
659 /*
660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
661 %                                                                             %
662 %                                                                             %
663 %                                                                             %
664 %   C o n s t a n t S t r i n g                                               %
665 %                                                                             %
666 %                                                                             %
667 %                                                                             %
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
669 %
670 %  ConstantString() allocates memory for a string and copies the source string
671 %  to that memory location (and returns it).  Use it for strings that you do
672 %  do not expect to change over its lifetime.
673 %
674 %  The format of the ConstantString method is:
675 %
676 %      char *ConstantString(const char *source)
677 %
678 %  A description of each parameter follows:
679 %
680 %    o source: A character string.
681 %
682 */
683 MagickExport char *ConstantString(const char *source)
684 {
685   char
686     *destination;
687
688   size_t
689     length;
690
691   length=0;
692   if (source != (char *) NULL)
693     length+=strlen(source);
694   destination=(char *) NULL;
695   if (~length >= 1UL)
696     destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
697   if (destination == (char *) NULL)
698     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
699   *destination='\0';
700   if (source != (char *) NULL)
701     (void) memcpy(destination,source,length*sizeof(*destination));
702   destination[length]='\0';
703   return(destination);
704 }
705 \f
706 /*
707 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708 %                                                                             %
709 %                                                                             %
710 %                                                                             %
711 %   C o p y M a g i c k S t r i n g                                           %
712 %                                                                             %
713 %                                                                             %
714 %                                                                             %
715 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 %
717 %  CopyMagickString() copies the source string to the destination string.  The
718 %  destination buffer is always null-terminated even if the string must be
719 %  truncated.  The return value is the minimum of the source string length
720 %  or the length parameter.
721 %
722 %  The format of the CopyMagickString method is:
723 %
724 %      size_t CopyMagickString(const char *destination,char *source,
725 %        const size_t length)
726 %
727 %  A description of each parameter follows:
728 %
729 %    o destination: the destination string.
730 %
731 %    o source: the source string.
732 %
733 %    o length: the length of the destination string.
734 %
735 */
736 MagickExport size_t CopyMagickString(char *destination,const char *source,
737   const size_t length)
738 {
739   register char
740     *q;
741
742   register const char
743     *p;
744
745   register size_t
746     n;
747
748   if (source == (const char *) NULL)
749     return(0);
750   p=source;
751   q=destination;
752   for (n=length; n > 4; n-=4)
753   {
754     *q=(*p++);
755     if (*q == '\0')
756       return((size_t) (p-source-1));
757     q++;
758     *q=(*p++);
759     if (*q == '\0')
760       return((size_t) (p-source-1));
761     q++;
762     *q=(*p++);
763     if (*q == '\0')
764       return((size_t) (p-source-1));
765     q++;
766     *q=(*p++);
767     if (*q == '\0')
768       return((size_t) (p-source-1));
769     q++;
770   }
771   if (n != 0)
772     for (n--; n != 0; n--)
773     {
774       *q=(*p++);
775       if (*q == '\0')
776         return((size_t) (p-source-1));
777       q++;
778     }
779   if (length != 0)
780     *q='\0';
781   return((size_t) (p-source-1));
782 }
783 \f
784 /*
785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
786 %                                                                             %
787 %                                                                             %
788 %                                                                             %
789 %   D e s t r o y S t r i n g                                                 %
790 %                                                                             %
791 %                                                                             %
792 %                                                                             %
793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
794 %
795 %  DestroyString() destroys memory associated with a string.
796 %
797 %  The format of the DestroyString method is:
798 %
799 %      char *DestroyString(char *string)
800 %
801 %  A description of each parameter follows:
802 %
803 %    o string: the string.
804 %
805 */
806 MagickExport char *DestroyString(char *string)
807 {
808   return((char *) RelinquishMagickMemory(string));
809 }
810 \f
811 /*
812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
813 %                                                                             %
814 %                                                                             %
815 %                                                                             %
816 %   D e s t r o y S t r i n g I n f o                                         %
817 %                                                                             %
818 %                                                                             %
819 %                                                                             %
820 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
821 %
822 %  DestroyStringInfo() destroys memory associated with the StringInfo structure.
823 %
824 %  The format of the DestroyStringInfo method is:
825 %
826 %      StringInfo *DestroyStringInfo(StringInfo *string_info)
827 %
828 %  A description of each parameter follows:
829 %
830 %    o string_info: the string info.
831 %
832 */
833 MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
834 {
835   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
836   assert(string_info != (StringInfo *) NULL);
837   assert(string_info->signature == MagickSignature);
838   if (string_info->datum != (unsigned char *) NULL)
839     string_info->datum=(unsigned char *) RelinquishMagickMemory(
840       string_info->datum);
841   string_info->signature=(~MagickSignature);
842   string_info=(StringInfo *) RelinquishMagickMemory(string_info);
843   return(string_info);
844 }
845 \f
846 /*
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 %                                                                             %
849 %                                                                             %
850 %                                                                             %
851 %   D e s t r o y S t r i n g L i s t                                         %
852 %                                                                             %
853 %                                                                             %
854 %                                                                             %
855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 %
857 %  DestroyStringList() zeros memory associated with a string list.
858 %
859 %  The format of the DestroyStringList method is:
860 %
861 %      char **DestroyStringList(char **list)
862 %
863 %  A description of each parameter follows:
864 %
865 %    o list: the string list.
866 %
867 */
868 MagickExport char **DestroyStringList(char **list)
869 {
870   register ssize_t
871     i;
872
873   assert(list != (char **) NULL);
874   for (i=0; list[i] != (char *) NULL; i++)
875     list[i]=DestroyString(list[i]);
876   list=(char **) RelinquishMagickMemory(list);
877   return(list);
878 }
879 \f
880 /*
881 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
882 %                                                                             %
883 %                                                                             %
884 %                                                                             %
885 %   E s c a p e S t r i n g                                                   %
886 %                                                                             %
887 %                                                                             %
888 %                                                                             %
889 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
890 %
891 %  EscapeString() allocates memory for a backslash-escaped version of a
892 %  source text string, copies the escaped version of the text to that
893 %  memory location while adding backslash characters, and returns the
894 %  escaped string.
895 %
896 %  The format of the EscapeString method is:
897 %
898 %      char *EscapeString(const char *source,const char escape)
899 %
900 %  A description of each parameter follows:
901 %
902 %    o allocate_string:  Method EscapeString returns the escaped string.
903 %
904 %    o source: A character string.
905 %
906 %    o escape: the quoted string termination character to escape (e.g. '"').
907 %
908 */
909 MagickExport char *EscapeString(const char *source,const char escape)
910 {
911   char
912     *destination;
913
914   register char
915     *q;
916
917   register const char
918     *p;
919
920   size_t
921     length;
922
923   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
924   assert(source != (const char *) NULL);
925   length=strlen(source);
926   for (p=source; *p != '\0'; p++)
927     if ((*p == '\\') || (*p == escape))
928       {
929         if (~length < 1)
930           ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
931         length++;
932       }
933   destination=(char *) NULL;
934   if (~length >= (MaxTextExtent-1))
935     destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
936       sizeof(*destination));
937   if (destination == (char *) NULL)
938     ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
939   *destination='\0';
940   if (source != (char *) NULL)
941     {
942       q=destination;
943       for (p=source; *p != '\0'; p++)
944       {
945         if ((*p == '\\') || (*p == escape))
946           *q++='\\';
947         *q++=(*p);
948       }
949       *q='\0';
950     }
951   return(destination);
952 }
953 \f
954 /*
955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956 %                                                                             %
957 %                                                                             %
958 %                                                                             %
959 %   F i l e T o S t r i n g                                                   %
960 %                                                                             %
961 %                                                                             %
962 %                                                                             %
963 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964 %
965 %  FileToString() returns the contents of a file as a string.
966 %
967 %  The format of the FileToString method is:
968 %
969 %      char *FileToString(const char *filename,const size_t extent,
970 %        ExceptionInfo *exception)
971 %
972 %  A description of each parameter follows:
973 %
974 %    o filename: the filename.
975 %
976 %    o extent: Maximum length of the string.
977 %
978 %    o exception: return any errors or warnings in this structure.
979 %
980 */
981 MagickExport char *FileToString(const char *filename,const size_t extent,
982   ExceptionInfo *exception)
983 {
984   size_t
985     length;
986
987   assert(filename != (const char *) NULL);
988   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
989   assert(exception != (ExceptionInfo *) NULL);
990   return((char *) FileToBlob(filename,extent,&length,exception));
991 }
992 \f
993 /*
994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 %                                                                             %
996 %                                                                             %
997 %                                                                             %
998 %   F i l e T o S t r i n g I n f o                                           %
999 %                                                                             %
1000 %                                                                             %
1001 %                                                                             %
1002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1003 %
1004 %  FileToStringInfo() returns the contents of a file as a string.
1005 %
1006 %  The format of the FileToStringInfo method is:
1007 %
1008 %      StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1009 %        ExceptionInfo *exception)
1010 %
1011 %  A description of each parameter follows:
1012 %
1013 %    o filename: the filename.
1014 %
1015 %    o extent: Maximum length of the string.
1016 %
1017 %    o exception: return any errors or warnings in this structure.
1018 %
1019 */
1020 MagickExport StringInfo *FileToStringInfo(const char *filename,
1021   const size_t extent,ExceptionInfo *exception)
1022 {
1023   StringInfo
1024     *string_info;
1025
1026   assert(filename != (const char *) NULL);
1027   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1028   assert(exception != (ExceptionInfo *) NULL);
1029   string_info=AcquireStringInfo(0);
1030   (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
1031   string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
1032   if (string_info->datum == (unsigned char *) NULL)
1033     {
1034       string_info=DestroyStringInfo(string_info);
1035       return((StringInfo *) NULL);
1036     }
1037   return(string_info);
1038 }
1039 \f
1040 /*
1041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042 %                                                                             %
1043 %                                                                             %
1044 %                                                                             %
1045 %  F o r m a t M a g i c k S i z e                                            %
1046 %                                                                             %
1047 %                                                                             %
1048 %                                                                             %
1049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050 %
1051 %  FormatMagickSize() converts a size to a human readable format, for example,
1052 %  14k, 234m, 2.7g, or 3.0t.  Scaling is done by repetitively dividing by
1053 %  1000.
1054 %
1055 %  The format of the FormatMagickSize method is:
1056 %
1057 %      ssize_t FormatMagickSize(const MagickSizeType size,char *format)
1058 %
1059 %  A description of each parameter follows:
1060 %
1061 %    o size:  convert this size to a human readable format.
1062 %
1063 %    o bi:  use power of two rather than power of ten.
1064 %
1065 %    o format:  human readable format.
1066 %
1067 */
1068 MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
1069   const MagickBooleanType bi,char *format)
1070 {
1071   const char
1072     **units;
1073
1074   double
1075     bytes,
1076     length;
1077
1078   register ssize_t
1079     i,
1080     j;
1081
1082   ssize_t
1083     count;
1084
1085   static const char
1086     *bi_units[] =
1087     {
1088       "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
1089     },
1090     *traditional_units[] =
1091     {
1092       "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
1093     };
1094
1095   bytes=1000.0;
1096   units=traditional_units;
1097   if (bi != MagickFalse)
1098     {
1099       bytes=1024.0;
1100       units=bi_units;
1101     }
1102 #if defined(_MSC_VER) && (_MSC_VER == 1200)
1103   length=(double) ((MagickOffsetType) size);
1104 #else
1105   length=(double) size;
1106 #endif
1107   for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
1108     length/=bytes;
1109   for (j=2; j < 12; j++)
1110   {
1111     count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
1112       units[i]);
1113     if (strchr(format,'+') == (char *) NULL)
1114       break;
1115   }
1116   return(count);
1117 }
1118 \f
1119 /*
1120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121 %                                                                             %
1122 %                                                                             %
1123 %                                                                             %
1124 %  F o r m a t M a g i c k T i m e                                            %
1125 %                                                                             %
1126 %                                                                             %
1127 %                                                                             %
1128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1129 %
1130 %  FormatMagickTime() returns the specified time in the Internet date/time
1131 %  format and the length of the timestamp.
1132 %
1133 %  The format of the FormatMagickTime method is:
1134 %
1135 %      ssize_t FormatMagickTime(const time_t time,const size_t length,
1136 %        char *timestamp)
1137 %
1138 %  A description of each parameter follows.
1139 %
1140 %   o time:  the time since the Epoch (00:00:00 UTC, January 1, 1970),
1141 %     measured in seconds.
1142 %
1143 %   o length: the maximum length of the string.
1144 %
1145 %   o timestamp:  Return the Internet date/time here.
1146 %
1147 */
1148 MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
1149   char *timestamp)
1150 {
1151   ssize_t
1152     count;
1153
1154   struct tm
1155     gm_time,
1156     local_time;
1157
1158   time_t
1159     timezone;
1160
1161   assert(timestamp != (char *) NULL);
1162   (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
1163   (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
1164 #if defined(MAGICKCORE_HAVE_LOCALTIME_R)
1165   (void) localtime_r(&time,&local_time);
1166 #else
1167   {
1168     struct tm
1169       *my_time;
1170
1171     my_time=localtime(&time);
1172     if (my_time != (struct tm *) NULL)
1173       (void) memcpy(&local_time,my_time,sizeof(local_time));
1174   }
1175 #endif
1176 #if defined(MAGICKCORE_HAVE_GMTIME_R)
1177   (void) gmtime_r(&time,&gm_time);
1178 #else
1179   {
1180     struct tm
1181       *my_time;
1182
1183     my_time=gmtime(&time);
1184     if (my_time != (struct tm *) NULL)
1185       (void) memcpy(&gm_time,my_time,sizeof(gm_time));
1186   }
1187 #endif
1188   timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
1189     local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
1190     gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
1191     (local_time.tm_yday-gm_time.tm_yday)));
1192   count=FormatLocaleString(timestamp,length,
1193     "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
1194     local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
1195     local_time.tm_min,local_time.tm_sec,(long) timezone);
1196   return(count);
1197 }
1198 \f
1199 /*
1200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1201 %                                                                             %
1202 %                                                                             %
1203 %                                                                             %
1204 %   G e t E n v i r o n m e n t V a l u e                                     %
1205 %                                                                             %
1206 %                                                                             %
1207 %                                                                             %
1208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1209 %
1210 %  GetEnvironmentValue() returns the environment string that matches the
1211 %  specified name.
1212 %
1213 %  The format of the GetEnvironmentValue method is:
1214 %
1215 %      char *GetEnvironmentValue(const char *name)
1216 %
1217 %  A description of each parameter follows:
1218 %
1219 %    o name: the environment name.
1220 %
1221 */
1222 MagickExport char *GetEnvironmentValue(const char *name)
1223 {
1224   const char
1225     *environment;
1226
1227   environment=getenv(name);
1228   if (environment == (const char *) NULL)
1229     return((char *) NULL);
1230   return(ConstantString(environment));
1231 }
1232 \f
1233 /*
1234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1235 %                                                                             %
1236 %                                                                             %
1237 %                                                                             %
1238 %   G e t S t r i n g I n f o D a t u m                                       %
1239 %                                                                             %
1240 %                                                                             %
1241 %                                                                             %
1242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1243 %
1244 %  GetStringInfoDatum() returns the datum associated with the string.
1245 %
1246 %  The format of the GetStringInfoDatum method is:
1247 %
1248 %      unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1249 %
1250 %  A description of each parameter follows:
1251 %
1252 %    o string_info: the string info.
1253 %
1254 */
1255 MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1256 {
1257   assert(string_info != (StringInfo *) NULL);
1258   assert(string_info->signature == MagickSignature);
1259   return(string_info->datum);
1260 }
1261 \f
1262 /*
1263 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264 %                                                                             %
1265 %                                                                             %
1266 %                                                                             %
1267 %   G e t S t r i n g I n f o L e n g t h                                     %
1268 %                                                                             %
1269 %                                                                             %
1270 %                                                                             %
1271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272 %
1273 %  GetStringInfoLength() returns the string length.
1274 %
1275 %  The format of the GetStringInfoLength method is:
1276 %
1277 %      size_t GetStringInfoLength(const StringInfo *string_info)
1278 %
1279 %  A description of each parameter follows:
1280 %
1281 %    o string_info: the string info.
1282 %
1283 */
1284 MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1285 {
1286   assert(string_info != (StringInfo *) NULL);
1287   assert(string_info->signature == MagickSignature);
1288   return(string_info->length);
1289 }
1290 \f
1291 /*
1292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293 %                                                                             %
1294 %                                                                             %
1295 %                                                                             %
1296 %   G e t S t r i n g I n f o P a t h                                         %
1297 %                                                                             %
1298 %                                                                             %
1299 %                                                                             %
1300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301 %
1302 %  GetStringInfoPath() returns the path associated with the string.
1303 %
1304 %  The format of the GetStringInfoPath method is:
1305 %
1306 %      const char *GetStringInfoPath(const StringInfo *string_info)
1307 %
1308 %  A description of each parameter follows:
1309 %
1310 %    o string_info: the string info.
1311 %
1312 */
1313 MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1314 {
1315   assert(string_info != (StringInfo *) NULL);
1316   assert(string_info->signature == MagickSignature);
1317   return(string_info->path);
1318 }
1319 \f
1320 /*
1321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1322 %                                                                             %
1323 %                                                                             %
1324 %                                                                             %
1325 +   I n t e r p r e t S i P r e f i x V a l u e                               %
1326 %                                                                             %
1327 %                                                                             %
1328 %                                                                             %
1329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1330 %
1331 %  InterpretSiPrefixValue() converts the initial portion of the string to a
1332 %  double representation.  It also recognizes SI prefixes (e.g. B, KB, MiB,
1333 %  etc.).
1334 %
1335 %  The format of the InterpretSiPrefixValue method is:
1336 %
1337 %      double InterpretSiPrefixValue(const char *value,char **sentinal)
1338 %
1339 %  A description of each parameter follows:
1340 %
1341 %    o value: the string value.
1342 %
1343 %    o sentinal:  if sentinal is not NULL, return a pointer to the character
1344 %      after the last character used in the conversion.
1345 %
1346 */
1347 MagickExport double InterpretSiPrefixValue(const char *restrict string,
1348   char **restrict sentinal)
1349 {
1350   char
1351     *q;
1352
1353   double
1354     value;
1355
1356   value=InterpretLocaleValue(string,&q);
1357   if (q != string)
1358     {
1359       if ((*q >= 'E') && (*q <= 'z'))
1360         {
1361           double
1362             e;
1363
1364           switch ((int) ((unsigned char) *q))
1365           {
1366             case 'y': e=(-24.0); break;
1367             case 'z': e=(-21.0); break;
1368             case 'a': e=(-18.0); break;
1369             case 'f': e=(-15.0); break;
1370             case 'p': e=(-12.0); break;
1371             case 'n': e=(-9.0); break;
1372             case 'u': e=(-6.0); break;
1373             case 'm': e=(-3.0); break;
1374             case 'c': e=(-2.0); break;
1375             case 'd': e=(-1.0); break;
1376             case 'h': e=2.0; break;
1377             case 'k': e=3.0; break;
1378             case 'K': e=3.0; break;
1379             case 'M': e=6.0; break;
1380             case 'G': e=9.0; break;
1381             case 'T': e=12.0; break;
1382             case 'P': e=15.0; break;
1383             case 'E': e=18.0; break;
1384             case 'Z': e=21.0; break;
1385             case 'Y': e=24.0; break;
1386             default: e=0.0; break;
1387           }
1388           if (e >= MagickEpsilon)
1389             {
1390               if (q[1] == 'i')
1391                 {
1392                   value*=pow(2.0,e/0.3);
1393                   q+=2;
1394                 }
1395               else
1396                 {
1397                   value*=pow(10.0,e);
1398                   q++;
1399                 }
1400             }
1401         }
1402       if (*q == 'B')
1403         q++;
1404     }
1405   if (sentinal != (char **) NULL)
1406     *sentinal=q;
1407   return(value);
1408 }
1409 \f
1410 /*
1411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1412 %                                                                             %
1413 %                                                                             %
1414 %                                                                             %
1415 %   I s S t r i n g T r u e                                                   %
1416 %                                                                             %
1417 %                                                                             %
1418 %                                                                             %
1419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1420 %
1421 %  IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1422 %  "1". Any other string or undefined returns MagickFalse.
1423 %
1424 %  Typically this is used to look at strings (options or artifacts) which
1425 %  has a default value of "false", when not defined.
1426 %
1427 %  The format of the IsStringTrue method is:
1428 %
1429 %      MagickBooleanType IsStringTrue(const char *value)
1430 %
1431 %  A description of each parameter follows:
1432 %
1433 %    o value: Specifies a pointer to a character array.
1434 %
1435 */
1436 MagickExport MagickBooleanType IsStringTrue(const char *value)
1437 {
1438   if (value == (const char *) NULL)
1439     return(MagickFalse);
1440   if (LocaleCompare(value,"true") == 0)
1441     return(MagickTrue);
1442   if (LocaleCompare(value,"on") == 0)
1443     return(MagickTrue);
1444   if (LocaleCompare(value,"yes") == 0)
1445     return(MagickTrue);
1446   if (LocaleCompare(value,"1") == 0)
1447     return(MagickTrue);
1448   return(MagickFalse);
1449 }
1450 \f
1451 /*
1452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453 %                                                                             %
1454 %                                                                             %
1455 %                                                                             %
1456 %   I s S t r i n g N o t F a l s e                                           %
1457 %                                                                             %
1458 %                                                                             %
1459 %                                                                             %
1460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1461 %
1462 %  IsStringNotFalse() returns MagickTrue, unless the string specifically
1463 %  has a value that makes this false.  that is if it has a value of
1464 %  "false", "off", "no" or "0".
1465 %
1466 %  Typically this is used to look at strings (options or artifacts) which
1467 %  has a default value of "true", when it has not been defined.
1468 %
1469 %  The format of the IsStringNotFalse method is:
1470 %
1471 %      MagickBooleanType IsStringNotFalse(const char *value)
1472 %
1473 %  A description of each parameter follows:
1474 %
1475 %    o value: Specifies a pointer to a character array.
1476 %
1477 */
1478 MagickExport MagickBooleanType IsStringNotFalse(const char *value)
1479 {
1480   if (value == (const char *) NULL)
1481     return(MagickTrue);
1482   if (LocaleCompare(value,"false") == 0)
1483     return(MagickFalse);
1484   if (LocaleCompare(value,"off") == 0)
1485     return(MagickFalse);
1486   if (LocaleCompare(value,"no") == 0)
1487     return(MagickFalse);
1488   if (LocaleCompare(value,"0") == 0)
1489     return(MagickFalse);
1490   return(MagickTrue);
1491 }
1492 \f
1493 /*
1494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1495 %                                                                             %
1496 %                                                                             %
1497 %                                                                             %
1498 %   L o c a l e C o m p a r e                                                 %
1499 %                                                                             %
1500 %                                                                             %
1501 %                                                                             %
1502 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1503 %
1504 %  LocaleCompare() performs a case-insensitive comparison of two strings
1505 %  byte-by-byte, according to the ordering of the current locale encoding.
1506 %  LocaleCompare returns an integer greater than, equal to, or less than 0,
1507 %  if the string pointed to by p is greater than, equal to, or less than the
1508 %  string pointed to by q respectively.  The sign of a non-zero return value
1509 %  is determined by the sign of the difference between the values of the first
1510 %  pair of bytes that differ in the strings being compared.
1511 %
1512 %  The format of the LocaleCompare method is:
1513 %
1514 %      int LocaleCompare(const char *p,const char *q)
1515 %
1516 %  A description of each parameter follows:
1517 %
1518 %    o p: A pointer to a character string.
1519 %
1520 %    o q: A pointer to a character string to compare to p.
1521 %
1522 */
1523 MagickExport int LocaleCompare(const char *p,const char *q)
1524 {
1525   if ((p == (char *) NULL) && (q == (char *) NULL))
1526     return(0);
1527   if (p == (char *) NULL)
1528     return(-1);
1529   if (q == (char *) NULL)
1530     return(1);
1531 #if defined(MAGICKCORE_HAVE_STRCASECMP)
1532   return(strcasecmp(p,q));
1533 #else
1534   {
1535     register int
1536       c,
1537       d;
1538
1539     for ( ; ; )
1540     {
1541       c=(int) *((unsigned char *) p);
1542       d=(int) *((unsigned char *) q);
1543       if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
1544         break;
1545       p++;
1546       q++;
1547     }
1548     return(AsciiMap[c]-(int) AsciiMap[d]);
1549   }
1550 #endif
1551 }
1552 \f
1553 /*
1554 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1555 %                                                                             %
1556 %                                                                             %
1557 %                                                                             %
1558 %   L o c a l e L o w e r                                                     %
1559 %                                                                             %
1560 %                                                                             %
1561 %                                                                             %
1562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1563 %
1564 %  LocaleLower() transforms all of the characters in the supplied
1565 %  null-terminated string, changing all uppercase letters to lowercase.
1566 %
1567 %  The format of the LocaleLower method is:
1568 %
1569 %      void LocaleLower(char *string)
1570 %
1571 %  A description of each parameter follows:
1572 %
1573 %    o string: A pointer to the string to convert to lower-case Locale.
1574 %
1575 */
1576 MagickExport void LocaleLower(char *string)
1577 {
1578   register char
1579     *q;
1580
1581   assert(string != (char *) NULL);
1582   for (q=string; *q != '\0'; q++)
1583     *q=(char) tolower((int) *q);
1584 }
1585 \f
1586 /*
1587 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1588 %                                                                             %
1589 %                                                                             %
1590 %                                                                             %
1591 %   L o c a l e N C o m p a r e                                               %
1592 %                                                                             %
1593 %                                                                             %
1594 %                                                                             %
1595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1596 %
1597 %  LocaleNCompare() performs a case-insensitive comparison of two
1598 %  strings byte-by-byte, according to the ordering of the current locale
1599 %  encoding. LocaleNCompare returns an integer greater than, equal to, or
1600 %  less than 0, if the string pointed to by p is greater than, equal to, or
1601 %  less than the string pointed to by q respectively.  The sign of a non-zero
1602 %  return value is determined by the sign of the difference between the
1603 %  values of the first pair of bytes that differ in the strings being
1604 %  compared.  The LocaleNCompare method makes the same comparison as
1605 %  LocaleCompare but looks at a maximum of n bytes.  Bytes following a
1606 %  null byte are not compared.
1607 %
1608 %  The format of the LocaleNCompare method is:
1609 %
1610 %      int LocaleNCompare(const char *p,const char *q,const size_t n)
1611 %
1612 %  A description of each parameter follows:
1613 %
1614 %    o p: A pointer to a character string.
1615 %
1616 %    o q: A pointer to a character string to compare to p.
1617 %
1618 %    o length: the number of characters to compare in strings p and q.
1619 %
1620 */
1621 MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
1622 {
1623   if ((p == (char *) NULL) && (q == (char *) NULL))
1624     return(0);
1625   if (p == (char *) NULL)
1626     return(-1);
1627   if (q == (char *) NULL)
1628     return(1);
1629 #if defined(MAGICKCORE_HAVE_STRNCASECMP)
1630   return(strncasecmp(p,q,length));
1631 #else
1632   {
1633     register int
1634       c,
1635       d;
1636
1637     register size_t
1638       i;
1639
1640     for (i=length; i != 0; i--)
1641     {
1642       c=(int) *((unsigned char *) p);
1643       d=(int) *((unsigned char *) q);
1644       if (AsciiMap[c] != AsciiMap[d])
1645         return(AsciiMap[c]-(int) AsciiMap[d]);
1646       if (c == 0)
1647         return(0);
1648       p++;
1649       q++;
1650     }
1651     return(0);
1652   }
1653 #endif
1654 }
1655 \f
1656 /*
1657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1658 %                                                                             %
1659 %                                                                             %
1660 %                                                                             %
1661 %   L o c a l e U p p e r                                                     %
1662 %                                                                             %
1663 %                                                                             %
1664 %                                                                             %
1665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1666 %
1667 %  LocaleUpper() transforms all of the characters in the supplied
1668 %  null-terminated string, changing all lowercase letters to uppercase.
1669 %
1670 %  The format of the LocaleUpper method is:
1671 %
1672 %      void LocaleUpper(char *string)
1673 %
1674 %  A description of each parameter follows:
1675 %
1676 %    o string: A pointer to the string to convert to upper-case Locale.
1677 %
1678 */
1679 MagickExport void LocaleUpper(char *string)
1680 {
1681   register char
1682     *q;
1683
1684   assert(string != (char *) NULL);
1685   for (q=string; *q != '\0'; q++)
1686     *q=(char) toupper((int) *q);
1687 }
1688 \f
1689 /*
1690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1691 %                                                                             %
1692 %                                                                             %
1693 %                                                                             %
1694 %   P r i n t S t r i n g I n f o                                             %
1695 %                                                                             %
1696 %                                                                             %
1697 %                                                                             %
1698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1699 %
1700 %  PrintStringInfo() prints the string.
1701 %
1702 %  The format of the PrintStringInfo method is:
1703 %
1704 %      void PrintStringInfo(FILE *file,const char *id,
1705 %        const StringInfo *string_info)
1706 %
1707 %  A description of each parameter follows:
1708 %
1709 %    o file: the file, typically stdout.
1710 %
1711 %    o id: the string id.
1712 %
1713 %    o string_info: the string info.
1714 %
1715 */
1716 MagickExport void PrintStringInfo(FILE *file,const char *id,
1717   const StringInfo *string_info)
1718 {
1719   register const char
1720     *p;
1721
1722   register size_t
1723     i,
1724     j;
1725
1726   assert(id != (const char *) NULL);
1727   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
1728   assert(string_info != (StringInfo *) NULL);
1729   assert(string_info->signature == MagickSignature);
1730   p=(char *) string_info->datum;
1731   for (i=0; i < string_info->length; i++)
1732   {
1733     if (((int) ((unsigned char) *p) < 32) &&
1734         (isspace((int) ((unsigned char) *p)) == 0))
1735       break;
1736     p++;
1737   }
1738   if (i == string_info->length)
1739     {
1740       (void) fputs((char *) string_info->datum,file);
1741       (void) fputc('\n',file);
1742       return;
1743     }
1744   /*
1745     Convert string to a HEX list.
1746   */
1747   p=(char *) string_info->datum;
1748   for (i=0; i < string_info->length; i+=0x14)
1749   {
1750     (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
1751     for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1752     {
1753       (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
1754       if ((j % 0x04) == 0)
1755         (void) fputc(' ',file);
1756     }
1757     for ( ; j <= 0x14; j++)
1758     {
1759       (void) fputc(' ',file);
1760       (void) fputc(' ',file);
1761       if ((j % 0x04) == 0)
1762         (void) fputc(' ',file);
1763     }
1764     (void) fputc(' ',file);
1765     for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
1766     {
1767       if (isprint((int) ((unsigned char) *p)) != 0)
1768         (void) fputc(*p,file);
1769       else
1770         (void) fputc('-',file);
1771       p++;
1772     }
1773     (void) fputc('\n',file);
1774   }
1775 }
1776 \f
1777 /*
1778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1779 %                                                                             %
1780 %                                                                             %
1781 %                                                                             %
1782 %   R e s e t S t r i n g I n f o                                             %
1783 %                                                                             %
1784 %                                                                             %
1785 %                                                                             %
1786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1787 %
1788 %  ResetStringInfo() reset the string to all null bytes.
1789 %
1790 %  The format of the ResetStringInfo method is:
1791 %
1792 %      void ResetStringInfo(StringInfo *string_info)
1793 %
1794 %  A description of each parameter follows:
1795 %
1796 %    o string_info: the string info.
1797 %
1798 */
1799 MagickExport void ResetStringInfo(StringInfo *string_info)
1800 {
1801   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1802   assert(string_info != (StringInfo *) NULL);
1803   assert(string_info->signature == MagickSignature);
1804   (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1805 }
1806 \f
1807 /*
1808 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1809 %                                                                             %
1810 %                                                                             %
1811 %                                                                             %
1812 %   S e t S t r i n g I n f o                                                 %
1813 %                                                                             %
1814 %                                                                             %
1815 %                                                                             %
1816 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1817 %
1818 %  SetStringInfo() copies the source string to the destination string.
1819 %
1820 %  The format of the SetStringInfo method is:
1821 %
1822 %      void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1823 %
1824 %  A description of each parameter follows:
1825 %
1826 %    o string_info: the string info.
1827 %
1828 %    o source: the source string.
1829 %
1830 */
1831 MagickExport void SetStringInfo(StringInfo *string_info,
1832   const StringInfo *source)
1833 {
1834   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1835   assert(string_info != (StringInfo *) NULL);
1836   assert(string_info->signature == MagickSignature);
1837   assert(source != (StringInfo *) NULL);
1838   assert(source->signature == MagickSignature);
1839   if (string_info->length == 0)
1840     return;
1841   (void) ResetMagickMemory(string_info->datum,0,string_info->length);
1842   (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1843     source->length));
1844 }
1845 \f
1846 /*
1847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1848 %                                                                             %
1849 %                                                                             %
1850 %                                                                             %
1851 %   S e t S t r i n g I n f o D a t u m                                       %
1852 %                                                                             %
1853 %                                                                             %
1854 %                                                                             %
1855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1856 %
1857 %  SetStringInfoDatum() copies bytes from the source string for the length of
1858 %  the destination string.
1859 %
1860 %  The format of the SetStringInfoDatum method is:
1861 %
1862 %      void SetStringInfoDatum(StringInfo *string_info,
1863 %        const unsigned char *source)
1864 %
1865 %  A description of each parameter follows:
1866 %
1867 %    o string_info: the string info.
1868 %
1869 %    o source: the source string.
1870 %
1871 */
1872 MagickExport void SetStringInfoDatum(StringInfo *string_info,
1873   const unsigned char *source)
1874 {
1875   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1876   assert(string_info != (StringInfo *) NULL);
1877   assert(string_info->signature == MagickSignature);
1878   if (string_info->length != 0)
1879     (void) memcpy(string_info->datum,source,string_info->length);
1880 }
1881 \f
1882 /*
1883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1884 %                                                                             %
1885 %                                                                             %
1886 %                                                                             %
1887 %   S e t S t r i n g I n f o L e n g t h                                     %
1888 %                                                                             %
1889 %                                                                             %
1890 %                                                                             %
1891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1892 %
1893 %  SetStringInfoLength() set the string length to the specified value.
1894 %
1895 %  The format of the SetStringInfoLength method is:
1896 %
1897 %      void SetStringInfoLength(StringInfo *string_info,const size_t length)
1898 %
1899 %  A description of each parameter follows:
1900 %
1901 %    o string_info: the string info.
1902 %
1903 %    o length: the string length.
1904 %
1905 */
1906 MagickExport void SetStringInfoLength(StringInfo *string_info,
1907   const size_t length)
1908 {
1909   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1910   assert(string_info != (StringInfo *) NULL);
1911   assert(string_info->signature == MagickSignature);
1912   if (~length < MaxTextExtent)
1913     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1914   string_info->length=length;
1915   if (string_info->datum == (unsigned char *) NULL)
1916     string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1917       MaxTextExtent,sizeof(*string_info->datum));
1918   else
1919     string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1920       length+MaxTextExtent,sizeof(*string_info->datum));
1921   if (string_info->datum == (unsigned char *) NULL)
1922     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1923 }
1924 \f
1925 /*
1926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1927 %                                                                             %
1928 %                                                                             %
1929 %                                                                             %
1930 %   S e t S t r i n g I n f o D a t u m                                       %
1931 %                                                                             %
1932 %                                                                             %
1933 %                                                                             %
1934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1935 %
1936 %  SetStringInfoPath() sets the path associated with the string.
1937 %
1938 %  The format of the SetStringInfoPath method is:
1939 %
1940 %      void SetStringInfoPath(StringInfo *string_info,const char *path)
1941 %
1942 %  A description of each parameter follows:
1943 %
1944 %    o string_info: the string info.
1945 %
1946 %    o path: the path.
1947 %
1948 */
1949 MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1950 {
1951   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1952   assert(string_info != (StringInfo *) NULL);
1953   assert(string_info->signature == MagickSignature);
1954   assert(path != (const char *) NULL);
1955   (void) CopyMagickString(string_info->path,path,MaxTextExtent);
1956 }
1957 \f
1958 /*
1959 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1960 %                                                                             %
1961 %                                                                             %
1962 %                                                                             %
1963 %   S p l i t S t r i n g I n f o                                             %
1964 %                                                                             %
1965 %                                                                             %
1966 %                                                                             %
1967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1968 %
1969 %  SplitStringInfo() splits a string into two and returns it.
1970 %
1971 %  The format of the SplitStringInfo method is:
1972 %
1973 %      StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1974 %
1975 %  A description of each parameter follows:
1976 %
1977 %    o string_info: the string info.
1978 %
1979 */
1980 MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1981   const size_t offset)
1982 {
1983   StringInfo
1984     *split_info;
1985
1986   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1987   assert(string_info != (StringInfo *) NULL);
1988   assert(string_info->signature == MagickSignature);
1989   if (offset > string_info->length)
1990     return((StringInfo *) NULL);
1991   split_info=AcquireStringInfo(offset);
1992   SetStringInfo(split_info,string_info);
1993   (void) memmove(string_info->datum,string_info->datum+offset,
1994     string_info->length-offset+MaxTextExtent);
1995   SetStringInfoLength(string_info,string_info->length-offset);
1996   return(split_info);
1997 }
1998 \f
1999 /*
2000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2001 %                                                                             %
2002 %                                                                             %
2003 %                                                                             %
2004 %   S t r i n g I n f o T o S t r i n g                                       %
2005 %                                                                             %
2006 %                                                                             %
2007 %                                                                             %
2008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2009 %
2010 %  StringInfoToString() converts a string info string to a C string.
2011 %
2012 %  The format of the StringInfoToString method is:
2013 %
2014 %      char *StringInfoToString(const StringInfo *string_info)
2015 %
2016 %  A description of each parameter follows:
2017 %
2018 %    o string_info: the string.
2019 %
2020 */
2021 MagickExport char *StringInfoToString(const StringInfo *string_info)
2022 {
2023   char
2024     *string;
2025
2026   size_t
2027     length;
2028
2029   string=(char *) NULL;
2030   length=string_info->length;
2031   if (~length >= (MaxTextExtent-1))
2032     string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
2033   if (string == (char *) NULL)
2034     return((char *) NULL);
2035   (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
2036   string[length]='\0';
2037   return(string);
2038 }
2039 \f
2040 /*
2041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2042 %                                                                             %
2043 %                                                                             %
2044 %                                                                             %
2045 %   S t r i n g I n f o T o H e x S t r i n g                                 %
2046 %                                                                             %
2047 %                                                                             %
2048 %                                                                             %
2049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2050 %
2051 %  StringInfoToHexString() converts a string info string to a C string.
2052 %
2053 %  The format of the StringInfoToHexString method is:
2054 %
2055 %      char *StringInfoToHexString(const StringInfo *string_info)
2056 %
2057 %  A description of each parameter follows:
2058 %
2059 %    o string_info: the string.
2060 %
2061 */
2062 MagickExport char *StringInfoToHexString(const StringInfo *string_info)
2063 {
2064   char
2065     *string;
2066
2067   register const unsigned char
2068     *p;
2069
2070   register ssize_t
2071     i;
2072
2073   register unsigned char
2074     *q;
2075
2076   size_t
2077     length;
2078
2079   unsigned char
2080     hex_digits[16];
2081
2082   length=string_info->length;
2083   if (~length < MaxTextExtent)
2084     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2085   string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
2086   if (string == (char *) NULL)
2087     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2088   hex_digits[0]='0';
2089   hex_digits[1]='1';
2090   hex_digits[2]='2';
2091   hex_digits[3]='3';
2092   hex_digits[4]='4';
2093   hex_digits[5]='5';
2094   hex_digits[6]='6';
2095   hex_digits[7]='7';
2096   hex_digits[8]='8';
2097   hex_digits[9]='9';
2098   hex_digits[10]='a';
2099   hex_digits[11]='b';
2100   hex_digits[12]='c';
2101   hex_digits[13]='d';
2102   hex_digits[14]='e';
2103   hex_digits[15]='f';
2104   p=string_info->datum;
2105   q=(unsigned char *) string;
2106   for (i=0; i < (ssize_t) string_info->length; i++)
2107   {
2108     *q++=hex_digits[(*p >> 4) & 0x0f];
2109     *q++=hex_digits[*p & 0x0f];
2110     p++;
2111   }
2112   *q='\0';
2113   return(string);
2114 }
2115 \f
2116 /*
2117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2118 %                                                                             %
2119 %                                                                             %
2120 %                                                                             %
2121 %  S t r i n g T o A r g v                                                    %
2122 %                                                                             %
2123 %                                                                             %
2124 %                                                                             %
2125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2126 %
2127 %  StringToArgv() converts a text string into command line arguments.
2128 %  The 'argv' array of arguments, is returned while the number of arguments
2129 %  is returned via the provided integer variable pointer.
2130 %
2131 %  Simple 'word' tokenizer, which allows for each word to be optionally
2132 %  quoted.  However it will not allow use of partial quotes, or escape
2133 %  characters.
2134 %
2135 %  The format of the StringToArgv method is:
2136 %
2137 %      char **StringToArgv(const char *text,int *argc)
2138 %
2139 %  A description of each parameter follows:
2140 %
2141 %    o argv:  Method StringToArgv returns the string list unless an error
2142 %      occurs, otherwise NULL.
2143 %
2144 %    o text:  Specifies the string to segment into a list.
2145 %
2146 %    o argc:  This integer pointer returns the number of arguments in the
2147 %      list.
2148 %
2149 */
2150 MagickExport char **StringToArgv(const char *text,int *argc)
2151 {
2152   char
2153     **argv;
2154
2155   register const char
2156     *p,
2157     *q;
2158
2159   register ssize_t
2160     i;
2161
2162   *argc=0;
2163   if (text == (char *) NULL)
2164     return((char **) NULL);
2165   /*
2166     Determine the number of arguments.
2167   */
2168   for (p=text; *p != '\0'; )
2169   {
2170     while (isspace((int) ((unsigned char) *p)) != 0)
2171       p++;
2172     if (*p == '\0')
2173       break;
2174     (*argc)++;
2175     if (*p == '"')
2176       for (p++; (*p != '"') && (*p != '\0'); p++) ;
2177     if (*p == '\'')
2178       for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2179     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2180       p++;
2181   }
2182   (*argc)++;
2183   argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
2184   if (argv == (char **) NULL)
2185     ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2186   /*
2187     Convert string to an ASCII list.
2188   */
2189   argv[0]=AcquireString("magick");
2190   p=text;
2191   for (i=1; i < (ssize_t) *argc; i++)
2192   {
2193     while (isspace((int) ((unsigned char) *p)) != 0)
2194       p++;
2195     q=p;
2196     if (*q == '"')
2197       {
2198         p++;
2199         for (q++; (*q != '"') && (*q != '\0'); q++) ;
2200       }
2201     else
2202       if (*q == '\'')
2203         {
2204           p++;
2205           for (q++; (*q != '\'') && (*q != '\0'); q++) ;
2206         }
2207       else
2208         while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2209           q++;
2210     argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2211       sizeof(**argv));
2212     if (argv[i] == (char *) NULL)
2213       {
2214         for (i--; i >= 0; i--)
2215           argv[i]=DestroyString(argv[i]);
2216         argv=(char **) RelinquishMagickMemory(argv);
2217         ThrowFatalException(ResourceLimitFatalError,
2218           "UnableToConvertStringToARGV");
2219       }
2220     (void) memcpy(argv[i],p,(size_t) (q-p));
2221     argv[i][q-p]='\0';
2222     p=q;
2223     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2224       p++;
2225   }
2226   argv[i]=(char *) NULL;
2227   return(argv);
2228 }
2229 \f
2230 /*
2231 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2232 %                                                                             %
2233 %                                                                             %
2234 %                                                                             %
2235 %   S t r i n g T o A r r a y O f D o u b l e s                               %
2236 %                                                                             %
2237 %                                                                             %
2238 %                                                                             %
2239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2240 %
2241 %  StringToArrayOfDoubles() converts a string of space or comma seperated
2242 %  numbers into array of floating point numbers (doubles). Any number that
2243 %  failes to parse properly will produce a syntax error. As will two commas
2244 %  without a  number between them.  However a final comma at the end will
2245 %  not be regarded as an error so as to simplify automatic list generation.
2246 %
2247 %  A NULL value is returned on syntax or memory errors.
2248 %
2249 %  Use RelinquishMagickMemory() to free returned array when finished.
2250 %
2251 %  The format of the StringToArrayOfDoubles method is:
2252 %
2253 %     double *StringToArrayOfDoubles(const char *string,
2254 %          size_t *count, ExceptionInfo *exception)
2255 %
2256 %  A description of each parameter follows:
2257 %
2258 %    o string: the string containing the comma/space seperated values.
2259 %
2260 %    o count: returns number of arguments in returned array
2261 %
2262 %    o exception: return 'memory failure' exceptions
2263 %
2264 */
2265 MagickExport double *StringToArrayOfDoubles(const char *string,
2266      ssize_t *count, ExceptionInfo *exception)
2267 {
2268   const char
2269     *p;
2270
2271   char
2272     *q;
2273
2274   double
2275     *array;
2276
2277   register ssize_t
2278     i;
2279
2280   /* Determine count of values, and check syntax */
2281   *count=0;
2282   p=string;
2283   i=0;
2284   while( *p != '\0' )
2285   {
2286     (void) StringToDouble(p, &q);       /* get value - ignores leading space */
2287     if (p == q) return((double *)NULL); /* no value found */
2288     p=q; i++;                           /* inc value count */
2289     while ( isspace((int)*p) ) p++;     /* skip spaces */
2290     if ( *p == ',' )           p++;     /* skip comma */
2291     while ( isspace((int)*p) ) p++;     /* and more spaces */
2292   }
2293
2294   /* Allocate floating point argument list */
2295   *count=i;
2296   array=(double *) AcquireQuantumMemory(i,sizeof(*array));
2297   if (array == (double *) NULL) {
2298     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
2299     (void) ThrowMagickException(exception,GetMagickModule(),
2300          ResourceLimitFatalError,"MemoryAllocationFailed"," ");
2301     return((double *)NULL);
2302   }
2303
2304   /* Fill in the floating point values */
2305   p=string;
2306   i=0;
2307   while( *p != '\0' && i < *count ) {
2308     array[i++]=StringToDouble(p,&q);
2309     p=q;
2310     while ( isspace((int)*p) || *p == ',' ) p++;
2311   }
2312
2313   return(array);
2314 }
2315 \f
2316 /*
2317 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2318 %                                                                             %
2319 %                                                                             %
2320 %                                                                             %
2321 +   S t r i n g T o k e n                                                     %
2322 %                                                                             %
2323 %                                                                             %
2324 %                                                                             %
2325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2326 %
2327 %  StringToken() Looks for any one of given delimiters and splits the string
2328 %  into two separate strings by replacing the delimiter character found with a
2329 %  nul character.
2330 %
2331 %  The given string pointer is changed to point to the string following the
2332 %  delimiter character found, or NULL.  A pointer to the start of the
2333 %  string is returned, representing the token before the delimiter.
2334 %
2335 %  In may ways this is equivent to the strtok() C library function, but with
2336 %  multiple delimiter characters rather than a delimiter string.
2337 %
2338 %  The format of the StringToken method is:
2339 %
2340 %      char *StringToken(const char *delimiters,char **string)
2341 %
2342 %  A description of each parameter follows:
2343 %
2344 %    o delimiters: one or more delimiters.
2345 %
2346 %    o string: return the first token in the string.  If none is found, return
2347 %      NULL.
2348 %
2349 */
2350 MagickExport char *StringToken(const char *delimiters,char **string)
2351 {
2352   char
2353     *q;
2354
2355   register char
2356     *p;
2357
2358   register const char
2359     *r;
2360
2361   register int
2362     c,
2363     d;
2364
2365   p=(*string);
2366   if (p == (char *) NULL)
2367     return((char *) NULL);
2368   q=p;
2369   for ( ; ; )
2370   {
2371     c=(*p++);
2372     r=delimiters;
2373     do
2374     {
2375       d=(*r++);
2376       if (c == d)
2377         {
2378           if (c == '\0')
2379             p=(char *) NULL;
2380           else
2381             p[-1]='\0';
2382           *string=p;
2383           return(q);
2384         }
2385     } while (d != '\0');
2386   }
2387 }
2388 \f
2389 /*
2390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2391 %                                                                             %
2392 %                                                                             %
2393 %                                                                             %
2394 %  S t r i n g T o L i s t                                                    %
2395 %                                                                             %
2396 %                                                                             %
2397 %                                                                             %
2398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2399 %
2400 %  StringToList() converts a text string into a list by segmenting the text
2401 %  string at each carriage return discovered.  The list is converted to HEX
2402 %  characters if any control characters are discovered within the text string.
2403 %
2404 %  The format of the StringToList method is:
2405 %
2406 %      char **StringToList(const char *text)
2407 %
2408 %  A description of each parameter follows:
2409 %
2410 %    o text:  Specifies the string to segment into a list.
2411 %
2412 */
2413 MagickExport char **StringToList(const char *text)
2414 {
2415   char
2416     **textlist;
2417
2418   register const char
2419     *p;
2420
2421   register ssize_t
2422     i;
2423
2424   size_t
2425     lines;
2426
2427   if (text == (char *) NULL)
2428     return((char **) NULL);
2429   for (p=text; *p != '\0'; p++)
2430     if (((int) ((unsigned char) *p) < 32) &&
2431         (isspace((int) ((unsigned char) *p)) == 0))
2432       break;
2433   if (*p == '\0')
2434     {
2435       register const char
2436         *q;
2437
2438       /*
2439         Convert string to an ASCII list.
2440       */
2441       lines=1;
2442       for (p=text; *p != '\0'; p++)
2443         if (*p == '\n')
2444           lines++;
2445       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2446         sizeof(*textlist));
2447       if (textlist == (char **) NULL)
2448         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2449       p=text;
2450       for (i=0; i < (ssize_t) lines; i++)
2451       {
2452         for (q=p; *q != '\0'; q++)
2453           if ((*q == '\r') || (*q == '\n'))
2454             break;
2455         textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
2456           sizeof(**textlist));
2457         if (textlist[i] == (char *) NULL)
2458           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2459         (void) memcpy(textlist[i],p,(size_t) (q-p));
2460         textlist[i][q-p]='\0';
2461         if (*q == '\r')
2462           q++;
2463         p=q+1;
2464       }
2465     }
2466   else
2467     {
2468       char
2469         hex_string[MaxTextExtent];
2470
2471       register char
2472         *q;
2473
2474       register ssize_t
2475         j;
2476
2477       /*
2478         Convert string to a HEX list.
2479       */
2480       lines=(size_t) (strlen(text)/0x14)+1;
2481       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2482         sizeof(*textlist));
2483       if (textlist == (char **) NULL)
2484         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2485       p=text;
2486       for (i=0; i < (ssize_t) lines; i++)
2487       {
2488         textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
2489           sizeof(**textlist));
2490         if (textlist[i] == (char *) NULL)
2491           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2492         (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
2493           (long) (0x14*i));
2494         q=textlist[i]+strlen(textlist[i]);
2495         for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
2496         {
2497           (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
2498           (void) CopyMagickString(q,hex_string,MaxTextExtent);
2499           q+=2;
2500           if ((j % 0x04) == 0)
2501             *q++=' ';
2502         }
2503         for ( ; j <= 0x14; j++)
2504         {
2505           *q++=' ';
2506           *q++=' ';
2507           if ((j % 0x04) == 0)
2508             *q++=' ';
2509         }
2510         *q++=' ';
2511         for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
2512         {
2513           if (isprint((int) ((unsigned char) *p)) != 0)
2514             *q++=(*p);
2515           else
2516             *q++='-';
2517           p++;
2518         }
2519         *q='\0';
2520       }
2521     }
2522   textlist[i]=(char *) NULL;
2523   return(textlist);
2524 }
2525 \f
2526 /*
2527 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2528 %                                                                             %
2529 %                                                                             %
2530 %                                                                             %
2531 %   S t r i n g T o S t r i n g I n f o                                       %
2532 %                                                                             %
2533 %                                                                             %
2534 %                                                                             %
2535 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2536 %
2537 %  StringToStringInfo() converts a string to a StringInfo type.
2538 %
2539 %  The format of the StringToStringInfo method is:
2540 %
2541 %      StringInfo *StringToStringInfo(const char *string)
2542 %
2543 %  A description of each parameter follows:
2544 %
2545 %    o string:  The string.
2546 %
2547 */
2548 MagickExport StringInfo *StringToStringInfo(const char *string)
2549 {
2550   StringInfo
2551     *string_info;
2552
2553   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
2554   assert(string != (const char *) NULL);
2555   string_info=AcquireStringInfo(strlen(string));
2556   SetStringInfoDatum(string_info,(const unsigned char *) string);
2557   return(string_info);
2558 }
2559 \f
2560 /*
2561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2562 %                                                                             %
2563 %                                                                             %
2564 %                                                                             %
2565 %   S t r i p S t r i n g                                                     %
2566 %                                                                             %
2567 %                                                                             %
2568 %                                                                             %
2569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2570 %
2571 %  StripString() strips any whitespace or quotes from the beginning and end of
2572 %  a string of characters.
2573 %
2574 %  The format of the StripString method is:
2575 %
2576 %      void StripString(char *message)
2577 %
2578 %  A description of each parameter follows:
2579 %
2580 %    o message: Specifies an array of characters.
2581 %
2582 */
2583 MagickExport void StripString(char *message)
2584 {
2585   register char
2586     *p,
2587     *q;
2588
2589   size_t
2590     length;
2591
2592   assert(message != (char *) NULL);
2593   if (*message == '\0')
2594     return;
2595   length=strlen(message);
2596   p=message;
2597   while (isspace((int) ((unsigned char) *p)) != 0)
2598     p++;
2599   if ((*p == '\'') || (*p == '"'))
2600     p++;
2601   q=message+length-1;
2602   while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2603     q--;
2604   if (q > p)
2605     if ((*q == '\'') || (*q == '"'))
2606       q--;
2607   (void) memmove(message,p,(size_t) (q-p+1));
2608   message[q-p+1]='\0';
2609   for (p=message; *p != '\0'; p++)
2610     if (*p == '\n')
2611       *p=' ';
2612 }
2613 \f
2614 /*
2615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2616 %                                                                             %
2617 %                                                                             %
2618 %                                                                             %
2619 %   S u b s t i t u t e S t r i n g                                           %
2620 %                                                                             %
2621 %                                                                             %
2622 %                                                                             %
2623 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2624 %
2625 %  SubstituteString() performs string substitution on a string, replacing the
2626 %  string with the substituted version. Buffer must be allocated from the heap.
2627 %  If the string is matched and status, MagickTrue is returned otherwise
2628 %  MagickFalse.
2629 %
2630 %  The format of the SubstituteString method is:
2631 %
2632 %      MagickBooleanType SubstituteString(char **string,const char *search,
2633 %        const char *replace)
2634 %
2635 %  A description of each parameter follows:
2636 %
2637 %    o string: the string to perform replacements on;  replaced with new
2638 %      allocation if a replacement is made.
2639 %
2640 %    o search: search for this string.
2641 %
2642 %    o replace: replace any matches with this string.
2643 %
2644 */
2645 MagickExport MagickBooleanType SubstituteString(char **string,
2646   const char *search,const char *replace)
2647 {
2648   MagickBooleanType
2649     status;
2650
2651   register char
2652     *p;
2653
2654   size_t
2655     extent,
2656     replace_extent,
2657     search_extent;
2658
2659   ssize_t
2660     offset;
2661
2662   status=MagickFalse;
2663   search_extent=0,
2664   replace_extent=0;
2665   for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
2666   {
2667     if (search_extent == 0)
2668       search_extent=strlen(search);
2669     if (strncmp(p,search,search_extent) != 0)
2670       continue;
2671     /*
2672       We found a match.
2673     */
2674     status=MagickTrue;
2675     if (replace_extent == 0)
2676       replace_extent=strlen(replace);
2677     if (replace_extent > search_extent)
2678       {
2679         /*
2680           Make room for the replacement string.
2681         */
2682         offset=(ssize_t) (p-(*string));
2683         extent=strlen(*string)+replace_extent-search_extent+1;
2684         *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
2685           sizeof(*p));
2686         if (*string == (char *) NULL)
2687           ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2688         p=(*string)+offset;
2689       }
2690     /*
2691       Replace string.
2692     */
2693     if (search_extent != replace_extent)
2694       (void) CopyMagickMemory(p+replace_extent,p+search_extent,
2695         strlen(p+search_extent)+1);
2696     (void) CopyMagickMemory(p,replace,replace_extent);
2697     p+=replace_extent-1;
2698   }
2699   return(status);
2700 }