]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/Split/Split.c
Move Smbios table MAX length definition to Mde header filer.
[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
1be2ed90 5Copyright (c) 1999 - 2014, 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
29//\r
30// Utility Name\r
31//\r
32#define UTILITY_NAME "Split"\r
33\r
34//\r
35// Utility version information\r
36//\r
37#define UTILITY_MAJOR_VERSION 0\r
38#define UTILITY_MINOR_VERSION 1\r
39\r
40void\r
41Version (\r
42 void\r
43 )\r
44/*++\r
45\r
46Routine Description:\r
47\r
48 Displays the standard utility information to SDTOUT\r
49\r
50Arguments:\r
51\r
52 None\r
53\r
54Returns:\r
55\r
56 None\r
57\r
58--*/\r
59{\r
d90aa462 60 printf ("%s Version %d.%d %s\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
1be2ed90 61 printf ("Copyright (c) 1999-2014 Intel Corporation. All rights reserved.\n");\r
d90aa462 62 printf ("\n SplitFile creates two Binary files either in the same directory as the current working\n");\r
63 printf (" directory or in the specified directory.\n");\r
30fdf114
LG
64}\r
65\r
66void\r
67Usage (\r
68 void\r
69 )\r
70/*++\r
71\r
72Routine Description:\r
73\r
74 GC_TODO: Add function description\r
75\r
76Arguments:\r
77\r
78\r
79Returns:\r
80\r
81 GC_TODO: add return values\r
82\r
83--*/\r
84{\r
85 Version();\r
86 printf ("\nUsage: \n\\r
87 Split\n\\r
88 -f, --filename inputFile to split\n\\r
89 -s, --split VALUE the number of bytes in the first file\n\\r
90 [-p, --prefix OutputDir]\n\\r
91 [-o, --firstfile Filename1]\n\\r
92 [-t, --secondfile Filename2]\n\\r
93 [-v, --verbose]\n\\r
94 [--version]\n\\r
95 [-q, --quiet disable all messages except fatal errors]\n\\r
96 [-d, --debug[#]\n\\r
97 [-h, --help]\n");\r
98}\r
99\r
100EFI_STATUS\r
101GetSplitValue (\r
102 IN CONST CHAR8* SplitValueString,\r
103 OUT UINT64 *ReturnValue\r
104)\r
105{\r
106 UINT64 len = strlen(SplitValueString);\r
107 UINT64 base = 1;\r
108 UINT64 index = 0;\r
109 UINT64 number = 0;\r
110 CHAR8 lastCHAR = 0;\r
111 EFI_STATUS Status = EFI_SUCCESS;\r
112\r
113 if (len == 0) {\r
114 return EFI_ABORTED;\r
115 }\r
116\r
117 Status = AsciiStringToUint64 (SplitValueString, FALSE, ReturnValue);\r
118 if (!EFI_ERROR (Status)) {\r
119 return Status;\r
120 }\r
121\r
122 if (SplitValueString[0] == '0' && (SplitValueString[1] == 'x' || SplitValueString[1] == 'X')) {\r
123 Status = AsciiStringToUint64 (SplitValueString, TRUE, ReturnValue);\r
124 if (!EFI_ERROR (Status)) {\r
125 return Status;\r
126 }\r
127 }\r
128\r
a709adfa 129 lastCHAR = (CHAR8)toupper((int)SplitValueString[len - 1]);\r
30fdf114
LG
130\r
131 if (lastCHAR != 'K' && lastCHAR != 'M' && lastCHAR != 'G') {\r
132 return STATUS_ERROR;\r
133 }\r
134\r
135 for (;index < len - 1; ++index) {\r
a709adfa 136 if (!isdigit((int)SplitValueString[index])) {\r
30fdf114
LG
137 return EFI_ABORTED;\r
138 }\r
139 }\r
140\r
141 number = atol (SplitValueString);\r
142 if (lastCHAR == 'K')\r
143 base = 1024;\r
144 else if (lastCHAR == 'M')\r
145 base = 1024*1024;\r
146 else\r
147 base = 1024*1024*1024;\r
148\r
149 *ReturnValue = number*base;\r
150\r
151 return EFI_SUCCESS;\r
152}\r
153\r
154EFI_STATUS\r
155CountVerboseLevel (\r
156 IN CONST CHAR8* VerboseLevelString,\r
157 IN CONST UINT64 Length,\r
158 OUT UINT64 *ReturnValue\r
159)\r
160{\r
161 UINT64 i = 0;\r
162 for (;i < Length; ++i) {\r
163 if (VerboseLevelString[i] != 'v' && VerboseLevelString[i] != 'V') {\r
164 return EFI_ABORTED;\r
165 }\r
166 ++(*ReturnValue);\r
167 }\r
168\r
169 return EFI_SUCCESS;\r
170}\r
171\r
172EFI_STATUS\r
173CreateDir (\r
174 IN OUT CHAR8** FullFileName\r
175)\r
176{\r
177 CHAR8* temp = *FullFileName;\r
178 CHAR8* start = temp;\r
179 UINT64 index = 0;\r
180\r
181 for (;index < strlen(temp); ++index) {\r
182 if (temp[index] == '\\' || temp[index] == '/') {\r
183 temp[index] = 0;\r
184 if (chdir(start)) {\r
185 if (mkdir(start, S_IRWXU | S_IRWXG | S_IRWXO) != 0) {\r
186 return EFI_ABORTED;\r
187 }\r
188 chdir(start);\r
189 }\r
190 start = temp + index + 1;\r
191 temp[index] = '/';\r
192 }\r
193 }\r
194\r
195 return EFI_SUCCESS;\r
196}\r
197\r
198int\r
199main (\r
200 int argc,\r
201 char*argv[]\r
202 )\r
203/*++\r
204\r
205Routine Description:\r
206\r
207 GC_TODO: Add function description\r
208\r
209Arguments:\r
210\r
211 argc - GC_TODO: add argument description\r
212 ] - GC_TODO: add argument description\r
213\r
214Returns:\r
215\r
216 GC_TODO: add return values\r
217\r
218--*/\r
219{\r
220 EFI_STATUS Status = EFI_SUCCESS;\r
221 FILE *In;\r
222 CHAR8 *InputFileName = NULL;\r
223 CHAR8 *OutputDir = NULL;\r
224 CHAR8 *OutFileName1 = NULL;\r
225 CHAR8 *OutFileName2 = NULL;\r
fd171542 226 UINT64 SplitValue = (UINT64) -1;\r
30fdf114
LG
227 FILE *Out1;\r
228 FILE *Out2;\r
229 CHAR8 *OutName1 = NULL;\r
230 CHAR8 *OutName2 = NULL;\r
231 CHAR8 *CurrentDir = NULL;\r
232 UINT64 Index;\r
233 CHAR8 CharC;\r
30fdf114
LG
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
30fdf114
LG
311 argc --;\r
312 argv ++;\r
313 continue;\r
314 }\r
315\r
316 if ((strlen(argv[0]) >= 2 && argv[0][0] == '-' && (argv[0][1] == 'v' || argv[0][1] == 'V')) || (stricmp (argv[0], "--verbose") == 0)) {\r
317 VerboseLevel = 1;\r
318 if (strlen(argv[0]) > 2) {\r
319 Status = CountVerboseLevel (&argv[0][2], strlen(argv[0]) - 2, &VerboseLevel);\r
320 if (EFI_ERROR (Status)) {\r
321 Error (NULL, 0, 0x1003, NULL, "%s is invaild paramter!", argv[0]);\r
322 return STATUS_ERROR;\r
323 }\r
324 }\r
325\r
326 argc --;\r
327 argv ++;\r
328 continue;\r
329 }\r
330\r
331 if ((stricmp (argv[0], "-d") == 0) || (stricmp (argv[0], "--debug") == 0)) {\r
332 Status = AsciiStringToUint64 (argv[1], FALSE, &DebugLevel);\r
333 if (EFI_ERROR (Status)) {\r
334 Error (NULL, 0, 0x1003, "Input debug level is not one valid integrator.", NULL);\r
335 return STATUS_ERROR;\r
336 }\r
337 argc -= 2;\r
338 argv += 2;\r
339 continue;\r
340 }\r
341 //\r
342 // Don't recognize the paramter.\r
343 //\r
344 Error (NULL, 0, 0x1003, NULL, "%s is invaild paramter!", argv[0]);\r
345 return STATUS_ERROR;\r
346 }\r
347\r
348 if (InputFileName == NULL) {\r
349 Error (NULL, 0, 0x1001, "NO Input file specified.", NULL);\r
350 return STATUS_ERROR;\r
351 }\r
352\r
1be2ed90 353 In = fopen (LongFilePath (InputFileName), "rb");\r
30fdf114
LG
354 if (In == NULL) {\r
355 // ("Unable to open file \"%s\"\n", InputFileName);\r
356 Error (InputFileName, 0, 1, "File open failure", NULL);\r
357 return STATUS_ERROR;\r
358 }\r
359\r
360 if (OutFileName1 == NULL) {\r
361 OutName1 = (CHAR8*)malloc(strlen(InputFileName) + 16);\r
362 if (OutName1 == NULL) {\r
363 Warning (NULL, 0, 0, NULL, "Memory Allocation Fail.");\r
364 return STATUS_ERROR;\r
365 }\r
366 strcpy (OutName1, InputFileName);\r
367 strcat (OutName1, "1");\r
368 OutFileName1 = OutName1;\r
369\r
370 }\r
371 if (OutFileName2 == NULL) {\r
372 OutName2 = (CHAR8*)malloc(strlen(InputFileName) + 16);\r
373 if (OutName2 == NULL) {\r
374 Warning (NULL, 0, 0, NULL, "Memory Allocation Fail.");\r
375 return STATUS_ERROR;\r
376 }\r
377 strcpy (OutName2, InputFileName);\r
378 strcat (OutName2, "2");\r
379 OutFileName2 = OutName2;\r
380\r
381 }\r
382\r
383 if (OutputDir != NULL) {\r
384 //OutputDirSpecified = TRUE;\r
385 if (chdir(OutputDir) != 0) {\r
386 Warning (NULL, 0, 0, NULL, "Change dir to OutputDir Fail.");\r
387 return STATUS_ERROR;\r
388 }\r
389 }\r
390\r
391 CurrentDir = (CHAR8*)getcwd((CHAR8*)0, 0);\r
392 if (EFI_ERROR(CreateDir(&OutFileName1))) {\r
393 Error (OutFileName1, 0, 5, "Create Dir for File1 Fail.", NULL);\r
394 return STATUS_ERROR;\r
395 }\r
396 chdir(CurrentDir);\r
397\r
398 if (EFI_ERROR(CreateDir(&OutFileName2))) {\r
399 Error (OutFileName2, 0, 5, "Create Dir for File2 Fail.", NULL);\r
400 return STATUS_ERROR;\r
401 }\r
402 chdir(CurrentDir);\r
403 free(CurrentDir);\r
404\r
1be2ed90 405 Out1 = fopen (LongFilePath (OutFileName1), "wb");\r
30fdf114
LG
406 if (Out1 == NULL) {\r
407 // ("Unable to open file \"%s\"\n", OutFileName1);\r
408 Error (OutFileName1, 0, 1, "File open failure", NULL);\r
409 return STATUS_ERROR;\r
410 }\r
411\r
1be2ed90 412 Out2 = fopen (LongFilePath (OutFileName2), "wb");\r
30fdf114
LG
413 if (Out2 == NULL) {\r
414 // ("Unable to open file \"%s\"\n", OutFileName2);\r
415 Error (OutFileName2, 0, 1, "File open failure", NULL);\r
416 return STATUS_ERROR;\r
417 }\r
418\r
419 for (Index = 0; Index < SplitValue; Index++) {\r
420 CharC = (CHAR8) fgetc (In);\r
421 if (feof (In)) {\r
422 break;\r
423 }\r
424\r
425 fputc (CharC, Out1);\r
426 }\r
427\r
428 for (;;) {\r
429 CharC = (CHAR8) fgetc (In);\r
430 if (feof (In)) {\r
431 break;\r
432 }\r
433\r
434 fputc (CharC, Out2);\r
435 }\r
436\r
437 if (OutName1 != NULL) {\r
438 free(OutName1);\r
439 }\r
440 if (OutName2 != NULL) {\r
441 free(OutName2);\r
442 }\r
443 fclose (In);\r
444 fclose (Out1);\r
445 fclose (Out2);\r
446\r
447 return STATUS_SUCCESS;\r
448}\r