]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbSupportUI.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / EdbSupportUI.c
CommitLineData
e8a5ac7c 1/** @file\r
748edcd5 2\r
e8a5ac7c 3Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>\r
9d510e61 4SPDX-License-Identifier: BSD-2-Clause-Patent\r
748edcd5 5\r
748edcd5 6\r
e8a5ac7c 7**/\r
748edcd5
PB
8\r
9#include "Edb.h"\r
10\r
d138a2e9
DB
11/**\r
12 Set the current coordinates of the cursor position.\r
13\r
14 @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.\r
15 @param Column The position to set the cursor to.\r
16 @param Row The position to set the cursor to.\r
17 @param LineLength Length of a line.\r
18 @param TotalRow Total row of a screen.\r
19 @param Str Point to the string.\r
20 @param StrPos The position of the string.\r
21 @param Len The length of the string.\r
22\r
23**/\r
748edcd5
PB
24VOID\r
25EFIAPI\r
26SetCursorPosition (\r
27 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut,\r
28 IN UINTN Column,\r
29 IN INTN Row,\r
30 IN UINTN LineLength,\r
31 IN UINTN TotalRow,\r
32 IN CHAR16 *Str,\r
33 IN UINTN StrPos,\r
34 IN UINTN Len\r
35 );\r
36\r
e8a5ac7c
DB
37/**\r
38\r
39 Function waits for a given event to fire, or for an optional timeout to expire.\r
40\r
41 @param Event - The event to wait for\r
42 @param Timeout - An optional timeout value in 100 ns units.\r
43\r
44 @retval EFI_SUCCESS - Event fired before Timeout expired.\r
45 @retval EFI_TIME_OUT - Timout expired before Event fired..\r
46\r
47**/\r
748edcd5
PB
48EFI_STATUS\r
49EFIAPI\r
50WaitForSingleEvent (\r
51 IN EFI_EVENT Event,\r
52 IN UINT64 Timeout OPTIONAL\r
53 )\r
748edcd5
PB
54{\r
55 EFI_STATUS Status;\r
56 UINTN Index;\r
57 EFI_EVENT TimerEvent;\r
58 EFI_EVENT WaitList[2];\r
59\r
532daaed 60 if (Timeout != 0) {\r
748edcd5
PB
61 //\r
62 // Create a timer event\r
63 //\r
64 Status = gBS->CreateEvent (EVT_TIMER, 0, NULL, NULL, &TimerEvent);\r
65 if (!EFI_ERROR (Status)) {\r
66 //\r
67 // Set the timer event\r
68 //\r
69 gBS->SetTimer (\r
70 TimerEvent,\r
71 TimerRelative,\r
72 Timeout\r
73 );\r
74\r
75 //\r
76 // Wait for the original event or the timer\r
77 //\r
78 WaitList[0] = Event;\r
79 WaitList[1] = TimerEvent;\r
80 Status = gBS->WaitForEvent (2, WaitList, &Index);\r
81 gBS->CloseEvent (TimerEvent);\r
82\r
83 //\r
84 // If the timer expired, change the return to timed out\r
85 //\r
86 if (!EFI_ERROR (Status) && Index == 1) {\r
87 Status = EFI_TIMEOUT;\r
88 }\r
89 }\r
90 } else {\r
91 //\r
92 // No timeout... just wait on the event\r
93 //\r
94 Status = gBS->WaitForEvent (1, &Event, &Index);\r
95 ASSERT (!EFI_ERROR (Status));\r
96 ASSERT (Index == 0);\r
97 }\r
98\r
99 return Status;\r
100}\r
101\r
e8a5ac7c
DB
102/**\r
103\r
104 Move the cursor position one character backward.\r
105\r
106 @param LineLength Length of a line. Get it by calling QueryMode\r
107 @param Column Current column of the cursor position\r
108 @param Row Current row of the cursor position\r
109\r
110**/\r
748edcd5
PB
111VOID\r
112EFIAPI\r
113ConMoveCursorBackward (\r
114 IN UINTN LineLength,\r
115 IN OUT UINTN *Column,\r
116 IN OUT UINTN *Row\r
117 )\r
748edcd5
PB
118{\r
119 ASSERT (Column != NULL);\r
120 ASSERT (Row != NULL);\r
121 //\r
122 // If current column is 0, move to the last column of the previous line,\r
123 // otherwise, just decrement column.\r
124 //\r
125 if (*Column == 0) {\r
126 (*Column) = LineLength - 1;\r
127 //\r
128 // if (*Row > 0) {\r
129 //\r
130 (*Row)--;\r
131 //\r
132 // }\r
133 //\r
134 } else {\r
135 (*Column)--;\r
136 }\r
137}\r
138\r
e8a5ac7c
DB
139/**\r
140\r
141 Move the cursor position one character backward.\r
142\r
143 @param LineLength Length of a line. Get it by calling QueryMode\r
144 @param TotalRow Total row of a screen, get by calling QueryMode\r
145 @param Column Current column of the cursor position\r
146 @param Row Current row of the cursor position\r
147\r
148**/\r
748edcd5
PB
149VOID\r
150EFIAPI\r
151ConMoveCursorForward (\r
152 IN UINTN LineLength,\r
153 IN UINTN TotalRow,\r
154 IN OUT UINTN *Column,\r
155 IN OUT UINTN *Row\r
156 )\r
748edcd5
PB
157{\r
158 ASSERT (Column != NULL);\r
159 ASSERT (Row != NULL);\r
160 //\r
161 // If current column is at line end, move to the first column of the nest\r
162 // line, otherwise, just increment column.\r
163 //\r
164 (*Column)++;\r
165 if (*Column >= LineLength) {\r
166 (*Column) = 0;\r
167 if ((*Row) < TotalRow - 1) {\r
168 (*Row)++;\r
169 }\r
170 }\r
171}\r
172\r
173CHAR16 mBackupSpace[EFI_DEBUG_INPUS_BUFFER_SIZE];\r
174CHAR16 mInputBufferHistory[EFI_DEBUG_INPUS_BUFFER_SIZE];\r
175\r
d138a2e9
DB
176/**\r
177\r
178 Get user input.\r
179\r
180 @param Prompt The prompt string.\r
181 @param InStr Point to the input string.\r
182 @param StrLength The max length of string user can input.\r
183\r
184**/\r
748edcd5
PB
185VOID\r
186EFIAPI\r
187Input (\r
188 IN CHAR16 *Prompt OPTIONAL,\r
189 OUT CHAR16 *InStr,\r
190 IN UINTN StrLength\r
191 )\r
192{\r
193 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;\r
194 EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;\r
195 BOOLEAN Done;\r
196 UINTN Column;\r
197 UINTN Row;\r
198 UINTN StartColumn;\r
199 UINTN Update;\r
200 UINTN Delete;\r
201 UINTN Len;\r
202 UINTN StrPos;\r
203 UINTN Index;\r
204 UINTN LineLength;\r
205 UINTN TotalRow;\r
206 UINTN SkipLength;\r
207 UINTN OutputLength;\r
208 UINTN TailRow;\r
209 UINTN TailColumn;\r
210 EFI_INPUT_KEY Key;\r
211 BOOLEAN InsertMode;\r
212 BOOLEAN NeedAdjust;\r
213 UINTN SubIndex;\r
214 CHAR16 *CommandStr;\r
215\r
216 ConOut = gST->ConOut;\r
217 ConIn = gST->ConIn;\r
218\r
219 ASSERT (ConOut != NULL);\r
220 ASSERT (ConIn != NULL);\r
221 ASSERT (InStr != NULL);\r
222\r
532daaed 223 if (Prompt != NULL) {\r
748edcd5
PB
224 ConOut->OutputString (ConOut, Prompt);\r
225 }\r
226 //\r
227 // Read a line from the console\r
228 //\r
229 Len = 0;\r
230 StrPos = 0;\r
231 OutputLength = 0;\r
232 Update = 0;\r
233 Delete = 0;\r
234 InsertMode = TRUE;\r
235 NeedAdjust = FALSE;\r
236\r
237 //\r
238 // If buffer is not large enough to hold a CHAR16, do nothing.\r
239 //\r
240 if (StrLength < 1) {\r
241 return ;\r
242 }\r
243 //\r
244 // Get the screen setting and the current cursor location\r
245 //\r
246 StartColumn = ConOut->Mode->CursorColumn;\r
247 Column = StartColumn;\r
248 Row = ConOut->Mode->CursorRow;\r
249 ConOut->QueryMode (ConOut, ConOut->Mode->Mode, &LineLength, &TotalRow);\r
250 if (LineLength == 0) {\r
251 return ;\r
252 }\r
253\r
254 SetMem (InStr, StrLength * sizeof (CHAR16), 0);\r
255 Done = FALSE;\r
256 do {\r
257 //\r
258 // Read a key\r
259 //\r
260 WaitForSingleEvent (ConIn->WaitForKey, 0);\r
261 ConIn->ReadKeyStroke (ConIn, &Key);\r
262\r
263 switch (Key.UnicodeChar) {\r
264 case CHAR_CARRIAGE_RETURN:\r
265 //\r
266 // All done, print a newline at the end of the string\r
267 //\r
268 TailRow = Row + (Len - StrPos + Column) / LineLength;\r
269 TailColumn = (Len - StrPos + Column) % LineLength;\r
270 Done = TRUE;\r
271 break;\r
272\r
273 case CHAR_BACKSPACE:\r
532daaed 274 if (StrPos != 0) {\r
748edcd5
PB
275 //\r
276 // If not move back beyond string beginning, move all characters behind\r
277 // the current position one character forward\r
278 //\r
279 StrPos -= 1;\r
280 Update = StrPos;\r
281 Delete = 1;\r
282 CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));\r
283\r
284 //\r
285 // Adjust the current column and row\r
286 //\r
287 ConMoveCursorBackward (LineLength, &Column, &Row);\r
288\r
289 NeedAdjust = TRUE;\r
290 }\r
291 break;\r
292\r
293 default:\r
294 if (Key.UnicodeChar >= ' ') {\r
295 //\r
296 // If we are at the buffer's end, drop the key\r
297 //\r
298 if (Len == StrLength - 1 && (InsertMode || StrPos == Len)) {\r
299 break;\r
300 }\r
301 //\r
302 // If in insert mode, move all characters behind the current position\r
303 // one character backward to make space for this character. Then store\r
304 // the character.\r
305 //\r
306 if (InsertMode) {\r
307 for (Index = Len; Index > StrPos; Index -= 1) {\r
308 InStr[Index] = InStr[Index - 1];\r
309 }\r
310 }\r
311\r
312 InStr[StrPos] = Key.UnicodeChar;\r
313 Update = StrPos;\r
314\r
315 StrPos += 1;\r
316 OutputLength = 1;\r
317 }\r
318 break;\r
319\r
320 case 0:\r
321 switch (Key.ScanCode) {\r
322 case SCAN_DELETE:\r
323 //\r
324 // Move characters behind current position one character forward\r
325 //\r
532daaed 326 if (Len != 0) {\r
748edcd5
PB
327 Update = StrPos;\r
328 Delete = 1;\r
329 CopyMem (InStr + StrPos, InStr + StrPos + 1, sizeof (CHAR16) * (Len - StrPos));\r
330\r
331 NeedAdjust = TRUE;\r
332 }\r
333 break;\r
334\r
335 case SCAN_LEFT:\r
336 //\r
337 // Adjust current cursor position\r
338 //\r
532daaed 339 if (StrPos != 0) {\r
748edcd5
PB
340 StrPos -= 1;\r
341 ConMoveCursorBackward (LineLength, &Column, &Row);\r
342 }\r
343 break;\r
344\r
345 case SCAN_RIGHT:\r
346 //\r
347 // Adjust current cursor position\r
348 //\r
349 if (StrPos < Len) {\r
350 StrPos += 1;\r
351 ConMoveCursorForward (LineLength, TotalRow, &Column, &Row);\r
352 }\r
353 break;\r
354\r
355 case SCAN_HOME:\r
356 //\r
357 // Move current cursor position to the beginning of the command line\r
358 //\r
359 Row -= (StrPos + StartColumn) / LineLength;\r
360 Column = StartColumn;\r
361 StrPos = 0;\r
362 break;\r
363\r
364 case SCAN_END:\r
365 //\r
366 // Move current cursor position to the end of the command line\r
367 //\r
368 TailRow = Row + (Len - StrPos + Column) / LineLength;\r
369 TailColumn = (Len - StrPos + Column) % LineLength;\r
370 Row = TailRow;\r
371 Column = TailColumn;\r
372 StrPos = Len;\r
373 break;\r
374\r
375 case SCAN_ESC:\r
376 //\r
377 // Prepare to clear the current command line\r
378 //\r
379 InStr[0] = 0;\r
380 Update = 0;\r
381 Delete = Len;\r
382 Row -= (StrPos + StartColumn) / LineLength;\r
383 Column = StartColumn;\r
384 OutputLength = 0;\r
385\r
386 NeedAdjust = TRUE;\r
387 break;\r
388\r
389 case SCAN_INSERT:\r
390 //\r
391 // Toggle the SEnvInsertMode flag\r
392 //\r
393 InsertMode = (BOOLEAN)!InsertMode;\r
394 break;\r
395\r
396 case SCAN_UP:\r
397 case SCAN_DOWN:\r
398 //\r
399 // show history\r
400 //\r
401 CopyMem (InStr, mInputBufferHistory, StrLength * sizeof(CHAR16));\r
402 StrPos = StrLen (mInputBufferHistory);\r
403 Update = 0;\r
404 Delete = 0;\r
405 OutputLength = 0;\r
406\r
407 TailRow = Row + (StrPos + StartColumn) / LineLength;\r
408 TailColumn = (StrPos + StartColumn) % LineLength;\r
409 Row = TailRow;\r
410 Column = TailColumn;\r
411 NeedAdjust = FALSE;\r
412\r
413 ConOut->SetCursorPosition (ConOut, StartColumn, Row);\r
414 for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {\r
415 mBackupSpace[SubIndex] = L' ';\r
416 }\r
417 EDBPrint (mBackupSpace);\r
418 SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (StartColumn - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0);\r
419\r
420 ConOut->SetCursorPosition (ConOut, StartColumn, Row);\r
421 Len = StrPos;\r
422\r
423 break;\r
424\r
425 case SCAN_F1:\r
426 case SCAN_F2:\r
427 case SCAN_F3:\r
428 case SCAN_F4:\r
429 case SCAN_F5:\r
430 case SCAN_F6:\r
431 case SCAN_F7:\r
432 case SCAN_F8:\r
433 case SCAN_F9:\r
434 case SCAN_F10:\r
435 case SCAN_F11:\r
436 case SCAN_F12:\r
437 CommandStr = GetCommandNameByKey (Key);\r
438 if (CommandStr != NULL) {\r
439 StrnCpyS (InStr, StrLength, CommandStr, StrLength - 1);\r
440 return ;\r
441 }\r
442 break;\r
443 }\r
444 }\r
445\r
446 if (Done) {\r
447 break;\r
448 }\r
449 //\r
450 // If we need to update the output do so now\r
451 //\r
452 if (Update != -1) {\r
453 if (NeedAdjust) {\r
454 ConOut->SetCursorPosition (ConOut, Column, Row);\r
455 for (SubIndex = 0; SubIndex < EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN); SubIndex++) {\r
456 mBackupSpace[SubIndex] = L' ';\r
457 }\r
458 EDBPrint (mBackupSpace);\r
459 SetMem (mBackupSpace, (EFI_DEBUG_INPUS_BUFFER_SIZE - (Column - EFI_DEBUG_PROMPT_COLUMN)) * sizeof(CHAR16), 0);\r
460 ConOut->SetCursorPosition (ConOut, Column, Row);\r
461 NeedAdjust = FALSE;\r
462 }\r
463 EDBPrint (InStr + Update);\r
464 Len = StrLen (InStr);\r
465\r
532daaed 466 if (Delete != 0) {\r
748edcd5
PB
467 SetMem (InStr + Len, Delete * sizeof (CHAR16), 0x00);\r
468 }\r
469\r
470 if (StrPos > Len) {\r
471 StrPos = Len;\r
472 }\r
473\r
474 Update = (UINTN) -1;\r
475\r
476 //\r
477 // After using print to reflect newly updates, if we're not using\r
478 // BACKSPACE and DELETE, we need to move the cursor position forward,\r
479 // so adjust row and column here.\r
480 //\r
481 if (Key.UnicodeChar != CHAR_BACKSPACE && !(Key.UnicodeChar == 0 && Key.ScanCode == SCAN_DELETE)) {\r
482 //\r
483 // Calulate row and column of the tail of current string\r
484 //\r
485 TailRow = Row + (Len - StrPos + Column + OutputLength) / LineLength;\r
486 TailColumn = (Len - StrPos + Column + OutputLength) % LineLength;\r
487\r
488 //\r
489 // If the tail of string reaches screen end, screen rolls up, so if\r
490 // Row does not equal TailRow, Row should be decremented\r
491 //\r
492 // (if we are recalling commands using UPPER and DOWN key, and if the\r
493 // old command is too long to fit the screen, TailColumn must be 79.\r
494 //\r
495 if (TailColumn == 0 && TailRow >= TotalRow && (UINTN) Row != TailRow) {\r
496 Row--;\r
497 }\r
498 //\r
499 // Calculate the cursor position after current operation. If cursor\r
500 // reaches line end, update both row and column, otherwise, only\r
501 // column will be changed.\r
502 //\r
503 if (Column + OutputLength >= LineLength) {\r
504 SkipLength = OutputLength - (LineLength - Column);\r
505\r
506 Row += SkipLength / LineLength + 1;\r
507 if ((UINTN) Row > TotalRow - 1) {\r
508 Row = TotalRow - 1;\r
509 }\r
510\r
511 Column = SkipLength % LineLength;\r
512 } else {\r
513 Column += OutputLength;\r
514 }\r
515 }\r
516\r
517 Delete = 0;\r
518 }\r
519 //\r
520 // Set the cursor position for this key\r
521 //\r
522 SetCursorPosition (ConOut, Column, Row, LineLength, TotalRow, InStr, StrPos, Len);\r
523 } while (!Done);\r
524\r
525 CopyMem (mInputBufferHistory, InStr, StrLength * sizeof(CHAR16));\r
526\r
527 //\r
528 // Return the data to the caller\r
529 //\r
530 return ;\r
531}\r
532\r
d138a2e9
DB
533/**\r
534 Set the current coordinates of the cursor position.\r
535\r
536 @param ConOut Point to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.\r
537 @param Column The position to set the cursor to.\r
538 @param Row The position to set the cursor to.\r
539 @param LineLength Length of a line.\r
540 @param TotalRow Total row of a screen.\r
541 @param Str Point to the string.\r
542 @param StrPos The position of the string.\r
543 @param Len The length of the string.\r
544\r
545**/\r
748edcd5
PB
546VOID\r
547EFIAPI\r
548SetCursorPosition (\r
549 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut,\r
550 IN UINTN Column,\r
551 IN INTN Row,\r
552 IN UINTN LineLength,\r
553 IN UINTN TotalRow,\r
554 IN CHAR16 *Str,\r
555 IN UINTN StrPos,\r
556 IN UINTN Len\r
557 )\r
558{\r
559 CHAR16 Backup;\r
560\r
561 ASSERT (ConOut != NULL);\r
562 ASSERT (Str != NULL);\r
563\r
564 Backup = 0;\r
565 if (Row >= 0) {\r
566 ConOut->SetCursorPosition (ConOut, Column, Row);\r
567 return ;\r
568 }\r
569\r
570 if (Len - StrPos > Column * Row) {\r
571 Backup = *(Str + StrPos + Column * Row);\r
572 *(Str + StrPos + Column * Row) = 0;\r
573 }\r
574\r
575 EDBPrint (L"%s", Str + StrPos);\r
576 if (Len - StrPos > Column * Row) {\r
577 *(Str + StrPos + Column * Row) = Backup;\r
578 }\r
579\r
580 ConOut->SetCursorPosition (ConOut, 0, 0);\r
581}\r
582\r
d138a2e9
DB
583/**\r
584\r
585 SetPageBreak.\r
586\r
587**/\r
748edcd5
PB
588BOOLEAN\r
589EFIAPI\r
590SetPageBreak (\r
591 VOID\r
592 )\r
593{\r
594 EFI_INPUT_KEY Key;\r
595 CHAR16 Str[3];\r
596 BOOLEAN OmitPrint;\r
597\r
598 //\r
599 // Check\r
600 //\r
601 if (!mDebuggerPrivate.EnablePageBreak) {\r
602 return FALSE;\r
603 }\r
604\r
605 gST->ConOut->OutputString (gST->ConOut, L"Press ENTER to continue, 'q' to exit:");\r
606\r
607 OmitPrint = FALSE;\r
608 //\r
609 // Wait for user input\r
610 //\r
611 Str[0] = ' ';\r
612 Str[1] = 0;\r
613 Str[2] = 0;\r
614 for (;;) {\r
615 WaitForSingleEvent (gST->ConIn->WaitForKey, 0);\r
616 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
617\r
618 //\r
619 // handle control keys\r
620 //\r
621 if (Key.UnicodeChar == CHAR_NULL) {\r
622 if (Key.ScanCode == SCAN_ESC) {\r
623 gST->ConOut->OutputString (gST->ConOut, L"\r\n");\r
624 OmitPrint = TRUE;\r
625 break;\r
626 }\r
627\r
628 continue;\r
629 }\r
630\r
631 if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
632 gST->ConOut->OutputString (gST->ConOut, L"\r\n");\r
633 break;\r
634 }\r
635 //\r
636 // Echo input\r
637 //\r
638 Str[1] = Key.UnicodeChar;\r
639 if (Str[1] == CHAR_BACKSPACE) {\r
640 continue;\r
641 }\r
642\r
643 gST->ConOut->OutputString (gST->ConOut, Str);\r
644\r
645 if ((Str[1] == L'q') || (Str[1] == L'Q')) {\r
646 OmitPrint = TRUE;\r
647 } else {\r
648 OmitPrint = FALSE;\r
649 }\r
650\r
651 Str[0] = CHAR_BACKSPACE;\r
652 }\r
653\r
654 return OmitPrint;\r
655}\r
656\r
d138a2e9
DB
657/**\r
658 Print a Unicode string to the output device.\r
659\r
660 @param Format A Null-terminated Unicode format string.\r
661 @param ... The variable argument list that contains pointers to Null-\r
662 terminated Unicode strings to be printed\r
663\r
664**/\r
748edcd5
PB
665UINTN\r
666EFIAPI\r
667EDBPrint (\r
668 IN CONST CHAR16 *Format,\r
669 ...\r
670 )\r
671{\r
672 UINTN Return;\r
673 VA_LIST Marker;\r
674 CHAR16 Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];\r
675\r
676 VA_START (Marker, Format);\r
677 Return = UnicodeVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
678 VA_END (Marker);\r
679\r
680 if (gST->ConOut != NULL) {\r
681 //\r
682 // To be extra safe make sure ConOut has been initialized\r
683 //\r
684 gST->ConOut->OutputString (gST->ConOut, Buffer);\r
685 }\r
686\r
687 return Return;\r
688}\r
689\r
d138a2e9
DB
690/**\r
691 Print a Unicode string to the output buffer.\r
692\r
693 @param Buffer A pointer to the output buffer for the produced Null-terminated\r
694 Unicode string.\r
695 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
696 @param Format A Null-terminated Unicode format string.\r
697 @param ... The variable argument list that contains pointers to Null-\r
698 terminated Unicode strings to be printed\r
699\r
700**/\r
748edcd5
PB
701UINTN\r
702EFIAPI\r
703EDBSPrint (\r
704 OUT CHAR16 *Buffer,\r
705 IN INTN BufferSize,\r
706 IN CONST CHAR16 *Format,\r
707 ...\r
708 )\r
709{\r
710 UINTN Return;\r
711 VA_LIST Marker;\r
712\r
713 ASSERT (BufferSize > 0);\r
714\r
715 VA_START (Marker, Format);\r
716 Return = UnicodeVSPrint (Buffer, (UINTN)BufferSize, Format, Marker);\r
717 VA_END (Marker);\r
718\r
719 return Return;\r
720}\r
721\r
d138a2e9
DB
722/**\r
723 Print a Unicode string to the output buffer with specified offset..\r
724\r
725 @param Buffer A pointer to the output buffer for the produced Null-terminated\r
726 Unicode string.\r
727 @param BufferSize The size, in bytes, of the output buffer specified by StartOfBuffer.\r
728 @param Offset The offset of the buffer.\r
729 @param Format A Null-terminated Unicode format string.\r
730 @param ... The variable argument list that contains pointers to Null-\r
731 terminated Unicode strings to be printed\r
732\r
733**/\r
748edcd5
PB
734UINTN\r
735EFIAPI\r
736EDBSPrintWithOffset (\r
737 OUT CHAR16 *Buffer,\r
738 IN INTN BufferSize,\r
739 IN UINTN Offset,\r
740 IN CONST CHAR16 *Format,\r
741 ...\r
742 )\r
743{\r
744 UINTN Return;\r
745 VA_LIST Marker;\r
746\r
747 ASSERT (BufferSize - (Offset * sizeof(CHAR16)) > 0);\r
748\r
749 VA_START (Marker, Format);\r
750 Return = UnicodeVSPrint (Buffer + Offset, (UINTN)(BufferSize - (Offset * sizeof(CHAR16))), Format, Marker);\r
751 VA_END (Marker);\r
752\r
753 return Return;\r
754}\r