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