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