1 /** @file 2 Functions useful to operate file directories by parsing file path. 3 4 Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include "CommonLib.h" 19 #include "OsPath.h" 20 21 // 22 // Functions implementations 23 // 24 25 #if 0 26 // 27 // BUGBUG: Not fully implemented yet. 28 // 29 CHAR8* 30 OsPathDirName ( 31 IN CHAR8 *FilePath 32 ) 33 /*++ 34 35 Routine Description: 36 37 This function returns the directory path which contains the particular path. 38 Some examples: 39 "a/b/c" -> "a/b" 40 "a/b/c/" -> "a/b" 41 "a" -> "." 42 "." -> ".." 43 "/" -> NULL 44 45 This function does not check for the existence of the file. 46 47 The caller must free the string returned. 48 49 Arguments: 50 51 FilePath Path name of file to get the parent directory for. 52 53 Returns: 54 55 NULL if error 56 57 --*/ 58 { 59 CHAR8 *Return; 60 CHAR8 *Pos; 61 CHAR8 Char; 62 UINTN Length; 63 INTN Offset; 64 65 Length = strlen (FilePath); 66 67 if (Length == 0) { 68 return NULL; 69 } 70 71 // 72 // Check for the root directory case 73 // 74 if ( 75 (Length == 3 && isalpha (FilePath[0]) && (strcmp(FilePath + 1, ":\\") == 0)) || 76 (strcmp(FilePath, "/") == 0) 77 ) { 78 return NULL; 79 } 80 81 // 82 // If the path ends with a path separator, then just append ".." 83 // 84 Char = FilePath[Length - 1]; 85 if (Char == '/' || Char == '\\') { 86 return OsPathJoin (FilePath, ".."); 87 } 88 89 // 90 // 91 // 92 for (Offset = Length; Offset > 0; Offset--) { 93 if ((Return[Offset] == '/') || (Return[Offset] == '\\')) { 94 Return[Offset] = '\0'; 95 return Return; 96 } 97 } 98 } 99 #endif 100 101 102 #if 0 103 // 104 // BUGBUG: Not fully implemented yet. 105 // 106 VOID 107 OsPathNormPathInPlace ( 108 IN CHAR8 *Path 109 ) 110 /*++ 111 112 Routine Description: 113 114 This function returns the directory path which contains the particular path. 115 Some examples: 116 "a/b/../c" -> "a/c" 117 "a/b//c" -> "a/b/c" 118 "a/./b" -> "a/b" 119 120 This function does not check for the existence of the file. 121 122 Arguments: 123 124 Path Path name of file to normalize 125 126 Returns: 127 128 The string is altered in place. 129 130 --*/ 131 { 132 CHAR8 *Pos; 133 INTN Offset; 134 BOOLEAN TryAgain; 135 UINTN Length; 136 UINTN Remaining; 137 UINTN SubLength; 138 139 do { 140 TryAgain = FALSE; 141 Length = strlen (Path); 142 143 for (Offset = 0; Offset < Length; Offset++) { 144 Remaining = Length - Offset; 145 146 // 147 // Collapse '//' -> '/' 148 // 149 if ( 150 (Remaining >= 2) && 151 ((Offset > 0) || (Path[0] != '\\')) && 152 IsDirSep (Path[Offset]) && IsDirSep (Path[Offset + 1]) 153 ) { 154 memmove (&Path[Offset], &Path[Offset + 1], Remaining); 155 TryAgain = TRUE; 156 break; 157 } 158 159 // 160 // Collapse '/./' -> '/' 161 // 162 if ((Remaining >= 3) && IsDirSep (Path[Offset]) && 163 (Path[Offset + 1] == '.') && IsDirSep (Path[Offset + 2]) 164 ) { 165 memmove (&Path[Offset], &Path[Offset + 1], Remaining); 166 TryAgain = TRUE; 167 break; 168 } 169 170 // 171 // Collapse 'a/../b' -> 'b' 172 // 173 // BUGBUG: Not implemented yet 174 175 } 176 177 } while (TryAgain); 178 179 Return = CloneString (FilePath); 180 if (Return == NULL) { 181 return NULL; 182 } 183 184 Length = strlen (Return); 185 186 // 187 // Check for the root directory case 188 // 189 if ( 190 (Length == 3 && isalpha (Return[0]) && (strcmp(Return + 1, ":\\") == 0)) || 191 (strcmp(Return, "/") == 0) 192 ) { 193 free (Return); 194 return NULL; 195 } 196 197 // 198 // 199 // 200 for (Offset = Length; Offset > 0; Offset--) { 201 if ((Return[Offset] == '/') || (Return[Offset] == '\\')) { 202 Return[Offset] = '\0'; 203 return Return; 204 } 205 } 206 } 207 #endif 208 209 210 CHAR8* 211 OsPathPeerFilePath ( 212 IN CHAR8 *OldPath, 213 IN CHAR8 *Peer 214 ) 215 /*++ 216 217 Routine Description: 218 219 This function replaces the final portion of a path with an alternative 220 'peer' filename. For example: 221 "a/b/../c", "peer" -> "a/b/../peer" 222 "a/b/", "peer" -> "a/b/peer" 223 "/a", "peer" -> "/peer" 224 "a", "peer" -> "peer" 225 226 This function does not check for the existence of the file. 227 228 Arguments: 229 230 OldPath Path name of replace the final segment 231 Peer The new path name to concatinate to become the peer path 232 233 Returns: 234 235 A CHAR8* string, which must be freed by the caller 236 237 --*/ 238 { 239 CHAR8 *Result; 240 INTN Offset; 241 242 Result = (CHAR8 *) malloc (strlen (OldPath) + strlen (Peer) + 1); 243 if (Result == NULL) { 244 return NULL; 245 } 246 247 strcpy (Result, OldPath); 248 249 // 250 // Search for the last '/' or '\' in the string. If found, replace 251 // everything following it with Peer 252 // 253 for (Offset = strlen (Result); Offset >= 0; Offset--) { 254 if ((Result[Offset] == '/') || (Result[Offset] == '\\')) { 255 Result[Offset + 1] = '\0'; 256 strcat (Result, Peer); 257 return Result; 258 } 259 } 260 261 // 262 // Neither a '/' nor a '\' was found. Therefore, we simply return Peer. 263 // 264 strcpy (Result, Peer); 265 return Result; 266 } 267 268 269 BOOLEAN 270 OsPathExists ( 271 IN CHAR8 *InputFileName 272 ) 273 /*++ 274 275 Routine Description: 276 277 Checks if a file exists 278 279 Arguments: 280 281 InputFileName The name of the file to check for existence 282 283 Returns: 284 285 TRUE The file exists 286 FALSE The file does not exist 287 288 --*/ 289 { 290 FILE *InputFile; 291 InputFile = fopen (LongFilePath (InputFileName), "rb"); 292 if (InputFile == NULL) { 293 return FALSE; 294 } else { 295 fclose (InputFile); 296 return TRUE; 297 } 298 } 299 300 301 302