utility.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %             U   U  TTTTT  IIIII  L      IIIII  TTTTT  Y   Y                 %
00007 %             U   U    T      I    L        I      T     Y Y                  %
00008 %             U   U    T      I    L        I      T      Y                   %
00009 %             U   U    T      I    L        I      T      Y                   %
00010 %              UUU     T    IIIII  LLLLL  IIIII    T      Y                   %
00011 %                                                                             %
00012 %                                                                             %
00013 %                     Wizard's Toolkit Utility Methods                        %
00014 %                                                                             %
00015 %                             Software Design                                 %
00016 %                               John Cristy                                   %
00017 %                               March 2003                                    %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2010 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.wizards-toolkit.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 "wizard/studio.h"
00043 #include "wizard/exception.h"
00044 #include "wizard/exception-private.h"
00045 #include "wizard/memory_.h"
00046 #include "wizard/resource_.h"
00047 #include "wizard/utility.h"
00048 #if defined(WIZARDSTOOLKIT_HAVE_MACH_O_DYLD_H)
00049 #include <mach-o/dyld.h>
00050 #endif
00051 
00052 /*
00053   Static declarations.
00054 */
00055 static const char
00056   Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00057 
00058 /*
00059   Forward declaration.
00060 */
00061 static int
00062   IsDirectory(const char *);
00063 
00064 /*
00065 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00066 %                                                                             %
00067 %                                                                             %
00068 %                                                                             %
00069 %  A p p e n d F i l e E x t e n s i o n                                      %
00070 %                                                                             %
00071 %                                                                             %
00072 %                                                                             %
00073 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00074 %
00075 %  AppendFileExtension() appends a file extension type to the filename.  If an
00076 %  extension to the file already exists, it is first removed.
00077 %
00078 %  The extension of the AppendFileExtension method is:
00079 %
00080 %      void AppendFileExtension(const char *extension,char *filename)
00081 %
00082 %  A description of each parameter follows.
00083 %
00084 %   o  extension:  Specifies a pointer to an array of characters.  This is the
00085 %      extension of the image.
00086 %
00087 %   o  filename:  Specifies a pointer to an array of characters.  The unique
00088 %      file name is returned in this array.
00089 %
00090 */
00091 WizardExport void AppendFileExtension(const char *extension,char *filename)
00092 {
00093   char
00094     root[MaxTextExtent];
00095 
00096   assert(extension != (char *) NULL);
00097   assert(filename != (char *) NULL);
00098   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",filename);
00099   if ((*extension == '\0') || (*filename == '\0'))
00100     return;
00101   GetPathComponent(filename,RootPath,root);
00102   (void) CopyWizardString(filename,root,MaxTextExtent);
00103   (void) ConcatenateWizardString(filename,".",MaxTextExtent);
00104   (void) ConcatenateWizardString(filename,extension,MaxTextExtent);
00105 }
00106 
00107 /*
00108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00109 %                                                                             %
00110 %                                                                             %
00111 %                                                                             %
00112 %   B a s e 6 4 D e c o d e                                                   %
00113 %                                                                             %
00114 %                                                                             %
00115 %                                                                             %
00116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00117 %
00118 %  Base64Decode() decodes Base64-encoded text and returns its binary
00119 %  equivalent.  NULL is returned if the text is not valid Base64 data, or a
00120 %  memory allocation failure occurs.
00121 %
00122 %  The format of the Base64Decode method is:
00123 %
00124 %      unsigned char *Base64Decode(const char *source,length_t *length)
00125 %
00126 %  A description of each parameter follows:
00127 %
00128 %    o source:  A pointer to a Base64-encoded string.
00129 %
00130 %    o length: The number of bytes decoded.
00131 %
00132 */
00133 WizardExport unsigned char *Base64Decode(const char *source,size_t *length)
00134 {
00135   int
00136     state;
00137 
00138   register const char
00139     *p,
00140     *q;
00141 
00142   register size_t
00143     i;
00144 
00145   unsigned char
00146     *decode;
00147 
00148   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00149   assert(source != (char *) NULL);
00150   assert(length != (size_t *) NULL);
00151   *length=0;
00152   decode=(unsigned char *) AcquireQuantumMemory(strlen(source)/4+4,
00153     3*sizeof(*decode));
00154   if (decode == (unsigned char *) NULL)
00155     return((unsigned char *) NULL);
00156   i=0;
00157   state=0;
00158   for (p=source; *p != '\0'; p++)
00159   {
00160     if (isspace((int) ((unsigned char) *p)) != 0)
00161       continue;
00162     if (*p == '=')
00163       break;
00164     q=strchr(Base64,*p);
00165     if (q == (char *) NULL)
00166       {
00167         decode=(unsigned char *) RelinquishWizardMemory(decode);
00168         return((unsigned char *) NULL);  /* non-Base64 character */
00169       }
00170     switch (state)
00171     {
00172       case 0:
00173       {
00174         decode[i]=(q-Base64) << 2;
00175         state++;
00176         break;
00177       }
00178       case 1:
00179       {
00180         decode[i++]|=(q-Base64) >> 4;
00181         decode[i]=((q-Base64) & 0x0f) << 4;
00182         state++;
00183         break;
00184       }
00185       case 2:
00186       {
00187         decode[i++]|=(q-Base64) >> 2;
00188         decode[i]=((q-Base64) & 0x03) << 6;
00189         state++;
00190         break;
00191       }
00192       case 3:
00193       {
00194         decode[i++]|=(q-Base64);
00195         state=0;
00196         break;
00197       }
00198     }
00199   }
00200   /*
00201     Verify Base-64 string has proper terminal characters.
00202   */
00203   if (*p != '=')
00204     {
00205       if (state != 0)
00206         {
00207           decode=(unsigned char *) RelinquishWizardMemory(decode);
00208           return((unsigned char *) NULL);
00209         }
00210     }
00211   else
00212     {
00213       p++;
00214       switch (state)
00215       {
00216         case 0:
00217         case 1:
00218         {
00219           /*
00220             Unrecognized '=' character.
00221           */
00222           decode=(unsigned char *) RelinquishWizardMemory(decode);
00223           return((unsigned char *) NULL);
00224         }
00225         case 2:
00226         {
00227           for ( ; *p != '\0'; p++)
00228             if (isspace((int) ((unsigned char) *p)) == 0)
00229               break;
00230           if (*p != '=')
00231             {
00232               decode=(unsigned char *) RelinquishWizardMemory(decode);
00233               return((unsigned char *) NULL);
00234             }
00235           p++;
00236         }
00237         case 3:
00238         {
00239           for ( ; *p != '\0'; p++)
00240             if (isspace((int) ((unsigned char) *p)) == 0)
00241               {
00242                 decode=(unsigned char *) RelinquishWizardMemory(decode);
00243                 return((unsigned char *) NULL);
00244               }
00245           if ((int) decode[i] != 0)
00246             {
00247               decode=(unsigned char *) RelinquishWizardMemory(decode);
00248               return((unsigned char *) NULL);
00249             }
00250         }
00251       }
00252     }
00253   *length=i;
00254   return(decode);
00255 }
00256 
00257 /*
00258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00259 %                                                                             %
00260 %                                                                             %
00261 %                                                                             %
00262 %   B a s e 6 4 E n c o d e                                                   %
00263 %                                                                             %
00264 %                                                                             %
00265 %                                                                             %
00266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00267 %
00268 %  Base64Encode() encodes arbitrary binary data to Base64 encoded format as
00269 %  described by the "Base64 Content-Transfer-Encoding" section of RFC 2045 and
00270 %  returns the result as a null-terminated ASCII string.  NULL is returned if
00271 %  a memory allocation failure occurs.
00272 %
00273 %  The format of the Base64Encode method is:
00274 %
00275 %      char *Base64Encode(const unsigned char *blob,const size_t blob_length,
00276 %        size_t *encode_length)
00277 %
00278 %  A description of each parameter follows:
00279 %
00280 %    o blob:  A pointer to binary data to encode.
00281 %
00282 %    o blob_length: The number of bytes to encode.
00283 %
00284 %    o encode_length:  The number of bytes encoded.
00285 %
00286 */
00287 WizardExport char *Base64Encode(const unsigned char *blob,
00288   const size_t blob_length,size_t *encode_length)
00289 {
00290   char
00291     *encode;
00292 
00293   register const unsigned char
00294     *p;
00295 
00296   register size_t
00297     i;
00298 
00299   size_t
00300     quantum,
00301     remainder;
00302 
00303   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00304   assert(blob != (const unsigned char *) NULL);
00305   assert(blob_length != 0);
00306   assert(encode_length != (size_t *) NULL);
00307   *encode_length=0;
00308   quantum=4*blob_length/3+4;
00309   encode=(char *) AcquireQuantumMemory(quantum,sizeof(*encode));
00310   if (encode == (char *) NULL)
00311     return((char *) NULL);
00312   i=0;
00313   for (p=blob; p < (blob+blob_length-2); p+=3)
00314   {
00315     encode[i++]=Base64[(int) (*p >> 2)];
00316     encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
00317     encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
00318     encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
00319   }
00320   remainder=blob_length % 3;
00321   if (remainder != 0)
00322     {
00323       ssize_t
00324         j;
00325 
00326       unsigned char
00327         code[3];
00328 
00329       code[0]='\0';
00330       code[1]='\0';
00331       code[2]='\0';
00332       for (j=0; j < (ssize_t) remainder; j++)
00333         code[j]=(*p++);
00334       encode[i++]=Base64[(int) (code[0] >> 2)];
00335       encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
00336       if (remainder == 1)
00337         encode[i++]='=';
00338       else
00339         encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))];
00340       encode[i++]='=';
00341     }
00342   *encode_length=i;
00343   encode[i++]='\0';
00344   assert(i <= quantum);
00345   return(encode);
00346 }
00347 
00348 /*
00349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00350 %                                                                             %
00351 %                                                                             %
00352 %                                                                             %
00353 %   C h o p P a t h C o m p o n e n t s                                       %
00354 %                                                                             %
00355 %                                                                             %
00356 %                                                                             %
00357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00358 %
00359 %  ChopPathComponents() removes the number of specified file components from a
00360 %  path.
00361 %
00362 %  The format of the ChopPathComponents method is:
00363 %
00364 %      ChopPathComponents(char *path,size_t components)
00365 %
00366 %  A description of each parameter follows:
00367 %
00368 %    o path:  The path.
00369 %
00370 %    o components:  The number of components to chop.
00371 %
00372 */
00373 WizardExport void ChopPathComponents(char *path,const size_t components)
00374 {
00375   register ssize_t
00376     i;
00377 
00378   for (i=0; i < (ssize_t) components; i++)
00379     GetPathComponent(path,HeadPath,path);
00380 }
00381 
00382 /*
00383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00384 %                                                                             %
00385 %                                                                             %
00386 %                                                                             %
00387 +   G e t P a t h C o m p o n e n t                                           %
00388 %                                                                             %
00389 %                                                                             %
00390 %                                                                             %
00391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00392 %
00393 %  GetPathComponent() returns the parent directory name, filename, basename,
00394 %  or extension of a file path.
00395 %
00396 %  The format of the GetPathComponent function is:
00397 %
00398 %      GetPathComponent(const char *path,PathType type,char *component)
00399 %
00400 %  A description of each parameter follows:
00401 %
00402 %    o path: Specifies a pointer to a character array that contains the
00403 %      file path.
00404 %
00405 %    o type: Specififies which file path component to return.
00406 %
00407 %    o component: The selected file path component is returned here.
00408 %
00409 */
00410 WizardExport void GetPathComponent(const char *path,PathType type,
00411   char *component)
00412 {
00413   char
00414     filesystem[MaxTextExtent],
00415     subnode[MaxTextExtent],
00416     *q;
00417 
00418   register char
00419     *p;
00420 
00421   /*
00422     Get basename of client.
00423   */
00424   assert(path != (const char *) NULL);
00425   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",path);
00426   assert(component != (const char *) NULL);
00427   if (*path == '\0')
00428     {
00429       *component='\0';
00430       return;
00431     }
00432   (void) CopyWizardString(component,path,MaxTextExtent);
00433   *filesystem='\0';
00434   for (p=component; *p != '\0'; p++)
00435     if ((*p == ':') && (IsDirectory(path) < 0) &&
00436         (IsAccessible(path) == WizardFalse))
00437       {     
00438         /*
00439           Look for filesystem specification (e.g. c:/documents).
00440         */
00441         (void) CopyWizardString(filesystem,component,(size_t)
00442           (p-component+1));
00443         if (IsDirectory(filesystem) < 0)
00444           *filesystem='\0';
00445         else         
00446           for (q=component; *q != '\0'; q++)
00447             *q=(*++p);
00448         break;
00449       }
00450   *subnode='\0';
00451   p=component;
00452   if (*p != '\0')
00453     p=component+strlen(component)-1;
00454   if ((*p == ']') && (strchr(component,'[') != (char *) NULL))
00455     {
00456       /*
00457         Look for subnode specification (e.g. book[2]).
00458       */
00459       for (q=p-1; q > component; q--)
00460         if (*q == '[')
00461           break;
00462       if (*q == '[')
00463         {
00464           (void) CopyWizardString(subnode,q+1,MaxTextExtent);
00465           subnode[p-q-1]='\0';
00466           *q='\0';
00467         }
00468     }
00469   p=component;
00470   if (*p != '\0')
00471     for (p=component+(strlen(component)-1); p > component; p--)
00472       if (IsBasenameSeparator(*p))
00473         break;
00474   switch (type)
00475   {
00476     case FilesystemPath:
00477     {
00478       (void) CopyWizardString(component,filesystem,MaxTextExtent);
00479       break;
00480     }
00481     case RootPath:
00482     {
00483       for (p=component+(strlen(component)-1); p > component; p--)
00484       {
00485         if (IsBasenameSeparator(*p) != WizardFalse)
00486           break;
00487         if (*p == '.')
00488           break;
00489       }
00490       if (*p == '.')
00491         *p='\0';
00492       break;
00493     }
00494     case HeadPath:
00495     {
00496       *p='\0';
00497       break;
00498     }
00499     case TailPath:
00500     {
00501       if (IsBasenameSeparator(*p) != WizardFalse)
00502         (void) CopyWizardMemory((unsigned char *) component,
00503           (const unsigned char *) (p+1),strlen(p+1)+1);
00504       break;
00505     }
00506     case BasePath:
00507     {
00508       if (IsBasenameSeparator(*p) != WizardFalse)
00509         (void) CopyWizardString(component,p+1,MaxTextExtent);
00510       for (p=component+(strlen(component)-1); p > component; p--)
00511         if (*p == '.')
00512           {
00513             *p='\0';
00514             break;
00515           }
00516       break;
00517     }
00518     case ExtensionPath:
00519     {
00520       if (IsBasenameSeparator(*p) != WizardFalse)
00521         (void) CopyWizardString(component,p+1,MaxTextExtent);
00522       p=component;
00523       if (*p != '\0')
00524         for (p=component+strlen(component)-1; p > component; p--)
00525           if (*p == '.')
00526             break;
00527       *component='\0';
00528       if (*p == '.')
00529         (void) CopyWizardString(component,p+1,MaxTextExtent);
00530       p=strchr(component,'?');
00531       if (p != (char *) NULL)
00532         *p='\0';
00533       break;
00534     }
00535     case SubnodePath:
00536     {
00537       (void) CopyWizardString(component,subnode,MaxTextExtent);
00538       break;
00539     }
00540     case CanonicalPath:
00541     case UndefinedPath:
00542       break;
00543   }
00544 }
00545 
00546 /*
00547 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00548 %                                                                             %
00549 %                                                                             %
00550 %                                                                             %
00551 %  G e t P a t h C o m p o n e n t s                                          %
00552 %                                                                             %
00553 %                                                                             %
00554 %                                                                             %
00555 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00556 %
00557 %  GetPathComponents() returns a list of path components.
00558 %
00559 %  The format of the GetPathComponents method is:
00560 %
00561 %      char **GetPathComponents(const char *path,
00562 %        size_t *number_componenets)
00563 %
00564 %  A description of each parameter follows:
00565 %
00566 %    o path:  Specifies the string to segment into a list.
00567 %
00568 %    o number_components:  return the number of components in the list
00569 %
00570 */
00571 WizardExport char **GetPathComponents(const char *path,
00572   size_t *number_components)
00573 {
00574   char
00575     **components;
00576 
00577   register char
00578     *q;
00579 
00580   register const char
00581     *p;
00582 
00583   register ssize_t
00584     i;
00585 
00586   if (path == (char *) NULL)
00587     return((char **) NULL);
00588   *number_components=1;
00589   for (p=path; *p != '\0'; p++)
00590     if (IsBasenameSeparator(*p))
00591       (*number_components)++;
00592   components=(char **) AcquireQuantumMemory((size_t) (*number_components+1),
00593     sizeof(*components));
00594   if (components == (char **) NULL)
00595     ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00596   p=path;
00597   for (i=0; i < (ssize_t) *number_components; i++)
00598   {
00599     for (q=(char *) p; *q != '\0'; q++)
00600       if (IsBasenameSeparator(*q))
00601         break;
00602     components[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MaxTextExtent,
00603       sizeof(*components));
00604     if (components[i] == (char *) NULL)
00605       ThrowFatalException(ResourceFatalError,"memory allocation failed `%s'");
00606     (void) CopyWizardString(components[i],p,(size_t) (q-p+1));
00607     p=q+1;
00608   }
00609   components[i]=(char *) NULL;
00610   return(components);
00611 }
00612 
00613 /*
00614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00615 %                                                                             %
00616 %                                                                             %
00617 %                                                                             %
00618 %   G e t E x e c u t i o n P a t h                                           %
00619 %                                                                             %
00620 %                                                                             %
00621 %                                                                             %
00622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00623 %
00624 %  GetExecutionPath() returns the pathname of the executable that started
00625 %  the process.  On success WizardTrue is returned, otherwise WizardFalse.
00626 %
00627 %  The format of the GetExecutionPath method is:
00628 %
00629 %      WizardBooleanType GetExecutionPath(char *path,const size_t extent)
00630 %
00631 %  A description of each parameter follows:
00632 %
00633 %    o path: The pathname of the executable that started the process.
00634 %
00635 %    o extent: the maximum extent of the path.
00636 %
00637 */
00638 WizardExport WizardBooleanType GetExecutionPath(char *path,const size_t extent)
00639 {
00640   *path='\0';
00641   (void) getcwd(path,(unsigned long) extent);
00642 #if defined(WIZARDSTOOLKIT_HAVE_GETPID) && defined(WIZARDSTOOLKIT_HAVE_READLINK) && defined(PATH_MAX)
00643   {
00644     char
00645       link_path[MaxTextExtent],
00646       real_path[PATH_MAX+1];
00647 
00648     int
00649       length;
00650 
00651     (void) FormatWizardString(link_path,MaxTextExtent,"/proc/%.20g/exe",
00652       (double) getpid());
00653     length=readlink(link_path,real_path,PATH_MAX);
00654     if (length == -1)
00655       {
00656         (void) FormatWizardString(link_path,MaxTextExtent,"/proc/%.20g/file",
00657           (double) getpid());
00658         length=readlink(link_path,real_path,PATH_MAX);
00659       }
00660     if ((length > 0) && ((size_t) length <= PATH_MAX))
00661       {
00662         real_path[length]='\0';
00663         (void) CopyWizardString(path,real_path,extent);
00664       }
00665   }
00666 #endif
00667 #if defined(WIZARDSTOOLKIT_HAVE__NSGETEXECUTABLEPATH)
00668   {
00669 
00670     char
00671       executable_path[PATH_MAX << 1],
00672       real_path[PATH_MAX+1];
00673    
00674     size_t
00675       length;
00676 
00677     length=sizeof(executable_path);
00678     if ((_NSGetExecutablePath(executable_path,&length) == 0) &&
00679         (realpath(executable_path,real_path) != (char *) NULL))
00680       (void) CopyWizardString(path,real_path,extent);
00681   }
00682 #endif
00683 #if defined(WIZARDSTOOLKIT_HAVE_GETEXECNAME)
00684   {
00685     const char
00686       *execution_path;
00687 
00688     execution_path=(const char *) getexecname();
00689     if (execution_path != (const char *) NULL)
00690       {
00691         if (*execution_path != *DirectorySeparator)
00692           (void) ConcatenateWizardString(path,DirectorySeparator,extent);
00693         (void) ConcatenateWizardString(path,execution_path,extent);
00694       }
00695   }
00696 #endif
00697 #if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
00698   NTGetExecutionPath(path,extent);
00699 #endif
00700 #if defined(__GNU__)
00701   {
00702     char
00703       *program_name,
00704       *execution_path;
00705 
00706     ssize_t
00707       count;
00708 
00709     count=0;
00710     execution_path=(char *) NULL;
00711     program_name=program_invocation_name;
00712     if (*program_invocation_name != '/')
00713       {
00714         size_t
00715           extent;
00716 
00717         extent=strlen(cwd)+strlen(program_name)+1;
00718         program_name=AcquireQuantumMemory(extent,sizeof(*program_name));
00719         if (program_name == (char *) NULL)
00720           program_name=program_invocation_name;
00721         else
00722           count=FormatWizardString(program_name,extent,"%s/%s",cwd,
00723             program_invocation_name);
00724       }
00725     if (count != -1)
00726       {
00727         execution_path=realpath(program_name,NULL);
00728         if (execution_path != (char *) NULL)
00729           (void) CopyWizardString(path,execution_path,extent);
00730       }
00731     if (program_name != program_invocation_name)
00732       program_name=(char *) RelinquishWizardMemory(program_name);
00733     execution_path=(char *) RelinquishWizardMemory(execution_path);
00734   }
00735 #endif
00736   return(IsAccessible(path));
00737 }
00738 
00739 /*
00740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00741 %                                                                             %
00742 %                                                                             %
00743 %                                                                             %
00744 %  I s A c c e s s i b l e                                                    %
00745 %                                                                             %
00746 %                                                                             %
00747 %                                                                             %
00748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00749 %
00750 %  IsAccessible() returns WizardTrue if the file as defined by the path is
00751 %  accessible.
00752 %
00753 %  The format of the IsAccessible method is:
00754 %
00755 %      WizardBooleanType IsAccessible(const char *filename)
00756 %
00757 %  A description of each parameter follows.
00758 %
00759 %    o path:  Specifies a path to a file.
00760 %
00761 */
00762 WizardExport WizardBooleanType IsAccessible(const char *path)
00763 {
00764   int
00765     status;
00766 
00767   struct stat
00768     file_info;
00769 
00770   if ((path == (const char *) NULL) || (*path == '\0'))
00771     return(WizardFalse);
00772   status=stat(path,&file_info);
00773   if (status != 0)
00774     return(WizardFalse);
00775   if (S_ISREG(file_info.st_mode) == 0)
00776     return(WizardFalse);
00777   if (access(path,F_OK) != 0)
00778     return(WizardFalse);
00779   return(WizardTrue);
00780 }
00781 
00782 /*
00783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00784 %                                                                             %
00785 %                                                                             %
00786 %                                                                             %
00787 +  I s D i r e c t o r y                                                      %
00788 %                                                                             %
00789 %                                                                             %
00790 %                                                                             %
00791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00792 %
00793 %  IsDirectory() returns -1 if the directory does not exist,  1 is returned
00794 %  if the path represents a directory otherwise 0.
00795 %
00796 %  The format of the IsAccessible method is:
00797 %
00798 %      int IsDirectory(const char *path)
00799 %
00800 %  A description of each parameter follows.
00801 %
00802 %   o  path:  The directory path.
00803 %
00804 %
00805 */
00806 static int IsDirectory(const char *path)
00807 {
00808 #if !defined(X_OK)
00809 #define X_OK  1
00810 #endif
00811 
00812   int
00813     status;
00814 
00815   struct stat
00816     file_info;
00817 
00818   if ((path == (const char *) NULL) || (*path == '\0'))
00819     return(WizardFalse);
00820   status=stat(path,&file_info);
00821   if (status != 0)
00822     return(-1);
00823   if (S_ISDIR(file_info.st_mode) == 0)
00824     return(0);
00825   if (access(path,X_OK) != 0)
00826     return(0);
00827   return(1);
00828 }
00829 
00830 /*
00831 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00832 %                                                                             %
00833 %                                                                             %
00834 %                                                                             %
00835 %   I s W i z a r d T r u e                                                   %
00836 %                                                                             %
00837 %                                                                             %
00838 %                                                                             %
00839 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00840 %
00841 %  IsWizardTrue() returns WizardTrue if the value is "true", "on", "yes" or
00842 %  "1".
00843 %
00844 %  The format of the IsWizardTrue method is:
00845 %
00846 %      WizardBooleanType IsWizardTrue(const char *value)
00847 %
00848 %  A description of each parameter follows:
00849 %
00850 %    o option: either WizardTrue or WizardFalse depending on the value
00851 %      parameter.
00852 %
00853 %    o value: Specifies a pointer to a character array.
00854 %
00855 */
00856 WizardExport WizardBooleanType IsWizardTrue(const char *value)
00857 {
00858   if (value == (char *) NULL)
00859     return(WizardFalse);
00860   if (LocaleCompare(value,"true") == 0)
00861     return(WizardTrue);
00862   if (LocaleCompare(value,"on") == 0)
00863     return(WizardTrue);
00864   if (LocaleCompare(value,"yes") == 0)
00865     return(WizardTrue);
00866   if (LocaleCompare(value,"1") == 0)
00867     return(WizardTrue);
00868   return(WizardFalse);
00869 }
00870 
00871 /*
00872 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00873 %                                                                             %
00874 %                                                                             %
00875 %                                                                             %
00876 %  P a r s e W i z a r d T i m e                                              %
00877 %                                                                             %
00878 %                                                                             %
00879 %                                                                             %
00880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00881 %
00882 %  ParseWizardTime() parses the specified time in the Internet date/time
00883 %  format and the returns the results.
00884 %
00885 %  The format of the ParseWizardTime method is:
00886 %
00887 %      const char *ParseWizardTime(const char *timestamp,time_t *target)
00888 %
00889 %  A description of each parameter follows.
00890 %
00891 %   o timestamp:  the Internet date/time here.
00892 %
00893 %   o target:  return the time since the Epoch (00:00:00 UTC, January 1, 1970),
00894 %     measured in seconds.
00895 %
00896 */
00897 WizardExport const char *ParseWizardTime(const char *timestamp,time_t *target)
00898 {
00899   char
00900     *q;
00901 
00902   double
00903     value;
00904 
00905   ssize_t
00906     timezone;
00907 
00908   register const char
00909     *p;
00910 
00911   register ssize_t
00912     i;
00913 
00914   static char
00915     separators[] = "--T::-:";
00916 
00917   struct tm
00918     gm_time,
00919     local_time,
00920     target_time;
00921 
00922   *target=time((time_t *) NULL);
00923 #if defined(WIZARDSTOOLKIT_HAVE_LOCALTIME_R)
00924   (void) localtime_r(target,&local_time);
00925 #else
00926   (void) memcpy(&local_time,localtime(target),sizeof(local_time));
00927 #endif
00928 #if defined(WIZARDSTOOLKIT_HAVE_GMTIME_R)
00929   (void) gmtime_r(target,&gm_time);
00930 #else
00931   (void) memcpy(&gm_time,gmtime(target),sizeof(gm_time));
00932 #endif
00933   timezone=(ssize_t) ((local_time.tm_min-gm_time.tm_min)/60+local_time.tm_hour-
00934     gm_time.tm_hour+24*((local_time.tm_year-gm_time.tm_year) != 0 ?
00935     (local_time.tm_year-gm_time.tm_year) : (local_time.tm_yday-
00936     gm_time.tm_yday)));
00937   (void) ResetWizardMemory(&target_time,0,sizeof(target_time));
00938   p=timestamp;
00939   for (i=0; ; i++)
00940   {
00941     value=strtod(p,&q);
00942     if (*q != separators[i])
00943       break;
00944     switch (i)
00945     {
00946       case 0: target_time.tm_year=(int) (value+0.5)-1900; break;
00947       case 1: target_time.tm_mon=(int) (value+0.5)-1; break;
00948       case 2: target_time.tm_mday=(int) (value+0.5); break;
00949       case 3: target_time.tm_hour=(int) (value+0.5); break;
00950       case 4: target_time.tm_min=(int) (value+0.5); break;
00951       case 5: target_time.tm_sec=(int) (value+0.5); break;
00952       case 6: timezone+=(int) (value+0.5); break;
00953       default: break;
00954     }
00955     p=q;
00956     if (*q == '\0')
00957       break;
00958     p++;
00959   }
00960   *target=mktime(&target_time)-3600*timezone;
00961   return(p);
00962 }
00963 
00964 /*
00965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00966 %                                                                             %
00967 %                                                                             %
00968 %                                                                             %
00969 %   W i z a r d O p e n S t r e a m                                           %
00970 %                                                                             %
00971 %                                                                             %
00972 %                                                                             %
00973 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00974 %
00975 %  WizardOpenStream() opens the file whose name is the string pointed to by
00976 %  path and associates a stream with it.
00977 %
00978 %  The path of the WizardOpenStream method is:
00979 %
00980 %      FILE *WizardOpenStream(const char *path,const char *mode)
00981 %
00982 %  A description of each parameter follows.
00983 %
00984 %   o  path: the file path.
00985 %
00986 %   o  mode: the file mode.
00987 %
00988 */
00989 
00990 #if defined(WIZARDSTOOLKIT_HAVE__WFOPEN)
00991 static size_t UTF8ToUTF16(const unsigned char *utf8,wchar_t *utf16)
00992 {
00993   register const unsigned char
00994     *p;
00995 
00996   if (utf16 != (wchar_t *) NULL)
00997     {
00998       register wchar_t
00999         *q;
01000 
01001       wchar_t
01002         c;
01003 
01004       /*
01005         Convert UTF-8 to UTF-16.
01006       */
01007       q=utf16;
01008       for (p=utf8; *p != '\0'; p++)
01009       {
01010         if ((*p & 0x80) == 0)
01011           *q=(*p);
01012         else
01013           if ((*p & 0xE0) == 0xC0)
01014             {
01015               c=(*p);
01016               *q=(c & 0x1F) << 6;
01017               p++;
01018               if ((*p & 0xC0) != 0x80)
01019                 return(0);
01020               *q|=(*p & 0x3F);
01021             }
01022           else
01023             if ((*p & 0xF0) == 0xE0)
01024               {
01025                 c=(*p);
01026                 *q=c << 12;
01027                 p++;
01028                 if ((*p & 0xC0) != 0x80)
01029                   return(0);
01030                 c=(*p);
01031                 *q|=(c & 0x3F) << 6;
01032                 p++;
01033                 if ((*p & 0xC0) != 0x80)
01034                   return(0);
01035                 *q|=(*p & 0x3F);
01036               }
01037             else
01038               return(0);
01039         q++;
01040       }
01041       *q++='\0';
01042       return(q-utf16);
01043     }
01044   /*
01045     Compute UTF-16 string length.
01046   */
01047   for (p=utf8; *p != '\0'; p++)
01048   {
01049     if ((*p & 0x80) == 0)
01050       ;
01051     else
01052       if ((*p & 0xE0) == 0xC0)
01053         {
01054           p++;
01055           if ((*p & 0xC0) != 0x80)
01056             return(0);
01057         }
01058       else
01059         if ((*p & 0xF0) == 0xE0)
01060           {
01061             p++;
01062             if ((*p & 0xC0) != 0x80)
01063               return(0);
01064             p++;
01065             if ((*p & 0xC0) != 0x80)
01066               return(0);
01067          }
01068        else
01069          return(0);
01070   }
01071   return(p-utf8);
01072 }
01073 
01074 static wchar_t *ConvertUTF8ToUTF16(const unsigned char *source)
01075 {
01076   size_t
01077     length;
01078 
01079   wchar_t
01080     *utf16;
01081 
01082   length=UTF8ToUTF16(source,(wchar_t *) NULL);
01083   if (length == 0)
01084     {
01085       register ssize_t
01086         i;
01087 
01088       /*
01089         Not UTF-8, just copy.
01090       */
01091       length=strlen(source);
01092       utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01093       if (utf16 == (wchar_t *) NULL)
01094         return((wchar_t *) NULL);
01095       for (i=0; i <= (ssize_t) length; i++)
01096         utf16[i]=source[i];
01097       return(utf16);
01098     }
01099   utf16=(wchar_t *) AcquireQuantumMemory(length+1,sizeof(*utf16));
01100   if (utf16 == (wchar_t *) NULL)
01101     return((wchar_t *) NULL);
01102   length=UTF8ToUTF16(source,utf16);
01103   return(utf16);
01104 }
01105 #endif
01106 
01107 WizardExport FILE *WizardOpenStream(const char *path,const char *mode)
01108 {
01109   FILE
01110     *file;
01111 
01112   if ((path == (const char *) NULL) || (mode == (const char *) NULL))
01113     {
01114       errno=EINVAL;
01115       return((FILE *) NULL);
01116     }
01117   file=(FILE *) NULL;
01118 #if defined(WIZARDSTOOLKIT_HAVE__WFOPEN)
01119   {
01120     wchar_t
01121       *unicode_mode,
01122       *unicode_path;
01123 
01124     unicode_path=ConvertUTF8ToUTF16(path);
01125     if (unicode_path == (wchar_t *) NULL)
01126       return((FILE *) NULL);
01127     unicode_mode=ConvertUTF8ToUTF16(mode);
01128     if (unicode_path == (wchar_t *) NULL)
01129       {
01130         unicode_path=(wchar_t *) RelinquishWizardMemory(unicode_path);
01131         return((FILE *) NULL);
01132       }
01133     file=_wfopen(unicode_path,unicode_mode);
01134     unicode_mode=(wchar_t *) RelinquishWizardMemory(unicode_mode);
01135     unicode_path=(wchar_t *) RelinquishWizardMemory(unicode_path);
01136   }
01137 #endif
01138   if (file == (FILE *) NULL)
01139     file=fopen(path,mode);
01140   return(file);
01141 }
Generated by  doxygen 1.6.2-20100208