]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Foundation/Library/Dxe/Print/Print.c
GCC cleanup for all EDK I DXE libraries.
[mirror_edk2.git] / EdkCompatibilityPkg / Foundation / Library / Dxe / Print / Print.c
CommitLineData
3eb9473e 1/*++\r
2\r
c7f33ca4 3Copyright (c) 2004 - 2007, Intel Corporation \r
3eb9473e 4All rights reserved. This program and the accompanying materials \r
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 Print.c\r
15\r
16Abstract:\r
17\r
18 Basic Ascii AvSPrintf() function named VSPrint(). VSPrint() enables very\r
19 simple implemenation of SPrint() and Print() to support debug. \r
20\r
21 You can not Print more than EFI_DRIVER_LIB_MAX_PRINT_BUFFER characters at a \r
22 time. This makes the implementation very simple.\r
23\r
24 VSPrint, Print, SPrint format specification has the follwoing form\r
25\r
26 %[flags][width]type\r
27\r
28 flags:\r
29 '-' - Left justify\r
30 '+' - Prefix a sign\r
31 ' ' - Prefix a blank\r
32 ',' - Place commas in numberss\r
33 '0' - Prefix for width with zeros\r
34 'l' - UINT64\r
35 'L' - UINT64\r
36\r
37 width:\r
38 '*' - Get width from a UINTN argumnet from the argument list\r
39 Decimal number that represents width of print\r
40\r
41 type:\r
42 'X' - argument is a UINTN hex number, prefix '0'\r
43 'x' - argument is a hex number\r
44 'd' - argument is a decimal number\r
45 'a' - argument is an ascii string \r
46 'S','s' - argument is an Unicode string\r
47 'g' - argument is a pointer to an EFI_GUID\r
48 't' - argument is a pointer to an EFI_TIME structure\r
49 'c' - argument is an ascii character\r
50 'r' - argument is EFI_STATUS\r
51 '%' - Print a %\r
52\r
53--*/\r
54\r
55#include "TianoCommon.h"\r
56#include "EfiCommonLib.h"\r
57#include "PrintWidth.h"\r
58#include "EfiPrintLib.h"\r
59#include "Print.h"\r
60\r
61\r
62STATIC\r
63CHAR_W *\r
64GetFlagsAndWidth (\r
65 IN CHAR_W *Format, \r
66 OUT UINTN *Flags, \r
67 OUT UINTN *Width,\r
68 IN OUT VA_LIST *Marker\r
69 );\r
70\r
71STATIC\r
72UINTN\r
73GuidToString (\r
74 IN EFI_GUID *Guid,\r
75 IN OUT CHAR_W *Buffer,\r
76 IN UINTN BufferSize\r
77 );\r
78\r
79STATIC\r
80UINTN\r
81TimeToString (\r
82 IN EFI_TIME *Time,\r
83 IN OUT CHAR_W *Buffer,\r
84 IN UINTN BufferSize\r
85 );\r
86\r
87STATIC\r
88UINTN\r
89EfiStatusToString (\r
90 IN EFI_STATUS Status,\r
91 OUT CHAR_W *Buffer,\r
92 IN UINTN BufferSize\r
93 );\r
94\r
95UINTN\r
96SPrint (\r
97 OUT CHAR_W *Buffer,\r
98 IN UINTN BufferSize,\r
99 IN CONST CHAR_W *Format,\r
100 ...\r
101 )\r
102/*++\r
103\r
104Routine Description:\r
105\r
106 SPrint function to process format and place the results in Buffer.\r
107\r
108Arguments:\r
109\r
110 Buffer - Wide char buffer to print the results of the parsing of Format into.\r
111\r
112 BufferSize - Maximum number of characters to put into buffer. Zero means no \r
113 limit.\r
114\r
115 Format - Format string see file header for more details.\r
116\r
117 ... - Vararg list consumed by processing Format.\r
118\r
119Returns: \r
120\r
121 Number of characters printed.\r
122\r
123--*/\r
124{\r
125 UINTN Return;\r
126 VA_LIST Marker;\r
127\r
128 VA_START (Marker, Format);\r
129 Return = VSPrint (Buffer, BufferSize, Format, Marker);\r
130 VA_END (Marker);\r
131 \r
132 return Return;\r
133}\r
134\r
135\r
136UINTN\r
c7f33ca4 137EFIAPI\r
3eb9473e 138VSPrint (\r
139 OUT CHAR_W *StartOfBuffer,\r
140 IN UINTN BufferSize,\r
141 IN CONST CHAR_W *FormatString,\r
142 IN VA_LIST Marker\r
143 )\r
144/*++\r
145\r
146Routine Description:\r
147\r
148 VSPrint function to process format and place the results in Buffer. Since a \r
149 VA_LIST is used this rountine allows the nesting of Vararg routines. Thus \r
150 this is the main print working routine\r
151\r
152Arguments:\r
153\r
154 StartOfBuffer - Unicode buffer to print the results of the parsing of Format into.\r
155\r
156 BufferSize - Maximum number of characters to put into buffer. Zero means \r
157 no limit.\r
158\r
159 FormatString - Unicode format string see file header for more details.\r
160\r
161 Marker - Vararg list consumed by processing Format.\r
162\r
163Returns: \r
164\r
165 Number of characters printed.\r
166\r
167--*/\r
168{\r
169 CHAR16 TempBuffer[CHARACTER_NUMBER_FOR_VALUE];\r
170 CHAR_W *Buffer;\r
171 CHAR8 *AsciiStr;\r
172 CHAR16 *UnicodeStr;\r
173 CHAR_W *Format;\r
174 UINTN Index;\r
175 UINTN Flags;\r
176 UINTN Width;\r
177 UINTN Count;\r
178 UINTN NumberOfCharacters;\r
179 UINTN BufferLeft;\r
180 UINT64 Value;\r
181 EFI_GUID *TmpGUID;\r
182\r
183 //\r
184 // Process the format string. Stop if Buffer is over run.\r
185 //\r
186\r
187 Buffer = StartOfBuffer;\r
188 Format = (CHAR_W *)FormatString; \r
189 NumberOfCharacters = BufferSize/sizeof(CHAR_W);\r
190 BufferLeft = BufferSize;\r
191 for (Index = 0; (*Format != '\0') && (Index < NumberOfCharacters - 1); Format++) {\r
192 if (*Format != '%') {\r
193 if ((*Format == '\n') && (Index < NumberOfCharacters - 2)) { \r
194 //\r
195 // If carage return add line feed\r
196 //\r
197 Buffer[Index++] = '\r';\r
198 BufferLeft -= sizeof(CHAR_W);\r
199 }\r
200 Buffer[Index++] = *Format;\r
201 BufferLeft -= sizeof(CHAR_W);\r
202 } else {\r
203 \r
204 //\r
205 // Now it's time to parse what follows after %\r
206 //\r
207 Format = GetFlagsAndWidth (Format, &Flags, &Width, &Marker);\r
208 switch (*Format) {\r
209 case 'X':\r
210 Flags |= PREFIX_ZERO;\r
211 Width = sizeof (UINT64) * 2;\r
212 //\r
213 // break skiped on purpose\r
214 //\r
215 case 'x':\r
216 if ((Flags & LONG_TYPE) == LONG_TYPE) {\r
217 Value = VA_ARG (Marker, UINT64);\r
218 } else {\r
219 Value = VA_ARG (Marker, UINTN);\r
220 }\r
221\r
222 EfiValueToHexStr (TempBuffer, Value, Flags, Width);\r
223 UnicodeStr = TempBuffer;\r
224\r
225 for ( ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {\r
226 Buffer[Index++] = *UnicodeStr;\r
227 }\r
228 break;\r
229\r
230 case 'd':\r
231 if ((Flags & LONG_TYPE) == LONG_TYPE) {\r
232 Value = VA_ARG (Marker, UINT64);\r
233 } else {\r
234 Value = (UINTN)VA_ARG (Marker, UINTN);\r
235 }\r
236\r
237 EfiValueToString (TempBuffer, Value, Flags, Width);\r
238 UnicodeStr = TempBuffer; \r
239\r
240 for ( ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++) {\r
241 Buffer[Index++] = *UnicodeStr;\r
242 }\r
243 break;\r
244\r
245 case 's':\r
246 case 'S':\r
247 UnicodeStr = (CHAR16 *)VA_ARG (Marker, CHAR_W *);\r
248 if (UnicodeStr == NULL) {\r
249 UnicodeStr = L"<null string>";\r
250 }\r
251 for (Count = 0 ;(*UnicodeStr != '\0') && (Index < NumberOfCharacters - 1); UnicodeStr++, Count++) {\r
252 Buffer[Index++] = *UnicodeStr;\r
253 }\r
254 //\r
255 // Add padding if needed\r
256 //\r
257 for (; (Count < Width) && (Index < NumberOfCharacters - 1); Count++) {\r
258 Buffer[Index++] = ' ';\r
259 }\r
260\r
261 break;\r
262\r
263 case 'a':\r
264 AsciiStr = (CHAR8 *)VA_ARG (Marker, CHAR8 *);\r
265 if (AsciiStr == NULL) {\r
57d40fe2 266 AsciiStr = (CHAR8 *) "<null string>";\r
3eb9473e 267 }\r
268 for (Count = 0 ;(*AsciiStr != '\0') && (Index < NumberOfCharacters - 1); AsciiStr++, Count++) {\r
269 Buffer[Index++] = (CHAR_W)*AsciiStr;\r
270 }\r
271 //\r
272 // Add padding if needed\r
273 //\r
274 for (;(Count < Width) && (Index < NumberOfCharacters - 1); Count++) {\r
275 Buffer[Index++] = ' ';\r
276 }\r
277 break;\r
278\r
279 case 'c':\r
280 Buffer[Index++] = (CHAR_W)VA_ARG (Marker, UINTN);\r
281 break;\r
282\r
283 case 'g':\r
284 TmpGUID = VA_ARG (Marker, EFI_GUID *); \r
285 if (TmpGUID != NULL) {\r
286 Index += GuidToString (\r
287 TmpGUID, \r
288 &Buffer[Index], \r
289 BufferLeft\r
290 );\r
291 }\r
292 break;\r
293\r
294 case 't':\r
295 Index += TimeToString (\r
296 VA_ARG (Marker, EFI_TIME *), \r
297 &Buffer[Index], \r
298 BufferLeft\r
299 );\r
300 break;\r
301\r
302 case 'r':\r
303 Index += EfiStatusToString (\r
304 VA_ARG (Marker, EFI_STATUS), \r
305 &Buffer[Index], \r
306 BufferLeft\r
307 );\r
308 break;\r
309\r
310 case '%':\r
311 Buffer[Index++] = *Format;\r
312 break;\r
313 \r
314 default:\r
315 //\r
316 // if the type is unknown print it to the screen\r
317 //\r
318 Buffer[Index++] = *Format;\r
319 }\r
320 BufferLeft = BufferSize - Index * sizeof(CHAR_W) ;\r
321 } \r
322 }\r
323 Buffer[Index++] = '\0'; \r
324 \r
325 return &Buffer[Index] - StartOfBuffer;\r
326}\r
327\r
328\r
329\r
330STATIC\r
331CHAR_W *\r
332GetFlagsAndWidth (\r
333 IN CHAR_W *Format, \r
334 OUT UINTN *Flags, \r
335 OUT UINTN *Width,\r
336 IN OUT VA_LIST *Marker\r
337 )\r
338/*++\r
339\r
340Routine Description:\r
341\r
342 VSPrint worker function that parses flag and width information from the \r
343 Format string and returns the next index into the Format string that needs\r
344 to be parsed. See file headed for details of Flag and Width.\r
345\r
346Arguments:\r
347\r
348 Format - Current location in the VSPrint format string.\r
349\r
350 Flags - Returns flags\r
351\r
352 Width - Returns width of element\r
353\r
354 Marker - Vararg list that may be paritally consumed and returned.\r
355\r
356Returns: \r
357\r
358 Pointer indexed into the Format string for all the information parsed\r
359 by this routine.\r
360\r
361--*/\r
362{\r
363 UINTN Count;\r
364 BOOLEAN Done;\r
365\r
366 *Flags = 0;\r
367 *Width = 0;\r
368 for (Done = FALSE; !Done; ) {\r
369 Format++;\r
370\r
371 switch (*Format) {\r
372\r
373 case '-': *Flags |= LEFT_JUSTIFY; break;\r
374 case '+': *Flags |= PREFIX_SIGN; break;\r
375 case ' ': *Flags |= PREFIX_BLANK; break;\r
376 case ',': *Flags |= COMMA_TYPE; break;\r
377 case 'L':\r
378 case 'l': *Flags |= LONG_TYPE; break;\r
379\r
380 case '*':\r
381 *Width = VA_ARG (*Marker, UINTN);\r
382 break;\r
383\r
384 case '0':\r
385 *Flags |= PREFIX_ZERO;\r
386 case '1':\r
387 case '2':\r
388 case '3':\r
389 case '4':\r
390 case '5':\r
391 case '6':\r
392 case '7':\r
393 case '8':\r
394 case '9':\r
395 Count = 0;\r
396 do {\r
397 Count = (Count * 10) + *Format - '0';\r
398 Format++;\r
399 } while ((*Format >= '0') && (*Format <= '9'));\r
400 Format--;\r
401 *Width = Count;\r
402 break;\r
403\r
404 default:\r
405 Done = TRUE;\r
406 }\r
407 }\r
408 return Format;\r
409}\r
410\r
411STATIC\r
412UINTN\r
413GuidToString (\r
414 IN EFI_GUID *Guid,\r
415 IN CHAR_W *Buffer,\r
416 IN UINTN BufferSize\r
417 )\r
418/*++\r
419\r
420Routine Description:\r
421\r
422 VSPrint worker function that prints an EFI_GUID.\r
423\r
424Arguments:\r
425\r
426 Guid - Pointer to GUID to print.\r
427\r
428 Buffer - Buffe to print Guid into.\r
429 \r
430 BufferSize - Size of Buffer.\r
431\r
432Returns: \r
433\r
434 Number of characters printed. \r
435\r
436--*/\r
437{\r
438 UINTN Size;\r
439\r
440 Size = SPrint (\r
441 Buffer,\r
442 BufferSize, \r
443 STRING_W ("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),\r
444 (UINTN)Guid->Data1, \r
445 (UINTN)Guid->Data2,\r
446 (UINTN)Guid->Data3,\r
447 (UINTN)Guid->Data4[0],\r
448 (UINTN)Guid->Data4[1],\r
449 (UINTN)Guid->Data4[2],\r
450 (UINTN)Guid->Data4[3],\r
451 (UINTN)Guid->Data4[4],\r
452 (UINTN)Guid->Data4[5],\r
453 (UINTN)Guid->Data4[6],\r
454 (UINTN)Guid->Data4[7]\r
455 );\r
456\r
457 //\r
458 // SPrint will null terminate the string. The -1 skips the null\r
459 //\r
460 return Size - 1;\r
461}\r
462\r
463\r
464STATIC\r
465UINTN\r
466TimeToString (\r
467 IN EFI_TIME *Time,\r
468 OUT CHAR_W *Buffer,\r
469 IN UINTN BufferSize\r
470 )\r
471/*++\r
472\r
473Routine Description:\r
474\r
475 VSPrint worker function that prints EFI_TIME.\r
476\r
477Arguments:\r
478\r
479 Time - Pointer to EFI_TIME sturcture to print.\r
480\r
481 Buffer - Buffer to print Time into.\r
482 \r
483 BufferSize - Size of Buffer.\r
484\r
485Returns: \r
486\r
487 Number of characters printed. \r
488\r
489--*/\r
490{ \r
491 UINTN Size;\r
492\r
493 Size = SPrint (\r
494 Buffer,\r
495 BufferSize, \r
496 STRING_W ("%02d/%02d/%04d %02d:%02d"),\r
497 (UINTN)Time->Month,\r
498 (UINTN)Time->Day,\r
499 (UINTN)Time->Year,\r
500 (UINTN)Time->Hour,\r
501 (UINTN)Time->Minute\r
502 );\r
503\r
504 //\r
505 // SPrint will null terminate the string. The -1 skips the null\r
506 //\r
507 return Size - 1;\r
508} \r
509\r
510STATIC\r
511UINTN\r
512EfiStatusToString (\r
513 IN EFI_STATUS Status,\r
514 OUT CHAR_W *Buffer,\r
515 IN UINTN BufferSize\r
516 )\r
517/*++\r
518\r
519Routine Description:\r
520\r
521 VSPrint worker function that prints EFI_STATUS as a string. If string is\r
522 not known a hex value will be printed.\r
523\r
524Arguments:\r
525\r
526 Status - EFI_STATUS sturcture to print.\r
527\r
528 Buffer - Buffer to print EFI_STATUS message string into.\r
529 \r
530 BufferSize - Size of Buffer.\r
531\r
532Returns: \r
533\r
534 Number of characters printed. \r
535\r
536--*/\r
537{\r
538 UINTN Size;\r
539 CHAR8 *Desc;\r
540 \r
541 Desc = NULL;\r
542\r
543 //\r
544 // Can't use global Status String Array as UINTN is not constant for EBC\r
545 //\r
57d40fe2 546 if (Status == EFI_SUCCESS) { Desc = (CHAR8 *) "Success"; } else \r
547 if (Status == EFI_LOAD_ERROR) { Desc = (CHAR8 *) "Load Error"; } else\r
548 if (Status == EFI_INVALID_PARAMETER) { Desc = (CHAR8 *) "Invalid Parameter"; } else\r
549 if (Status == EFI_UNSUPPORTED) { Desc = (CHAR8 *) "Unsupported"; } else\r
550 if (Status == EFI_BAD_BUFFER_SIZE) { Desc = (CHAR8 *) "Bad Buffer Size"; } else\r
551 if (Status == EFI_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Buffer Too Small"; } else\r
552 if (Status == EFI_NOT_READY) { Desc = (CHAR8 *) "Not Ready"; } else\r
553 if (Status == EFI_DEVICE_ERROR) { Desc = (CHAR8 *) "Device Error"; } else\r
554 if (Status == EFI_WRITE_PROTECTED) { Desc = (CHAR8 *) "Write Protected"; } else\r
555 if (Status == EFI_OUT_OF_RESOURCES) { Desc = (CHAR8 *) "Out of Resources"; } else\r
556 if (Status == EFI_VOLUME_CORRUPTED) { Desc = (CHAR8 *) "Volume Corrupt"; } else\r
557 if (Status == EFI_VOLUME_FULL) { Desc = (CHAR8 *) "Volume Full"; } else\r
558 if (Status == EFI_NO_MEDIA) { Desc = (CHAR8 *) "No Media"; } else\r
559 if (Status == EFI_MEDIA_CHANGED) { Desc = (CHAR8 *) "Media changed"; } else\r
560 if (Status == EFI_NOT_FOUND) { Desc = (CHAR8 *) "Not Found"; } else\r
561 if (Status == EFI_ACCESS_DENIED) { Desc = (CHAR8 *) "Access Denied"; } else\r
562 if (Status == EFI_NO_RESPONSE) { Desc = (CHAR8 *) "No Response"; } else\r
563 if (Status == EFI_NO_MAPPING) { Desc = (CHAR8 *) "No mapping"; } else\r
564 if (Status == EFI_TIMEOUT) { Desc = (CHAR8 *) "Time out"; } else\r
565 if (Status == EFI_NOT_STARTED) { Desc = (CHAR8 *) "Not started"; } else\r
566 if (Status == EFI_ALREADY_STARTED) { Desc = (CHAR8 *) "Already started"; } else\r
567 if (Status == EFI_ABORTED) { Desc = (CHAR8 *) "Aborted"; } else\r
568 if (Status == EFI_ICMP_ERROR) { Desc = (CHAR8 *) "ICMP Error"; } else\r
569 if (Status == EFI_TFTP_ERROR) { Desc = (CHAR8 *) "TFTP Error"; } else\r
570 if (Status == EFI_PROTOCOL_ERROR) { Desc = (CHAR8 *) "Protocol Error"; } else\r
571 if (Status == EFI_WARN_UNKNOWN_GLYPH) { Desc = (CHAR8 *) "Warning Unknown Glyph"; } else\r
572 if (Status == EFI_WARN_DELETE_FAILURE) { Desc = (CHAR8 *) "Warning Delete Failure"; } else\r
573 if (Status == EFI_WARN_WRITE_FAILURE) { Desc = (CHAR8 *) "Warning Write Failure"; } else\r
574 if (Status == EFI_WARN_BUFFER_TOO_SMALL) { Desc = (CHAR8 *) "Warning Buffer Too Small"; } \r
3eb9473e 575 \r
576 //\r
577 // If we found a match, copy the message to the user's buffer. Otherwise\r
578 // sprint the hex status code to their buffer.\r
579 //\r
580 if (Desc != NULL) {\r
581 Size = SPrint (Buffer, BufferSize, STRING_W ("%a"), Desc);\r
582 } else {\r
583 Size = SPrint (Buffer, BufferSize, STRING_W ("%X"), Status);\r
584 }\r
585 return Size - 1;\r
586}\r