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