]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/C/Common/OsPath.c
BaseTools: Clean up source files
[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 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