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