pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 00029 /* 00030 00031 @deftypefn Replacement {const char*} lrealpath (const char *@var{name}) 00032 00033 Given a pointer to a string containing a pathname, returns a canonical 00034 version of the filename. Symlinks will be resolved, and ``.'' and ``..'' 00035 components will be simplified. The returned value will be allocated using 00036 @code{malloc}, or @code{NULL} will be returned on a memory allocation error. 00037 00038 @end deftypefn 00039 00040 */ 00041 00042 #include "config.h" 00043 #include "lrealpath.h" 00044 00045 #ifdef HAVE_LIMITS_H 00046 #include <limits.h> 00047 #endif 00048 #ifdef HAVE_STDLIB_H 00049 #include <stdlib.h> 00050 #endif 00051 #ifdef HAVE_UNISTD_H 00052 #include <unistd.h> 00053 #endif 00054 #ifdef HAVE_STRING_H 00055 #include <string.h> 00056 #endif 00057 00058 /* On GNU libc systems the declaration is only visible with _GNU_SOURCE. */ 00059 #if defined(HAVE_CANONICALIZE_FILE_NAME) \ 00060 && defined(NEED_DECLARATION_CANONICALIZE_FILE_NAME) 00061 extern char *canonicalize_file_name (const char *); 00062 #endif 00063 00064 #if defined(HAVE_REALPATH) 00065 # if defined (PATH_MAX) 00066 # define REALPATH_LIMIT PATH_MAX 00067 # else 00068 # if defined (MAXPATHLEN) 00069 # define REALPATH_LIMIT MAXPATHLEN 00070 # endif 00071 # endif 00072 #else 00073 /* cygwin has realpath, so it won't get here. */ 00074 # if defined (_WIN32) 00075 # define WIN32_LEAN_AND_MEAN 00076 # include <windows.h> /* for GetFullPathName */ 00077 # endif 00078 #endif 00079 00083 char * 00084 lrealpath (const char *filename) 00085 { 00086 /* Method 1: The system has a compile time upper bound on a filename 00087 path. Use that and realpath() to canonicalize the name. This is 00088 the most common case. Note that, if there isn't a compile time 00089 upper bound, you want to avoid realpath() at all costs. */ 00090 #if defined(REALPATH_LIMIT) 00091 { 00092 char buf[REALPATH_LIMIT]; 00093 const char *rp = realpath (filename, buf); 00094 if (rp == NULL) 00095 rp = filename; 00096 return strdup (rp); 00097 } 00098 /* REALPATH_LIMIT */ 00099 00100 /* Method 2: The host system (i.e., GNU) has the function 00101 canonicalize_file_name() which malloc's a chunk of memory and 00102 returns that, use that. */ 00103 #elif defined(HAVE_CANONICALIZE_FILE_NAME) 00104 { 00105 char *rp = canonicalize_file_name (filename); 00106 if (rp == NULL) 00107 return strdup (filename); 00108 else 00109 return rp; 00110 } 00111 /* HAVE_CANONICALIZE_FILE_NAME */ 00112 00113 /* Method 3: Now we're getting desperate! The system doesn't have a 00114 compile time buffer size and no alternative function. Query the 00115 OS, using pathconf(), for the buffer limit. Care is needed 00116 though, some systems do not limit PATH_MAX (return -1 for 00117 pathconf()) making it impossible to pass a correctly sized buffer 00118 to realpath() (it could always overflow). On those systems, we 00119 skip this. */ 00120 #elif defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) 00121 { 00122 /* Find out the max path size. */ 00123 long path_max = pathconf ("/", _PC_PATH_MAX); 00124 if (path_max > 0) 00125 { 00126 /* PATH_MAX is bounded. */ 00127 char *buf, *rp, *ret; 00128 buf = (char *) malloc (path_max); 00129 if (buf == NULL) 00130 return NULL; 00131 rp = realpath (filename, buf); 00132 ret = strdup (rp ? rp : filename); 00133 free (buf); 00134 return ret; 00135 } 00136 } 00137 /* HAVE_REALPATH && HAVE_UNISTD_H */ 00138 00139 /* The MS Windows method. If we don't have realpath, we assume we 00140 don't have symlinks and just canonicalize to a Windows absolute 00141 path. GetFullPath converts ../ and ./ in relative paths to 00142 absolute paths, filling in current drive if one is not given 00143 or using the current directory of a specified drive (eg, "E:foo"). 00144 It also converts all forward slashes to back slashes. */ 00145 #elif defined (_WIN32) 00146 { 00147 char buf[MAX_PATH]; 00148 char* basename; 00149 DWORD len = GetFullPathName (filename, MAX_PATH, buf, &basename); 00150 if (len == 0 || len > MAX_PATH - 1) 00151 return strdup (filename); 00152 else 00153 { 00154 /* The file system is case-preserving but case-insensitive, 00155 Canonicalize to lowercase, using the codepage associated 00156 with the process locale. */ 00157 CharLowerBuff (buf, len); 00158 return strdup (buf); 00159 } 00160 } 00161 #else 00162 00163 /* This system is a lost cause, just duplicate the filename. */ 00164 return strdup (filename); 00165 #endif 00166 }