MagickCore  6.7.5
string.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                  SSSSS   TTTTT  RRRR   IIIII  N   N   GGGG                  %
00007 %                  SS        T    R   R    I    NN  N  G                      %
00008 %                   SSS      T    RRRR     I    N N N  G GGG                  %
00009 %                     SS     T    R R      I    N  NN  G   G                  %
00010 %                  SSSSS     T    R  R   IIIII  N   N   GGGG                  %
00011 %                                                                             %
00012 %                                                                             %
00013 %                        MagickCore String Methods                            %
00014 %                                                                             %
00015 %                             Software Design                                 %
00016 %                               John Cristy                                   %
00017 %                               August 2003                                   %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the license.  You may  %
00024 %  obtain a copy of the license at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the license is distributed on an "as is" basis,          %
00030 %  without warranties or conditions of any kind, either express or implied.   %
00031 %  See the license for the specific language governing permissions and        %
00032 %  limitations under the license.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   include declarations.
00041 */
00042 #include "MagickCore/studio.h"
00043 #include "MagickCore/blob.h"
00044 #include "MagickCore/blob-private.h"
00045 #include "MagickCore/exception.h"
00046 #include "MagickCore/exception-private.h"
00047 #include "MagickCore/list.h"
00048 #include "MagickCore/locale_.h"
00049 #include "MagickCore/log.h"
00050 #include "MagickCore/memory_.h"
00051 #include "MagickCore/property.h"
00052 #include "MagickCore/resource_.h"
00053 #include "MagickCore/signature-private.h"
00054 #include "MagickCore/string_.h"
00055 #include "MagickCore/utility-private.h"
00056 
00057 /*
00058   static declarations.
00059 */
00060 #if !defined(MAGICKCORE_HAVE_STRCASECMP) || !defined(MAGICKCORE_HAVE_STRNCASECMP)
00061 static const unsigned char
00062   asciimap[] =
00063   {
00064     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
00065     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
00066     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
00067     0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
00068     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
00069     0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
00070     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
00071     0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
00072     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
00073     0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
00074     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
00075     0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
00076     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
00077     0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
00078     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
00079     0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
00080     0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb,
00081     0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
00082     0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
00083     0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
00084     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
00085     0xfc, 0xfd, 0xfe, 0xff,
00086   };
00087 #endif
00088 
00089 /*
00090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00091 %                                                                             %
00092 %                                                                             %
00093 %                                                                             %
00094 %   A c q u i r e S t r i n g                                                 %
00095 %                                                                             %
00096 %                                                                             %
00097 %                                                                             %
00098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00099 %
00100 %  AcquireString() allocates memory for a string and copies the source string
00101 %  to that memory location (and returns it).
00102 %
00103 %  The format of the AcquireString method is:
00104 %
00105 %      char *AcquireString(const char *source)
00106 %
00107 %  A description of each parameter follows:
00108 %
00109 %    o source: A character string.
00110 %
00111 */
00112 MagickExport char *AcquireString(const char *source)
00113 {
00114   char
00115     *destination;
00116 
00117   size_t
00118     length;
00119 
00120   length=0;
00121   if (source != (char *) NULL)
00122     length+=strlen(source);
00123   if (~length < MaxTextExtent)
00124     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
00125   destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
00126     sizeof(*destination));
00127   if (destination == (char *) NULL)
00128     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
00129   *destination='\0';
00130   if (source != (char *) NULL)
00131     (void) memcpy(destination,source,length*sizeof(*destination));
00132   destination[length]='\0';
00133   return(destination);
00134 }
00135 
00136 /*
00137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00138 %                                                                             %
00139 %                                                                             %
00140 %                                                                             %
00141 %   A c q u i r e S t r i n g I n f o                                         %
00142 %                                                                             %
00143 %                                                                             %
00144 %                                                                             %
00145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00146 %
00147 %  AcquireStringInfo() allocates the StringInfo structure.
00148 %
00149 %  The format of the AcquireStringInfo method is:
00150 %
00151 %      StringInfo *AcquireStringInfo(const size_t length)
00152 %
00153 %  A description of each parameter follows:
00154 %
00155 %    o length: the string length.
00156 %
00157 */
00158 MagickExport StringInfo *AcquireStringInfo(const size_t length)
00159 {
00160   StringInfo
00161     *string_info;
00162 
00163   string_info=(StringInfo *) AcquireMagickMemory(sizeof(*string_info));
00164   if (string_info == (StringInfo *) NULL)
00165     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00166   (void) ResetMagickMemory(string_info,0,sizeof(*string_info));
00167   string_info->signature=MagickSignature;
00168   string_info->length=length;
00169   if (string_info->length != 0)
00170     {
00171       string_info->datum=(unsigned char *) NULL;
00172       if (~string_info->length >= (MaxTextExtent-1))
00173         string_info->datum=(unsigned char *) AcquireQuantumMemory(
00174           string_info->length+MaxTextExtent,sizeof(*string_info->datum));
00175       if (string_info->datum == (unsigned char *) NULL)
00176         ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00177     }
00178   return(string_info);
00179 }
00180 
00181 /*
00182 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00183 %                                                                             %
00184 %                                                                             %
00185 %                                                                             %
00186 %   B l o b T o S t r i n g I n f o                                           %
00187 %                                                                             %
00188 %                                                                             %
00189 %                                                                             %
00190 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00191 %
00192 %  BlobToStringInfo() returns the contents of a blob as a string.
00193 %
00194 %  The format of the BlobToStringInfo method is:
00195 %
00196 %      StringInfo *BlobToStringInfo(const void *blob,const size_t length)
00197 %
00198 %  A description of each parameter follows:
00199 %
00200 %    o blob: the blob.
00201 %
00202 %    o length: the length of the blob.
00203 %
00204 */
00205 MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
00206 {
00207   StringInfo
00208     *string_info;
00209 
00210   string_info=AcquireStringInfo(0);
00211   string_info->length=length;
00212   if (~string_info->length >= (MaxTextExtent-1))
00213     string_info->datum=(unsigned char *) AcquireQuantumMemory(
00214       string_info->length+MaxTextExtent,sizeof(*string_info->datum));
00215   if (string_info->datum == (unsigned char *) NULL)
00216     {
00217       string_info=DestroyStringInfo(string_info);
00218       return((StringInfo *) NULL);
00219     }
00220   if (blob != (const void *) NULL)
00221     (void) memcpy(string_info->datum,blob,length);
00222   return(string_info);
00223 }
00224 
00225 /*
00226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00227 %                                                                             %
00228 %                                                                             %
00229 %                                                                             %
00230 %   C l o n e S t r i n g                                                     %
00231 %                                                                             %
00232 %                                                                             %
00233 %                                                                             %
00234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00235 %
00236 %  CloneString() allocates memory for the destination string and copies
00237 %  the source string to that memory location.
00238 %
00239 %  If source is a NULL pointer the destination will also be set to a NULL
00240 %  point (any existing string is freed).  Otherwise the memory is allocated
00241 %  (or resized) and the source string copied into it.
00242 %
00243 %  A pointer to the copy of the source string, or NULL is returned.
00244 %
00245 %  The format of the CloneString method is:
00246 %
00247 %      char *CloneString(char **destination,const char *source)
00248 %
00249 %  A description of each parameter follows:
00250 %
00251 %    o destination:  A pointer to a character string.
00252 %
00253 %    o source: A character string.
00254 %
00255 */
00256 MagickExport char *CloneString(char **destination,const char *source)
00257 {
00258   size_t
00259     length;
00260 
00261   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00262   assert(destination != (char **) NULL);
00263   if (source == (const char *) NULL)
00264     {
00265       if (*destination != (char *) NULL)
00266         *destination=DestroyString(*destination);
00267       return(*destination);
00268     }
00269   if (*destination == (char *) NULL)
00270     {
00271       *destination=AcquireString(source);
00272       return(*destination);
00273     }
00274   length=strlen(source);
00275   if (~length < MaxTextExtent)
00276     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
00277   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
00278     sizeof(**destination));
00279   if (*destination == (char *) NULL)
00280     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
00281   if (length != 0)
00282     (void) memcpy(*destination,source,length*sizeof(**destination));
00283   (*destination)[length]='\0';
00284   return(*destination);
00285 }
00286 
00287 /*
00288 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00289 %                                                                             %
00290 %                                                                             %
00291 %                                                                             %
00292 %   C l o n e S t r i n g I n f o                                             %
00293 %                                                                             %
00294 %                                                                             %
00295 %                                                                             %
00296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00297 %
00298 %  CloneStringInfo() clones a copy of the StringInfo structure.
00299 %
00300 %  The format of the CloneStringInfo method is:
00301 %
00302 %      StringInfo *CloneStringInfo(const StringInfo *string_info)
00303 %
00304 %  A description of each parameter follows:
00305 %
00306 %    o string_info: the string info.
00307 %
00308 */
00309 MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
00310 {
00311   StringInfo
00312     *clone_info;
00313 
00314   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00315   assert(string_info != (StringInfo *) NULL);
00316   assert(string_info->signature == MagickSignature);
00317   clone_info=AcquireStringInfo(string_info->length);
00318   if (string_info->length != 0)
00319     (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
00320   return(clone_info);
00321 }
00322 
00323 /*
00324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00325 %                                                                             %
00326 %                                                                             %
00327 %                                                                             %
00328 %   C o m p a r e S t r i n g I n f o                                         %
00329 %                                                                             %
00330 %                                                                             %
00331 %                                                                             %
00332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00333 %
00334 %  CompareStringInfo() compares the two datums target and source.  It returns
00335 %  an integer less than, equal to, or greater than zero if target is found,
00336 %  respectively, to be less than, to match, or be greater than source.
00337 %
00338 %  The format of the CompareStringInfo method is:
00339 %
00340 %      int CompareStringInfo(const StringInfo *target,const StringInfo *source)
00341 %
00342 %  A description of each parameter follows:
00343 %
00344 %    o target: the target string.
00345 %
00346 %    o source: the source string.
00347 %
00348 */
00349 
00350 static inline size_t MagickMin(const size_t x,const size_t y)
00351 {
00352   if (x < y)
00353     return(x);
00354   return(y);
00355 }
00356 
00357 MagickExport int CompareStringInfo(const StringInfo *target,
00358   const StringInfo *source)
00359 {
00360   int
00361     status;
00362 
00363   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00364   assert(target != (StringInfo *) NULL);
00365   assert(target->signature == MagickSignature);
00366   assert(source != (StringInfo *) NULL);
00367   assert(source->signature == MagickSignature);
00368   status=memcmp(target->datum,source->datum,MagickMin(target->length,
00369     source->length));
00370   if (status != 0)
00371     return(status);
00372   if (target->length == source->length)
00373     return(0);
00374   return(target->length < source->length ? -1 : 1);
00375 }
00376 
00377 /*
00378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00379 %                                                                             %
00380 %                                                                             %
00381 %                                                                             %
00382 %   C o n c a t e n a t e M a g i c k S t r i n g                             %
00383 %                                                                             %
00384 %                                                                             %
00385 %                                                                             %
00386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00387 %
00388 %  ConcatenateMagickString() concatenates the source string to the destination
00389 %  string.  The destination buffer is always null-terminated even if the
00390 %  string must be truncated.
00391 %
00392 %  The format of the ConcatenateMagickString method is:
00393 %
00394 %      size_t ConcatenateMagickString(char *destination,const char *source,
00395 %        const size_t length)
00396 %
00397 %  A description of each parameter follows:
00398 %
00399 %    o destination: the destination string.
00400 %
00401 %    o source: the source string.
00402 %
00403 %    o length: the length of the destination string.
00404 %
00405 */
00406 MagickExport size_t ConcatenateMagickString(char *destination,
00407   const char *source,const size_t length)
00408 {
00409   register char
00410     *q;
00411 
00412   register const char
00413     *p;
00414 
00415   register size_t
00416     i;
00417 
00418   size_t
00419     count;
00420 
00421   assert(destination != (char *) NULL);
00422   assert(source != (const char *) NULL);
00423   assert(length >= 1);
00424   p=source;
00425   q=destination;
00426   i=length;
00427   while ((i-- != 0) && (*q != '\0'))
00428     q++;
00429   count=(size_t) (q-destination);
00430   i=length-count;
00431   if (i == 0)
00432     return(count+strlen(p));
00433   while (*p != '\0')
00434   {
00435     if (i != 1)
00436       {
00437         *q++=(*p);
00438         i--;
00439       }
00440     p++;
00441   }
00442   *q='\0';
00443   return(count+(p-source));
00444 }
00445 
00446 /*
00447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00448 %                                                                             %
00449 %                                                                             %
00450 %                                                                             %
00451 %   C o n c a t e n a t e S t r i n g                                         %
00452 %                                                                             %
00453 %                                                                             %
00454 %                                                                             %
00455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00456 %
00457 %  ConcatenateString() appends a copy of string source, including the
00458 %  terminating null character, to the end of string destination.
00459 %
00460 %  The format of the ConcatenateString method is:
00461 %
00462 %      MagickBooleanType ConcatenateString(char **destination,
00463 %        const char *source)
00464 %
00465 %  A description of each parameter follows:
00466 %
00467 %    o destination:  A pointer to a character string.
00468 %
00469 %    o source: A character string.
00470 %
00471 */
00472 MagickExport MagickBooleanType ConcatenateString(char **destination,
00473   const char *source)
00474 {
00475   size_t
00476     destination_length,
00477     length,
00478     source_length;
00479 
00480   assert(destination != (char **) NULL);
00481   if (source == (const char *) NULL)
00482     return(MagickTrue);
00483   if (*destination == (char *) NULL)
00484     {
00485       *destination=AcquireString(source);
00486       return(MagickTrue);
00487     }
00488   destination_length=strlen(*destination);
00489   source_length=strlen(source);
00490   length=destination_length;
00491   if (~length < source_length)
00492     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
00493   length+=source_length;
00494   if (~length < MaxTextExtent)
00495     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
00496   *destination=(char *) ResizeQuantumMemory(*destination,length+MaxTextExtent,
00497     sizeof(**destination));
00498   if (*destination == (char *) NULL)
00499     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
00500   if (source_length != 0)
00501     (void) memcpy((*destination)+destination_length,source,source_length);
00502   (*destination)[length]='\0';
00503   return(MagickTrue);
00504 }
00505 
00506 /*
00507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00508 %                                                                             %
00509 %                                                                             %
00510 %                                                                             %
00511 %   C o n c a t e n a t e S t r i n g I n f o                                 %
00512 %                                                                             %
00513 %                                                                             %
00514 %                                                                             %
00515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00516 %
00517 %  ConcatenateStringInfo() concatenates the source string to the destination
00518 %  string.
00519 %
00520 %  The format of the ConcatenateStringInfo method is:
00521 %
00522 %      void ConcatenateStringInfo(StringInfo *string_info,
00523 %        const StringInfo *source)
00524 %
00525 %  A description of each parameter follows:
00526 %
00527 %    o string_info: the string info.
00528 %
00529 %    o source: the source string.
00530 %
00531 */
00532 MagickExport void ConcatenateStringInfo(StringInfo *string_info,
00533   const StringInfo *source)
00534 {
00535   size_t
00536     length;
00537 
00538   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00539   assert(string_info != (StringInfo *) NULL);
00540   assert(string_info->signature == MagickSignature);
00541   assert(source != (const StringInfo *) NULL);
00542   length=string_info->length;
00543   if (~length < source->length)
00544     ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
00545   SetStringInfoLength(string_info,length+source->length);
00546   (void) memcpy(string_info->datum+length,source->datum,source->length);
00547 }
00548 
00549 /*
00550 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00551 %                                                                             %
00552 %                                                                             %
00553 %                                                                             %
00554 %   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                         %
00555 %                                                                             %
00556 %                                                                             %
00557 %                                                                             %
00558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00559 %
00560 %  ConfigureFileToStringInfo() returns the contents of a configure file as a
00561 %  string.
00562 %
00563 %  The format of the ConfigureFileToStringInfo method is:
00564 %
00565 %      StringInfo *ConfigureFileToStringInfo(const char *filename)
00566 %        ExceptionInfo *exception)
00567 %
00568 %  A description of each parameter follows:
00569 %
00570 %    o filename: the filename.
00571 %
00572 */
00573 MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
00574 {
00575   char
00576     *string;
00577 
00578   int
00579     file;
00580 
00581   MagickOffsetType
00582     offset;
00583 
00584   size_t
00585     length;
00586 
00587   StringInfo
00588     *string_info;
00589 
00590   void
00591     *map;
00592 
00593   assert(filename != (const char *) NULL);
00594   file=open_utf8(filename,O_RDONLY | O_BINARY,0);
00595   if (file == -1)
00596     return((StringInfo *) NULL);
00597   offset=(MagickOffsetType) lseek(file,0,SEEK_END);
00598   if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
00599     {
00600       file=close(file)-1;
00601       return((StringInfo *) NULL);
00602     }
00603   length=(size_t) offset;
00604   string=(char *) NULL;
00605   if (~length >= (MaxTextExtent-1))
00606     string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
00607   if (string == (char *) NULL)
00608     {
00609       file=close(file)-1;
00610       return((StringInfo *) NULL);
00611     }
00612   map=MapBlob(file,ReadMode,0,length);
00613   if (map != (void *) NULL)
00614     {
00615       (void) memcpy(string,map,length);
00616       (void) UnmapBlob(map,length);
00617     }
00618   else
00619     {
00620       register size_t
00621         i;
00622 
00623       ssize_t
00624         count;
00625 
00626       (void) lseek(file,0,SEEK_SET);
00627       for (i=0; i < length; i+=count)
00628       {
00629         count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
00630           SSIZE_MAX));
00631         if (count <= 0)
00632           {
00633             count=0;
00634             if (errno != EINTR)
00635               break;
00636           }
00637       }
00638       if (i < length)
00639         {
00640           file=close(file)-1;
00641           string=DestroyString(string);
00642           return((StringInfo *) NULL);
00643         }
00644     }
00645   string[length]='\0';
00646   file=close(file)-1;
00647   string_info=AcquireStringInfo(0);
00648   (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
00649   string_info->length=length;
00650   string_info->datum=(unsigned char *) string;
00651   return(string_info);
00652 }
00653 
00654 /*
00655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00656 %                                                                             %
00657 %                                                                             %
00658 %                                                                             %
00659 %   C o n s t a n t S t r i n g                                               %
00660 %                                                                             %
00661 %                                                                             %
00662 %                                                                             %
00663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00664 %
00665 %  ConstantString() allocates memory for a string and copies the source string
00666 %  to that memory location (and returns it).  Use it for strings that you do
00667 %  do not expect to change over its lifetime.
00668 %
00669 %  The format of the ConstantString method is:
00670 %
00671 %      char *ConstantString(const char *source)
00672 %
00673 %  A description of each parameter follows:
00674 %
00675 %    o source: A character string.
00676 %
00677 */
00678 MagickExport char *ConstantString(const char *source)
00679 {
00680   char
00681     *destination;
00682 
00683   size_t
00684     length;
00685 
00686   length=0;
00687   if (source != (char *) NULL)
00688     length+=strlen(source);
00689   destination=(char *) NULL;
00690   if (~length >= 1UL)
00691     destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
00692   if (destination == (char *) NULL)
00693     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
00694   *destination='\0';
00695   if (source != (char *) NULL)
00696     (void) memcpy(destination,source,length*sizeof(*destination));
00697   destination[length]='\0';
00698   return(destination);
00699 }
00700 
00701 /*
00702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00703 %                                                                             %
00704 %                                                                             %
00705 %                                                                             %
00706 %   C o p y M a g i c k S t r i n g                                           %
00707 %                                                                             %
00708 %                                                                             %
00709 %                                                                             %
00710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00711 %
00712 %  CopyMagickString() copies the source string to the destination string.  The
00713 %  destination buffer is always null-terminated even if the string must be
00714 %  truncated.  The return value is the minimum of the source string length
00715 %  or the length parameter.
00716 %
00717 %  The format of the CopyMagickString method is:
00718 %
00719 %      size_t CopyMagickString(const char *destination,char *source,
00720 %        const size_t length)
00721 %
00722 %  A description of each parameter follows:
00723 %
00724 %    o destination: the destination string.
00725 %
00726 %    o source: the source string.
00727 %
00728 %    o length: the length of the destination string.
00729 %
00730 */
00731 MagickExport size_t CopyMagickString(char *destination,const char *source,
00732   const size_t length)
00733 {
00734   register char
00735     *q;
00736 
00737   register const char
00738     *p;
00739 
00740   register size_t
00741     n;
00742 
00743   if (source == (const char *) NULL)
00744     return(0);
00745   p=source;
00746   q=destination;
00747   for (n=length; n > 4; n-=4)
00748   {
00749     *q=(*p++);
00750     if (*q == '\0')
00751       return((size_t) (p-source-1));
00752     q++;
00753     *q=(*p++);
00754     if (*q == '\0')
00755       return((size_t) (p-source-1));
00756     q++;
00757     *q=(*p++);
00758     if (*q == '\0')
00759       return((size_t) (p-source-1));
00760     q++;
00761     *q=(*p++);
00762     if (*q == '\0')
00763       return((size_t) (p-source-1));
00764     q++;
00765   }
00766   if (n != 0)
00767     for (n--; n != 0; n--)
00768     {
00769       *q=(*p++);
00770       if (*q == '\0')
00771         return((size_t) (p-source-1));
00772       q++;
00773     }
00774   if (length != 0)
00775     *q='\0';
00776   return((size_t) (p-source-1));
00777 }
00778 
00779 /*
00780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00781 %                                                                             %
00782 %                                                                             %
00783 %                                                                             %
00784 %   D e s t r o y S t r i n g                                                 %
00785 %                                                                             %
00786 %                                                                             %
00787 %                                                                             %
00788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00789 %
00790 %  DestroyString() destroys memory associated with a string.
00791 %
00792 %  The format of the DestroyString method is:
00793 %
00794 %      char *DestroyString(char *string)
00795 %
00796 %  A description of each parameter follows:
00797 %
00798 %    o string: the string.
00799 %
00800 */
00801 MagickExport char *DestroyString(char *string)
00802 {
00803   return((char *) RelinquishMagickMemory(string));
00804 }
00805 
00806 /*
00807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00808 %                                                                             %
00809 %                                                                             %
00810 %                                                                             %
00811 %   D e s t r o y S t r i n g I n f o                                         %
00812 %                                                                             %
00813 %                                                                             %
00814 %                                                                             %
00815 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00816 %
00817 %  DestroyStringInfo() destroys memory associated with the StringInfo structure.
00818 %
00819 %  The format of the DestroyStringInfo method is:
00820 %
00821 %      StringInfo *DestroyStringInfo(StringInfo *string_info)
00822 %
00823 %  A description of each parameter follows:
00824 %
00825 %    o string_info: the string info.
00826 %
00827 */
00828 MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
00829 {
00830   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00831   assert(string_info != (StringInfo *) NULL);
00832   assert(string_info->signature == MagickSignature);
00833   if (string_info->datum != (unsigned char *) NULL)
00834     string_info->datum=(unsigned char *) RelinquishMagickMemory(
00835       string_info->datum);
00836   string_info->signature=(~MagickSignature);
00837   string_info=(StringInfo *) RelinquishMagickMemory(string_info);
00838   return(string_info);
00839 }
00840 
00841 /*
00842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00843 %                                                                             %
00844 %                                                                             %
00845 %                                                                             %
00846 %   D e s t r o y S t r i n g L i s t                                         %
00847 %                                                                             %
00848 %                                                                             %
00849 %                                                                             %
00850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00851 %
00852 %  DestroyStringList() zeros memory associated with a string list.
00853 %
00854 %  The format of the DestroyStringList method is:
00855 %
00856 %      char **DestroyStringList(char **list)
00857 %
00858 %  A description of each parameter follows:
00859 %
00860 %    o list: the string list.
00861 %
00862 */
00863 MagickExport char **DestroyStringList(char **list)
00864 {
00865   register ssize_t
00866     i;
00867 
00868   assert(list != (char **) NULL);
00869   for (i=0; list[i] != (char *) NULL; i++)
00870     list[i]=DestroyString(list[i]);
00871   list=(char **) RelinquishMagickMemory(list);
00872   return(list);
00873 }
00874 
00875 /*
00876 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00877 %                                                                             %
00878 %                                                                             %
00879 %                                                                             %
00880 %   E s c a p e S t r i n g                                                   %
00881 %                                                                             %
00882 %                                                                             %
00883 %                                                                             %
00884 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00885 %
00886 %  EscapeString() allocates memory for a backslash-escaped version of a
00887 %  source text string, copies the escaped version of the text to that
00888 %  memory location while adding backslash characters, and returns the
00889 %  escaped string.
00890 %
00891 %  The format of the EscapeString method is:
00892 %
00893 %      char *EscapeString(const char *source,const char escape)
00894 %
00895 %  A description of each parameter follows:
00896 %
00897 %    o allocate_string:  Method EscapeString returns the escaped string.
00898 %
00899 %    o source: A character string.
00900 %
00901 %    o escape: the quoted string termination character to escape (e.g. '"').
00902 %
00903 */
00904 MagickExport char *EscapeString(const char *source,const char escape)
00905 {
00906   char
00907     *destination;
00908 
00909   register char
00910     *q;
00911 
00912   register const char
00913     *p;
00914 
00915   size_t
00916     length;
00917 
00918   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00919   assert(source != (const char *) NULL);
00920   length=strlen(source);
00921   for (p=source; *p != '\0'; p++)
00922     if ((*p == '\\') || (*p == escape))
00923       {
00924         if (~length < 1)
00925           ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
00926         length++;
00927       }
00928   destination=(char *) NULL;
00929   if (~length >= (MaxTextExtent-1))
00930     destination=(char *) AcquireQuantumMemory(length+MaxTextExtent,
00931       sizeof(*destination));
00932   if (destination == (char *) NULL)
00933     ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
00934   *destination='\0';
00935   if (source != (char *) NULL)
00936     {
00937       q=destination;
00938       for (p=source; *p != '\0'; p++)
00939       {
00940         if ((*p == '\\') || (*p == escape))
00941           *q++='\\';
00942         *q++=(*p);
00943       }
00944       *q='\0';
00945     }
00946   return(destination);
00947 }
00948 
00949 /*
00950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00951 %                                                                             %
00952 %                                                                             %
00953 %                                                                             %
00954 %   F i l e T o S t r i n g                                                   %
00955 %                                                                             %
00956 %                                                                             %
00957 %                                                                             %
00958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00959 %
00960 %  FileToString() returns the contents of a file as a string.
00961 %
00962 %  The format of the FileToString method is:
00963 %
00964 %      char *FileToString(const char *filename,const size_t extent,
00965 %        ExceptionInfo *exception)
00966 %
00967 %  A description of each parameter follows:
00968 %
00969 %    o filename: the filename.
00970 %
00971 %    o extent: Maximum length of the string.
00972 %
00973 %    o exception: return any errors or warnings in this structure.
00974 %
00975 */
00976 MagickExport char *FileToString(const char *filename,const size_t extent,
00977   ExceptionInfo *exception)
00978 {
00979   size_t
00980     length;
00981 
00982   assert(filename != (const char *) NULL);
00983   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
00984   assert(exception != (ExceptionInfo *) NULL);
00985   return((char *) FileToBlob(filename,extent,&length,exception));
00986 }
00987 
00988 /*
00989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00990 %                                                                             %
00991 %                                                                             %
00992 %                                                                             %
00993 %   F i l e T o S t r i n g I n f o                                           %
00994 %                                                                             %
00995 %                                                                             %
00996 %                                                                             %
00997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00998 %
00999 %  FileToStringInfo() returns the contents of a file as a string.
01000 %
01001 %  The format of the FileToStringInfo method is:
01002 %
01003 %      StringInfo *FileToStringInfo(const char *filename,const size_t extent,
01004 %        ExceptionInfo *exception)
01005 %
01006 %  A description of each parameter follows:
01007 %
01008 %    o filename: the filename.
01009 %
01010 %    o extent: Maximum length of the string.
01011 %
01012 %    o exception: return any errors or warnings in this structure.
01013 %
01014 */
01015 MagickExport StringInfo *FileToStringInfo(const char *filename,
01016   const size_t extent,ExceptionInfo *exception)
01017 {
01018   StringInfo
01019     *string_info;
01020 
01021   assert(filename != (const char *) NULL);
01022   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
01023   assert(exception != (ExceptionInfo *) NULL);
01024   string_info=AcquireStringInfo(0);
01025   (void) CopyMagickString(string_info->path,filename,MaxTextExtent);
01026   string_info->datum=FileToBlob(filename,extent,&string_info->length,exception);
01027   if (string_info->datum == (unsigned char *) NULL)
01028     {
01029       string_info=DestroyStringInfo(string_info);
01030       return((StringInfo *) NULL);
01031     }
01032   return(string_info);
01033 }
01034 
01035 /*
01036 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01037 %                                                                             %
01038 %                                                                             %
01039 %                                                                             %
01040 %  F o r m a t M a g i c k S i z e                                            %
01041 %                                                                             %
01042 %                                                                             %
01043 %                                                                             %
01044 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01045 %
01046 %  FormatMagickSize() converts a size to a human readable format, for example,
01047 %  14k, 234m, 2.7g, or 3.0t.  Scaling is done by repetitively dividing by
01048 %  1000.
01049 %
01050 %  The format of the FormatMagickSize method is:
01051 %
01052 %      ssize_t FormatMagickSize(const MagickSizeType size,char *format)
01053 %
01054 %  A description of each parameter follows:
01055 %
01056 %    o size:  convert this size to a human readable format.
01057 %
01058 %    o bi:  use power of two rather than power of ten.
01059 %
01060 %    o format:  human readable format.
01061 %
01062 */
01063 MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
01064   const MagickBooleanType bi,char *format)
01065 {
01066   const char
01067     **units;
01068 
01069   double
01070     bytes,
01071     length;
01072 
01073   register ssize_t
01074     i,
01075     j;
01076 
01077   ssize_t
01078     count;
01079 
01080   static const char
01081     *bi_units[] =
01082     {
01083       "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", (char *) NULL
01084     },
01085     *traditional_units[] =
01086     {
01087       "", "K", "M", "G", "T", "P", "E", "Z", "Y", (char *) NULL
01088     };
01089 
01090   bytes=1000.0;
01091   units=traditional_units;
01092   if (bi != MagickFalse)
01093     {
01094       bytes=1024.0;
01095       units=bi_units;
01096     }
01097 #if defined(_MSC_VER) && (_MSC_VER == 1200)
01098   length=(double) ((MagickOffsetType) size);
01099 #else
01100   length=(double) size;
01101 #endif
01102   for (i=0; (length >= bytes) && (units[i+1] != (const char *) NULL); i++)
01103     length/=bytes;
01104   for (j=2; j < 12; j++)
01105   {
01106     count=FormatLocaleString(format,MaxTextExtent,"%.*g%sB",(int) (i+j),length,
01107       units[i]);
01108     if (strchr(format,'+') == (char *) NULL)
01109       break;
01110   }
01111   return(count);
01112 }
01113 
01114 /*
01115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01116 %                                                                             %
01117 %                                                                             %
01118 %                                                                             %
01119 %  F o r m a t M a g i c k T i m e                                            %
01120 %                                                                             %
01121 %                                                                             %
01122 %                                                                             %
01123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01124 %
01125 %  FormatMagickTime() returns the specified time in the Internet date/time
01126 %  format and the length of the timestamp.
01127 %
01128 %  The format of the FormatMagickTime method is:
01129 %
01130 %      ssize_t FormatMagickTime(const time_t time,const size_t length,
01131 %        char *timestamp)
01132 %
01133 %  A description of each parameter follows.
01134 %
01135 %   o time:  the time since the Epoch (00:00:00 UTC, January 1, 1970),
01136 %     measured in seconds.
01137 %
01138 %   o length: the maximum length of the string.
01139 %
01140 %   o timestamp:  Return the Internet date/time here.
01141 %
01142 */
01143 MagickExport ssize_t FormatMagickTime(const time_t time,const size_t length,
01144   char *timestamp)
01145 {
01146   ssize_t
01147     count;
01148 
01149   struct tm
01150     gm_time,
01151     local_time;
01152 
01153   time_t
01154     timezone;
01155 
01156   assert(timestamp != (char *) NULL);
01157   (void) ResetMagickMemory(&local_time,0,sizeof(local_time));
01158   (void) ResetMagickMemory(&gm_time,0,sizeof(gm_time));
01159 #if defined(MAGICKCORE_HAVE_LOCALTIME_R)
01160   (void) localtime_r(&time,&local_time);
01161 #else
01162   {
01163     struct tm
01164       *my_time;
01165 
01166     my_time=localtime(&time);
01167     if (my_time != (struct tm *) NULL)
01168       (void) memcpy(&local_time,my_time,sizeof(local_time));
01169   }
01170 #endif
01171 #if defined(MAGICKCORE_HAVE_GMTIME_R)
01172   (void) gmtime_r(&time,&gm_time);
01173 #else
01174   {
01175     struct tm
01176       *my_time;
01177 
01178     my_time=gmtime(&time);
01179     if (my_time != (struct tm *) NULL)
01180       (void) memcpy(&gm_time,my_time,sizeof(gm_time));
01181   }
01182 #endif
01183   timezone=(time_t) ((local_time.tm_min-gm_time.tm_min)/60+
01184     local_time.tm_hour-gm_time.tm_hour+24*((local_time.tm_year-
01185     gm_time.tm_year) != 0 ? (local_time.tm_year-gm_time.tm_year) :
01186     (local_time.tm_yday-gm_time.tm_yday)));
01187   count=FormatLocaleString(timestamp,length,
01188     "%04d-%02d-%02dT%02d:%02d:%02d%+03ld:00",local_time.tm_year+1900,
01189     local_time.tm_mon+1,local_time.tm_mday,local_time.tm_hour,
01190     local_time.tm_min,local_time.tm_sec,(long) timezone);
01191   return(count);
01192 }
01193 
01194 /*
01195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01196 %                                                                             %
01197 %                                                                             %
01198 %                                                                             %
01199 %   G e t E n v i r o n m e n t V a l u e                                     %
01200 %                                                                             %
01201 %                                                                             %
01202 %                                                                             %
01203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01204 %
01205 %  GetEnvironmentValue() returns the environment string that matches the
01206 %  specified name.
01207 %
01208 %  The format of the GetEnvironmentValue method is:
01209 %
01210 %      char *GetEnvironmentValue(const char *name)
01211 %
01212 %  A description of each parameter follows:
01213 %
01214 %    o name: the environment name.
01215 %
01216 */
01217 MagickExport char *GetEnvironmentValue(const char *name)
01218 {
01219   const char
01220     *environment;
01221 
01222   environment=getenv(name);
01223   if (environment == (const char *) NULL)
01224     return((char *) NULL);
01225   return(ConstantString(environment));
01226 }
01227 
01228 /*
01229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01230 %                                                                             %
01231 %                                                                             %
01232 %                                                                             %
01233 %   G e t S t r i n g I n f o D a t u m                                       %
01234 %                                                                             %
01235 %                                                                             %
01236 %                                                                             %
01237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01238 %
01239 %  GetStringInfoDatum() returns the datum associated with the string.
01240 %
01241 %  The format of the GetStringInfoDatum method is:
01242 %
01243 %      unsigned char *GetStringInfoDatum(const StringInfo *string_info)
01244 %
01245 %  A description of each parameter follows:
01246 %
01247 %    o string_info: the string info.
01248 %
01249 */
01250 MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
01251 {
01252   assert(string_info != (StringInfo *) NULL);
01253   assert(string_info->signature == MagickSignature);
01254   return(string_info->datum);
01255 }
01256 
01257 /*
01258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01259 %                                                                             %
01260 %                                                                             %
01261 %                                                                             %
01262 %   G e t S t r i n g I n f o L e n g t h                                     %
01263 %                                                                             %
01264 %                                                                             %
01265 %                                                                             %
01266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01267 %
01268 %  GetStringInfoLength() returns the string length.
01269 %
01270 %  The format of the GetStringInfoLength method is:
01271 %
01272 %      size_t GetStringInfoLength(const StringInfo *string_info)
01273 %
01274 %  A description of each parameter follows:
01275 %
01276 %    o string_info: the string info.
01277 %
01278 */
01279 MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
01280 {
01281   assert(string_info != (StringInfo *) NULL);
01282   assert(string_info->signature == MagickSignature);
01283   return(string_info->length);
01284 }
01285 
01286 /*
01287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01288 %                                                                             %
01289 %                                                                             %
01290 %                                                                             %
01291 %   G e t S t r i n g I n f o P a t h                                         %
01292 %                                                                             %
01293 %                                                                             %
01294 %                                                                             %
01295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01296 %
01297 %  GetStringInfoPath() returns the path associated with the string.
01298 %
01299 %  The format of the GetStringInfoPath method is:
01300 %
01301 %      const char *GetStringInfoPath(const StringInfo *string_info)
01302 %
01303 %  A description of each parameter follows:
01304 %
01305 %    o string_info: the string info.
01306 %
01307 */
01308 MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
01309 {
01310   assert(string_info != (StringInfo *) NULL);
01311   assert(string_info->signature == MagickSignature);
01312   return(string_info->path);
01313 }
01314 
01315 /*
01316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01317 %                                                                             %
01318 %                                                                             %
01319 %                                                                             %
01320 +   I n t e r p r e t S i P r e f i x V a l u e                               %
01321 %                                                                             %
01322 %                                                                             %
01323 %                                                                             %
01324 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01325 %
01326 %  InterpretSiPrefixValue() converts the initial portion of the string to a
01327 %  double representation.  It also recognizes SI prefixes (e.g. B, KB, MiB,
01328 %  etc.).
01329 %
01330 %  The format of the InterpretSiPrefixValue method is:
01331 %
01332 %      double InterpretSiPrefixValue(const char *value,char **sentinal)
01333 %
01334 %  A description of each parameter follows:
01335 %
01336 %    o value: the string value.
01337 %
01338 %    o sentinal:  if sentinal is not NULL, return a pointer to the character
01339 %      after the last character used in the conversion.
01340 %
01341 */
01342 MagickExport double InterpretSiPrefixValue(const char *restrict string,
01343   char **restrict sentinal)
01344 {
01345   char
01346     *q;
01347 
01348   double
01349     value;
01350 
01351   value=InterpretLocaleValue(string,&q);
01352   if (q != string)
01353     {
01354       if ((*q >= 'E') && (*q <= 'z'))
01355         {
01356           double
01357             e;
01358 
01359           switch ((int) ((unsigned char) *q))
01360           {
01361             case 'y': e=(-24.0); break;
01362             case 'z': e=(-21.0); break;
01363             case 'a': e=(-18.0); break;
01364             case 'f': e=(-15.0); break;
01365             case 'p': e=(-12.0); break;
01366             case 'n': e=(-9.0); break;
01367             case 'u': e=(-6.0); break;
01368             case 'm': e=(-3.0); break;
01369             case 'c': e=(-2.0); break;
01370             case 'd': e=(-1.0); break;
01371             case 'h': e=2.0; break;
01372             case 'k': e=3.0; break;
01373             case 'K': e=3.0; break;
01374             case 'M': e=6.0; break;
01375             case 'G': e=9.0; break;
01376             case 'T': e=12.0; break;
01377             case 'P': e=15.0; break;
01378             case 'E': e=18.0; break;
01379             case 'Z': e=21.0; break;
01380             case 'Y': e=24.0; break;
01381             default: e=0.0; break;
01382           }
01383           if (e >= MagickEpsilon)
01384             {
01385               if (q[1] == 'i')
01386                 {
01387                   value*=pow(2.0,e/0.3);
01388                   q+=2;
01389                 }
01390               else
01391                 {
01392                   value*=pow(10.0,e);
01393                   q++;
01394                 }
01395             }
01396         }
01397       if (*q == 'B')
01398         q++;
01399     }
01400   if (sentinal != (char **) NULL)
01401     *sentinal=q;
01402   return(value);
01403 }
01404 
01405 /*
01406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01407 %                                                                             %
01408 %                                                                             %
01409 %                                                                             %
01410 %   L o c a l e C o m p a r e                                                 %
01411 %                                                                             %
01412 %                                                                             %
01413 %                                                                             %
01414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01415 %
01416 %  LocaleCompare() performs a case-insensitive comparison of two strings
01417 %  byte-by-byte, according to the ordering of the current locale encoding.
01418 %  LocaleCompare returns an integer greater than, equal to, or less than 0,
01419 %  if the string pointed to by p is greater than, equal to, or less than the
01420 %  string pointed to by q respectively.  The sign of a non-zero return value
01421 %  is determined by the sign of the difference between the values of the first
01422 %  pair of bytes that differ in the strings being compared.
01423 %
01424 %  The format of the LocaleCompare method is:
01425 %
01426 %      int LocaleCompare(const char *p,const char *q)
01427 %
01428 %  A description of each parameter follows:
01429 %
01430 %    o p: A pointer to a character string.
01431 %
01432 %    o q: A pointer to a character string to compare to p.
01433 %
01434 */
01435 MagickExport int LocaleCompare(const char *p,const char *q)
01436 {
01437   if ((p == (char *) NULL) && (q == (char *) NULL))
01438     return(0);
01439   if (p == (char *) NULL)
01440     return(-1);
01441   if (q == (char *) NULL)
01442     return(1);
01443 #if defined(MAGICKCORE_HAVE_STRCASECMP)
01444   return(strcasecmp(p,q));
01445 #else
01446   {
01447     register int
01448       c,
01449       d;
01450 
01451     for ( ; ; )
01452     {
01453       c=(int) *((unsigned char *) p);
01454       d=(int) *((unsigned char *) q);
01455       if ((c == 0) || (AsciiMap[c] != AsciiMap[d]))
01456         break;
01457       p++;
01458       q++;
01459     }
01460     return(AsciiMap[c]-(int) AsciiMap[d]);
01461   }
01462 #endif
01463 }
01464 
01465 /*
01466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01467 %                                                                             %
01468 %                                                                             %
01469 %                                                                             %
01470 %   L o c a l e L o w e r                                                     %
01471 %                                                                             %
01472 %                                                                             %
01473 %                                                                             %
01474 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01475 %
01476 %  LocaleLower() transforms all of the characters in the supplied
01477 %  null-terminated string, changing all uppercase letters to lowercase.
01478 %
01479 %  The format of the LocaleLower method is:
01480 %
01481 %      void LocaleLower(char *string)
01482 %
01483 %  A description of each parameter follows:
01484 %
01485 %    o string: A pointer to the string to convert to lower-case Locale.
01486 %
01487 */
01488 MagickExport void LocaleLower(char *string)
01489 {
01490   register char
01491     *q;
01492 
01493   assert(string != (char *) NULL);
01494   for (q=string; *q != '\0'; q++)
01495     *q=(char) tolower((int) *q);
01496 }
01497 
01498 /*
01499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01500 %                                                                             %
01501 %                                                                             %
01502 %                                                                             %
01503 %   L o c a l e N C o m p a r e                                               %
01504 %                                                                             %
01505 %                                                                             %
01506 %                                                                             %
01507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01508 %
01509 %  LocaleNCompare() performs a case-insensitive comparison of two
01510 %  strings byte-by-byte, according to the ordering of the current locale
01511 %  encoding. LocaleNCompare returns an integer greater than, equal to, or
01512 %  less than 0, if the string pointed to by p is greater than, equal to, or
01513 %  less than the string pointed to by q respectively.  The sign of a non-zero
01514 %  return value is determined by the sign of the difference between the
01515 %  values of the first pair of bytes that differ in the strings being
01516 %  compared.  The LocaleNCompare method makes the same comparison as
01517 %  LocaleCompare but looks at a maximum of n bytes.  Bytes following a
01518 %  null byte are not compared.
01519 %
01520 %  The format of the LocaleNCompare method is:
01521 %
01522 %      int LocaleNCompare(const char *p,const char *q,const size_t n)
01523 %
01524 %  A description of each parameter follows:
01525 %
01526 %    o p: A pointer to a character string.
01527 %
01528 %    o q: A pointer to a character string to compare to p.
01529 %
01530 %    o length: the number of characters to compare in strings p and q.
01531 %
01532 */
01533 MagickExport int LocaleNCompare(const char *p,const char *q,const size_t length)
01534 {
01535   if ((p == (char *) NULL) && (q == (char *) NULL))
01536     return(0);
01537   if (p == (char *) NULL)
01538     return(-1);
01539   if (q == (char *) NULL)
01540     return(1);
01541 #if defined(MAGICKCORE_HAVE_STRNCASECMP)
01542   return(strncasecmp(p,q,length));
01543 #else
01544   {
01545     register int
01546       c,
01547       d;
01548 
01549     register size_t
01550       i;
01551 
01552     for (i=length; i != 0; i--)
01553     {
01554       c=(int) *((unsigned char *) p);
01555       d=(int) *((unsigned char *) q);
01556       if (AsciiMap[c] != AsciiMap[d])
01557         return(AsciiMap[c]-(int) AsciiMap[d]);
01558       if (c == 0)
01559         return(0);
01560       p++;
01561       q++;
01562     }
01563     return(0);
01564   }
01565 #endif
01566 }
01567 
01568 /*
01569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01570 %                                                                             %
01571 %                                                                             %
01572 %                                                                             %
01573 %   L o c a l e U p p e r                                                     %
01574 %                                                                             %
01575 %                                                                             %
01576 %                                                                             %
01577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01578 %
01579 %  LocaleUpper() transforms all of the characters in the supplied
01580 %  null-terminated string, changing all lowercase letters to uppercase.
01581 %
01582 %  The format of the LocaleUpper method is:
01583 %
01584 %      void LocaleUpper(char *string)
01585 %
01586 %  A description of each parameter follows:
01587 %
01588 %    o string: A pointer to the string to convert to upper-case Locale.
01589 %
01590 */
01591 MagickExport void LocaleUpper(char *string)
01592 {
01593   register char
01594     *q;
01595 
01596   assert(string != (char *) NULL);
01597   for (q=string; *q != '\0'; q++)
01598     *q=(char) toupper((int) *q);
01599 }
01600 
01601 /*
01602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01603 %                                                                             %
01604 %                                                                             %
01605 %                                                                             %
01606 %   P r i n t S t r i n g I n f o                                             %
01607 %                                                                             %
01608 %                                                                             %
01609 %                                                                             %
01610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01611 %
01612 %  PrintStringInfo() prints the string.
01613 %
01614 %  The format of the PrintStringInfo method is:
01615 %
01616 %      void PrintStringInfo(FILE *file,const char *id,
01617 %        const StringInfo *string_info)
01618 %
01619 %  A description of each parameter follows:
01620 %
01621 %    o file: the file, typically stdout.
01622 %
01623 %    o id: the string id.
01624 %
01625 %    o string_info: the string info.
01626 %
01627 */
01628 MagickExport void PrintStringInfo(FILE *file,const char *id,
01629   const StringInfo *string_info)
01630 {
01631   register const char
01632     *p;
01633 
01634   register size_t
01635     i,
01636     j;
01637 
01638   assert(id != (const char *) NULL);
01639   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",id);
01640   assert(string_info != (StringInfo *) NULL);
01641   assert(string_info->signature == MagickSignature);
01642   p=(char *) string_info->datum;
01643   for (i=0; i < string_info->length; i++)
01644   {
01645     if (((int) ((unsigned char) *p) < 32) &&
01646         (isspace((int) ((unsigned char) *p)) == 0))
01647       break;
01648     p++;
01649   }
01650   if (i == string_info->length)
01651     {
01652       (void) fputs((char *) string_info->datum,file);
01653       (void) fputc('\n',file);
01654       return;
01655     }
01656   /*
01657     Convert string to a HEX list.
01658   */
01659   p=(char *) string_info->datum;
01660   for (i=0; i < string_info->length; i+=0x14)
01661   {
01662     (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) (0x14*i));
01663     for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
01664     {
01665       (void) FormatLocaleFile(file,"%02lx",(unsigned long) (*(p+j)) & 0xff);
01666       if ((j % 0x04) == 0)
01667         (void) fputc(' ',file);
01668     }
01669     for ( ; j <= 0x14; j++)
01670     {
01671       (void) fputc(' ',file);
01672       (void) fputc(' ',file);
01673       if ((j % 0x04) == 0)
01674         (void) fputc(' ',file);
01675     }
01676     (void) fputc(' ',file);
01677     for (j=1; j <= MagickMin(string_info->length-i,0x14); j++)
01678     {
01679       if (isprint((int) ((unsigned char) *p)) != 0)
01680         (void) fputc(*p,file);
01681       else
01682         (void) fputc('-',file);
01683       p++;
01684     }
01685     (void) fputc('\n',file);
01686   }
01687 }
01688 
01689 /*
01690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01691 %                                                                             %
01692 %                                                                             %
01693 %                                                                             %
01694 %   R e s e t S t r i n g I n f o                                             %
01695 %                                                                             %
01696 %                                                                             %
01697 %                                                                             %
01698 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01699 %
01700 %  ResetStringInfo() reset the string to all null bytes.
01701 %
01702 %  The format of the ResetStringInfo method is:
01703 %
01704 %      void ResetStringInfo(StringInfo *string_info)
01705 %
01706 %  A description of each parameter follows:
01707 %
01708 %    o string_info: the string info.
01709 %
01710 */
01711 MagickExport void ResetStringInfo(StringInfo *string_info)
01712 {
01713   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01714   assert(string_info != (StringInfo *) NULL);
01715   assert(string_info->signature == MagickSignature);
01716   (void) ResetMagickMemory(string_info->datum,0,string_info->length);
01717 }
01718 
01719 /*
01720 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01721 %                                                                             %
01722 %                                                                             %
01723 %                                                                             %
01724 %   S e t S t r i n g I n f o                                                 %
01725 %                                                                             %
01726 %                                                                             %
01727 %                                                                             %
01728 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01729 %
01730 %  SetStringInfo() copies the source string to the destination string.
01731 %
01732 %  The format of the SetStringInfo method is:
01733 %
01734 %      void SetStringInfo(StringInfo *string_info,const StringInfo *source)
01735 %
01736 %  A description of each parameter follows:
01737 %
01738 %    o string_info: the string info.
01739 %
01740 %    o source: the source string.
01741 %
01742 */
01743 MagickExport void SetStringInfo(StringInfo *string_info,
01744   const StringInfo *source)
01745 {
01746   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01747   assert(string_info != (StringInfo *) NULL);
01748   assert(string_info->signature == MagickSignature);
01749   assert(source != (StringInfo *) NULL);
01750   assert(source->signature == MagickSignature);
01751   if (string_info->length == 0)
01752     return;
01753   (void) ResetMagickMemory(string_info->datum,0,string_info->length);
01754   (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
01755     source->length));
01756 }
01757 
01758 /*
01759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01760 %                                                                             %
01761 %                                                                             %
01762 %                                                                             %
01763 %   S e t S t r i n g I n f o D a t u m                                       %
01764 %                                                                             %
01765 %                                                                             %
01766 %                                                                             %
01767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01768 %
01769 %  SetStringInfoDatum() copies bytes from the source string for the length of
01770 %  the destination string.
01771 %
01772 %  The format of the SetStringInfoDatum method is:
01773 %
01774 %      void SetStringInfoDatum(StringInfo *string_info,
01775 %        const unsigned char *source)
01776 %
01777 %  A description of each parameter follows:
01778 %
01779 %    o string_info: the string info.
01780 %
01781 %    o source: the source string.
01782 %
01783 */
01784 MagickExport void SetStringInfoDatum(StringInfo *string_info,
01785   const unsigned char *source)
01786 {
01787   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01788   assert(string_info != (StringInfo *) NULL);
01789   assert(string_info->signature == MagickSignature);
01790   if (string_info->length != 0)
01791     (void) memcpy(string_info->datum,source,string_info->length);
01792 }
01793 
01794 /*
01795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01796 %                                                                             %
01797 %                                                                             %
01798 %                                                                             %
01799 %   S e t S t r i n g I n f o L e n g t h                                     %
01800 %                                                                             %
01801 %                                                                             %
01802 %                                                                             %
01803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01804 %
01805 %  SetStringInfoLength() set the string length to the specified value.
01806 %
01807 %  The format of the SetStringInfoLength method is:
01808 %
01809 %      void SetStringInfoLength(StringInfo *string_info,const size_t length)
01810 %
01811 %  A description of each parameter follows:
01812 %
01813 %    o string_info: the string info.
01814 %
01815 %    o length: the string length.
01816 %
01817 */
01818 MagickExport void SetStringInfoLength(StringInfo *string_info,
01819   const size_t length)
01820 {
01821   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01822   assert(string_info != (StringInfo *) NULL);
01823   assert(string_info->signature == MagickSignature);
01824   if (~length < MaxTextExtent)
01825     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01826   string_info->length=length;
01827   if (string_info->datum == (unsigned char *) NULL)
01828     string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
01829       MaxTextExtent,sizeof(*string_info->datum));
01830   else
01831     string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
01832       length+MaxTextExtent,sizeof(*string_info->datum));
01833   if (string_info->datum == (unsigned char *) NULL)
01834     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01835 }
01836 
01837 /*
01838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01839 %                                                                             %
01840 %                                                                             %
01841 %                                                                             %
01842 %   S e t S t r i n g I n f o D a t u m                                       %
01843 %                                                                             %
01844 %                                                                             %
01845 %                                                                             %
01846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01847 %
01848 %  SetStringInfoPath() sets the path associated with the string.
01849 %
01850 %  The format of the SetStringInfoPath method is:
01851 %
01852 %      void SetStringInfoPath(StringInfo *string_info,const char *path)
01853 %
01854 %  A description of each parameter follows:
01855 %
01856 %    o string_info: the string info.
01857 %
01858 %    o path: the path.
01859 %
01860 */
01861 MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
01862 {
01863   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01864   assert(string_info != (StringInfo *) NULL);
01865   assert(string_info->signature == MagickSignature);
01866   assert(path != (const char *) NULL);
01867   (void) CopyMagickString(string_info->path,path,MaxTextExtent);
01868 }
01869 
01870 /*
01871 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01872 %                                                                             %
01873 %                                                                             %
01874 %                                                                             %
01875 %   S p l i t S t r i n g I n f o                                             %
01876 %                                                                             %
01877 %                                                                             %
01878 %                                                                             %
01879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01880 %
01881 %  SplitStringInfo() splits a string into two and returns it.
01882 %
01883 %  The format of the SplitStringInfo method is:
01884 %
01885 %      StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
01886 %
01887 %  A description of each parameter follows:
01888 %
01889 %    o string_info: the string info.
01890 %
01891 */
01892 MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
01893   const size_t offset)
01894 {
01895   StringInfo
01896     *split_info;
01897 
01898   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
01899   assert(string_info != (StringInfo *) NULL);
01900   assert(string_info->signature == MagickSignature);
01901   if (offset > string_info->length)
01902     return((StringInfo *) NULL);
01903   split_info=AcquireStringInfo(offset);
01904   SetStringInfo(split_info,string_info);
01905   (void) memmove(string_info->datum,string_info->datum+offset,
01906     string_info->length-offset+MaxTextExtent);
01907   SetStringInfoLength(string_info,string_info->length-offset);
01908   return(split_info);
01909 }
01910 
01911 /*
01912 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01913 %                                                                             %
01914 %                                                                             %
01915 %                                                                             %
01916 %   S t r i n g I n f o T o S t r i n g                                       %
01917 %                                                                             %
01918 %                                                                             %
01919 %                                                                             %
01920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01921 %
01922 %  StringInfoToString() converts a string info string to a C string.
01923 %
01924 %  The format of the StringInfoToString method is:
01925 %
01926 %      char *StringInfoToString(const StringInfo *string_info)
01927 %
01928 %  A description of each parameter follows:
01929 %
01930 %    o string_info: the string.
01931 %
01932 */
01933 MagickExport char *StringInfoToString(const StringInfo *string_info)
01934 {
01935   char
01936     *string;
01937 
01938   size_t
01939     length;
01940 
01941   string=(char *) NULL;
01942   length=string_info->length;
01943   if (~length >= (MaxTextExtent-1))
01944     string=(char *) AcquireQuantumMemory(length+MaxTextExtent,sizeof(*string));
01945   if (string == (char *) NULL)
01946     return((char *) NULL);
01947   (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
01948   string[length]='\0';
01949   return(string);
01950 }
01951 
01952 /*
01953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01954 %                                                                             %
01955 %                                                                             %
01956 %                                                                             %
01957 %  S t r i n g T o A r g v                                                    %
01958 %                                                                             %
01959 %                                                                             %
01960 %                                                                             %
01961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01962 %
01963 %  StringToArgv() converts a text string into command line arguments.
01964 %  The 'argv' array of arguments, is returned while the number of arguments
01965 %  is returned via the provided integer variable pointer.
01966 %
01967 %  Simple 'word' tokenizer, which allows for each word to be optionally
01968 %  quoted.  However it will not allow use of partial quotes, or escape
01969 %  characters.
01970 %
01971 %  The format of the StringToArgv method is:
01972 %
01973 %      char **StringToArgv(const char *text,int *argc)
01974 %
01975 %  A description of each parameter follows:
01976 %
01977 %    o argv:  Method StringToArgv returns the string list unless an error
01978 %      occurs, otherwise NULL.
01979 %
01980 %    o text:  Specifies the string to segment into a list.
01981 %
01982 %    o argc:  This integer pointer returns the number of arguments in the
01983 %      list.
01984 %
01985 */
01986 MagickExport char **StringToArgv(const char *text,int *argc)
01987 {
01988   char
01989     **argv;
01990 
01991   register const char
01992     *p,
01993     *q;
01994 
01995   register ssize_t
01996     i;
01997 
01998   *argc=0;
01999   if (text == (char *) NULL)
02000     return((char **) NULL);
02001   /*
02002     Determine the number of arguments.
02003   */
02004   for (p=text; *p != '\0'; )
02005   {
02006     while (isspace((int) ((unsigned char) *p)) != 0)
02007       p++;
02008     if (*p == '\0')
02009       break;
02010     (*argc)++;
02011     if (*p == '"')
02012       for (p++; (*p != '"') && (*p != '\0'); p++) ;
02013     if (*p == '\'')
02014       for (p++; (*p != '\'') && (*p != '\0'); p++) ;
02015     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
02016       p++;
02017   }
02018   (*argc)++;
02019   argv=(char **) AcquireQuantumMemory((size_t) (*argc+1UL),sizeof(*argv));
02020   if (argv == (char **) NULL)
02021     ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
02022   /*
02023     Convert string to an ASCII list.
02024   */
02025   argv[0]=AcquireString("magick");
02026   p=text;
02027   for (i=1; i < (ssize_t) *argc; i++)
02028   {
02029     while (isspace((int) ((unsigned char) *p)) != 0)
02030       p++;
02031     q=p;
02032     if (*q == '"')
02033       {
02034         p++;
02035         for (q++; (*q != '"') && (*q != '\0'); q++) ;
02036       }
02037     else
02038       if (*q == '\'')
02039         {
02040           p++;
02041           for (q++; (*q != '\'') && (*q != '\0'); q++) ;
02042         }
02043       else
02044         while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
02045           q++;
02046     argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
02047       sizeof(**argv));
02048     if (argv[i] == (char *) NULL)
02049       {
02050         for (i--; i >= 0; i--)
02051           argv[i]=DestroyString(argv[i]);
02052         argv=(char **) RelinquishMagickMemory(argv);
02053         ThrowFatalException(ResourceLimitFatalError,
02054           "UnableToConvertStringToARGV");
02055       }
02056     (void) memcpy(argv[i],p,(size_t) (q-p));
02057     argv[i][q-p]='\0';
02058     p=q;
02059     while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
02060       p++;
02061   }
02062   argv[i]=(char *) NULL;
02063   return(argv);
02064 }
02065 
02066 /*
02067 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02068 %                                                                             %
02069 %                                                                             %
02070 %                                                                             %
02071 %   S t r i n g I n f o T o H e x S t r i n g                                 %
02072 %                                                                             %
02073 %                                                                             %
02074 %                                                                             %
02075 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02076 %
02077 %  StringInfoToHexString() converts a string info string to a C string.
02078 %
02079 %  The format of the StringInfoToHexString method is:
02080 %
02081 %      char *StringInfoToHexString(const StringInfo *string_info)
02082 %
02083 %  A description of each parameter follows:
02084 %
02085 %    o string_info: the string.
02086 %
02087 */
02088 MagickExport char *StringInfoToHexString(const StringInfo *string_info)
02089 {
02090   char
02091     *string;
02092 
02093   register const unsigned char
02094     *p;
02095 
02096   register ssize_t
02097     i;
02098 
02099   register unsigned char
02100     *q;
02101 
02102   size_t
02103     length;
02104 
02105   unsigned char
02106     hex_digits[16];
02107 
02108   length=string_info->length;
02109   if (~length < MaxTextExtent)
02110     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
02111   string=(char *) AcquireQuantumMemory(length+MaxTextExtent,2*sizeof(*string));
02112   if (string == (char *) NULL)
02113     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
02114   hex_digits[0]='0';
02115   hex_digits[1]='1';
02116   hex_digits[2]='2';
02117   hex_digits[3]='3';
02118   hex_digits[4]='4';
02119   hex_digits[5]='5';
02120   hex_digits[6]='6';
02121   hex_digits[7]='7';
02122   hex_digits[8]='8';
02123   hex_digits[9]='9';
02124   hex_digits[10]='a';
02125   hex_digits[11]='b';
02126   hex_digits[12]='c';
02127   hex_digits[13]='d';
02128   hex_digits[14]='e';
02129   hex_digits[15]='f';
02130   p=string_info->datum;
02131   q=(unsigned char *) string;
02132   for (i=0; i < (ssize_t) string_info->length; i++)
02133   {
02134     *q++=hex_digits[(*p >> 4) & 0x0f];
02135     *q++=hex_digits[*p & 0x0f];
02136     p++;
02137   }
02138   *q='\0';
02139   return(string);
02140 }
02141 
02142 /*
02143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02144 %                                                                             %
02145 %                                                                             %
02146 %                                                                             %
02147 %   S t r i n g T o k e n                                                     %
02148 %                                                                             %
02149 %                                                                             %
02150 %                                                                             %
02151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02152 %
02153 %  StringToken() extracts a token a from the string.
02154 %
02155 %  The format of the StringToken method is:
02156 %
02157 %      char *StringToken(const char *delimiters,char **string)
02158 %
02159 %  A description of each parameter follows:
02160 %
02161 %    o delimiters: one or more delimiters.
02162 %
02163 %    o string: return the first token in the string.  If none is found, return
02164 %      NULL.
02165 %
02166 */
02167 MagickExport char *StringToken(const char *delimiters,char **string)
02168 {
02169   char
02170     *q;
02171 
02172   register char
02173     *p;
02174 
02175   register const char
02176     *r;
02177 
02178   register int
02179     c,
02180     d;
02181 
02182   p=(*string);
02183   if (p == (char *) NULL)
02184     return((char *) NULL);
02185   for (q=p; ; )
02186   {
02187     c=(*p++);
02188     r=delimiters;
02189     do
02190     {
02191       d=(*r++);
02192       if (c == d)
02193         {
02194           if (c == '\0')
02195             p=(char *) NULL;
02196           else
02197             p[-1]='\0';
02198           *string=p;
02199           return(q);
02200         }
02201     } while (d != '\0');
02202   }
02203 }
02204 
02205 /*
02206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02207 %                                                                             %
02208 %                                                                             %
02209 %                                                                             %
02210 %  S t r i n g T o L i s t                                                    %
02211 %                                                                             %
02212 %                                                                             %
02213 %                                                                             %
02214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02215 %
02216 %  StringToList() converts a text string into a list by segmenting the text
02217 %  string at each carriage return discovered.  The list is converted to HEX
02218 %  characters if any control characters are discovered within the text string.
02219 %
02220 %  The format of the StringToList method is:
02221 %
02222 %      char **StringToList(const char *text)
02223 %
02224 %  A description of each parameter follows:
02225 %
02226 %    o text:  Specifies the string to segment into a list.
02227 %
02228 */
02229 MagickExport char **StringToList(const char *text)
02230 {
02231   char
02232     **textlist;
02233 
02234   register const char
02235     *p;
02236 
02237   register ssize_t
02238     i;
02239 
02240   size_t
02241     lines;
02242 
02243   if (text == (char *) NULL)
02244     return((char **) NULL);
02245   for (p=text; *p != '\0'; p++)
02246     if (((int) ((unsigned char) *p) < 32) &&
02247         (isspace((int) ((unsigned char) *p)) == 0))
02248       break;
02249   if (*p == '\0')
02250     {
02251       register const char
02252         *q;
02253 
02254       /*
02255         Convert string to an ASCII list.
02256       */
02257       lines=1;
02258       for (p=text; *p != '\0'; p++)
02259         if (*p == '\n')
02260           lines++;
02261       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
02262         sizeof(*textlist));
02263       if (textlist == (char **) NULL)
02264         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
02265       p=text;
02266       for (i=0; i < (ssize_t) lines; i++)
02267       {
02268         for (q=p; *q != '\0'; q++)
02269           if ((*q == '\r') || (*q == '\n'))
02270             break;
02271         textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
02272           sizeof(**textlist));
02273         if (textlist[i] == (char *) NULL)
02274           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
02275         (void) memcpy(textlist[i],p,(size_t) (q-p));
02276         textlist[i][q-p]='\0';
02277         if (*q == '\r')
02278           q++;
02279         p=q+1;
02280       }
02281     }
02282   else
02283     {
02284       char
02285         hex_string[MaxTextExtent];
02286 
02287       register char
02288         *q;
02289 
02290       register ssize_t
02291         j;
02292 
02293       /*
02294         Convert string to a HEX list.
02295       */
02296       lines=(size_t) (strlen(text)/0x14)+1;
02297       textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
02298         sizeof(*textlist));
02299       if (textlist == (char **) NULL)
02300         ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
02301       p=text;
02302       for (i=0; i < (ssize_t) lines; i++)
02303       {
02304         textlist[i]=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
02305           sizeof(**textlist));
02306         if (textlist[i] == (char *) NULL)
02307           ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
02308         (void) FormatLocaleString(textlist[i],MaxTextExtent,"0x%08lx: ",
02309           (long) (0x14*i));
02310         q=textlist[i]+strlen(textlist[i]);
02311         for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
02312         {
02313           (void) FormatLocaleString(hex_string,MaxTextExtent,"%02x",*(p+j));
02314           (void) CopyMagickString(q,hex_string,MaxTextExtent);
02315           q+=2;
02316           if ((j % 0x04) == 0)
02317             *q++=' ';
02318         }
02319         for ( ; j <= 0x14; j++)
02320         {
02321           *q++=' ';
02322           *q++=' ';
02323           if ((j % 0x04) == 0)
02324             *q++=' ';
02325         }
02326         *q++=' ';
02327         for (j=1; j <= (ssize_t) MagickMin(strlen(p),0x14); j++)
02328         {
02329           if (isprint((int) ((unsigned char) *p)) != 0)
02330             *q++=(*p);
02331           else
02332             *q++='-';
02333           p++;
02334         }
02335         *q='\0';
02336       }
02337     }
02338   textlist[i]=(char *) NULL;
02339   return(textlist);
02340 }
02341 
02342 /*
02343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02344 %                                                                             %
02345 %                                                                             %
02346 %                                                                             %
02347 %   S t r i n g T o S t r i n g I n f o                                       %
02348 %                                                                             %
02349 %                                                                             %
02350 %                                                                             %
02351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02352 %
02353 %  StringToStringInfo() converts a string to a StringInfo type.
02354 %
02355 %  The format of the StringToStringInfo method is:
02356 %
02357 %      StringInfo *StringToStringInfo(const char *string)
02358 %
02359 %  A description of each parameter follows:
02360 %
02361 %    o string:  The string.
02362 %
02363 */
02364 MagickExport StringInfo *StringToStringInfo(const char *string)
02365 {
02366   StringInfo
02367     *string_info;
02368 
02369   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
02370   assert(string != (const char *) NULL);
02371   string_info=AcquireStringInfo(strlen(string));
02372   SetStringInfoDatum(string_info,(const unsigned char *) string);
02373   return(string_info);
02374 }
02375 
02376 /*
02377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02378 %                                                                             %
02379 %                                                                             %
02380 %                                                                             %
02381 %   S t r i p S t r i n g                                                     %
02382 %                                                                             %
02383 %                                                                             %
02384 %                                                                             %
02385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02386 %
02387 %  StripString() strips any whitespace or quotes from the beginning and end of
02388 %  a string of characters.
02389 %
02390 %  The format of the StripString method is:
02391 %
02392 %      void StripString(char *message)
02393 %
02394 %  A description of each parameter follows:
02395 %
02396 %    o message: Specifies an array of characters.
02397 %
02398 */
02399 MagickExport void StripString(char *message)
02400 {
02401   register char
02402     *p,
02403     *q;
02404 
02405   size_t
02406     length;
02407 
02408   assert(message != (char *) NULL);
02409   if (*message == '\0')
02410     return;
02411   length=strlen(message);
02412   p=message;
02413   while (isspace((int) ((unsigned char) *p)) != 0)
02414     p++;
02415   if ((*p == '\'') || (*p == '"'))
02416     p++;
02417   q=message+length-1;
02418   while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
02419     q--;
02420   if (q > p)
02421     if ((*q == '\'') || (*q == '"'))
02422       q--;
02423   (void) memmove(message,p,(size_t) (q-p+1));
02424   message[q-p+1]='\0';
02425   for (p=message; *p != '\0'; p++)
02426     if (*p == '\n')
02427       *p=' ';
02428 }
02429 
02430 /*
02431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02432 %                                                                             %
02433 %                                                                             %
02434 %                                                                             %
02435 %   S u b s t i t u t e S t r i n g                                           %
02436 %                                                                             %
02437 %                                                                             %
02438 %                                                                             %
02439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
02440 %
02441 %  SubstituteString() performs string substitution on a string, replacing the
02442 %  string with the substituted version. Buffer must be allocated from the heap.
02443 %  If the string is matched and status, MagickTrue is returned otherwise
02444 %  MagickFalse.
02445 %
02446 %  The format of the SubstituteString method is:
02447 %
02448 %      MagickBooleanType SubstituteString(char **string,const char *search,
02449 %        const char *replace)
02450 %
02451 %  A description of each parameter follows:
02452 %
02453 %    o string: the string to perform replacements on;  replaced with new
02454 %      allocation if a replacement is made.
02455 %
02456 %    o search: search for this string.
02457 %
02458 %    o replace: replace any matches with this string.
02459 %
02460 */
02461 MagickExport MagickBooleanType SubstituteString(char **string,
02462   const char *search,const char *replace)
02463 {
02464   MagickBooleanType
02465     status;
02466 
02467   register char
02468     *p;
02469 
02470   size_t
02471     extent,
02472     replace_extent,
02473     search_extent;
02474 
02475   ssize_t
02476     offset;
02477 
02478   status=MagickFalse;
02479   search_extent=0,
02480   replace_extent=0;
02481   for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
02482   {
02483     if (search_extent == 0)
02484       search_extent=strlen(search);
02485     if (strncmp(p,search,search_extent) != 0)
02486       continue;
02487     /*
02488       We found a match.
02489     */
02490     status=MagickTrue;
02491     if (replace_extent == 0)
02492       replace_extent=strlen(replace);
02493     if (replace_extent > search_extent)
02494       {
02495         /*
02496           Make room for the replacement string.
02497         */
02498         offset=(ssize_t) (p-(*string));
02499         extent=strlen(*string)+replace_extent-search_extent+1;
02500         *string=(char *) ResizeQuantumMemory(*string,extent+MaxTextExtent,
02501           sizeof(*p));
02502         if (*string == (char *) NULL)
02503           ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
02504         p=(*string)+offset;
02505       }
02506     /*
02507       Replace string.
02508     */
02509     if (search_extent != replace_extent)
02510       (void) CopyMagickMemory(p+replace_extent,p+search_extent,
02511         strlen(p+search_extent)+1);
02512     (void) CopyMagickMemory(p,replace,replace_extent);
02513     p+=replace_extent-1;
02514   }
02515   return(status);
02516 }