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