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