1530d68baSNigel Croxon /*++
2530d68baSNigel Croxon
3530d68baSNigel Croxon Copyright (c) 1998 Intel Corporation
4530d68baSNigel Croxon
5530d68baSNigel Croxon Module Name:
6530d68baSNigel Croxon
7530d68baSNigel Croxon print.c
8530d68baSNigel Croxon
9530d68baSNigel Croxon Abstract:
10530d68baSNigel Croxon
11530d68baSNigel Croxon
12530d68baSNigel Croxon
13530d68baSNigel Croxon
14530d68baSNigel Croxon Revision History
15530d68baSNigel Croxon
16530d68baSNigel Croxon --*/
17530d68baSNigel Croxon
18530d68baSNigel Croxon #include "lib.h"
19530d68baSNigel Croxon #include "efistdarg.h" // !!!
20530d68baSNigel Croxon
21530d68baSNigel Croxon //
22530d68baSNigel Croxon // Declare runtime functions
23530d68baSNigel Croxon //
24530d68baSNigel Croxon
25530d68baSNigel Croxon #ifdef RUNTIME_CODE
26530d68baSNigel Croxon #ifndef __GNUC__
27530d68baSNigel Croxon #pragma RUNTIME_CODE(DbgPrint)
28530d68baSNigel Croxon
29530d68baSNigel Croxon // For debugging..
30530d68baSNigel Croxon
31530d68baSNigel Croxon /*
32530d68baSNigel Croxon #pragma RUNTIME_CODE(_Print)
33530d68baSNigel Croxon #pragma RUNTIME_CODE(PFLUSH)
34530d68baSNigel Croxon #pragma RUNTIME_CODE(PSETATTR)
35530d68baSNigel Croxon #pragma RUNTIME_CODE(PPUTC)
36530d68baSNigel Croxon #pragma RUNTIME_CODE(PGETC)
37530d68baSNigel Croxon #pragma RUNTIME_CODE(PITEM)
38530d68baSNigel Croxon #pragma RUNTIME_CODE(ValueToHex)
39530d68baSNigel Croxon #pragma RUNTIME_CODE(ValueToString)
40530d68baSNigel Croxon #pragma RUNTIME_CODE(TimeToString)
41530d68baSNigel Croxon */
42530d68baSNigel Croxon
43530d68baSNigel Croxon #endif /* !defined(__GNUC__) */
44530d68baSNigel Croxon #endif
45530d68baSNigel Croxon
46530d68baSNigel Croxon //
47530d68baSNigel Croxon //
48530d68baSNigel Croxon //
49530d68baSNigel Croxon
50530d68baSNigel Croxon
51530d68baSNigel Croxon #define PRINT_STRING_LEN 200
52530d68baSNigel Croxon #define PRINT_ITEM_BUFFER_LEN 100
53530d68baSNigel Croxon
54530d68baSNigel Croxon typedef struct {
55530d68baSNigel Croxon BOOLEAN Ascii;
56530d68baSNigel Croxon UINTN Index;
57530d68baSNigel Croxon union {
58fa1b9779SNigel Croxon CONST CHAR16 *pw;
59fa1b9779SNigel Croxon CONST CHAR8 *pc;
60530d68baSNigel Croxon } un;
61530d68baSNigel Croxon } POINTER;
62530d68baSNigel Croxon
63530d68baSNigel Croxon #define pw un.pw
64530d68baSNigel Croxon #define pc un.pc
65530d68baSNigel Croxon
66530d68baSNigel Croxon typedef struct _pitem {
67530d68baSNigel Croxon
68530d68baSNigel Croxon POINTER Item;
69530d68baSNigel Croxon CHAR16 Scratch[PRINT_ITEM_BUFFER_LEN];
70530d68baSNigel Croxon UINTN Width;
71530d68baSNigel Croxon UINTN FieldWidth;
72530d68baSNigel Croxon UINTN *WidthParse;
73530d68baSNigel Croxon CHAR16 Pad;
74530d68baSNigel Croxon BOOLEAN PadBefore;
75530d68baSNigel Croxon BOOLEAN Comma;
76530d68baSNigel Croxon BOOLEAN Long;
77530d68baSNigel Croxon } PRINT_ITEM;
78530d68baSNigel Croxon
79530d68baSNigel Croxon
80530d68baSNigel Croxon typedef struct _pstate {
81530d68baSNigel Croxon // Input
82530d68baSNigel Croxon POINTER fmt;
83530d68baSNigel Croxon va_list args;
84530d68baSNigel Croxon
85530d68baSNigel Croxon // Output
86530d68baSNigel Croxon CHAR16 *Buffer;
87530d68baSNigel Croxon CHAR16 *End;
88530d68baSNigel Croxon CHAR16 *Pos;
89530d68baSNigel Croxon UINTN Len;
90530d68baSNigel Croxon
91530d68baSNigel Croxon UINTN Attr;
92530d68baSNigel Croxon UINTN RestoreAttr;
93530d68baSNigel Croxon
94530d68baSNigel Croxon UINTN AttrNorm;
95530d68baSNigel Croxon UINTN AttrHighlight;
96530d68baSNigel Croxon UINTN AttrError;
97530d68baSNigel Croxon
9809027207SNigel Croxon INTN (EFIAPI *Output)(VOID *context, CHAR16 *str);
9909027207SNigel Croxon INTN (EFIAPI *SetAttr)(VOID *context, UINTN attr);
100530d68baSNigel Croxon VOID *Context;
101530d68baSNigel Croxon
102530d68baSNigel Croxon // Current item being formatted
103530d68baSNigel Croxon struct _pitem *Item;
104530d68baSNigel Croxon } PRINT_STATE;
105530d68baSNigel Croxon
106530d68baSNigel Croxon //
107530d68baSNigel Croxon // Internal fucntions
108530d68baSNigel Croxon //
109530d68baSNigel Croxon
110530d68baSNigel Croxon STATIC
111530d68baSNigel Croxon UINTN
112530d68baSNigel Croxon _Print (
113530d68baSNigel Croxon IN PRINT_STATE *ps
114530d68baSNigel Croxon );
115530d68baSNigel Croxon
116530d68baSNigel Croxon STATIC
117530d68baSNigel Croxon UINTN
118530d68baSNigel Croxon _IPrint (
119530d68baSNigel Croxon IN UINTN Column,
120530d68baSNigel Croxon IN UINTN Row,
121530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
122fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
123fa1b9779SNigel Croxon IN CONST CHAR8 *fmta,
124530d68baSNigel Croxon IN va_list args
125530d68baSNigel Croxon );
126530d68baSNigel Croxon
127530d68baSNigel Croxon STATIC
128530d68baSNigel Croxon INTN EFIAPI
129530d68baSNigel Croxon _DbgOut (
130530d68baSNigel Croxon IN VOID *Context,
131530d68baSNigel Croxon IN CHAR16 *Buffer
132530d68baSNigel Croxon );
133530d68baSNigel Croxon
134530d68baSNigel Croxon STATIC
135530d68baSNigel Croxon VOID
136530d68baSNigel Croxon PFLUSH (
137530d68baSNigel Croxon IN OUT PRINT_STATE *ps
138530d68baSNigel Croxon );
139530d68baSNigel Croxon
140530d68baSNigel Croxon STATIC
141530d68baSNigel Croxon VOID
142530d68baSNigel Croxon PPUTC (
143530d68baSNigel Croxon IN OUT PRINT_STATE *ps,
144530d68baSNigel Croxon IN CHAR16 c
145530d68baSNigel Croxon );
146530d68baSNigel Croxon
147530d68baSNigel Croxon STATIC
148530d68baSNigel Croxon VOID
149530d68baSNigel Croxon PITEM (
150530d68baSNigel Croxon IN OUT PRINT_STATE *ps
151530d68baSNigel Croxon );
152530d68baSNigel Croxon
153530d68baSNigel Croxon STATIC
154530d68baSNigel Croxon CHAR16
155530d68baSNigel Croxon PGETC (
156530d68baSNigel Croxon IN POINTER *p
157530d68baSNigel Croxon );
158530d68baSNigel Croxon
159530d68baSNigel Croxon STATIC
160530d68baSNigel Croxon VOID
161530d68baSNigel Croxon PSETATTR (
162530d68baSNigel Croxon IN OUT PRINT_STATE *ps,
163530d68baSNigel Croxon IN UINTN Attr
164530d68baSNigel Croxon );
165530d68baSNigel Croxon
166530d68baSNigel Croxon //
167530d68baSNigel Croxon //
168530d68baSNigel Croxon //
169530d68baSNigel Croxon
170530d68baSNigel Croxon INTN EFIAPI
171530d68baSNigel Croxon _SPrint (
172530d68baSNigel Croxon IN VOID *Context,
173530d68baSNigel Croxon IN CHAR16 *Buffer
174530d68baSNigel Croxon );
175530d68baSNigel Croxon
176530d68baSNigel Croxon INTN EFIAPI
177530d68baSNigel Croxon _PoolPrint (
178530d68baSNigel Croxon IN VOID *Context,
179530d68baSNigel Croxon IN CHAR16 *Buffer
180530d68baSNigel Croxon );
181530d68baSNigel Croxon
182530d68baSNigel Croxon INTN
DbgPrint(IN INTN mask,IN CONST CHAR8 * fmt,...)183530d68baSNigel Croxon DbgPrint (
184530d68baSNigel Croxon IN INTN mask,
185fa1b9779SNigel Croxon IN CONST CHAR8 *fmt,
186530d68baSNigel Croxon ...
187530d68baSNigel Croxon )
188530d68baSNigel Croxon /*++
189530d68baSNigel Croxon
190530d68baSNigel Croxon Routine Description:
191530d68baSNigel Croxon
192530d68baSNigel Croxon Prints a formatted unicode string to the default StandardError console
193530d68baSNigel Croxon
194530d68baSNigel Croxon Arguments:
195530d68baSNigel Croxon
196530d68baSNigel Croxon mask - Bit mask of debug string. If a bit is set in the
197530d68baSNigel Croxon mask that is also set in EFIDebug the string is
198530d68baSNigel Croxon printed; otherwise, the string is not printed
199530d68baSNigel Croxon
200530d68baSNigel Croxon fmt - Format string
201530d68baSNigel Croxon
202530d68baSNigel Croxon Returns:
203530d68baSNigel Croxon
204530d68baSNigel Croxon Length of string printed to the StandardError console
205530d68baSNigel Croxon
206530d68baSNigel Croxon --*/
207530d68baSNigel Croxon {
208530d68baSNigel Croxon SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
209530d68baSNigel Croxon PRINT_STATE ps;
210530d68baSNigel Croxon va_list args;
211530d68baSNigel Croxon UINTN back;
212530d68baSNigel Croxon UINTN attr;
213530d68baSNigel Croxon UINTN SavedAttribute;
214530d68baSNigel Croxon
215530d68baSNigel Croxon
216530d68baSNigel Croxon if (!(EFIDebug & mask)) {
217530d68baSNigel Croxon return 0;
218530d68baSNigel Croxon }
219530d68baSNigel Croxon
220530d68baSNigel Croxon va_start (args, fmt);
221530d68baSNigel Croxon ZeroMem (&ps, sizeof(ps));
222530d68baSNigel Croxon
223530d68baSNigel Croxon ps.Output = _DbgOut;
224530d68baSNigel Croxon ps.fmt.Ascii = TRUE;
225530d68baSNigel Croxon ps.fmt.pc = fmt;
226530d68baSNigel Croxon va_copy(ps.args, args);
227530d68baSNigel Croxon ps.Attr = EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_RED);
228530d68baSNigel Croxon
229530d68baSNigel Croxon DbgOut = LibRuntimeDebugOut;
230530d68baSNigel Croxon
231530d68baSNigel Croxon if (!DbgOut) {
232530d68baSNigel Croxon DbgOut = ST->StdErr;
233530d68baSNigel Croxon }
234530d68baSNigel Croxon
235530d68baSNigel Croxon if (DbgOut) {
236530d68baSNigel Croxon ps.Attr = DbgOut->Mode->Attribute;
237530d68baSNigel Croxon ps.Context = DbgOut;
23809027207SNigel Croxon ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) DbgOut->SetAttribute;
239530d68baSNigel Croxon }
240530d68baSNigel Croxon
241530d68baSNigel Croxon SavedAttribute = ps.Attr;
242530d68baSNigel Croxon
243530d68baSNigel Croxon back = (ps.Attr >> 4) & 0xf;
244530d68baSNigel Croxon ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
245530d68baSNigel Croxon ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
246530d68baSNigel Croxon ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
247530d68baSNigel Croxon
248530d68baSNigel Croxon attr = ps.AttrNorm;
249530d68baSNigel Croxon
250530d68baSNigel Croxon if (mask & D_WARN) {
251530d68baSNigel Croxon attr = ps.AttrHighlight;
252530d68baSNigel Croxon }
253530d68baSNigel Croxon
254530d68baSNigel Croxon if (mask & D_ERROR) {
255530d68baSNigel Croxon attr = ps.AttrError;
256530d68baSNigel Croxon }
257530d68baSNigel Croxon
258530d68baSNigel Croxon if (ps.SetAttr) {
259530d68baSNigel Croxon ps.Attr = attr;
260530d68baSNigel Croxon uefi_call_wrapper(ps.SetAttr, 2, ps.Context, attr);
261530d68baSNigel Croxon }
262530d68baSNigel Croxon
263530d68baSNigel Croxon _Print (&ps);
264530d68baSNigel Croxon
265530d68baSNigel Croxon va_end (ps.args);
266530d68baSNigel Croxon va_end (args);
267530d68baSNigel Croxon
268530d68baSNigel Croxon //
269530d68baSNigel Croxon // Restore original attributes
270530d68baSNigel Croxon //
271530d68baSNigel Croxon
272530d68baSNigel Croxon if (ps.SetAttr) {
273530d68baSNigel Croxon uefi_call_wrapper(ps.SetAttr, 2, ps.Context, SavedAttribute);
274530d68baSNigel Croxon }
275530d68baSNigel Croxon
276530d68baSNigel Croxon return 0;
277530d68baSNigel Croxon }
278530d68baSNigel Croxon
279530d68baSNigel Croxon STATIC
280530d68baSNigel Croxon INTN
IsLocalPrint(void * func)281530d68baSNigel Croxon IsLocalPrint(void *func)
282530d68baSNigel Croxon {
283530d68baSNigel Croxon if (func == _DbgOut || func == _SPrint || func == _PoolPrint)
284530d68baSNigel Croxon return 1;
285530d68baSNigel Croxon return 0;
286530d68baSNigel Croxon }
287530d68baSNigel Croxon
288530d68baSNigel Croxon STATIC
289530d68baSNigel Croxon INTN EFIAPI
_DbgOut(IN VOID * Context,IN CHAR16 * Buffer)290530d68baSNigel Croxon _DbgOut (
291530d68baSNigel Croxon IN VOID *Context,
292530d68baSNigel Croxon IN CHAR16 *Buffer
293530d68baSNigel Croxon )
294530d68baSNigel Croxon // Append string worker for DbgPrint
295530d68baSNigel Croxon {
296530d68baSNigel Croxon SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
297530d68baSNigel Croxon
298530d68baSNigel Croxon DbgOut = Context;
299530d68baSNigel Croxon // if (!DbgOut && ST && ST->ConOut) {
300530d68baSNigel Croxon // DbgOut = ST->ConOut;
301530d68baSNigel Croxon // }
302530d68baSNigel Croxon
303530d68baSNigel Croxon if (DbgOut) {
304530d68baSNigel Croxon if (IsLocalPrint(DbgOut->OutputString))
305530d68baSNigel Croxon DbgOut->OutputString(DbgOut, Buffer);
306530d68baSNigel Croxon else
307530d68baSNigel Croxon uefi_call_wrapper(DbgOut->OutputString, 2, DbgOut, Buffer);
308530d68baSNigel Croxon }
309530d68baSNigel Croxon
310530d68baSNigel Croxon return 0;
311530d68baSNigel Croxon }
312530d68baSNigel Croxon
313530d68baSNigel Croxon INTN EFIAPI
_SPrint(IN VOID * Context,IN CHAR16 * Buffer)314530d68baSNigel Croxon _SPrint (
315530d68baSNigel Croxon IN VOID *Context,
316530d68baSNigel Croxon IN CHAR16 *Buffer
317530d68baSNigel Croxon )
318b39be0d5SPete Batard // Append string worker for UnicodeSPrint, PoolPrint and CatPrint
319530d68baSNigel Croxon {
320530d68baSNigel Croxon UINTN len;
321530d68baSNigel Croxon POOL_PRINT *spc;
322530d68baSNigel Croxon
323530d68baSNigel Croxon spc = Context;
324530d68baSNigel Croxon len = StrLen(Buffer);
325530d68baSNigel Croxon
326530d68baSNigel Croxon //
327530d68baSNigel Croxon // Is the string is over the max truncate it
328530d68baSNigel Croxon //
329530d68baSNigel Croxon
330530d68baSNigel Croxon if (spc->len + len > spc->maxlen) {
331530d68baSNigel Croxon len = spc->maxlen - spc->len;
332530d68baSNigel Croxon }
333530d68baSNigel Croxon
334530d68baSNigel Croxon //
335530d68baSNigel Croxon // Append the new text
336530d68baSNigel Croxon //
337530d68baSNigel Croxon
338530d68baSNigel Croxon CopyMem (spc->str + spc->len, Buffer, len * sizeof(CHAR16));
339530d68baSNigel Croxon spc->len += len;
340530d68baSNigel Croxon
341530d68baSNigel Croxon //
342530d68baSNigel Croxon // Null terminate it
343530d68baSNigel Croxon //
344530d68baSNigel Croxon
345530d68baSNigel Croxon if (spc->len < spc->maxlen) {
346530d68baSNigel Croxon spc->str[spc->len] = 0;
347530d68baSNigel Croxon } else if (spc->maxlen) {
348dada63fdSNigel Croxon spc->str[spc->maxlen] = 0;
349530d68baSNigel Croxon }
350530d68baSNigel Croxon
351530d68baSNigel Croxon return 0;
352530d68baSNigel Croxon }
353530d68baSNigel Croxon
354530d68baSNigel Croxon
355530d68baSNigel Croxon INTN EFIAPI
_PoolPrint(IN VOID * Context,IN CHAR16 * Buffer)356530d68baSNigel Croxon _PoolPrint (
357530d68baSNigel Croxon IN VOID *Context,
358530d68baSNigel Croxon IN CHAR16 *Buffer
359530d68baSNigel Croxon )
360530d68baSNigel Croxon // Append string worker for PoolPrint and CatPrint
361530d68baSNigel Croxon {
362530d68baSNigel Croxon UINTN newlen;
363530d68baSNigel Croxon POOL_PRINT *spc;
364530d68baSNigel Croxon
365530d68baSNigel Croxon spc = Context;
366530d68baSNigel Croxon newlen = spc->len + StrLen(Buffer) + 1;
367530d68baSNigel Croxon
368530d68baSNigel Croxon //
369530d68baSNigel Croxon // Is the string is over the max, grow the buffer
370530d68baSNigel Croxon //
371530d68baSNigel Croxon
372530d68baSNigel Croxon if (newlen > spc->maxlen) {
373530d68baSNigel Croxon
374530d68baSNigel Croxon //
375530d68baSNigel Croxon // Grow the pool buffer
376530d68baSNigel Croxon //
377530d68baSNigel Croxon
378530d68baSNigel Croxon newlen += PRINT_STRING_LEN;
379530d68baSNigel Croxon spc->maxlen = newlen;
380530d68baSNigel Croxon spc->str = ReallocatePool (
381530d68baSNigel Croxon spc->str,
382530d68baSNigel Croxon spc->len * sizeof(CHAR16),
383530d68baSNigel Croxon spc->maxlen * sizeof(CHAR16)
384530d68baSNigel Croxon );
385530d68baSNigel Croxon
386530d68baSNigel Croxon if (!spc->str) {
387530d68baSNigel Croxon spc->len = 0;
388530d68baSNigel Croxon spc->maxlen = 0;
389530d68baSNigel Croxon }
390530d68baSNigel Croxon }
391530d68baSNigel Croxon
392530d68baSNigel Croxon //
393530d68baSNigel Croxon // Append the new text
394530d68baSNigel Croxon //
395530d68baSNigel Croxon
396530d68baSNigel Croxon return _SPrint (Context, Buffer);
397530d68baSNigel Croxon }
398530d68baSNigel Croxon
399530d68baSNigel Croxon
400530d68baSNigel Croxon
401530d68baSNigel Croxon VOID
_PoolCatPrint(IN CONST CHAR16 * fmt,IN va_list args,IN OUT POOL_PRINT * spc,IN INTN (EFIAPI * Output)(VOID * context,CHAR16 * str))402530d68baSNigel Croxon _PoolCatPrint (
403fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
404530d68baSNigel Croxon IN va_list args,
405530d68baSNigel Croxon IN OUT POOL_PRINT *spc,
40609027207SNigel Croxon IN INTN (EFIAPI *Output)(VOID *context, CHAR16 *str)
407530d68baSNigel Croxon )
408b39be0d5SPete Batard // Dispatch function for UnicodeSPrint, PoolPrint, and CatPrint
409530d68baSNigel Croxon {
410530d68baSNigel Croxon PRINT_STATE ps;
411530d68baSNigel Croxon
412530d68baSNigel Croxon ZeroMem (&ps, sizeof(ps));
413530d68baSNigel Croxon ps.Output = Output;
414530d68baSNigel Croxon ps.Context = spc;
415530d68baSNigel Croxon ps.fmt.pw = fmt;
416530d68baSNigel Croxon va_copy(ps.args, args);
417530d68baSNigel Croxon _Print (&ps);
418530d68baSNigel Croxon va_end(ps.args);
419530d68baSNigel Croxon }
420530d68baSNigel Croxon
421530d68baSNigel Croxon
422530d68baSNigel Croxon
423530d68baSNigel Croxon UINTN
UnicodeVSPrint(OUT CHAR16 * Str,IN UINTN StrSize,IN CONST CHAR16 * fmt,va_list args)424b39be0d5SPete Batard UnicodeVSPrint (
425530d68baSNigel Croxon OUT CHAR16 *Str,
426530d68baSNigel Croxon IN UINTN StrSize,
427fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
428530d68baSNigel Croxon va_list args
429530d68baSNigel Croxon )
430530d68baSNigel Croxon /*++
431530d68baSNigel Croxon
432530d68baSNigel Croxon Routine Description:
433530d68baSNigel Croxon
434530d68baSNigel Croxon Prints a formatted unicode string to a buffer using a va_list
435530d68baSNigel Croxon
436530d68baSNigel Croxon Arguments:
437530d68baSNigel Croxon
438530d68baSNigel Croxon Str - Output buffer to print the formatted string into
439530d68baSNigel Croxon
440530d68baSNigel Croxon StrSize - Size of Str. String is truncated to this size.
441530d68baSNigel Croxon A size of 0 means there is no limit
442530d68baSNigel Croxon
443530d68baSNigel Croxon fmt - The format string
444530d68baSNigel Croxon
445530d68baSNigel Croxon args - va_list
446530d68baSNigel Croxon
447530d68baSNigel Croxon
448530d68baSNigel Croxon Returns:
449530d68baSNigel Croxon
450530d68baSNigel Croxon String length returned in buffer
451530d68baSNigel Croxon
452530d68baSNigel Croxon --*/
453530d68baSNigel Croxon {
454530d68baSNigel Croxon POOL_PRINT spc;
455530d68baSNigel Croxon
456530d68baSNigel Croxon spc.str = Str;
457530d68baSNigel Croxon spc.maxlen = StrSize / sizeof(CHAR16) - 1;
458530d68baSNigel Croxon spc.len = 0;
459530d68baSNigel Croxon
460530d68baSNigel Croxon _PoolCatPrint (fmt, args, &spc, _SPrint);
461530d68baSNigel Croxon
462530d68baSNigel Croxon return spc.len;
463530d68baSNigel Croxon }
464530d68baSNigel Croxon
465530d68baSNigel Croxon UINTN
UnicodeSPrint(OUT CHAR16 * Str,IN UINTN StrSize,IN CONST CHAR16 * fmt,...)466b39be0d5SPete Batard UnicodeSPrint (
467530d68baSNigel Croxon OUT CHAR16 *Str,
468530d68baSNigel Croxon IN UINTN StrSize,
469fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
470530d68baSNigel Croxon ...
471530d68baSNigel Croxon )
472530d68baSNigel Croxon /*++
473530d68baSNigel Croxon
474530d68baSNigel Croxon Routine Description:
475530d68baSNigel Croxon
476530d68baSNigel Croxon Prints a formatted unicode string to a buffer
477530d68baSNigel Croxon
478530d68baSNigel Croxon Arguments:
479530d68baSNigel Croxon
480530d68baSNigel Croxon Str - Output buffer to print the formatted string into
481530d68baSNigel Croxon
482530d68baSNigel Croxon StrSize - Size of Str. String is truncated to this size.
483530d68baSNigel Croxon A size of 0 means there is no limit
484530d68baSNigel Croxon
485530d68baSNigel Croxon fmt - The format string
486530d68baSNigel Croxon
487530d68baSNigel Croxon Returns:
488530d68baSNigel Croxon
489530d68baSNigel Croxon String length returned in buffer
490530d68baSNigel Croxon
491530d68baSNigel Croxon --*/
492530d68baSNigel Croxon {
493530d68baSNigel Croxon va_list args;
494530d68baSNigel Croxon UINTN len;
495530d68baSNigel Croxon
496530d68baSNigel Croxon va_start (args, fmt);
497b39be0d5SPete Batard len = UnicodeVSPrint(Str, StrSize, fmt, args);
498530d68baSNigel Croxon va_end (args);
499530d68baSNigel Croxon
500530d68baSNigel Croxon return len;
501530d68baSNigel Croxon }
502530d68baSNigel Croxon
503530d68baSNigel Croxon CHAR16 *
VPoolPrint(IN CONST CHAR16 * fmt,va_list args)504530d68baSNigel Croxon VPoolPrint (
505fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
506530d68baSNigel Croxon va_list args
507530d68baSNigel Croxon )
508530d68baSNigel Croxon /*++
509530d68baSNigel Croxon
510530d68baSNigel Croxon Routine Description:
511530d68baSNigel Croxon
512530d68baSNigel Croxon Prints a formatted unicode string to allocated pool using va_list argument.
513530d68baSNigel Croxon The caller must free the resulting buffer.
514530d68baSNigel Croxon
515530d68baSNigel Croxon Arguments:
516530d68baSNigel Croxon
517530d68baSNigel Croxon fmt - The format string
518530d68baSNigel Croxon args - The arguments in va_list form
519530d68baSNigel Croxon
520530d68baSNigel Croxon Returns:
521530d68baSNigel Croxon
522530d68baSNigel Croxon Allocated buffer with the formatted string printed in it.
523530d68baSNigel Croxon The caller must free the allocated buffer. The buffer
524530d68baSNigel Croxon allocation is not packed.
525530d68baSNigel Croxon
526530d68baSNigel Croxon --*/
527530d68baSNigel Croxon {
528530d68baSNigel Croxon POOL_PRINT spc;
529530d68baSNigel Croxon ZeroMem (&spc, sizeof(spc));
530530d68baSNigel Croxon _PoolCatPrint (fmt, args, &spc, _PoolPrint);
531530d68baSNigel Croxon return spc.str;
532530d68baSNigel Croxon }
533530d68baSNigel Croxon
534530d68baSNigel Croxon CHAR16 *
PoolPrint(IN CONST CHAR16 * fmt,...)535530d68baSNigel Croxon PoolPrint (
536fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
537530d68baSNigel Croxon ...
538530d68baSNigel Croxon )
539530d68baSNigel Croxon /*++
540530d68baSNigel Croxon
541530d68baSNigel Croxon Routine Description:
542530d68baSNigel Croxon
543530d68baSNigel Croxon Prints a formatted unicode string to allocated pool. The caller
544530d68baSNigel Croxon must free the resulting buffer.
545530d68baSNigel Croxon
546530d68baSNigel Croxon Arguments:
547530d68baSNigel Croxon
548530d68baSNigel Croxon fmt - The format string
549530d68baSNigel Croxon
550530d68baSNigel Croxon Returns:
551530d68baSNigel Croxon
552530d68baSNigel Croxon Allocated buffer with the formatted string printed in it.
553530d68baSNigel Croxon The caller must free the allocated buffer. The buffer
554530d68baSNigel Croxon allocation is not packed.
555530d68baSNigel Croxon
556530d68baSNigel Croxon --*/
557530d68baSNigel Croxon {
558530d68baSNigel Croxon va_list args;
559530d68baSNigel Croxon CHAR16 *pool;
560530d68baSNigel Croxon va_start (args, fmt);
561530d68baSNigel Croxon pool = VPoolPrint(fmt, args);
562530d68baSNigel Croxon va_end (args);
563530d68baSNigel Croxon return pool;
564530d68baSNigel Croxon }
565530d68baSNigel Croxon
566530d68baSNigel Croxon CHAR16 *
CatPrint(IN OUT POOL_PRINT * Str,IN CONST CHAR16 * fmt,...)567530d68baSNigel Croxon CatPrint (
568530d68baSNigel Croxon IN OUT POOL_PRINT *Str,
569fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
570530d68baSNigel Croxon ...
571530d68baSNigel Croxon )
572530d68baSNigel Croxon /*++
573530d68baSNigel Croxon
574530d68baSNigel Croxon Routine Description:
575530d68baSNigel Croxon
576530d68baSNigel Croxon Concatenates a formatted unicode string to allocated pool.
577530d68baSNigel Croxon The caller must free the resulting buffer.
578530d68baSNigel Croxon
579530d68baSNigel Croxon Arguments:
580530d68baSNigel Croxon
581530d68baSNigel Croxon Str - Tracks the allocated pool, size in use, and
582530d68baSNigel Croxon amount of pool allocated.
583530d68baSNigel Croxon
584530d68baSNigel Croxon fmt - The format string
585530d68baSNigel Croxon
586530d68baSNigel Croxon Returns:
587530d68baSNigel Croxon
588530d68baSNigel Croxon Allocated buffer with the formatted string printed in it.
589530d68baSNigel Croxon The caller must free the allocated buffer. The buffer
590530d68baSNigel Croxon allocation is not packed.
591530d68baSNigel Croxon
592530d68baSNigel Croxon --*/
593530d68baSNigel Croxon {
594530d68baSNigel Croxon va_list args;
595530d68baSNigel Croxon
596530d68baSNigel Croxon va_start (args, fmt);
597530d68baSNigel Croxon _PoolCatPrint (fmt, args, Str, _PoolPrint);
598530d68baSNigel Croxon va_end (args);
599530d68baSNigel Croxon return Str->str;
600530d68baSNigel Croxon }
601530d68baSNigel Croxon
602530d68baSNigel Croxon
603530d68baSNigel Croxon
604530d68baSNigel Croxon UINTN
Print(IN CONST CHAR16 * fmt,...)605530d68baSNigel Croxon Print (
606fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
607530d68baSNigel Croxon ...
608530d68baSNigel Croxon )
609530d68baSNigel Croxon /*++
610530d68baSNigel Croxon
611530d68baSNigel Croxon Routine Description:
612530d68baSNigel Croxon
613530d68baSNigel Croxon Prints a formatted unicode string to the default console
614530d68baSNigel Croxon
615530d68baSNigel Croxon Arguments:
616530d68baSNigel Croxon
617530d68baSNigel Croxon fmt - Format string
618530d68baSNigel Croxon
619530d68baSNigel Croxon Returns:
620530d68baSNigel Croxon
621530d68baSNigel Croxon Length of string printed to the console
622530d68baSNigel Croxon
623530d68baSNigel Croxon --*/
624530d68baSNigel Croxon {
625530d68baSNigel Croxon va_list args;
626530d68baSNigel Croxon UINTN back;
627530d68baSNigel Croxon
628530d68baSNigel Croxon va_start (args, fmt);
629530d68baSNigel Croxon back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
630530d68baSNigel Croxon va_end (args);
631530d68baSNigel Croxon return back;
632530d68baSNigel Croxon }
633530d68baSNigel Croxon
634530d68baSNigel Croxon UINTN
VPrint(IN CONST CHAR16 * fmt,va_list args)635530d68baSNigel Croxon VPrint (
636fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
637530d68baSNigel Croxon va_list args
638530d68baSNigel Croxon )
639530d68baSNigel Croxon /*++
640530d68baSNigel Croxon
641530d68baSNigel Croxon Routine Description:
642530d68baSNigel Croxon
643530d68baSNigel Croxon Prints a formatted unicode string to the default console using a va_list
644530d68baSNigel Croxon
645530d68baSNigel Croxon Arguments:
646530d68baSNigel Croxon
647530d68baSNigel Croxon fmt - Format string
648530d68baSNigel Croxon args - va_list
649530d68baSNigel Croxon Returns:
650530d68baSNigel Croxon
651530d68baSNigel Croxon Length of string printed to the console
652530d68baSNigel Croxon
653530d68baSNigel Croxon --*/
654530d68baSNigel Croxon {
655530d68baSNigel Croxon return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
656530d68baSNigel Croxon }
657530d68baSNigel Croxon
658530d68baSNigel Croxon
659530d68baSNigel Croxon UINTN
PrintAt(IN UINTN Column,IN UINTN Row,IN CONST CHAR16 * fmt,...)660530d68baSNigel Croxon PrintAt (
661530d68baSNigel Croxon IN UINTN Column,
662530d68baSNigel Croxon IN UINTN Row,
663fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
664530d68baSNigel Croxon ...
665530d68baSNigel Croxon )
666530d68baSNigel Croxon /*++
667530d68baSNigel Croxon
668530d68baSNigel Croxon Routine Description:
669530d68baSNigel Croxon
670530d68baSNigel Croxon Prints a formatted unicode string to the default console, at
671530d68baSNigel Croxon the supplied cursor position
672530d68baSNigel Croxon
673530d68baSNigel Croxon Arguments:
674530d68baSNigel Croxon
675530d68baSNigel Croxon Column, Row - The cursor position to print the string at
676530d68baSNigel Croxon
677530d68baSNigel Croxon fmt - Format string
678530d68baSNigel Croxon
679530d68baSNigel Croxon Returns:
680530d68baSNigel Croxon
681530d68baSNigel Croxon Length of string printed to the console
682530d68baSNigel Croxon
683530d68baSNigel Croxon --*/
684530d68baSNigel Croxon {
685530d68baSNigel Croxon va_list args;
686530d68baSNigel Croxon UINTN back;
687530d68baSNigel Croxon
688530d68baSNigel Croxon va_start (args, fmt);
689530d68baSNigel Croxon back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
690530d68baSNigel Croxon va_end (args);
691530d68baSNigel Croxon return back;
692530d68baSNigel Croxon }
693530d68baSNigel Croxon
694530d68baSNigel Croxon
695530d68baSNigel Croxon UINTN
IPrint(IN SIMPLE_TEXT_OUTPUT_INTERFACE * Out,IN CONST CHAR16 * fmt,...)696530d68baSNigel Croxon IPrint (
697530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
698fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
699530d68baSNigel Croxon ...
700530d68baSNigel Croxon )
701530d68baSNigel Croxon /*++
702530d68baSNigel Croxon
703530d68baSNigel Croxon Routine Description:
704530d68baSNigel Croxon
705530d68baSNigel Croxon Prints a formatted unicode string to the specified console
706530d68baSNigel Croxon
707530d68baSNigel Croxon Arguments:
708530d68baSNigel Croxon
709530d68baSNigel Croxon Out - The console to print the string too
710530d68baSNigel Croxon
711530d68baSNigel Croxon fmt - Format string
712530d68baSNigel Croxon
713530d68baSNigel Croxon Returns:
714530d68baSNigel Croxon
715530d68baSNigel Croxon Length of string printed to the console
716530d68baSNigel Croxon
717530d68baSNigel Croxon --*/
718530d68baSNigel Croxon {
719530d68baSNigel Croxon va_list args;
720530d68baSNigel Croxon UINTN back;
721530d68baSNigel Croxon
722530d68baSNigel Croxon va_start (args, fmt);
723530d68baSNigel Croxon back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args);
724530d68baSNigel Croxon va_end (args);
725530d68baSNigel Croxon return back;
726530d68baSNigel Croxon }
727530d68baSNigel Croxon
728530d68baSNigel Croxon
729530d68baSNigel Croxon UINTN
IPrintAt(IN SIMPLE_TEXT_OUTPUT_INTERFACE * Out,IN UINTN Column,IN UINTN Row,IN CONST CHAR16 * fmt,...)730530d68baSNigel Croxon IPrintAt (
731530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
732530d68baSNigel Croxon IN UINTN Column,
733530d68baSNigel Croxon IN UINTN Row,
734fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
735530d68baSNigel Croxon ...
736530d68baSNigel Croxon )
737530d68baSNigel Croxon /*++
738530d68baSNigel Croxon
739530d68baSNigel Croxon Routine Description:
740530d68baSNigel Croxon
741530d68baSNigel Croxon Prints a formatted unicode string to the specified console, at
742530d68baSNigel Croxon the supplied cursor position
743530d68baSNigel Croxon
744530d68baSNigel Croxon Arguments:
745530d68baSNigel Croxon
746ab6c6ef7SNigel Croxon Out - The console to print the string to
747530d68baSNigel Croxon
748530d68baSNigel Croxon Column, Row - The cursor position to print the string at
749530d68baSNigel Croxon
750530d68baSNigel Croxon fmt - Format string
751530d68baSNigel Croxon
752530d68baSNigel Croxon Returns:
753530d68baSNigel Croxon
754530d68baSNigel Croxon Length of string printed to the console
755530d68baSNigel Croxon
756530d68baSNigel Croxon --*/
757530d68baSNigel Croxon {
758530d68baSNigel Croxon va_list args;
759530d68baSNigel Croxon UINTN back;
760530d68baSNigel Croxon
761530d68baSNigel Croxon va_start (args, fmt);
762ab6c6ef7SNigel Croxon back = _IPrint (Column, Row, Out, fmt, NULL, args);
763530d68baSNigel Croxon va_end (args);
764530d68baSNigel Croxon return back;
765530d68baSNigel Croxon }
766530d68baSNigel Croxon
767530d68baSNigel Croxon
768530d68baSNigel Croxon UINTN
_IPrint(IN UINTN Column,IN UINTN Row,IN SIMPLE_TEXT_OUTPUT_INTERFACE * Out,IN CONST CHAR16 * fmt,IN CONST CHAR8 * fmta,IN va_list args)769530d68baSNigel Croxon _IPrint (
770530d68baSNigel Croxon IN UINTN Column,
771530d68baSNigel Croxon IN UINTN Row,
772530d68baSNigel Croxon IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
773fa1b9779SNigel Croxon IN CONST CHAR16 *fmt,
774fa1b9779SNigel Croxon IN CONST CHAR8 *fmta,
775530d68baSNigel Croxon IN va_list args
776530d68baSNigel Croxon )
777530d68baSNigel Croxon // Display string worker for: Print, PrintAt, IPrint, IPrintAt
778530d68baSNigel Croxon {
779530d68baSNigel Croxon PRINT_STATE ps;
780530d68baSNigel Croxon UINTN back;
781530d68baSNigel Croxon
782530d68baSNigel Croxon ZeroMem (&ps, sizeof(ps));
783530d68baSNigel Croxon ps.Context = Out;
78409027207SNigel Croxon ps.Output = (INTN (EFIAPI *)(VOID *, CHAR16 *)) Out->OutputString;
78509027207SNigel Croxon ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) Out->SetAttribute;
786530d68baSNigel Croxon ps.Attr = Out->Mode->Attribute;
787530d68baSNigel Croxon
788530d68baSNigel Croxon back = (ps.Attr >> 4) & 0xF;
789530d68baSNigel Croxon ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
790530d68baSNigel Croxon ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
791530d68baSNigel Croxon ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
792530d68baSNigel Croxon
793530d68baSNigel Croxon if (fmt) {
794530d68baSNigel Croxon ps.fmt.pw = fmt;
795530d68baSNigel Croxon } else {
796530d68baSNigel Croxon ps.fmt.Ascii = TRUE;
797530d68baSNigel Croxon ps.fmt.pc = fmta;
798530d68baSNigel Croxon }
799530d68baSNigel Croxon
800530d68baSNigel Croxon va_copy(ps.args, args);
801530d68baSNigel Croxon
802530d68baSNigel Croxon if (Column != (UINTN) -1) {
803530d68baSNigel Croxon uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row);
804530d68baSNigel Croxon }
805530d68baSNigel Croxon
806530d68baSNigel Croxon back = _Print (&ps);
807530d68baSNigel Croxon va_end(ps.args);
808530d68baSNigel Croxon return back;
809530d68baSNigel Croxon }
810530d68baSNigel Croxon
811530d68baSNigel Croxon
812530d68baSNigel Croxon UINTN
AsciiPrint(IN CONST CHAR8 * fmt,...)8130247cb7cSPete Batard AsciiPrint (
814fa1b9779SNigel Croxon IN CONST CHAR8 *fmt,
815530d68baSNigel Croxon ...
816530d68baSNigel Croxon )
817530d68baSNigel Croxon /*++
818530d68baSNigel Croxon
819530d68baSNigel Croxon Routine Description:
820530d68baSNigel Croxon
821530d68baSNigel Croxon For those whom really can't deal with unicode, a print
822530d68baSNigel Croxon function that takes an ascii format string
823530d68baSNigel Croxon
824530d68baSNigel Croxon Arguments:
825530d68baSNigel Croxon
826530d68baSNigel Croxon fmt - ascii format string
827530d68baSNigel Croxon
828530d68baSNigel Croxon Returns:
829530d68baSNigel Croxon
830530d68baSNigel Croxon Length of string printed to the console
831530d68baSNigel Croxon
832530d68baSNigel Croxon --*/
833530d68baSNigel Croxon
834530d68baSNigel Croxon {
835530d68baSNigel Croxon va_list args;
836530d68baSNigel Croxon UINTN back;
837530d68baSNigel Croxon
838530d68baSNigel Croxon va_start (args, fmt);
839530d68baSNigel Croxon back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args);
840530d68baSNigel Croxon va_end (args);
841530d68baSNigel Croxon return back;
842530d68baSNigel Croxon }
843530d68baSNigel Croxon
844530d68baSNigel Croxon
8450247cb7cSPete Batard UINTN
AsciiVSPrint(OUT CHAR8 * Str,IN UINTN StrSize,IN CONST CHAR8 * fmt,va_list args)8460247cb7cSPete Batard AsciiVSPrint (
8470247cb7cSPete Batard OUT CHAR8 *Str,
8480247cb7cSPete Batard IN UINTN StrSize,
8490247cb7cSPete Batard IN CONST CHAR8 *fmt,
8500247cb7cSPete Batard va_list args
8510247cb7cSPete Batard )
8520247cb7cSPete Batard /*++
8530247cb7cSPete Batard
8540247cb7cSPete Batard Routine Description:
8550247cb7cSPete Batard
8560247cb7cSPete Batard Prints a formatted ascii string to a buffer using a va_list
8570247cb7cSPete Batard
8580247cb7cSPete Batard Arguments:
8590247cb7cSPete Batard
8600247cb7cSPete Batard Str - Output buffer to print the formatted string into
8610247cb7cSPete Batard
8620247cb7cSPete Batard StrSize - Size of Str. String is truncated to this size.
8630247cb7cSPete Batard A size of 0 means there is no limit
8640247cb7cSPete Batard
8650247cb7cSPete Batard fmt - The format string
8660247cb7cSPete Batard
8670247cb7cSPete Batard args - va_list
8680247cb7cSPete Batard
8690247cb7cSPete Batard
8700247cb7cSPete Batard Returns:
8710247cb7cSPete Batard
8720247cb7cSPete Batard String length returned in buffer
8730247cb7cSPete Batard
8740247cb7cSPete Batard --*/
8750247cb7cSPete Batard // Use UnicodeVSPrint() and convert back to ASCII
8760247cb7cSPete Batard {
8770247cb7cSPete Batard CHAR16 *UnicodeStr, *UnicodeFmt;
8780247cb7cSPete Batard UINTN i, Len;
8790247cb7cSPete Batard
8800247cb7cSPete Batard UnicodeStr = AllocatePool(StrSize * sizeof(CHAR16));
8810247cb7cSPete Batard if (!UnicodeStr)
8820247cb7cSPete Batard return 0;
8830247cb7cSPete Batard
8840247cb7cSPete Batard UnicodeFmt = PoolPrint(L"%a", fmt);
8850247cb7cSPete Batard if (!UnicodeFmt) {
8860247cb7cSPete Batard FreePool(UnicodeStr);
8870247cb7cSPete Batard return 0;
8880247cb7cSPete Batard }
8890247cb7cSPete Batard
890b39be0d5SPete Batard Len = UnicodeVSPrint(UnicodeStr, StrSize, UnicodeFmt, args);
8910247cb7cSPete Batard FreePool(UnicodeFmt);
8920247cb7cSPete Batard
8930247cb7cSPete Batard // The strings are ASCII so just do a plain Unicode conversion
8940247cb7cSPete Batard for (i = 0; i < Len; i++)
8950247cb7cSPete Batard Str[i] = (CHAR8)UnicodeStr[i];
8960247cb7cSPete Batard Str[Len] = 0;
8970247cb7cSPete Batard FreePool(UnicodeStr);
8980247cb7cSPete Batard
8990247cb7cSPete Batard return Len;
9000247cb7cSPete Batard }
9010247cb7cSPete Batard
9020247cb7cSPete Batard
903530d68baSNigel Croxon STATIC
904530d68baSNigel Croxon VOID
PFLUSH(IN OUT PRINT_STATE * ps)905530d68baSNigel Croxon PFLUSH (
906530d68baSNigel Croxon IN OUT PRINT_STATE *ps
907530d68baSNigel Croxon )
908530d68baSNigel Croxon {
909530d68baSNigel Croxon *ps->Pos = 0;
910530d68baSNigel Croxon if (IsLocalPrint(ps->Output))
911530d68baSNigel Croxon ps->Output(ps->Context, ps->Buffer);
912530d68baSNigel Croxon else
913530d68baSNigel Croxon uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer);
914530d68baSNigel Croxon ps->Pos = ps->Buffer;
915530d68baSNigel Croxon }
916530d68baSNigel Croxon
917530d68baSNigel Croxon STATIC
918530d68baSNigel Croxon VOID
PSETATTR(IN OUT PRINT_STATE * ps,IN UINTN Attr)919530d68baSNigel Croxon PSETATTR (
920530d68baSNigel Croxon IN OUT PRINT_STATE *ps,
921530d68baSNigel Croxon IN UINTN Attr
922530d68baSNigel Croxon )
923530d68baSNigel Croxon {
924530d68baSNigel Croxon PFLUSH (ps);
925530d68baSNigel Croxon
926530d68baSNigel Croxon ps->RestoreAttr = ps->Attr;
927530d68baSNigel Croxon if (ps->SetAttr) {
928530d68baSNigel Croxon uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr);
929530d68baSNigel Croxon }
930530d68baSNigel Croxon
931530d68baSNigel Croxon ps->Attr = Attr;
932530d68baSNigel Croxon }
933530d68baSNigel Croxon
934530d68baSNigel Croxon STATIC
935530d68baSNigel Croxon VOID
PPUTC(IN OUT PRINT_STATE * ps,IN CHAR16 c)936530d68baSNigel Croxon PPUTC (
937530d68baSNigel Croxon IN OUT PRINT_STATE *ps,
938530d68baSNigel Croxon IN CHAR16 c
939530d68baSNigel Croxon )
940530d68baSNigel Croxon {
941530d68baSNigel Croxon // if this is a newline, add a carraige return
942530d68baSNigel Croxon if (c == '\n') {
943530d68baSNigel Croxon PPUTC (ps, '\r');
944530d68baSNigel Croxon }
945530d68baSNigel Croxon
946530d68baSNigel Croxon *ps->Pos = c;
947530d68baSNigel Croxon ps->Pos += 1;
948530d68baSNigel Croxon ps->Len += 1;
949530d68baSNigel Croxon
950530d68baSNigel Croxon // if at the end of the buffer, flush it
951530d68baSNigel Croxon if (ps->Pos >= ps->End) {
952530d68baSNigel Croxon PFLUSH(ps);
953530d68baSNigel Croxon }
954530d68baSNigel Croxon }
955530d68baSNigel Croxon
956530d68baSNigel Croxon
957530d68baSNigel Croxon STATIC
958530d68baSNigel Croxon CHAR16
PGETC(IN POINTER * p)959530d68baSNigel Croxon PGETC (
960530d68baSNigel Croxon IN POINTER *p
961530d68baSNigel Croxon )
962530d68baSNigel Croxon {
963530d68baSNigel Croxon CHAR16 c;
964530d68baSNigel Croxon
965530d68baSNigel Croxon c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index];
966530d68baSNigel Croxon p->Index += 1;
967530d68baSNigel Croxon
968530d68baSNigel Croxon return c;
969530d68baSNigel Croxon }
970530d68baSNigel Croxon
971530d68baSNigel Croxon
972530d68baSNigel Croxon STATIC
973530d68baSNigel Croxon VOID
PITEM(IN OUT PRINT_STATE * ps)974530d68baSNigel Croxon PITEM (
975530d68baSNigel Croxon IN OUT PRINT_STATE *ps
976530d68baSNigel Croxon )
977530d68baSNigel Croxon {
978530d68baSNigel Croxon UINTN Len, i;
979530d68baSNigel Croxon PRINT_ITEM *Item;
980530d68baSNigel Croxon CHAR16 c;
981530d68baSNigel Croxon
982530d68baSNigel Croxon // Get the length of the item
983530d68baSNigel Croxon Item = ps->Item;
984530d68baSNigel Croxon Item->Item.Index = 0;
985530d68baSNigel Croxon while (Item->Item.Index < Item->FieldWidth) {
986530d68baSNigel Croxon c = PGETC(&Item->Item);
987530d68baSNigel Croxon if (!c) {
988530d68baSNigel Croxon Item->Item.Index -= 1;
989530d68baSNigel Croxon break;
990530d68baSNigel Croxon }
991530d68baSNigel Croxon }
992530d68baSNigel Croxon Len = Item->Item.Index;
993530d68baSNigel Croxon
994530d68baSNigel Croxon // if there is no item field width, use the items width
995530d68baSNigel Croxon if (Item->FieldWidth == (UINTN) -1) {
996530d68baSNigel Croxon Item->FieldWidth = Len;
997530d68baSNigel Croxon }
998530d68baSNigel Croxon
999530d68baSNigel Croxon // if item is larger then width, update width
1000530d68baSNigel Croxon if (Len > Item->Width) {
1001530d68baSNigel Croxon Item->Width = Len;
1002530d68baSNigel Croxon }
1003530d68baSNigel Croxon
1004530d68baSNigel Croxon
1005530d68baSNigel Croxon // if pad field before, add pad char
1006530d68baSNigel Croxon if (Item->PadBefore) {
1007530d68baSNigel Croxon for (i=Item->Width; i < Item->FieldWidth; i+=1) {
1008530d68baSNigel Croxon PPUTC (ps, ' ');
1009530d68baSNigel Croxon }
1010530d68baSNigel Croxon }
1011530d68baSNigel Croxon
1012530d68baSNigel Croxon // pad item
1013530d68baSNigel Croxon for (i=Len; i < Item->Width; i++) {
1014530d68baSNigel Croxon PPUTC (ps, Item->Pad);
1015530d68baSNigel Croxon }
1016530d68baSNigel Croxon
1017530d68baSNigel Croxon // add the item
1018530d68baSNigel Croxon Item->Item.Index=0;
1019530d68baSNigel Croxon while (Item->Item.Index < Len) {
1020530d68baSNigel Croxon PPUTC (ps, PGETC(&Item->Item));
1021530d68baSNigel Croxon }
1022530d68baSNigel Croxon
1023530d68baSNigel Croxon // If pad at the end, add pad char
1024530d68baSNigel Croxon if (!Item->PadBefore) {
1025530d68baSNigel Croxon for (i=Item->Width; i < Item->FieldWidth; i+=1) {
1026530d68baSNigel Croxon PPUTC (ps, ' ');
1027530d68baSNigel Croxon }
1028530d68baSNigel Croxon }
1029530d68baSNigel Croxon }
1030530d68baSNigel Croxon
1031530d68baSNigel Croxon
1032530d68baSNigel Croxon STATIC
1033530d68baSNigel Croxon UINTN
_Print(IN PRINT_STATE * ps)1034530d68baSNigel Croxon _Print (
1035530d68baSNigel Croxon IN PRINT_STATE *ps
1036530d68baSNigel Croxon )
1037530d68baSNigel Croxon /*++
1038530d68baSNigel Croxon
1039530d68baSNigel Croxon Routine Description:
1040530d68baSNigel Croxon
1041530d68baSNigel Croxon %w.lF - w = width
1042530d68baSNigel Croxon l = field width
1043530d68baSNigel Croxon F = format of arg
1044530d68baSNigel Croxon
1045530d68baSNigel Croxon Args F:
1046530d68baSNigel Croxon 0 - pad with zeros
1047530d68baSNigel Croxon - - justify on left (default is on right)
1048530d68baSNigel Croxon , - add comma's to field
1049530d68baSNigel Croxon * - width provided on stack
1050530d68baSNigel Croxon n - Set output attribute to normal (for this field only)
1051530d68baSNigel Croxon h - Set output attribute to highlight (for this field only)
1052530d68baSNigel Croxon e - Set output attribute to error (for this field only)
1053530d68baSNigel Croxon l - Value is 64 bits
1054530d68baSNigel Croxon
1055530d68baSNigel Croxon a - ascii string
1056530d68baSNigel Croxon s - unicode string
1057530d68baSNigel Croxon X - fixed 8 byte value in hex
1058530d68baSNigel Croxon x - hex value
10591acb1d9dSNigel Croxon d - value as signed decimal
10601acb1d9dSNigel Croxon u - value as unsigned decimal
1061b2c4db06SNigel Croxon f - value as floating point
1062530d68baSNigel Croxon c - Unicode char
1063530d68baSNigel Croxon t - EFI time structure
1064530d68baSNigel Croxon g - Pointer to GUID
1065530d68baSNigel Croxon r - EFI status code (result code)
106628793041SPeter Jones D - pointer to Device Path with normal ending.
1067530d68baSNigel Croxon
1068530d68baSNigel Croxon N - Set output attribute to normal
1069530d68baSNigel Croxon H - Set output attribute to highlight
1070530d68baSNigel Croxon E - Set output attribute to error
1071530d68baSNigel Croxon % - Print a %
1072530d68baSNigel Croxon
1073530d68baSNigel Croxon Arguments:
1074530d68baSNigel Croxon
1075530d68baSNigel Croxon SystemTable - The system table
1076530d68baSNigel Croxon
1077530d68baSNigel Croxon Returns:
1078530d68baSNigel Croxon
1079530d68baSNigel Croxon Number of charactors written
1080530d68baSNigel Croxon
1081530d68baSNigel Croxon --*/
1082530d68baSNigel Croxon {
1083530d68baSNigel Croxon CHAR16 c;
1084530d68baSNigel Croxon UINTN Attr;
1085530d68baSNigel Croxon PRINT_ITEM Item;
1086530d68baSNigel Croxon CHAR16 Buffer[PRINT_STRING_LEN];
1087530d68baSNigel Croxon
1088530d68baSNigel Croxon ps->Len = 0;
1089530d68baSNigel Croxon ps->Buffer = Buffer;
1090530d68baSNigel Croxon ps->Pos = Buffer;
1091530d68baSNigel Croxon ps->End = Buffer + PRINT_STRING_LEN - 1;
1092530d68baSNigel Croxon ps->Item = &Item;
1093530d68baSNigel Croxon
1094530d68baSNigel Croxon ps->fmt.Index = 0;
1095530d68baSNigel Croxon while ((c = PGETC(&ps->fmt))) {
1096530d68baSNigel Croxon
1097530d68baSNigel Croxon if (c != '%') {
1098530d68baSNigel Croxon PPUTC ( ps, c );
1099530d68baSNigel Croxon continue;
1100530d68baSNigel Croxon }
1101530d68baSNigel Croxon
1102530d68baSNigel Croxon // setup for new item
1103530d68baSNigel Croxon Item.FieldWidth = (UINTN) -1;
1104530d68baSNigel Croxon Item.Width = 0;
1105530d68baSNigel Croxon Item.WidthParse = &Item.Width;
1106530d68baSNigel Croxon Item.Pad = ' ';
1107530d68baSNigel Croxon Item.PadBefore = TRUE;
1108530d68baSNigel Croxon Item.Comma = FALSE;
1109530d68baSNigel Croxon Item.Long = FALSE;
1110530d68baSNigel Croxon Item.Item.Ascii = FALSE;
1111530d68baSNigel Croxon Item.Item.pw = NULL;
1112530d68baSNigel Croxon ps->RestoreAttr = 0;
1113530d68baSNigel Croxon Attr = 0;
1114530d68baSNigel Croxon
1115530d68baSNigel Croxon while ((c = PGETC(&ps->fmt))) {
1116530d68baSNigel Croxon
1117530d68baSNigel Croxon switch (c) {
1118530d68baSNigel Croxon
1119530d68baSNigel Croxon case '%':
1120530d68baSNigel Croxon //
1121530d68baSNigel Croxon // %% -> %
1122530d68baSNigel Croxon //
1123fa1b9779SNigel Croxon Item.Scratch[0] = '%';
1124fa1b9779SNigel Croxon Item.Scratch[1] = 0;
1125530d68baSNigel Croxon Item.Item.pw = Item.Scratch;
1126530d68baSNigel Croxon break;
1127530d68baSNigel Croxon
1128f7bf4302SPeter Jones case ',':
1129f7bf4302SPeter Jones Item.Comma = TRUE;
1130530d68baSNigel Croxon break;
1131530d68baSNigel Croxon
1132530d68baSNigel Croxon case '-':
1133530d68baSNigel Croxon Item.PadBefore = FALSE;
1134530d68baSNigel Croxon break;
1135530d68baSNigel Croxon
1136f7bf4302SPeter Jones case '*':
1137f7bf4302SPeter Jones *Item.WidthParse = va_arg(ps->args, UINTN);
1138530d68baSNigel Croxon break;
1139530d68baSNigel Croxon
1140530d68baSNigel Croxon case '.':
1141530d68baSNigel Croxon Item.WidthParse = &Item.FieldWidth;
1142530d68baSNigel Croxon break;
1143530d68baSNigel Croxon
1144f7bf4302SPeter Jones case '0':
1145f7bf4302SPeter Jones Item.Pad = '0';
1146530d68baSNigel Croxon break;
1147530d68baSNigel Croxon
1148530d68baSNigel Croxon case '1':
1149530d68baSNigel Croxon case '2':
1150530d68baSNigel Croxon case '3':
1151530d68baSNigel Croxon case '4':
1152530d68baSNigel Croxon case '5':
1153530d68baSNigel Croxon case '6':
1154530d68baSNigel Croxon case '7':
1155530d68baSNigel Croxon case '8':
1156530d68baSNigel Croxon case '9':
1157530d68baSNigel Croxon *Item.WidthParse = 0;
1158530d68baSNigel Croxon do {
1159530d68baSNigel Croxon *Item.WidthParse = *Item.WidthParse * 10 + c - '0';
1160530d68baSNigel Croxon c = PGETC(&ps->fmt);
1161530d68baSNigel Croxon } while (c >= '0' && c <= '9') ;
1162530d68baSNigel Croxon ps->fmt.Index -= 1;
1163530d68baSNigel Croxon break;
1164530d68baSNigel Croxon
1165530d68baSNigel Croxon case 'a':
1166530d68baSNigel Croxon Item.Item.pc = va_arg(ps->args, CHAR8 *);
1167530d68baSNigel Croxon Item.Item.Ascii = TRUE;
1168530d68baSNigel Croxon if (!Item.Item.pc) {
1169530d68baSNigel Croxon Item.Item.pc = (CHAR8 *)"(null)";
1170530d68baSNigel Croxon }
1171530d68baSNigel Croxon break;
1172530d68baSNigel Croxon
1173530d68baSNigel Croxon case 'c':
1174fa1b9779SNigel Croxon Item.Scratch[0] = (CHAR16) va_arg(ps->args, UINTN);
1175fa1b9779SNigel Croxon Item.Scratch[1] = 0;
1176530d68baSNigel Croxon Item.Item.pw = Item.Scratch;
1177530d68baSNigel Croxon break;
1178530d68baSNigel Croxon
117928793041SPeter Jones case 'D':
118028793041SPeter Jones {
118128793041SPeter Jones EFI_DEVICE_PATH *dp = va_arg(ps->args, EFI_DEVICE_PATH *);
118228793041SPeter Jones CHAR16 *dpstr = DevicePathToStr(dp);
118328793041SPeter Jones StrnCpy(Item.Scratch, dpstr, PRINT_ITEM_BUFFER_LEN);
118428793041SPeter Jones Item.Scratch[PRINT_ITEM_BUFFER_LEN-1] = L'\0';
118528793041SPeter Jones FreePool(dpstr);
118628793041SPeter Jones
118728793041SPeter Jones Item.Item.pw = Item.Scratch;
118828793041SPeter Jones break;
118928793041SPeter Jones }
119028793041SPeter Jones
1191f7bf4302SPeter Jones case 'd':
1192f7bf4302SPeter Jones ValueToString (
1193f7bf4302SPeter Jones Item.Scratch,
1194f7bf4302SPeter Jones Item.Comma,
1195f7bf4302SPeter Jones Item.Long ? va_arg(ps->args, INT64) : va_arg(ps->args, INT32)
1196f7bf4302SPeter Jones );
1197f7bf4302SPeter Jones Item.Item.pw = Item.Scratch;
1198f7bf4302SPeter Jones break;
1199f7bf4302SPeter Jones
1200f7bf4302SPeter Jones case 'E':
1201f7bf4302SPeter Jones Attr = ps->AttrError;
1202f7bf4302SPeter Jones break;
1203f7bf4302SPeter Jones
1204f7bf4302SPeter Jones case 'e':
1205f7bf4302SPeter Jones PSETATTR(ps, ps->AttrError);
1206f7bf4302SPeter Jones break;
1207f7bf4302SPeter Jones
1208b2c4db06SNigel Croxon case 'f':
1209b2c4db06SNigel Croxon FloatToString (
1210fa1b9779SNigel Croxon Item.Scratch,
1211b2c4db06SNigel Croxon Item.Comma,
1212b2c4db06SNigel Croxon va_arg(ps->args, double)
1213b2c4db06SNigel Croxon );
1214fa1b9779SNigel Croxon Item.Item.pw = Item.Scratch;
1215b2c4db06SNigel Croxon break;
1216b2c4db06SNigel Croxon
1217f7bf4302SPeter Jones case 'g':
1218f7bf4302SPeter Jones GuidToString (Item.Scratch, va_arg(ps->args, EFI_GUID *));
1219530d68baSNigel Croxon Item.Item.pw = Item.Scratch;
1220530d68baSNigel Croxon break;
1221530d68baSNigel Croxon
1222f7bf4302SPeter Jones case 'H':
1223f7bf4302SPeter Jones Attr = ps->AttrHighlight;
1224f7bf4302SPeter Jones break;
1225f7bf4302SPeter Jones
1226f7bf4302SPeter Jones case 'h':
1227f7bf4302SPeter Jones PSETATTR(ps, ps->AttrHighlight);
1228f7bf4302SPeter Jones break;
1229f7bf4302SPeter Jones
1230f7bf4302SPeter Jones case 'l':
1231f7bf4302SPeter Jones Item.Long = TRUE;
1232f7bf4302SPeter Jones break;
1233f7bf4302SPeter Jones
1234f7bf4302SPeter Jones case 'N':
1235f7bf4302SPeter Jones Attr = ps->AttrNorm;
1236f7bf4302SPeter Jones break;
1237f7bf4302SPeter Jones
1238f7bf4302SPeter Jones case 'n':
1239f7bf4302SPeter Jones PSETATTR(ps, ps->AttrNorm);
1240f7bf4302SPeter Jones break;
1241f7bf4302SPeter Jones
1242*4b5db35eSPeter Jones case 'p':
1243*4b5db35eSPeter Jones Item.Width = sizeof(void *) == (8 ? 16 : 8) + 2;
1244*4b5db35eSPeter Jones Item.Pad = '0';
1245*4b5db35eSPeter Jones Item.Scratch[0] = ' ';
1246*4b5db35eSPeter Jones Item.Scratch[1] = ' ';
1247*4b5db35eSPeter Jones ValueToHex (
1248*4b5db35eSPeter Jones Item.Scratch+2,
1249*4b5db35eSPeter Jones Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
1250*4b5db35eSPeter Jones );
1251*4b5db35eSPeter Jones Item.Scratch[0] = '0';
1252*4b5db35eSPeter Jones Item.Scratch[1] = 'x';
1253*4b5db35eSPeter Jones Item.Item.pw = Item.Scratch;
1254*4b5db35eSPeter Jones break;
1255*4b5db35eSPeter Jones
1256530d68baSNigel Croxon case 'r':
1257fa1b9779SNigel Croxon StatusToString (Item.Scratch, va_arg(ps->args, EFI_STATUS));
1258530d68baSNigel Croxon Item.Item.pw = Item.Scratch;
1259530d68baSNigel Croxon break;
1260530d68baSNigel Croxon
1261f7bf4302SPeter Jones case 's':
1262f7bf4302SPeter Jones Item.Item.pw = va_arg(ps->args, CHAR16 *);
1263f7bf4302SPeter Jones if (!Item.Item.pw) {
1264f7bf4302SPeter Jones Item.Item.pw = L"(null)";
1265f7bf4302SPeter Jones }
1266530d68baSNigel Croxon break;
1267530d68baSNigel Croxon
1268f7bf4302SPeter Jones case 't':
1269f7bf4302SPeter Jones TimeToString (Item.Scratch, va_arg(ps->args, EFI_TIME *));
1270f7bf4302SPeter Jones Item.Item.pw = Item.Scratch;
1271530d68baSNigel Croxon break;
1272530d68baSNigel Croxon
1273f7bf4302SPeter Jones case 'u':
1274f7bf4302SPeter Jones ValueToString (
1275f7bf4302SPeter Jones Item.Scratch,
1276f7bf4302SPeter Jones Item.Comma,
1277f7bf4302SPeter Jones Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
1278f7bf4302SPeter Jones );
1279f7bf4302SPeter Jones Item.Item.pw = Item.Scratch;
1280530d68baSNigel Croxon break;
1281530d68baSNigel Croxon
1282f7bf4302SPeter Jones case 'X':
1283f7bf4302SPeter Jones Item.Width = Item.Long ? 16 : 8;
1284f7bf4302SPeter Jones Item.Pad = '0';
1285f7bf4302SPeter Jones #if __GNUC__ >= 7
1286f7bf4302SPeter Jones __attribute__ ((fallthrough));
1287f7bf4302SPeter Jones #endif
1288f7bf4302SPeter Jones case 'x':
1289f7bf4302SPeter Jones ValueToHex (
1290f7bf4302SPeter Jones Item.Scratch,
1291f7bf4302SPeter Jones Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
1292f7bf4302SPeter Jones );
1293f7bf4302SPeter Jones Item.Item.pw = Item.Scratch;
1294530d68baSNigel Croxon break;
1295530d68baSNigel Croxon
1296530d68baSNigel Croxon default:
1297fa1b9779SNigel Croxon Item.Scratch[0] = '?';
1298fa1b9779SNigel Croxon Item.Scratch[1] = 0;
1299530d68baSNigel Croxon Item.Item.pw = Item.Scratch;
1300530d68baSNigel Croxon break;
1301530d68baSNigel Croxon }
1302530d68baSNigel Croxon
1303530d68baSNigel Croxon // if we have an Item
1304530d68baSNigel Croxon if (Item.Item.pw) {
1305530d68baSNigel Croxon PITEM (ps);
1306530d68baSNigel Croxon break;
1307530d68baSNigel Croxon }
1308530d68baSNigel Croxon
1309530d68baSNigel Croxon // if we have an Attr set
1310530d68baSNigel Croxon if (Attr) {
1311530d68baSNigel Croxon PSETATTR(ps, Attr);
1312530d68baSNigel Croxon ps->RestoreAttr = 0;
1313530d68baSNigel Croxon break;
1314530d68baSNigel Croxon }
1315530d68baSNigel Croxon }
1316530d68baSNigel Croxon
1317530d68baSNigel Croxon if (ps->RestoreAttr) {
1318530d68baSNigel Croxon PSETATTR(ps, ps->RestoreAttr);
1319530d68baSNigel Croxon }
1320530d68baSNigel Croxon }
1321530d68baSNigel Croxon
1322530d68baSNigel Croxon // Flush buffer
1323530d68baSNigel Croxon PFLUSH (ps);
1324530d68baSNigel Croxon return ps->Len;
1325530d68baSNigel Croxon }
1326530d68baSNigel Croxon
1327530d68baSNigel Croxon STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7',
1328530d68baSNigel Croxon '8','9','A','B','C','D','E','F'};
1329530d68baSNigel Croxon
1330530d68baSNigel Croxon VOID
ValueToHex(IN CHAR16 * Buffer,IN UINT64 v)1331530d68baSNigel Croxon ValueToHex (
1332530d68baSNigel Croxon IN CHAR16 *Buffer,
1333530d68baSNigel Croxon IN UINT64 v
1334530d68baSNigel Croxon )
1335530d68baSNigel Croxon {
1336530d68baSNigel Croxon CHAR8 str[30], *p1;
1337530d68baSNigel Croxon CHAR16 *p2;
1338530d68baSNigel Croxon
1339530d68baSNigel Croxon if (!v) {
1340530d68baSNigel Croxon Buffer[0] = '0';
1341530d68baSNigel Croxon Buffer[1] = 0;
1342530d68baSNigel Croxon return ;
1343530d68baSNigel Croxon }
1344530d68baSNigel Croxon
1345530d68baSNigel Croxon p1 = str;
1346530d68baSNigel Croxon p2 = Buffer;
1347530d68baSNigel Croxon
1348530d68baSNigel Croxon while (v) {
134938c57d52SNigel Croxon // Without the cast, the MSVC compiler may insert a reference to __allmull
135038c57d52SNigel Croxon *(p1++) = Hex[(UINTN)(v & 0xf)];
1351530d68baSNigel Croxon v = RShiftU64 (v, 4);
1352530d68baSNigel Croxon }
1353530d68baSNigel Croxon
1354530d68baSNigel Croxon while (p1 != str) {
1355530d68baSNigel Croxon *(p2++) = *(--p1);
1356530d68baSNigel Croxon }
1357530d68baSNigel Croxon *p2 = 0;
1358530d68baSNigel Croxon }
1359530d68baSNigel Croxon
1360530d68baSNigel Croxon
1361530d68baSNigel Croxon VOID
ValueToString(IN CHAR16 * Buffer,IN BOOLEAN Comma,IN INT64 v)1362530d68baSNigel Croxon ValueToString (
1363530d68baSNigel Croxon IN CHAR16 *Buffer,
1364530d68baSNigel Croxon IN BOOLEAN Comma,
1365530d68baSNigel Croxon IN INT64 v
1366530d68baSNigel Croxon )
1367530d68baSNigel Croxon {
1368530d68baSNigel Croxon STATIC CHAR8 ca[] = { 3, 1, 2 };
1369530d68baSNigel Croxon CHAR8 str[40], *p1;
1370530d68baSNigel Croxon CHAR16 *p2;
1371530d68baSNigel Croxon UINTN c, r;
1372530d68baSNigel Croxon
1373530d68baSNigel Croxon if (!v) {
1374530d68baSNigel Croxon Buffer[0] = '0';
1375530d68baSNigel Croxon Buffer[1] = 0;
1376530d68baSNigel Croxon return ;
1377530d68baSNigel Croxon }
1378530d68baSNigel Croxon
1379530d68baSNigel Croxon p1 = str;
1380530d68baSNigel Croxon p2 = Buffer;
1381530d68baSNigel Croxon
1382530d68baSNigel Croxon if (v < 0) {
1383530d68baSNigel Croxon *(p2++) = '-';
1384530d68baSNigel Croxon v = -v;
1385530d68baSNigel Croxon }
1386530d68baSNigel Croxon
1387530d68baSNigel Croxon while (v) {
1388530d68baSNigel Croxon v = (INT64)DivU64x32 ((UINT64)v, 10, &r);
1389530d68baSNigel Croxon *(p1++) = (CHAR8)r + '0';
1390530d68baSNigel Croxon }
1391530d68baSNigel Croxon
13924ef18335SPete Batard c = (UINTN) (Comma ? ca[(p1 - str) % 3] : 999) + 1;
1393530d68baSNigel Croxon while (p1 != str) {
1394530d68baSNigel Croxon
1395530d68baSNigel Croxon c -= 1;
1396530d68baSNigel Croxon if (!c) {
1397530d68baSNigel Croxon *(p2++) = ',';
1398530d68baSNigel Croxon c = 3;
1399530d68baSNigel Croxon }
1400530d68baSNigel Croxon
1401530d68baSNigel Croxon *(p2++) = *(--p1);
1402530d68baSNigel Croxon }
1403530d68baSNigel Croxon *p2 = 0;
1404530d68baSNigel Croxon }
1405530d68baSNigel Croxon
1406530d68baSNigel Croxon VOID
FloatToString(IN CHAR16 * Buffer,IN BOOLEAN Comma,IN double v)1407b2c4db06SNigel Croxon FloatToString (
1408b2c4db06SNigel Croxon IN CHAR16 *Buffer,
1409b2c4db06SNigel Croxon IN BOOLEAN Comma,
1410b2c4db06SNigel Croxon IN double v
1411b2c4db06SNigel Croxon )
1412b2c4db06SNigel Croxon {
1413b2c4db06SNigel Croxon /*
1414b2c4db06SNigel Croxon * Integer part.
1415b2c4db06SNigel Croxon */
1416b2c4db06SNigel Croxon INTN i = (INTN)v;
1417b2c4db06SNigel Croxon ValueToString(Buffer, Comma, i);
1418b2c4db06SNigel Croxon
1419b2c4db06SNigel Croxon
1420b2c4db06SNigel Croxon /*
1421b2c4db06SNigel Croxon * Decimal point.
1422b2c4db06SNigel Croxon */
1423b2c4db06SNigel Croxon UINTN x = StrLen(Buffer);
1424b2c4db06SNigel Croxon Buffer[x] = L'.';
142544d9ae19SNigel Croxon x++;
1426b2c4db06SNigel Croxon
1427b2c4db06SNigel Croxon
1428b2c4db06SNigel Croxon /*
142944d9ae19SNigel Croxon * Keep fractional part.
1430b2c4db06SNigel Croxon */
143193ef2655SNigel Croxon float f = (float)(v - i);
1432b2c4db06SNigel Croxon if (f < 0) f = -f;
143344d9ae19SNigel Croxon
143444d9ae19SNigel Croxon
143544d9ae19SNigel Croxon /*
143644d9ae19SNigel Croxon * Leading fractional zeroes.
143744d9ae19SNigel Croxon */
143844d9ae19SNigel Croxon f *= 10.0;
143944d9ae19SNigel Croxon while ( (f != 0)
144044d9ae19SNigel Croxon && ((INTN)f == 0))
144144d9ae19SNigel Croxon {
144244d9ae19SNigel Croxon Buffer[x] = L'0';
144344d9ae19SNigel Croxon x++;
144444d9ae19SNigel Croxon f *= 10.0;
144544d9ae19SNigel Croxon }
144644d9ae19SNigel Croxon
144744d9ae19SNigel Croxon
144844d9ae19SNigel Croxon /*
144944d9ae19SNigel Croxon * Fractional digits.
145044d9ae19SNigel Croxon */
1451b2c4db06SNigel Croxon while ((float)(INTN)f != f)
1452b2c4db06SNigel Croxon {
1453b2c4db06SNigel Croxon f *= 10;
1454b2c4db06SNigel Croxon }
145544d9ae19SNigel Croxon ValueToString(Buffer + x, FALSE, (INTN)f);
1456b2c4db06SNigel Croxon return;
1457b2c4db06SNigel Croxon }
1458b2c4db06SNigel Croxon
1459b2c4db06SNigel Croxon VOID
TimeToString(OUT CHAR16 * Buffer,IN EFI_TIME * Time)1460530d68baSNigel Croxon TimeToString (
1461530d68baSNigel Croxon OUT CHAR16 *Buffer,
1462530d68baSNigel Croxon IN EFI_TIME *Time
1463530d68baSNigel Croxon )
1464530d68baSNigel Croxon {
1465530d68baSNigel Croxon UINTN Hour, Year;
1466530d68baSNigel Croxon CHAR16 AmPm;
1467530d68baSNigel Croxon
1468530d68baSNigel Croxon AmPm = 'a';
1469530d68baSNigel Croxon Hour = Time->Hour;
1470530d68baSNigel Croxon if (Time->Hour == 0) {
1471530d68baSNigel Croxon Hour = 12;
1472530d68baSNigel Croxon } else if (Time->Hour >= 12) {
1473530d68baSNigel Croxon AmPm = 'p';
1474530d68baSNigel Croxon if (Time->Hour >= 13) {
1475530d68baSNigel Croxon Hour -= 12;
1476530d68baSNigel Croxon }
1477530d68baSNigel Croxon }
1478530d68baSNigel Croxon
1479530d68baSNigel Croxon Year = Time->Year % 100;
1480530d68baSNigel Croxon
1481530d68baSNigel Croxon // bugbug: for now just print it any old way
1482b39be0d5SPete Batard UnicodeSPrint (Buffer, 0, L"%02d/%02d/%02d %02d:%02d%c",
1483530d68baSNigel Croxon Time->Month,
1484530d68baSNigel Croxon Time->Day,
1485530d68baSNigel Croxon Year,
1486530d68baSNigel Croxon Hour,
1487530d68baSNigel Croxon Time->Minute,
1488530d68baSNigel Croxon AmPm
1489530d68baSNigel Croxon );
1490530d68baSNigel Croxon }
1491530d68baSNigel Croxon
1492530d68baSNigel Croxon
1493530d68baSNigel Croxon
1494530d68baSNigel Croxon
1495530d68baSNigel Croxon VOID
DumpHex(IN UINTN Indent,IN UINTN Offset,IN UINTN DataSize,IN VOID * UserData)1496530d68baSNigel Croxon DumpHex (
1497530d68baSNigel Croxon IN UINTN Indent,
1498530d68baSNigel Croxon IN UINTN Offset,
1499530d68baSNigel Croxon IN UINTN DataSize,
1500530d68baSNigel Croxon IN VOID *UserData
1501530d68baSNigel Croxon )
1502530d68baSNigel Croxon {
1503530d68baSNigel Croxon CHAR8 *Data, Val[50], Str[20], c;
1504530d68baSNigel Croxon UINTN Size, Index;
1505530d68baSNigel Croxon
1506530d68baSNigel Croxon UINTN ScreenCount;
1507530d68baSNigel Croxon UINTN TempColumn;
1508530d68baSNigel Croxon UINTN ScreenSize;
1509530d68baSNigel Croxon CHAR16 ReturnStr[1];
1510530d68baSNigel Croxon
1511530d68baSNigel Croxon
1512530d68baSNigel Croxon uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
1513530d68baSNigel Croxon ScreenCount = 0;
1514530d68baSNigel Croxon ScreenSize -= 2;
1515530d68baSNigel Croxon
1516530d68baSNigel Croxon Data = UserData;
1517530d68baSNigel Croxon while (DataSize) {
1518530d68baSNigel Croxon Size = 16;
1519530d68baSNigel Croxon if (Size > DataSize) {
1520530d68baSNigel Croxon Size = DataSize;
1521530d68baSNigel Croxon }
1522530d68baSNigel Croxon
1523530d68baSNigel Croxon for (Index=0; Index < Size; Index += 1) {
1524530d68baSNigel Croxon c = Data[Index];
1525530d68baSNigel Croxon Val[Index*3+0] = Hex[c>>4];
1526530d68baSNigel Croxon Val[Index*3+1] = Hex[c&0xF];
1527530d68baSNigel Croxon Val[Index*3+2] = (Index == 7)?'-':' ';
1528530d68baSNigel Croxon Str[Index] = (c < ' ' || c > 'z') ? '.' : c;
1529530d68baSNigel Croxon }
1530530d68baSNigel Croxon
1531530d68baSNigel Croxon Val[Index*3] = 0;
1532530d68baSNigel Croxon Str[Index] = 0;
1533530d68baSNigel Croxon Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str);
1534530d68baSNigel Croxon
1535530d68baSNigel Croxon Data += Size;
1536530d68baSNigel Croxon Offset += Size;
1537530d68baSNigel Croxon DataSize -= Size;
1538530d68baSNigel Croxon
1539530d68baSNigel Croxon ScreenCount++;
1540530d68baSNigel Croxon if (ScreenCount >= ScreenSize && ScreenSize != 0) {
1541530d68baSNigel Croxon //
1542530d68baSNigel Croxon // If ScreenSize == 0 we have the console redirected so don't
1543530d68baSNigel Croxon // block updates
1544530d68baSNigel Croxon //
1545530d68baSNigel Croxon ScreenCount = 0;
1546530d68baSNigel Croxon Print (L"Press Enter to continue :");
1547530d68baSNigel Croxon Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
1548530d68baSNigel Croxon Print (L"\n");
1549530d68baSNigel Croxon }
1550530d68baSNigel Croxon
1551530d68baSNigel Croxon }
1552530d68baSNigel Croxon }
1553