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