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