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