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