]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/Split/Split.c
Sync BaseTools Branch (version r2321) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / C / Split / Split.c
CommitLineData
30fdf114
LG
1/** @file\r
2\r
3 Split a file into two pieces at the request offset.\r
4\r
40d841f6 5Copyright (c) 1999 - 2010, Intel Corporation. All rights reserved.<BR>\r
30fdf114
LG
6This program and the accompanying materials are licensed and made available\r
7under the terms and conditions of the BSD License which accompanies this\r
8distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16// GC_TODO: fix comment to start with /*++\r
17#include <stdio.h>\r
18#include <string.h>\r
19#include <stdlib.h>\r
20#ifdef __GNUC__\r
21#include <unistd.h>\r
fd171542 22#else\r
23#include <direct.h>\r
30fdf114
LG
24#endif\r
25#include <ctype.h>\r
26#include "ParseInf.h"\r
27#include "CommonLib.h"\r
28#include "EfiUtilityMsgs.h"\r
b36d134f 29\r
30fdf114
LG
30//\r
31// Utility Name\r
32//\r
33#define UTILITY_NAME "Split"\r
34\r
35//\r
36// Utility version information\r
37//\r
38#define UTILITY_MAJOR_VERSION 0\r
39#define UTILITY_MINOR_VERSION 1\r
40\r
41void\r
42Version (\r
43 void\r
44 )\r
45/*++\r
46\r
47Routine Description:\r
48\r
49 Displays the standard utility information to SDTOUT\r
50\r
51Arguments:\r
52\r
53 None\r
54\r
55Returns:\r
56\r
57 None\r
58\r
59--*/\r
60{\r
b36d134f 61 printf ("%s v%d.%d %s -Utility to break a file into two pieces at the request offset.\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
52302d4d 62 printf ("Copyright (c) 1999-2010 Intel Corporation. All rights reserved.\n");\r
30fdf114
LG
63}\r
64\r
65void\r
66Usage (\r
67 void\r
68 )\r
69/*++\r
70\r
71Routine Description:\r
72\r
73 GC_TODO: Add function description\r
74\r
75Arguments:\r
76\r
77\r
78Returns:\r
79\r
80 GC_TODO: add return values\r
81\r
82--*/\r
83{\r
84 Version();\r
85 printf ("\nUsage: \n\\r
86 Split\n\\r
87 -f, --filename inputFile to split\n\\r
88 -s, --split VALUE the number of bytes in the first file\n\\r
89 [-p, --prefix OutputDir]\n\\r
90 [-o, --firstfile Filename1]\n\\r
91 [-t, --secondfile Filename2]\n\\r
92 [-v, --verbose]\n\\r
93 [--version]\n\\r
94 [-q, --quiet disable all messages except fatal errors]\n\\r
95 [-d, --debug[#]\n\\r
96 [-h, --help]\n");\r
97}\r
98\r
99EFI_STATUS\r
100GetSplitValue (\r
101 IN CONST CHAR8* SplitValueString,\r
102 OUT UINT64 *ReturnValue\r
103)\r
104{\r
105 UINT64 len = strlen(SplitValueString);\r
106 UINT64 base = 1;\r
107 UINT64 index = 0;\r
108 UINT64 number = 0;\r
109 CHAR8 lastCHAR = 0;\r
110 EFI_STATUS Status = EFI_SUCCESS;\r
111\r
112 if (len == 0) {\r
113 return EFI_ABORTED;\r
114 }\r
115\r
116 Status = AsciiStringToUint64 (SplitValueString, FALSE, ReturnValue);\r
117 if (!EFI_ERROR (Status)) {\r
118 return Status;\r
119 }\r
120\r
121 if (SplitValueString[0] == '0' && (SplitValueString[1] == 'x' || SplitValueString[1] == 'X')) {\r
122 Status = AsciiStringToUint64 (SplitValueString, TRUE, ReturnValue);\r
123 if (!EFI_ERROR (Status)) {\r
124 return Status;\r
125 }\r
126 }\r
127\r
a709adfa 128 lastCHAR = (CHAR8)toupper((int)SplitValueString[len - 1]);\r
30fdf114
LG
129\r
130 if (lastCHAR != 'K' && lastCHAR != 'M' && lastCHAR != 'G') {\r
131 return STATUS_ERROR;\r
132 }\r
133\r
134 for (;index < len - 1; ++index) {\r
a709adfa 135 if (!isdigit((int)SplitValueString[index])) {\r
30fdf114
LG
136 return EFI_ABORTED;\r
137 }\r
138 }\r
139\r
140 number = atol (SplitValueString);\r
141 if (lastCHAR == 'K')\r
142 base = 1024;\r
143 else if (lastCHAR == 'M')\r
144 base = 1024*1024;\r
145 else\r
146 base = 1024*1024*1024;\r
147\r
148 *ReturnValue = number*base;\r
149\r
150 return EFI_SUCCESS;\r
151}\r
152\r
153EFI_STATUS\r
154CountVerboseLevel (\r
155 IN CONST CHAR8* VerboseLevelString,\r
156 IN CONST UINT64 Length,\r
157 OUT UINT64 *ReturnValue\r
158)\r
159{\r
160 UINT64 i = 0;\r
161 for (;i < Length; ++i) {\r
162 if (VerboseLevelString[i] != 'v' && VerboseLevelString[i] != 'V') {\r
163 return EFI_ABORTED;\r
164 }\r
165 ++(*ReturnValue);\r
166 }\r
167\r
168 return EFI_SUCCESS;\r
169}\r
170\r
171EFI_STATUS\r
172CreateDir (\r
173 IN OUT CHAR8** FullFileName\r
174)\r
175{\r
176 CHAR8* temp = *FullFileName;\r
177 CHAR8* start = temp;\r
178 UINT64 index = 0;\r
179\r
180 for (;index < strlen(temp); ++index) {\r
181 if (temp[index] == '\\' || temp[index] == '/') {\r
182 temp[index] = 0;\r
183 if (chdir(start)) {\r
184 if (mkdir(start, S_IRWXU | S_IRWXG | S_IRWXO) != 0) {\r
185 return EFI_ABORTED;\r
186 }\r
187 chdir(start);\r
188 }\r
189 start = temp + index + 1;\r
190 temp[index] = '/';\r
191 }\r
192 }\r
193\r
194 return EFI_SUCCESS;\r
195}\r
196\r
197int\r
198main (\r
199 int argc,\r
200 char*argv[]\r
201 )\r
202/*++\r
203\r
204Routine Description:\r
205\r
206 GC_TODO: Add function description\r
207\r
208Arguments:\r
209\r
210 argc - GC_TODO: add argument description\r
211 ] - GC_TODO: add argument description\r
212\r
213Returns:\r
214\r
215 GC_TODO: add return values\r
216\r
217--*/\r
218{\r
219 EFI_STATUS Status = EFI_SUCCESS;\r
220 FILE *In;\r
221 CHAR8 *InputFileName = NULL;\r
222 CHAR8 *OutputDir = NULL;\r
223 CHAR8 *OutFileName1 = NULL;\r
224 CHAR8 *OutFileName2 = NULL;\r
fd171542 225 UINT64 SplitValue = (UINT64) -1;\r
30fdf114
LG
226 FILE *Out1;\r
227 FILE *Out2;\r
228 CHAR8 *OutName1 = NULL;\r
229 CHAR8 *OutName2 = NULL;\r
230 CHAR8 *CurrentDir = NULL;\r
231 UINT64 Index;\r
232 CHAR8 CharC;\r
233 BOOLEAN QuietFlag = TRUE;\r
234 UINT64 DebugLevel = 0;\r
235 UINT64 VerboseLevel = 0;\r
236\r
237 SetUtilityName(UTILITY_NAME);\r
238 if (argc == 1) {\r
239 Usage();\r
240 return STATUS_ERROR;\r
241 }\r
242\r
243 argc --;\r
244 argv ++;\r
245\r
246 if ((stricmp (argv[0], "-h") == 0) || (stricmp (argv[0], "--help") == 0)) {\r
247 Usage();\r
248 return STATUS_SUCCESS;\r
249 }\r
250\r
251 if (stricmp (argv[0], "--version") == 0) {\r
252 Version();\r
253 return STATUS_SUCCESS;\r
254 }\r
255\r
256 while (argc > 0) {\r
257 if ((stricmp (argv[0], "-p") == 0) || (stricmp (argv[0], "--prefix") == 0)) {\r
258 OutputDir = argv[1];\r
259 if (OutputDir == NULL) {\r
260 Warning (NULL, 0, 0, "NO output directory specified.", NULL);\r
261 return STATUS_ERROR;\r
262 }\r
263 argc -= 2;\r
264 argv += 2;\r
265 continue;\r
266 }\r
267\r
268 if ((stricmp (argv[0], "-f") == 0) || (stricmp (argv[0], "--filename") == 0)) {\r
269 InputFileName = argv[1];\r
270 if (InputFileName == NULL) {\r
271 Error (NULL, 0, 0x1001, "NO Input file specified.", NULL);\r
272 return STATUS_ERROR;\r
273 }\r
274 argc -= 2;\r
275 argv += 2;\r
276 continue;\r
277 }\r
278\r
279 if ((stricmp (argv[0], "-s") == 0) || (stricmp (argv[0], "--split") == 0)) {\r
280 Status = GetSplitValue(argv[1], &SplitValue);\r
281 if (EFI_ERROR (Status)) {\r
282 Error (NULL, 0, 0x1003, "Input split value is not one valid integer.", NULL);\r
283 return STATUS_ERROR;\r
284 }\r
285 argc -= 2;\r
286 argv += 2;\r
287 continue;\r
288 }\r
289\r
290 if ((stricmp (argv[0], "-o") == 0) || (stricmp (argv[0], "--firstfile") == 0)) {\r
291 OutFileName1 = argv[1];\r
292 if (OutFileName1 == NULL) {\r
293 Warning (NULL, 0, 0, NULL, "No output file1 specified.");\r
294 }\r
295 argc -= 2;\r
296 argv += 2;\r
297 continue;\r
298 }\r
299\r
300 if ((stricmp (argv[0], "-t") == 0) || (stricmp (argv[0], "--secondfile") == 0)) {\r
301 OutFileName2 = argv[1];\r
302 if (OutFileName2 == NULL) {\r
303 Warning (NULL, 0, 0, NULL, "No output file2 specified.");\r
304 }\r
305 argc -= 2;\r
306 argv += 2;\r
307 continue;\r
308 }\r
309\r
310 if ((stricmp (argv[0], "-q") == 0) || (stricmp (argv[0], "--quiet") == 0)) {\r
311 QuietFlag = TRUE;\r
312 argc --;\r
313 argv ++;\r
314 continue;\r
315 }\r
316\r
317 if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (stricmp (argv[0], "--verbose") == 0)) {\r
318 VerboseLevel = 1;\r
319 if (strlen(argv[0]) > 2) {\r
320 Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel);\r
321 if (EFI_ERROR (Status)) {\r
322 Error (NULL, 0, 0x1003, NULL, "%s is invaild paramter!", argv[0]);\r
323 return STATUS_ERROR;\r
324 }\r
325 }\r
326\r
327 argc --;\r
328 argv ++;\r
329 continue;\r
330 }\r
331\r
332 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
333 Status = AsciiStringToUint64 (argv[1], FALSE, &DebugLevel);\r
334 if (EFI_ERROR (Status)) {\r
335 Error (NULL, 0, 0x1003, "Input debug level is not one valid integrator.", NULL);\r
336 return STATUS_ERROR;\r
337 }\r
338 argc -= 2;\r
339 argv += 2;\r
340 continue;\r
341 }\r
342 //\r
343 // Don't recognize the paramter.\r
344 //\r
345 Error (NULL, 0, 0x1003, NULL, "%s is invaild paramter!", argv[0]);\r
346 return STATUS_ERROR;\r
347 }\r
348\r
349 if (InputFileName == NULL) {\r
350 Error (NULL, 0, 0x1001, "NO Input file specified.", NULL);\r
351 return STATUS_ERROR;\r
352 }\r
353\r
354 In = fopen (InputFileName, "rb");\r
355 if (In == NULL) {\r
356 // ("Unable to open file \"%s\"\n", InputFileName);\r
357 Error (InputFileName, 0, 1, "File open failure", NULL);\r
358 return STATUS_ERROR;\r
359 }\r
360\r
361 if (OutFileName1 == NULL) {\r
362 OutName1 = (CHAR8*)malloc(strlen(InputFileName) + 16);\r
363 if (OutName1 == NULL) {\r
364 Warning (NULL, 0, 0, NULL, "Memory Allocation Fail.");\r
365 return STATUS_ERROR;\r
366 }\r
367 strcpy (OutName1, InputFileName);\r
368 strcat (OutName1, "1");\r
369 OutFileName1 = OutName1;\r
370\r
371 }\r
372 if (OutFileName2 == NULL) {\r
373 OutName2 = (CHAR8*)malloc(strlen(InputFileName) + 16);\r
374 if (OutName2 == NULL) {\r
375 Warning (NULL, 0, 0, NULL, "Memory Allocation Fail.");\r
376 return STATUS_ERROR;\r
377 }\r
378 strcpy (OutName2, InputFileName);\r
379 strcat (OutName2, "2");\r
380 OutFileName2 = OutName2;\r
381\r
382 }\r
383\r
384 if (OutputDir != NULL) {\r
385 //OutputDirSpecified = TRUE;\r
386 if (chdir(OutputDir) != 0) {\r
387 Warning (NULL, 0, 0, NULL, "Change dir to OutputDir Fail.");\r
388 return STATUS_ERROR;\r
389 }\r
390 }\r
391\r
392 CurrentDir = (CHAR8*)getcwd((CHAR8*)0, 0);\r
393 if (EFI_ERROR(CreateDir(&OutFileName1))) {\r
394 Error (OutFileName1, 0, 5, "Create Dir for File1 Fail.", NULL);\r
395 return STATUS_ERROR;\r
396 }\r
397 chdir(CurrentDir);\r
398\r
399 if (EFI_ERROR(CreateDir(&OutFileName2))) {\r
400 Error (OutFileName2, 0, 5, "Create Dir for File2 Fail.", NULL);\r
401 return STATUS_ERROR;\r
402 }\r
403 chdir(CurrentDir);\r
404 free(CurrentDir);\r
405\r
406 Out1 = fopen (OutFileName1, "wb");\r
407 if (Out1 == NULL) {\r
408 // ("Unable to open file \"%s\"\n", OutFileName1);\r
409 Error (OutFileName1, 0, 1, "File open failure", NULL);\r
410 return STATUS_ERROR;\r
411 }\r
412\r
413 Out2 = fopen (OutFileName2, "wb");\r
414 if (Out2 == NULL) {\r
415 // ("Unable to open file \"%s\"\n", OutFileName2);\r
416 Error (OutFileName2, 0, 1, "File open failure", NULL);\r
417 return STATUS_ERROR;\r
418 }\r
419\r
420 for (Index = 0; Index < SplitValue; Index++) {\r
421 CharC = (CHAR8) fgetc (In);\r
422 if (feof (In)) {\r
423 break;\r
424 }\r
425\r
426 fputc (CharC, Out1);\r
427 }\r
428\r
429 for (;;) {\r
430 CharC = (CHAR8) fgetc (In);\r
431 if (feof (In)) {\r
432 break;\r
433 }\r
434\r
435 fputc (CharC, Out2);\r
436 }\r
437\r
438 if (OutName1 != NULL) {\r
439 free(OutName1);\r
440 }\r
441 if (OutName2 != NULL) {\r
442 free(OutName2);\r
443 }\r
444 fclose (In);\r
445 fclose (Out1);\r
446 fclose (Out2);\r
447\r
448 return STATUS_SUCCESS;\r
449}\r