Home | History | Annotate | Download | only in Common
      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