/** @file Functions useful to operate file directories by parsing file path. Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include "CommonLib.h" #include "OsPath.h" // // Functions implementations // #if 0 // // BUGBUG: Not fully implemented yet. // CHAR8* OsPathDirName ( IN CHAR8 *FilePath ) /*++ Routine Description: This function returns the directory path which contains the particular path. Some examples: "a/b/c" -> "a/b" "a/b/c/" -> "a/b" "a" -> "." "." -> ".." "/" -> NULL This function does not check for the existence of the file. The caller must free the string returned. Arguments: FilePath Path name of file to get the parent directory for. Returns: NULL if error --*/ { CHAR8 *Return; CHAR8 *Pos; CHAR8 Char; UINTN Length; INTN Offset; Length = strlen (FilePath); if (Length == 0) { return NULL; } // // Check for the root directory case // if ( (Length == 3 && isalpha (FilePath[0]) && (strcmp(FilePath + 1, ":\\") == 0)) || (strcmp(FilePath, "/") == 0) ) { return NULL; } // // If the path ends with a path separator, then just append ".." // Char = FilePath[Length - 1]; if (Char == '/' || Char == '\\') { return OsPathJoin (FilePath, ".."); } // // // for (Offset = Length; Offset > 0; Offset--) { if ((Return[Offset] == '/') || (Return[Offset] == '\\')) { Return[Offset] = '\0'; return Return; } } } #endif #if 0 // // BUGBUG: Not fully implemented yet. // VOID OsPathNormPathInPlace ( IN CHAR8 *Path ) /*++ Routine Description: This function returns the directory path which contains the particular path. Some examples: "a/b/../c" -> "a/c" "a/b//c" -> "a/b/c" "a/./b" -> "a/b" This function does not check for the existence of the file. Arguments: Path Path name of file to normalize Returns: The string is altered in place. --*/ { CHAR8 *Pos; INTN Offset; BOOLEAN TryAgain; UINTN Length; UINTN Remaining; UINTN SubLength; do { TryAgain = FALSE; Length = strlen (Path); for (Offset = 0; Offset < Length; Offset++) { Remaining = Length - Offset; // // Collapse '//' -> '/' // if ( (Remaining >= 2) && ((Offset > 0) || (Path[0] != '\\')) && IsDirSep (Path[Offset]) && IsDirSep (Path[Offset + 1]) ) { memmove (&Path[Offset], &Path[Offset + 1], Remaining); TryAgain = TRUE; break; } // // Collapse '/./' -> '/' // if ((Remaining >= 3) && IsDirSep (Path[Offset]) && (Path[Offset + 1] == '.') && IsDirSep (Path[Offset + 2]) ) { memmove (&Path[Offset], &Path[Offset + 1], Remaining); TryAgain = TRUE; break; } // // Collapse 'a/../b' -> 'b' // // BUGBUG: Not implemented yet } } while (TryAgain); Return = CloneString (FilePath); if (Return == NULL) { return NULL; } Length = strlen (Return); // // Check for the root directory case // if ( (Length == 3 && isalpha (Return[0]) && (strcmp(Return + 1, ":\\") == 0)) || (strcmp(Return, "/") == 0) ) { free (Return); return NULL; } // // // for (Offset = Length; Offset > 0; Offset--) { if ((Return[Offset] == '/') || (Return[Offset] == '\\')) { Return[Offset] = '\0'; return Return; } } } #endif CHAR8* OsPathPeerFilePath ( IN CHAR8 *OldPath, IN CHAR8 *Peer ) /*++ Routine Description: This function replaces the final portion of a path with an alternative 'peer' filename. For example: "a/b/../c", "peer" -> "a/b/../peer" "a/b/", "peer" -> "a/b/peer" "/a", "peer" -> "/peer" "a", "peer" -> "peer" This function does not check for the existence of the file. Arguments: OldPath Path name of replace the final segment Peer The new path name to concatenate to become the peer path Returns: A CHAR8* string, which must be freed by the caller --*/ { CHAR8 *Result; INTN Offset; Result = (CHAR8 *) malloc (strlen (OldPath) + strlen (Peer) + 1); if (Result == NULL) { return NULL; } strcpy (Result, OldPath); // // Search for the last '/' or '\' in the string. If found, replace // everything following it with Peer // for (Offset = strlen (Result); Offset >= 0; Offset--) { if ((Result[Offset] == '/') || (Result[Offset] == '\\')) { Result[Offset + 1] = '\0'; strcat (Result, Peer); return Result; } } // // Neither a '/' nor a '\' was found. Therefore, we simply return Peer. // strcpy (Result, Peer); return Result; } BOOLEAN OsPathExists ( IN CHAR8 *InputFileName ) /*++ Routine Description: Checks if a file exists Arguments: InputFileName The name of the file to check for existence Returns: TRUE The file exists FALSE The file does not exist --*/ { FILE *InputFile; InputFile = fopen (LongFilePath (InputFileName), "rb"); if (InputFile == NULL) { return FALSE; } else { fclose (InputFile); return TRUE; } }