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