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