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