print.c revision 1.2 1 1.2 jmcneill /* $NetBSD: print.c,v 1.2 2018/08/19 14:50:24 jmcneill Exp $ */
2 1.1 jakllsch
3 1.1 jakllsch /*++
4 1.1 jakllsch
5 1.1 jakllsch Copyright (c) 1998 Intel Corporation
6 1.1 jakllsch
7 1.1 jakllsch Module Name:
8 1.1 jakllsch
9 1.1 jakllsch print.c
10 1.1 jakllsch
11 1.1 jakllsch Abstract:
12 1.1 jakllsch
13 1.1 jakllsch
14 1.1 jakllsch
15 1.1 jakllsch
16 1.1 jakllsch Revision History
17 1.1 jakllsch
18 1.1 jakllsch --*/
19 1.1 jakllsch
20 1.1 jakllsch #include "lib.h"
21 1.1 jakllsch #include "efistdarg.h" // !!!
22 1.1 jakllsch
23 1.1 jakllsch //
24 1.1 jakllsch // Declare runtime functions
25 1.1 jakllsch //
26 1.1 jakllsch
27 1.1 jakllsch #ifdef RUNTIME_CODE
28 1.1 jakllsch #ifndef __GNUC__
29 1.1 jakllsch #pragma RUNTIME_CODE(DbgPrint)
30 1.1 jakllsch
31 1.1 jakllsch // For debugging..
32 1.1 jakllsch
33 1.1 jakllsch /*
34 1.1 jakllsch #pragma RUNTIME_CODE(_Print)
35 1.1 jakllsch #pragma RUNTIME_CODE(PFLUSH)
36 1.1 jakllsch #pragma RUNTIME_CODE(PSETATTR)
37 1.1 jakllsch #pragma RUNTIME_CODE(PPUTC)
38 1.1 jakllsch #pragma RUNTIME_CODE(PGETC)
39 1.1 jakllsch #pragma RUNTIME_CODE(PITEM)
40 1.1 jakllsch #pragma RUNTIME_CODE(ValueToHex)
41 1.1 jakllsch #pragma RUNTIME_CODE(ValueToString)
42 1.1 jakllsch #pragma RUNTIME_CODE(TimeToString)
43 1.1 jakllsch */
44 1.1 jakllsch
45 1.1 jakllsch #endif /* !defined(__GNUC__) */
46 1.1 jakllsch #endif
47 1.1 jakllsch
48 1.1 jakllsch //
49 1.1 jakllsch //
50 1.1 jakllsch //
51 1.1 jakllsch
52 1.1 jakllsch
53 1.1 jakllsch #define PRINT_STRING_LEN 200
54 1.1 jakllsch #define PRINT_ITEM_BUFFER_LEN 100
55 1.1 jakllsch
56 1.1 jakllsch typedef struct {
57 1.1 jakllsch BOOLEAN Ascii;
58 1.1 jakllsch UINTN Index;
59 1.1 jakllsch union {
60 1.2 jmcneill CONST CHAR16 *pw;
61 1.2 jmcneill CONST CHAR8 *pc;
62 1.1 jakllsch } un;
63 1.1 jakllsch } POINTER;
64 1.1 jakllsch
65 1.1 jakllsch #define pw un.pw
66 1.1 jakllsch #define pc un.pc
67 1.1 jakllsch
68 1.1 jakllsch typedef struct _pitem {
69 1.1 jakllsch
70 1.1 jakllsch POINTER Item;
71 1.1 jakllsch CHAR16 Scratch[PRINT_ITEM_BUFFER_LEN];
72 1.1 jakllsch UINTN Width;
73 1.1 jakllsch UINTN FieldWidth;
74 1.1 jakllsch UINTN *WidthParse;
75 1.1 jakllsch CHAR16 Pad;
76 1.1 jakllsch BOOLEAN PadBefore;
77 1.1 jakllsch BOOLEAN Comma;
78 1.1 jakllsch BOOLEAN Long;
79 1.1 jakllsch } PRINT_ITEM;
80 1.1 jakllsch
81 1.1 jakllsch
82 1.1 jakllsch typedef struct _pstate {
83 1.1 jakllsch // Input
84 1.1 jakllsch POINTER fmt;
85 1.1 jakllsch va_list args;
86 1.1 jakllsch
87 1.1 jakllsch // Output
88 1.1 jakllsch CHAR16 *Buffer;
89 1.1 jakllsch CHAR16 *End;
90 1.1 jakllsch CHAR16 *Pos;
91 1.1 jakllsch UINTN Len;
92 1.1 jakllsch
93 1.2 jmcneill UINTN Attr;
94 1.1 jakllsch UINTN RestoreAttr;
95 1.1 jakllsch
96 1.1 jakllsch UINTN AttrNorm;
97 1.1 jakllsch UINTN AttrHighlight;
98 1.1 jakllsch UINTN AttrError;
99 1.1 jakllsch
100 1.2 jmcneill INTN (EFIAPI *Output)(VOID *context, CHAR16 *str);
101 1.2 jmcneill INTN (EFIAPI *SetAttr)(VOID *context, UINTN attr);
102 1.2 jmcneill VOID *Context;
103 1.1 jakllsch
104 1.1 jakllsch // Current item being formatted
105 1.1 jakllsch struct _pitem *Item;
106 1.1 jakllsch } PRINT_STATE;
107 1.1 jakllsch
108 1.1 jakllsch //
109 1.1 jakllsch // Internal fucntions
110 1.1 jakllsch //
111 1.1 jakllsch
112 1.1 jakllsch STATIC
113 1.1 jakllsch UINTN
114 1.1 jakllsch _Print (
115 1.1 jakllsch IN PRINT_STATE *ps
116 1.1 jakllsch );
117 1.1 jakllsch
118 1.1 jakllsch STATIC
119 1.1 jakllsch UINTN
120 1.1 jakllsch _IPrint (
121 1.1 jakllsch IN UINTN Column,
122 1.1 jakllsch IN UINTN Row,
123 1.1 jakllsch IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
124 1.2 jmcneill IN CONST CHAR16 *fmt,
125 1.2 jmcneill IN CONST CHAR8 *fmta,
126 1.1 jakllsch IN va_list args
127 1.1 jakllsch );
128 1.1 jakllsch
129 1.1 jakllsch STATIC
130 1.1 jakllsch INTN EFIAPI
131 1.1 jakllsch _DbgOut (
132 1.1 jakllsch IN VOID *Context,
133 1.1 jakllsch IN CHAR16 *Buffer
134 1.1 jakllsch );
135 1.1 jakllsch
136 1.1 jakllsch STATIC
137 1.1 jakllsch VOID
138 1.1 jakllsch PFLUSH (
139 1.1 jakllsch IN OUT PRINT_STATE *ps
140 1.1 jakllsch );
141 1.1 jakllsch
142 1.1 jakllsch STATIC
143 1.1 jakllsch VOID
144 1.1 jakllsch PPUTC (
145 1.1 jakllsch IN OUT PRINT_STATE *ps,
146 1.1 jakllsch IN CHAR16 c
147 1.1 jakllsch );
148 1.1 jakllsch
149 1.1 jakllsch STATIC
150 1.1 jakllsch VOID
151 1.1 jakllsch PITEM (
152 1.1 jakllsch IN OUT PRINT_STATE *ps
153 1.1 jakllsch );
154 1.1 jakllsch
155 1.1 jakllsch STATIC
156 1.1 jakllsch CHAR16
157 1.1 jakllsch PGETC (
158 1.1 jakllsch IN POINTER *p
159 1.1 jakllsch );
160 1.1 jakllsch
161 1.1 jakllsch STATIC
162 1.1 jakllsch VOID
163 1.1 jakllsch PSETATTR (
164 1.1 jakllsch IN OUT PRINT_STATE *ps,
165 1.1 jakllsch IN UINTN Attr
166 1.1 jakllsch );
167 1.1 jakllsch
168 1.1 jakllsch //
169 1.1 jakllsch //
170 1.1 jakllsch //
171 1.1 jakllsch
172 1.1 jakllsch INTN EFIAPI
173 1.1 jakllsch _SPrint (
174 1.1 jakllsch IN VOID *Context,
175 1.1 jakllsch IN CHAR16 *Buffer
176 1.1 jakllsch );
177 1.1 jakllsch
178 1.1 jakllsch INTN EFIAPI
179 1.1 jakllsch _PoolPrint (
180 1.1 jakllsch IN VOID *Context,
181 1.1 jakllsch IN CHAR16 *Buffer
182 1.1 jakllsch );
183 1.1 jakllsch
184 1.1 jakllsch INTN
185 1.1 jakllsch DbgPrint (
186 1.2 jmcneill IN INTN mask,
187 1.2 jmcneill IN CONST CHAR8 *fmt,
188 1.1 jakllsch ...
189 1.1 jakllsch )
190 1.1 jakllsch /*++
191 1.1 jakllsch
192 1.1 jakllsch Routine Description:
193 1.1 jakllsch
194 1.1 jakllsch Prints a formatted unicode string to the default StandardError console
195 1.1 jakllsch
196 1.1 jakllsch Arguments:
197 1.1 jakllsch
198 1.1 jakllsch mask - Bit mask of debug string. If a bit is set in the
199 1.2 jmcneill mask that is also set in EFIDebug the string is
200 1.1 jakllsch printed; otherwise, the string is not printed
201 1.1 jakllsch
202 1.1 jakllsch fmt - Format string
203 1.1 jakllsch
204 1.1 jakllsch Returns:
205 1.1 jakllsch
206 1.1 jakllsch Length of string printed to the StandardError console
207 1.1 jakllsch
208 1.1 jakllsch --*/
209 1.1 jakllsch {
210 1.1 jakllsch SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
211 1.1 jakllsch PRINT_STATE ps;
212 1.1 jakllsch va_list args;
213 1.1 jakllsch UINTN back;
214 1.1 jakllsch UINTN attr;
215 1.1 jakllsch UINTN SavedAttribute;
216 1.1 jakllsch
217 1.1 jakllsch
218 1.1 jakllsch if (!(EFIDebug & mask)) {
219 1.1 jakllsch return 0;
220 1.1 jakllsch }
221 1.1 jakllsch
222 1.1 jakllsch va_start (args, fmt);
223 1.1 jakllsch ZeroMem (&ps, sizeof(ps));
224 1.1 jakllsch
225 1.2 jmcneill ps.Output = _DbgOut;
226 1.1 jakllsch ps.fmt.Ascii = TRUE;
227 1.1 jakllsch ps.fmt.pc = fmt;
228 1.1 jakllsch va_copy(ps.args, args);
229 1.2 jmcneill ps.Attr = EFI_TEXT_ATTR(EFI_LIGHTGRAY, EFI_RED);
230 1.1 jakllsch
231 1.1 jakllsch DbgOut = LibRuntimeDebugOut;
232 1.1 jakllsch
233 1.1 jakllsch if (!DbgOut) {
234 1.1 jakllsch DbgOut = ST->StdErr;
235 1.1 jakllsch }
236 1.1 jakllsch
237 1.1 jakllsch if (DbgOut) {
238 1.1 jakllsch ps.Attr = DbgOut->Mode->Attribute;
239 1.1 jakllsch ps.Context = DbgOut;
240 1.2 jmcneill ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) DbgOut->SetAttribute;
241 1.1 jakllsch }
242 1.1 jakllsch
243 1.1 jakllsch SavedAttribute = ps.Attr;
244 1.1 jakllsch
245 1.1 jakllsch back = (ps.Attr >> 4) & 0xf;
246 1.1 jakllsch ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
247 1.1 jakllsch ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
248 1.1 jakllsch ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
249 1.1 jakllsch
250 1.1 jakllsch attr = ps.AttrNorm;
251 1.1 jakllsch
252 1.1 jakllsch if (mask & D_WARN) {
253 1.1 jakllsch attr = ps.AttrHighlight;
254 1.1 jakllsch }
255 1.1 jakllsch
256 1.1 jakllsch if (mask & D_ERROR) {
257 1.1 jakllsch attr = ps.AttrError;
258 1.1 jakllsch }
259 1.1 jakllsch
260 1.1 jakllsch if (ps.SetAttr) {
261 1.1 jakllsch ps.Attr = attr;
262 1.2 jmcneill uefi_call_wrapper(ps.SetAttr, 2, ps.Context, attr);
263 1.1 jakllsch }
264 1.1 jakllsch
265 1.1 jakllsch _Print (&ps);
266 1.1 jakllsch
267 1.1 jakllsch va_end (ps.args);
268 1.1 jakllsch va_end (args);
269 1.1 jakllsch
270 1.1 jakllsch //
271 1.1 jakllsch // Restore original attributes
272 1.1 jakllsch //
273 1.1 jakllsch
274 1.1 jakllsch if (ps.SetAttr) {
275 1.2 jmcneill uefi_call_wrapper(ps.SetAttr, 2, ps.Context, SavedAttribute);
276 1.1 jakllsch }
277 1.2 jmcneill
278 1.1 jakllsch return 0;
279 1.1 jakllsch }
280 1.1 jakllsch
281 1.1 jakllsch STATIC
282 1.1 jakllsch INTN
283 1.1 jakllsch IsLocalPrint(void *func)
284 1.1 jakllsch {
285 1.1 jakllsch if (func == _DbgOut || func == _SPrint || func == _PoolPrint)
286 1.1 jakllsch return 1;
287 1.1 jakllsch return 0;
288 1.1 jakllsch }
289 1.1 jakllsch
290 1.1 jakllsch STATIC
291 1.1 jakllsch INTN EFIAPI
292 1.1 jakllsch _DbgOut (
293 1.1 jakllsch IN VOID *Context,
294 1.1 jakllsch IN CHAR16 *Buffer
295 1.1 jakllsch )
296 1.1 jakllsch // Append string worker for DbgPrint
297 1.1 jakllsch {
298 1.1 jakllsch SIMPLE_TEXT_OUTPUT_INTERFACE *DbgOut;
299 1.1 jakllsch
300 1.1 jakllsch DbgOut = Context;
301 1.1 jakllsch // if (!DbgOut && ST && ST->ConOut) {
302 1.1 jakllsch // DbgOut = ST->ConOut;
303 1.1 jakllsch // }
304 1.1 jakllsch
305 1.1 jakllsch if (DbgOut) {
306 1.1 jakllsch if (IsLocalPrint(DbgOut->OutputString))
307 1.1 jakllsch DbgOut->OutputString(DbgOut, Buffer);
308 1.1 jakllsch else
309 1.1 jakllsch uefi_call_wrapper(DbgOut->OutputString, 2, DbgOut, Buffer);
310 1.1 jakllsch }
311 1.1 jakllsch
312 1.1 jakllsch return 0;
313 1.1 jakllsch }
314 1.1 jakllsch
315 1.1 jakllsch INTN EFIAPI
316 1.1 jakllsch _SPrint (
317 1.1 jakllsch IN VOID *Context,
318 1.1 jakllsch IN CHAR16 *Buffer
319 1.1 jakllsch )
320 1.1 jakllsch // Append string worker for SPrint, PoolPrint and CatPrint
321 1.1 jakllsch {
322 1.1 jakllsch UINTN len;
323 1.1 jakllsch POOL_PRINT *spc;
324 1.1 jakllsch
325 1.1 jakllsch spc = Context;
326 1.1 jakllsch len = StrLen(Buffer);
327 1.1 jakllsch
328 1.1 jakllsch //
329 1.1 jakllsch // Is the string is over the max truncate it
330 1.1 jakllsch //
331 1.1 jakllsch
332 1.1 jakllsch if (spc->len + len > spc->maxlen) {
333 1.1 jakllsch len = spc->maxlen - spc->len;
334 1.1 jakllsch }
335 1.1 jakllsch
336 1.1 jakllsch //
337 1.1 jakllsch // Append the new text
338 1.1 jakllsch //
339 1.1 jakllsch
340 1.1 jakllsch CopyMem (spc->str + spc->len, Buffer, len * sizeof(CHAR16));
341 1.1 jakllsch spc->len += len;
342 1.1 jakllsch
343 1.1 jakllsch //
344 1.1 jakllsch // Null terminate it
345 1.1 jakllsch //
346 1.1 jakllsch
347 1.1 jakllsch if (spc->len < spc->maxlen) {
348 1.1 jakllsch spc->str[spc->len] = 0;
349 1.1 jakllsch } else if (spc->maxlen) {
350 1.2 jmcneill spc->str[spc->maxlen] = 0;
351 1.1 jakllsch }
352 1.1 jakllsch
353 1.1 jakllsch return 0;
354 1.1 jakllsch }
355 1.1 jakllsch
356 1.1 jakllsch
357 1.1 jakllsch INTN EFIAPI
358 1.1 jakllsch _PoolPrint (
359 1.1 jakllsch IN VOID *Context,
360 1.1 jakllsch IN CHAR16 *Buffer
361 1.1 jakllsch )
362 1.1 jakllsch // Append string worker for PoolPrint and CatPrint
363 1.1 jakllsch {
364 1.1 jakllsch UINTN newlen;
365 1.1 jakllsch POOL_PRINT *spc;
366 1.1 jakllsch
367 1.1 jakllsch spc = Context;
368 1.1 jakllsch newlen = spc->len + StrLen(Buffer) + 1;
369 1.1 jakllsch
370 1.1 jakllsch //
371 1.1 jakllsch // Is the string is over the max, grow the buffer
372 1.1 jakllsch //
373 1.1 jakllsch
374 1.1 jakllsch if (newlen > spc->maxlen) {
375 1.1 jakllsch
376 1.1 jakllsch //
377 1.1 jakllsch // Grow the pool buffer
378 1.1 jakllsch //
379 1.1 jakllsch
380 1.1 jakllsch newlen += PRINT_STRING_LEN;
381 1.1 jakllsch spc->maxlen = newlen;
382 1.1 jakllsch spc->str = ReallocatePool (
383 1.2 jmcneill spc->str,
384 1.2 jmcneill spc->len * sizeof(CHAR16),
385 1.1 jakllsch spc->maxlen * sizeof(CHAR16)
386 1.1 jakllsch );
387 1.1 jakllsch
388 1.1 jakllsch if (!spc->str) {
389 1.1 jakllsch spc->len = 0;
390 1.1 jakllsch spc->maxlen = 0;
391 1.1 jakllsch }
392 1.1 jakllsch }
393 1.1 jakllsch
394 1.1 jakllsch //
395 1.1 jakllsch // Append the new text
396 1.1 jakllsch //
397 1.1 jakllsch
398 1.1 jakllsch return _SPrint (Context, Buffer);
399 1.1 jakllsch }
400 1.1 jakllsch
401 1.1 jakllsch
402 1.1 jakllsch
403 1.1 jakllsch VOID
404 1.1 jakllsch _PoolCatPrint (
405 1.2 jmcneill IN CONST CHAR16 *fmt,
406 1.1 jakllsch IN va_list args,
407 1.1 jakllsch IN OUT POOL_PRINT *spc,
408 1.2 jmcneill IN INTN (EFIAPI *Output)(VOID *context, CHAR16 *str)
409 1.1 jakllsch )
410 1.1 jakllsch // Dispath function for SPrint, PoolPrint, and CatPrint
411 1.1 jakllsch {
412 1.1 jakllsch PRINT_STATE ps;
413 1.1 jakllsch
414 1.1 jakllsch ZeroMem (&ps, sizeof(ps));
415 1.1 jakllsch ps.Output = Output;
416 1.1 jakllsch ps.Context = spc;
417 1.1 jakllsch ps.fmt.pw = fmt;
418 1.1 jakllsch va_copy(ps.args, args);
419 1.1 jakllsch _Print (&ps);
420 1.1 jakllsch va_end(ps.args);
421 1.1 jakllsch }
422 1.1 jakllsch
423 1.1 jakllsch
424 1.1 jakllsch
425 1.1 jakllsch UINTN
426 1.2 jmcneill VSPrint (
427 1.2 jmcneill OUT CHAR16 *Str,
428 1.2 jmcneill IN UINTN StrSize,
429 1.2 jmcneill IN CONST CHAR16 *fmt,
430 1.2 jmcneill va_list args
431 1.1 jakllsch )
432 1.1 jakllsch /*++
433 1.1 jakllsch
434 1.1 jakllsch Routine Description:
435 1.1 jakllsch
436 1.2 jmcneill Prints a formatted unicode string to a buffer using a va_list
437 1.1 jakllsch
438 1.1 jakllsch Arguments:
439 1.1 jakllsch
440 1.1 jakllsch Str - Output buffer to print the formatted string into
441 1.1 jakllsch
442 1.1 jakllsch StrSize - Size of Str. String is truncated to this size.
443 1.1 jakllsch A size of 0 means there is no limit
444 1.1 jakllsch
445 1.1 jakllsch fmt - The format string
446 1.1 jakllsch
447 1.2 jmcneill args - va_list
448 1.2 jmcneill
449 1.2 jmcneill
450 1.1 jakllsch Returns:
451 1.1 jakllsch
452 1.1 jakllsch String length returned in buffer
453 1.1 jakllsch
454 1.1 jakllsch --*/
455 1.1 jakllsch {
456 1.1 jakllsch POOL_PRINT spc;
457 1.1 jakllsch
458 1.1 jakllsch spc.str = Str;
459 1.1 jakllsch spc.maxlen = StrSize / sizeof(CHAR16) - 1;
460 1.1 jakllsch spc.len = 0;
461 1.1 jakllsch
462 1.1 jakllsch _PoolCatPrint (fmt, args, &spc, _SPrint);
463 1.2 jmcneill
464 1.2 jmcneill return spc.len;
465 1.2 jmcneill }
466 1.2 jmcneill
467 1.2 jmcneill UINTN
468 1.2 jmcneill SPrint (
469 1.2 jmcneill OUT CHAR16 *Str,
470 1.2 jmcneill IN UINTN StrSize,
471 1.2 jmcneill IN CONST CHAR16 *fmt,
472 1.2 jmcneill ...
473 1.2 jmcneill )
474 1.2 jmcneill /*++
475 1.2 jmcneill
476 1.2 jmcneill Routine Description:
477 1.2 jmcneill
478 1.2 jmcneill Prints a formatted unicode string to a buffer
479 1.2 jmcneill
480 1.2 jmcneill Arguments:
481 1.2 jmcneill
482 1.2 jmcneill Str - Output buffer to print the formatted string into
483 1.2 jmcneill
484 1.2 jmcneill StrSize - Size of Str. String is truncated to this size.
485 1.2 jmcneill A size of 0 means there is no limit
486 1.2 jmcneill
487 1.2 jmcneill fmt - The format string
488 1.2 jmcneill
489 1.2 jmcneill Returns:
490 1.2 jmcneill
491 1.2 jmcneill String length returned in buffer
492 1.2 jmcneill
493 1.2 jmcneill --*/
494 1.2 jmcneill {
495 1.2 jmcneill va_list args;
496 1.2 jmcneill UINTN len;
497 1.2 jmcneill
498 1.2 jmcneill va_start (args, fmt);
499 1.2 jmcneill len = VSPrint(Str, StrSize, fmt, args);
500 1.1 jakllsch va_end (args);
501 1.2 jmcneill
502 1.2 jmcneill return len;
503 1.1 jakllsch }
504 1.1 jakllsch
505 1.2 jmcneill CHAR16 *
506 1.2 jmcneill VPoolPrint (
507 1.2 jmcneill IN CONST CHAR16 *fmt,
508 1.2 jmcneill va_list args
509 1.2 jmcneill )
510 1.2 jmcneill /*++
511 1.2 jmcneill
512 1.2 jmcneill Routine Description:
513 1.2 jmcneill
514 1.2 jmcneill Prints a formatted unicode string to allocated pool using va_list argument.
515 1.2 jmcneill The caller must free the resulting buffer.
516 1.2 jmcneill
517 1.2 jmcneill Arguments:
518 1.2 jmcneill
519 1.2 jmcneill fmt - The format string
520 1.2 jmcneill args - The arguments in va_list form
521 1.2 jmcneill
522 1.2 jmcneill Returns:
523 1.2 jmcneill
524 1.2 jmcneill Allocated buffer with the formatted string printed in it.
525 1.2 jmcneill The caller must free the allocated buffer. The buffer
526 1.2 jmcneill allocation is not packed.
527 1.2 jmcneill
528 1.2 jmcneill --*/
529 1.2 jmcneill {
530 1.2 jmcneill POOL_PRINT spc;
531 1.2 jmcneill ZeroMem (&spc, sizeof(spc));
532 1.2 jmcneill _PoolCatPrint (fmt, args, &spc, _PoolPrint);
533 1.2 jmcneill return spc.str;
534 1.2 jmcneill }
535 1.1 jakllsch
536 1.1 jakllsch CHAR16 *
537 1.1 jakllsch PoolPrint (
538 1.2 jmcneill IN CONST CHAR16 *fmt,
539 1.1 jakllsch ...
540 1.1 jakllsch )
541 1.1 jakllsch /*++
542 1.1 jakllsch
543 1.1 jakllsch Routine Description:
544 1.1 jakllsch
545 1.1 jakllsch Prints a formatted unicode string to allocated pool. The caller
546 1.1 jakllsch must free the resulting buffer.
547 1.1 jakllsch
548 1.1 jakllsch Arguments:
549 1.1 jakllsch
550 1.1 jakllsch fmt - The format string
551 1.1 jakllsch
552 1.1 jakllsch Returns:
553 1.1 jakllsch
554 1.2 jmcneill Allocated buffer with the formatted string printed in it.
555 1.1 jakllsch The caller must free the allocated buffer. The buffer
556 1.1 jakllsch allocation is not packed.
557 1.1 jakllsch
558 1.1 jakllsch --*/
559 1.1 jakllsch {
560 1.2 jmcneill va_list args;
561 1.2 jmcneill CHAR16 *pool;
562 1.1 jakllsch va_start (args, fmt);
563 1.2 jmcneill pool = VPoolPrint(fmt, args);
564 1.1 jakllsch va_end (args);
565 1.2 jmcneill return pool;
566 1.1 jakllsch }
567 1.1 jakllsch
568 1.1 jakllsch CHAR16 *
569 1.1 jakllsch CatPrint (
570 1.1 jakllsch IN OUT POOL_PRINT *Str,
571 1.2 jmcneill IN CONST CHAR16 *fmt,
572 1.1 jakllsch ...
573 1.1 jakllsch )
574 1.1 jakllsch /*++
575 1.1 jakllsch
576 1.1 jakllsch Routine Description:
577 1.1 jakllsch
578 1.2 jmcneill Concatenates a formatted unicode string to allocated pool.
579 1.1 jakllsch The caller must free the resulting buffer.
580 1.1 jakllsch
581 1.1 jakllsch Arguments:
582 1.1 jakllsch
583 1.2 jmcneill Str - Tracks the allocated pool, size in use, and
584 1.1 jakllsch amount of pool allocated.
585 1.1 jakllsch
586 1.1 jakllsch fmt - The format string
587 1.1 jakllsch
588 1.1 jakllsch Returns:
589 1.1 jakllsch
590 1.2 jmcneill Allocated buffer with the formatted string printed in it.
591 1.1 jakllsch The caller must free the allocated buffer. The buffer
592 1.1 jakllsch allocation is not packed.
593 1.1 jakllsch
594 1.1 jakllsch --*/
595 1.1 jakllsch {
596 1.1 jakllsch va_list args;
597 1.1 jakllsch
598 1.1 jakllsch va_start (args, fmt);
599 1.1 jakllsch _PoolCatPrint (fmt, args, Str, _PoolPrint);
600 1.1 jakllsch va_end (args);
601 1.1 jakllsch return Str->str;
602 1.1 jakllsch }
603 1.1 jakllsch
604 1.1 jakllsch
605 1.1 jakllsch
606 1.1 jakllsch UINTN
607 1.1 jakllsch Print (
608 1.2 jmcneill IN CONST CHAR16 *fmt,
609 1.1 jakllsch ...
610 1.1 jakllsch )
611 1.1 jakllsch /*++
612 1.1 jakllsch
613 1.1 jakllsch Routine Description:
614 1.1 jakllsch
615 1.1 jakllsch Prints a formatted unicode string to the default console
616 1.1 jakllsch
617 1.1 jakllsch Arguments:
618 1.1 jakllsch
619 1.1 jakllsch fmt - Format string
620 1.1 jakllsch
621 1.1 jakllsch Returns:
622 1.1 jakllsch
623 1.1 jakllsch Length of string printed to the console
624 1.1 jakllsch
625 1.1 jakllsch --*/
626 1.1 jakllsch {
627 1.1 jakllsch va_list args;
628 1.1 jakllsch UINTN back;
629 1.1 jakllsch
630 1.1 jakllsch va_start (args, fmt);
631 1.1 jakllsch back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
632 1.1 jakllsch va_end (args);
633 1.1 jakllsch return back;
634 1.1 jakllsch }
635 1.1 jakllsch
636 1.1 jakllsch UINTN
637 1.1 jakllsch VPrint (
638 1.2 jmcneill IN CONST CHAR16 *fmt,
639 1.2 jmcneill va_list args
640 1.1 jakllsch )
641 1.1 jakllsch /*++
642 1.1 jakllsch
643 1.1 jakllsch Routine Description:
644 1.1 jakllsch
645 1.1 jakllsch Prints a formatted unicode string to the default console using a va_list
646 1.1 jakllsch
647 1.1 jakllsch Arguments:
648 1.1 jakllsch
649 1.1 jakllsch fmt - Format string
650 1.1 jakllsch args - va_list
651 1.1 jakllsch Returns:
652 1.1 jakllsch
653 1.1 jakllsch Length of string printed to the console
654 1.1 jakllsch
655 1.1 jakllsch --*/
656 1.1 jakllsch {
657 1.1 jakllsch return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
658 1.1 jakllsch }
659 1.1 jakllsch
660 1.1 jakllsch
661 1.1 jakllsch UINTN
662 1.1 jakllsch PrintAt (
663 1.2 jmcneill IN UINTN Column,
664 1.2 jmcneill IN UINTN Row,
665 1.2 jmcneill IN CONST CHAR16 *fmt,
666 1.1 jakllsch ...
667 1.1 jakllsch )
668 1.1 jakllsch /*++
669 1.1 jakllsch
670 1.1 jakllsch Routine Description:
671 1.1 jakllsch
672 1.2 jmcneill Prints a formatted unicode string to the default console, at
673 1.1 jakllsch the supplied cursor position
674 1.1 jakllsch
675 1.1 jakllsch Arguments:
676 1.1 jakllsch
677 1.1 jakllsch Column, Row - The cursor position to print the string at
678 1.1 jakllsch
679 1.1 jakllsch fmt - Format string
680 1.1 jakllsch
681 1.1 jakllsch Returns:
682 1.1 jakllsch
683 1.1 jakllsch Length of string printed to the console
684 1.1 jakllsch
685 1.1 jakllsch --*/
686 1.1 jakllsch {
687 1.1 jakllsch va_list args;
688 1.1 jakllsch UINTN back;
689 1.1 jakllsch
690 1.1 jakllsch va_start (args, fmt);
691 1.1 jakllsch back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
692 1.1 jakllsch va_end (args);
693 1.1 jakllsch return back;
694 1.1 jakllsch }
695 1.1 jakllsch
696 1.1 jakllsch
697 1.1 jakllsch UINTN
698 1.1 jakllsch IPrint (
699 1.1 jakllsch IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
700 1.2 jmcneill IN CONST CHAR16 *fmt,
701 1.1 jakllsch ...
702 1.1 jakllsch )
703 1.1 jakllsch /*++
704 1.1 jakllsch
705 1.1 jakllsch Routine Description:
706 1.1 jakllsch
707 1.1 jakllsch Prints a formatted unicode string to the specified console
708 1.1 jakllsch
709 1.1 jakllsch Arguments:
710 1.1 jakllsch
711 1.1 jakllsch Out - The console to print the string too
712 1.1 jakllsch
713 1.1 jakllsch fmt - Format string
714 1.1 jakllsch
715 1.1 jakllsch Returns:
716 1.1 jakllsch
717 1.1 jakllsch Length of string printed to the console
718 1.1 jakllsch
719 1.1 jakllsch --*/
720 1.1 jakllsch {
721 1.1 jakllsch va_list args;
722 1.1 jakllsch UINTN back;
723 1.1 jakllsch
724 1.1 jakllsch va_start (args, fmt);
725 1.1 jakllsch back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args);
726 1.1 jakllsch va_end (args);
727 1.1 jakllsch return back;
728 1.1 jakllsch }
729 1.1 jakllsch
730 1.1 jakllsch
731 1.1 jakllsch UINTN
732 1.1 jakllsch IPrintAt (
733 1.1 jakllsch IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
734 1.1 jakllsch IN UINTN Column,
735 1.1 jakllsch IN UINTN Row,
736 1.2 jmcneill IN CONST CHAR16 *fmt,
737 1.1 jakllsch ...
738 1.1 jakllsch )
739 1.1 jakllsch /*++
740 1.1 jakllsch
741 1.1 jakllsch Routine Description:
742 1.1 jakllsch
743 1.1 jakllsch Prints a formatted unicode string to the specified console, at
744 1.1 jakllsch the supplied cursor position
745 1.1 jakllsch
746 1.1 jakllsch Arguments:
747 1.1 jakllsch
748 1.2 jmcneill Out - The console to print the string to
749 1.1 jakllsch
750 1.1 jakllsch Column, Row - The cursor position to print the string at
751 1.1 jakllsch
752 1.1 jakllsch fmt - Format string
753 1.1 jakllsch
754 1.1 jakllsch Returns:
755 1.1 jakllsch
756 1.1 jakllsch Length of string printed to the console
757 1.1 jakllsch
758 1.1 jakllsch --*/
759 1.1 jakllsch {
760 1.1 jakllsch va_list args;
761 1.1 jakllsch UINTN back;
762 1.1 jakllsch
763 1.1 jakllsch va_start (args, fmt);
764 1.2 jmcneill back = _IPrint (Column, Row, Out, fmt, NULL, args);
765 1.1 jakllsch va_end (args);
766 1.1 jakllsch return back;
767 1.1 jakllsch }
768 1.1 jakllsch
769 1.1 jakllsch
770 1.1 jakllsch UINTN
771 1.1 jakllsch _IPrint (
772 1.1 jakllsch IN UINTN Column,
773 1.1 jakllsch IN UINTN Row,
774 1.1 jakllsch IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
775 1.2 jmcneill IN CONST CHAR16 *fmt,
776 1.2 jmcneill IN CONST CHAR8 *fmta,
777 1.1 jakllsch IN va_list args
778 1.1 jakllsch )
779 1.1 jakllsch // Display string worker for: Print, PrintAt, IPrint, IPrintAt
780 1.1 jakllsch {
781 1.1 jakllsch PRINT_STATE ps;
782 1.1 jakllsch UINTN back;
783 1.1 jakllsch
784 1.1 jakllsch ZeroMem (&ps, sizeof(ps));
785 1.1 jakllsch ps.Context = Out;
786 1.2 jmcneill ps.Output = (INTN (EFIAPI *)(VOID *, CHAR16 *)) Out->OutputString;
787 1.2 jmcneill ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) Out->SetAttribute;
788 1.1 jakllsch ps.Attr = Out->Mode->Attribute;
789 1.2 jmcneill
790 1.1 jakllsch back = (ps.Attr >> 4) & 0xF;
791 1.1 jakllsch ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
792 1.1 jakllsch ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
793 1.1 jakllsch ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
794 1.1 jakllsch
795 1.1 jakllsch if (fmt) {
796 1.1 jakllsch ps.fmt.pw = fmt;
797 1.1 jakllsch } else {
798 1.1 jakllsch ps.fmt.Ascii = TRUE;
799 1.1 jakllsch ps.fmt.pc = fmta;
800 1.1 jakllsch }
801 1.1 jakllsch
802 1.1 jakllsch va_copy(ps.args, args);
803 1.1 jakllsch
804 1.1 jakllsch if (Column != (UINTN) -1) {
805 1.1 jakllsch uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row);
806 1.1 jakllsch }
807 1.1 jakllsch
808 1.1 jakllsch back = _Print (&ps);
809 1.1 jakllsch va_end(ps.args);
810 1.1 jakllsch return back;
811 1.1 jakllsch }
812 1.1 jakllsch
813 1.1 jakllsch
814 1.1 jakllsch UINTN
815 1.1 jakllsch APrint (
816 1.2 jmcneill IN CONST CHAR8 *fmt,
817 1.1 jakllsch ...
818 1.1 jakllsch )
819 1.1 jakllsch /*++
820 1.1 jakllsch
821 1.1 jakllsch Routine Description:
822 1.1 jakllsch
823 1.1 jakllsch For those whom really can't deal with unicode, a print
824 1.1 jakllsch function that takes an ascii format string
825 1.1 jakllsch
826 1.1 jakllsch Arguments:
827 1.1 jakllsch
828 1.1 jakllsch fmt - ascii format string
829 1.1 jakllsch
830 1.1 jakllsch Returns:
831 1.1 jakllsch
832 1.1 jakllsch Length of string printed to the console
833 1.1 jakllsch
834 1.1 jakllsch --*/
835 1.1 jakllsch
836 1.1 jakllsch {
837 1.1 jakllsch va_list args;
838 1.1 jakllsch UINTN back;
839 1.1 jakllsch
840 1.1 jakllsch va_start (args, fmt);
841 1.1 jakllsch back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args);
842 1.1 jakllsch va_end (args);
843 1.1 jakllsch return back;
844 1.1 jakllsch }
845 1.1 jakllsch
846 1.1 jakllsch
847 1.1 jakllsch STATIC
848 1.1 jakllsch VOID
849 1.1 jakllsch PFLUSH (
850 1.1 jakllsch IN OUT PRINT_STATE *ps
851 1.1 jakllsch )
852 1.1 jakllsch {
853 1.1 jakllsch *ps->Pos = 0;
854 1.1 jakllsch if (IsLocalPrint(ps->Output))
855 1.2 jmcneill ps->Output(ps->Context, ps->Buffer);
856 1.1 jakllsch else
857 1.1 jakllsch uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer);
858 1.1 jakllsch ps->Pos = ps->Buffer;
859 1.1 jakllsch }
860 1.1 jakllsch
861 1.1 jakllsch STATIC
862 1.1 jakllsch VOID
863 1.1 jakllsch PSETATTR (
864 1.1 jakllsch IN OUT PRINT_STATE *ps,
865 1.1 jakllsch IN UINTN Attr
866 1.1 jakllsch )
867 1.1 jakllsch {
868 1.1 jakllsch PFLUSH (ps);
869 1.1 jakllsch
870 1.1 jakllsch ps->RestoreAttr = ps->Attr;
871 1.1 jakllsch if (ps->SetAttr) {
872 1.1 jakllsch uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr);
873 1.1 jakllsch }
874 1.1 jakllsch
875 1.1 jakllsch ps->Attr = Attr;
876 1.2 jmcneill }
877 1.1 jakllsch
878 1.1 jakllsch STATIC
879 1.1 jakllsch VOID
880 1.1 jakllsch PPUTC (
881 1.1 jakllsch IN OUT PRINT_STATE *ps,
882 1.1 jakllsch IN CHAR16 c
883 1.1 jakllsch )
884 1.1 jakllsch {
885 1.1 jakllsch // if this is a newline, add a carraige return
886 1.1 jakllsch if (c == '\n') {
887 1.1 jakllsch PPUTC (ps, '\r');
888 1.1 jakllsch }
889 1.1 jakllsch
890 1.1 jakllsch *ps->Pos = c;
891 1.1 jakllsch ps->Pos += 1;
892 1.1 jakllsch ps->Len += 1;
893 1.1 jakllsch
894 1.1 jakllsch // if at the end of the buffer, flush it
895 1.1 jakllsch if (ps->Pos >= ps->End) {
896 1.1 jakllsch PFLUSH(ps);
897 1.1 jakllsch }
898 1.1 jakllsch }
899 1.1 jakllsch
900 1.1 jakllsch
901 1.1 jakllsch STATIC
902 1.1 jakllsch CHAR16
903 1.1 jakllsch PGETC (
904 1.1 jakllsch IN POINTER *p
905 1.1 jakllsch )
906 1.1 jakllsch {
907 1.1 jakllsch CHAR16 c;
908 1.1 jakllsch
909 1.1 jakllsch c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index];
910 1.1 jakllsch p->Index += 1;
911 1.1 jakllsch
912 1.1 jakllsch return c;
913 1.1 jakllsch }
914 1.1 jakllsch
915 1.1 jakllsch
916 1.1 jakllsch STATIC
917 1.1 jakllsch VOID
918 1.1 jakllsch PITEM (
919 1.1 jakllsch IN OUT PRINT_STATE *ps
920 1.1 jakllsch )
921 1.1 jakllsch {
922 1.1 jakllsch UINTN Len, i;
923 1.1 jakllsch PRINT_ITEM *Item;
924 1.1 jakllsch CHAR16 c;
925 1.1 jakllsch
926 1.1 jakllsch // Get the length of the item
927 1.1 jakllsch Item = ps->Item;
928 1.1 jakllsch Item->Item.Index = 0;
929 1.1 jakllsch while (Item->Item.Index < Item->FieldWidth) {
930 1.1 jakllsch c = PGETC(&Item->Item);
931 1.1 jakllsch if (!c) {
932 1.1 jakllsch Item->Item.Index -= 1;
933 1.1 jakllsch break;
934 1.1 jakllsch }
935 1.1 jakllsch }
936 1.1 jakllsch Len = Item->Item.Index;
937 1.1 jakllsch
938 1.1 jakllsch // if there is no item field width, use the items width
939 1.1 jakllsch if (Item->FieldWidth == (UINTN) -1) {
940 1.1 jakllsch Item->FieldWidth = Len;
941 1.1 jakllsch }
942 1.1 jakllsch
943 1.1 jakllsch // if item is larger then width, update width
944 1.1 jakllsch if (Len > Item->Width) {
945 1.1 jakllsch Item->Width = Len;
946 1.1 jakllsch }
947 1.1 jakllsch
948 1.1 jakllsch
949 1.1 jakllsch // if pad field before, add pad char
950 1.1 jakllsch if (Item->PadBefore) {
951 1.1 jakllsch for (i=Item->Width; i < Item->FieldWidth; i+=1) {
952 1.1 jakllsch PPUTC (ps, ' ');
953 1.1 jakllsch }
954 1.1 jakllsch }
955 1.1 jakllsch
956 1.1 jakllsch // pad item
957 1.1 jakllsch for (i=Len; i < Item->Width; i++) {
958 1.1 jakllsch PPUTC (ps, Item->Pad);
959 1.1 jakllsch }
960 1.1 jakllsch
961 1.1 jakllsch // add the item
962 1.2 jmcneill Item->Item.Index=0;
963 1.1 jakllsch while (Item->Item.Index < Len) {
964 1.1 jakllsch PPUTC (ps, PGETC(&Item->Item));
965 1.1 jakllsch }
966 1.1 jakllsch
967 1.1 jakllsch // If pad at the end, add pad char
968 1.1 jakllsch if (!Item->PadBefore) {
969 1.1 jakllsch for (i=Item->Width; i < Item->FieldWidth; i+=1) {
970 1.1 jakllsch PPUTC (ps, ' ');
971 1.1 jakllsch }
972 1.1 jakllsch }
973 1.1 jakllsch }
974 1.1 jakllsch
975 1.1 jakllsch
976 1.1 jakllsch STATIC
977 1.1 jakllsch UINTN
978 1.1 jakllsch _Print (
979 1.1 jakllsch IN PRINT_STATE *ps
980 1.1 jakllsch )
981 1.1 jakllsch /*++
982 1.1 jakllsch
983 1.1 jakllsch Routine Description:
984 1.1 jakllsch
985 1.1 jakllsch %w.lF - w = width
986 1.1 jakllsch l = field width
987 1.1 jakllsch F = format of arg
988 1.1 jakllsch
989 1.1 jakllsch Args F:
990 1.1 jakllsch 0 - pad with zeros
991 1.1 jakllsch - - justify on left (default is on right)
992 1.2 jmcneill , - add comma's to field
993 1.1 jakllsch * - width provided on stack
994 1.1 jakllsch n - Set output attribute to normal (for this field only)
995 1.1 jakllsch h - Set output attribute to highlight (for this field only)
996 1.1 jakllsch e - Set output attribute to error (for this field only)
997 1.1 jakllsch l - Value is 64 bits
998 1.1 jakllsch
999 1.1 jakllsch a - ascii string
1000 1.1 jakllsch s - unicode string
1001 1.1 jakllsch X - fixed 8 byte value in hex
1002 1.1 jakllsch x - hex value
1003 1.2 jmcneill d - value as signed decimal
1004 1.2 jmcneill u - value as unsigned decimal
1005 1.2 jmcneill f - value as floating point
1006 1.1 jakllsch c - Unicode char
1007 1.1 jakllsch t - EFI time structure
1008 1.1 jakllsch g - Pointer to GUID
1009 1.1 jakllsch r - EFI status code (result code)
1010 1.2 jmcneill D - pointer to Device Path with normal ending.
1011 1.1 jakllsch
1012 1.1 jakllsch N - Set output attribute to normal
1013 1.1 jakllsch H - Set output attribute to highlight
1014 1.1 jakllsch E - Set output attribute to error
1015 1.1 jakllsch % - Print a %
1016 1.2 jmcneill
1017 1.1 jakllsch Arguments:
1018 1.1 jakllsch
1019 1.1 jakllsch SystemTable - The system table
1020 1.1 jakllsch
1021 1.1 jakllsch Returns:
1022 1.1 jakllsch
1023 1.2 jmcneill Number of charactors written
1024 1.1 jakllsch
1025 1.1 jakllsch --*/
1026 1.1 jakllsch {
1027 1.1 jakllsch CHAR16 c;
1028 1.1 jakllsch UINTN Attr;
1029 1.1 jakllsch PRINT_ITEM Item;
1030 1.1 jakllsch CHAR16 Buffer[PRINT_STRING_LEN];
1031 1.1 jakllsch
1032 1.1 jakllsch ps->Len = 0;
1033 1.1 jakllsch ps->Buffer = Buffer;
1034 1.1 jakllsch ps->Pos = Buffer;
1035 1.1 jakllsch ps->End = Buffer + PRINT_STRING_LEN - 1;
1036 1.1 jakllsch ps->Item = &Item;
1037 1.1 jakllsch
1038 1.1 jakllsch ps->fmt.Index = 0;
1039 1.1 jakllsch while ((c = PGETC(&ps->fmt))) {
1040 1.1 jakllsch
1041 1.1 jakllsch if (c != '%') {
1042 1.1 jakllsch PPUTC ( ps, c );
1043 1.2 jmcneill continue;
1044 1.1 jakllsch }
1045 1.1 jakllsch
1046 1.1 jakllsch // setup for new item
1047 1.1 jakllsch Item.FieldWidth = (UINTN) -1;
1048 1.1 jakllsch Item.Width = 0;
1049 1.1 jakllsch Item.WidthParse = &Item.Width;
1050 1.1 jakllsch Item.Pad = ' ';
1051 1.1 jakllsch Item.PadBefore = TRUE;
1052 1.1 jakllsch Item.Comma = FALSE;
1053 1.1 jakllsch Item.Long = FALSE;
1054 1.1 jakllsch Item.Item.Ascii = FALSE;
1055 1.1 jakllsch Item.Item.pw = NULL;
1056 1.1 jakllsch ps->RestoreAttr = 0;
1057 1.1 jakllsch Attr = 0;
1058 1.1 jakllsch
1059 1.1 jakllsch while ((c = PGETC(&ps->fmt))) {
1060 1.1 jakllsch
1061 1.1 jakllsch switch (c) {
1062 1.2 jmcneill
1063 1.1 jakllsch case '%':
1064 1.1 jakllsch //
1065 1.1 jakllsch // %% -> %
1066 1.1 jakllsch //
1067 1.2 jmcneill Item.Scratch[0] = '%';
1068 1.2 jmcneill Item.Scratch[1] = 0;
1069 1.1 jakllsch Item.Item.pw = Item.Scratch;
1070 1.1 jakllsch break;
1071 1.1 jakllsch
1072 1.1 jakllsch case '0':
1073 1.1 jakllsch Item.Pad = '0';
1074 1.1 jakllsch break;
1075 1.1 jakllsch
1076 1.1 jakllsch case '-':
1077 1.1 jakllsch Item.PadBefore = FALSE;
1078 1.1 jakllsch break;
1079 1.1 jakllsch
1080 1.1 jakllsch case ',':
1081 1.1 jakllsch Item.Comma = TRUE;
1082 1.1 jakllsch break;
1083 1.1 jakllsch
1084 1.1 jakllsch case '.':
1085 1.1 jakllsch Item.WidthParse = &Item.FieldWidth;
1086 1.1 jakllsch break;
1087 1.1 jakllsch
1088 1.1 jakllsch case '*':
1089 1.1 jakllsch *Item.WidthParse = va_arg(ps->args, UINTN);
1090 1.1 jakllsch break;
1091 1.2 jmcneill
1092 1.1 jakllsch case '1':
1093 1.1 jakllsch case '2':
1094 1.1 jakllsch case '3':
1095 1.1 jakllsch case '4':
1096 1.1 jakllsch case '5':
1097 1.1 jakllsch case '6':
1098 1.1 jakllsch case '7':
1099 1.1 jakllsch case '8':
1100 1.1 jakllsch case '9':
1101 1.1 jakllsch *Item.WidthParse = 0;
1102 1.1 jakllsch do {
1103 1.1 jakllsch *Item.WidthParse = *Item.WidthParse * 10 + c - '0';
1104 1.1 jakllsch c = PGETC(&ps->fmt);
1105 1.1 jakllsch } while (c >= '0' && c <= '9') ;
1106 1.1 jakllsch ps->fmt.Index -= 1;
1107 1.1 jakllsch break;
1108 1.1 jakllsch
1109 1.1 jakllsch case 'a':
1110 1.1 jakllsch Item.Item.pc = va_arg(ps->args, CHAR8 *);
1111 1.1 jakllsch Item.Item.Ascii = TRUE;
1112 1.1 jakllsch if (!Item.Item.pc) {
1113 1.1 jakllsch Item.Item.pc = (CHAR8 *)"(null)";
1114 1.1 jakllsch }
1115 1.1 jakllsch break;
1116 1.1 jakllsch
1117 1.1 jakllsch case 's':
1118 1.1 jakllsch Item.Item.pw = va_arg(ps->args, CHAR16 *);
1119 1.1 jakllsch if (!Item.Item.pw) {
1120 1.1 jakllsch Item.Item.pw = L"(null)";
1121 1.1 jakllsch }
1122 1.1 jakllsch break;
1123 1.1 jakllsch
1124 1.1 jakllsch case 'c':
1125 1.2 jmcneill Item.Scratch[0] = (CHAR16) va_arg(ps->args, UINTN);
1126 1.2 jmcneill Item.Scratch[1] = 0;
1127 1.1 jakllsch Item.Item.pw = Item.Scratch;
1128 1.1 jakllsch break;
1129 1.1 jakllsch
1130 1.1 jakllsch case 'l':
1131 1.1 jakllsch Item.Long = TRUE;
1132 1.1 jakllsch break;
1133 1.1 jakllsch
1134 1.1 jakllsch case 'X':
1135 1.1 jakllsch Item.Width = Item.Long ? 16 : 8;
1136 1.1 jakllsch Item.Pad = '0';
1137 1.2 jmcneill #if __GNUC__ >= 7
1138 1.2 jmcneill __attribute__ ((fallthrough));
1139 1.2 jmcneill #endif
1140 1.1 jakllsch case 'x':
1141 1.1 jakllsch ValueToHex (
1142 1.2 jmcneill Item.Scratch,
1143 1.1 jakllsch Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
1144 1.1 jakllsch );
1145 1.2 jmcneill Item.Item.pw = Item.Scratch;
1146 1.1 jakllsch
1147 1.1 jakllsch break;
1148 1.2 jmcneill
1149 1.1 jakllsch
1150 1.1 jakllsch case 'g':
1151 1.2 jmcneill GuidToString (Item.Scratch, va_arg(ps->args, EFI_GUID *));
1152 1.2 jmcneill Item.Item.pw = Item.Scratch;
1153 1.2 jmcneill break;
1154 1.2 jmcneill
1155 1.2 jmcneill case 'u':
1156 1.2 jmcneill ValueToString (
1157 1.2 jmcneill Item.Scratch,
1158 1.2 jmcneill Item.Comma,
1159 1.2 jmcneill Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
1160 1.2 jmcneill );
1161 1.1 jakllsch Item.Item.pw = Item.Scratch;
1162 1.1 jakllsch break;
1163 1.1 jakllsch
1164 1.1 jakllsch case 'd':
1165 1.2 jmcneill ValueToString (
1166 1.2 jmcneill Item.Scratch,
1167 1.2 jmcneill Item.Comma,
1168 1.2 jmcneill Item.Long ? va_arg(ps->args, INT64) : va_arg(ps->args, INT32)
1169 1.2 jmcneill );
1170 1.2 jmcneill Item.Item.pw = Item.Scratch;
1171 1.2 jmcneill break;
1172 1.2 jmcneill
1173 1.2 jmcneill case 'D':
1174 1.2 jmcneill {
1175 1.2 jmcneill EFI_DEVICE_PATH *dp = va_arg(ps->args, EFI_DEVICE_PATH *);
1176 1.2 jmcneill CHAR16 *dpstr = DevicePathToStr(dp);
1177 1.2 jmcneill StrnCpy(Item.Scratch, dpstr, PRINT_ITEM_BUFFER_LEN);
1178 1.2 jmcneill Item.Scratch[PRINT_ITEM_BUFFER_LEN-1] = L'\0';
1179 1.2 jmcneill FreePool(dpstr);
1180 1.2 jmcneill
1181 1.1 jakllsch Item.Item.pw = Item.Scratch;
1182 1.2 jmcneill break;
1183 1.2 jmcneill }
1184 1.2 jmcneill
1185 1.2 jmcneill #ifndef __NetBSD__
1186 1.2 jmcneill case 'f':
1187 1.2 jmcneill FloatToString (
1188 1.2 jmcneill Item.Scratch,
1189 1.2 jmcneill Item.Comma,
1190 1.2 jmcneill va_arg(ps->args, double)
1191 1.1 jakllsch );
1192 1.2 jmcneill Item.Item.pw = Item.Scratch;
1193 1.2 jmcneill break;
1194 1.2 jmcneill #endif
1195 1.2 jmcneill
1196 1.1 jakllsch case 't':
1197 1.2 jmcneill TimeToString (Item.Scratch, va_arg(ps->args, EFI_TIME *));
1198 1.1 jakllsch Item.Item.pw = Item.Scratch;
1199 1.1 jakllsch break;
1200 1.1 jakllsch
1201 1.1 jakllsch case 'r':
1202 1.2 jmcneill StatusToString (Item.Scratch, va_arg(ps->args, EFI_STATUS));
1203 1.1 jakllsch Item.Item.pw = Item.Scratch;
1204 1.1 jakllsch break;
1205 1.1 jakllsch
1206 1.1 jakllsch case 'n':
1207 1.1 jakllsch PSETATTR(ps, ps->AttrNorm);
1208 1.1 jakllsch break;
1209 1.1 jakllsch
1210 1.1 jakllsch case 'h':
1211 1.1 jakllsch PSETATTR(ps, ps->AttrHighlight);
1212 1.1 jakllsch break;
1213 1.1 jakllsch
1214 1.1 jakllsch case 'e':
1215 1.1 jakllsch PSETATTR(ps, ps->AttrError);
1216 1.1 jakllsch break;
1217 1.1 jakllsch
1218 1.1 jakllsch case 'N':
1219 1.1 jakllsch Attr = ps->AttrNorm;
1220 1.1 jakllsch break;
1221 1.1 jakllsch
1222 1.1 jakllsch case 'H':
1223 1.1 jakllsch Attr = ps->AttrHighlight;
1224 1.1 jakllsch break;
1225 1.1 jakllsch
1226 1.1 jakllsch case 'E':
1227 1.1 jakllsch Attr = ps->AttrError;
1228 1.1 jakllsch break;
1229 1.1 jakllsch
1230 1.1 jakllsch default:
1231 1.2 jmcneill Item.Scratch[0] = '?';
1232 1.2 jmcneill Item.Scratch[1] = 0;
1233 1.1 jakllsch Item.Item.pw = Item.Scratch;
1234 1.1 jakllsch break;
1235 1.1 jakllsch }
1236 1.1 jakllsch
1237 1.1 jakllsch // if we have an Item
1238 1.1 jakllsch if (Item.Item.pw) {
1239 1.1 jakllsch PITEM (ps);
1240 1.1 jakllsch break;
1241 1.1 jakllsch }
1242 1.1 jakllsch
1243 1.1 jakllsch // if we have an Attr set
1244 1.1 jakllsch if (Attr) {
1245 1.1 jakllsch PSETATTR(ps, Attr);
1246 1.1 jakllsch ps->RestoreAttr = 0;
1247 1.1 jakllsch break;
1248 1.1 jakllsch }
1249 1.1 jakllsch }
1250 1.1 jakllsch
1251 1.1 jakllsch if (ps->RestoreAttr) {
1252 1.1 jakllsch PSETATTR(ps, ps->RestoreAttr);
1253 1.1 jakllsch }
1254 1.1 jakllsch }
1255 1.1 jakllsch
1256 1.1 jakllsch // Flush buffer
1257 1.1 jakllsch PFLUSH (ps);
1258 1.1 jakllsch return ps->Len;
1259 1.1 jakllsch }
1260 1.1 jakllsch
1261 1.1 jakllsch STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7',
1262 1.1 jakllsch '8','9','A','B','C','D','E','F'};
1263 1.1 jakllsch
1264 1.1 jakllsch VOID
1265 1.1 jakllsch ValueToHex (
1266 1.1 jakllsch IN CHAR16 *Buffer,
1267 1.1 jakllsch IN UINT64 v
1268 1.1 jakllsch )
1269 1.1 jakllsch {
1270 1.1 jakllsch CHAR8 str[30], *p1;
1271 1.1 jakllsch CHAR16 *p2;
1272 1.1 jakllsch
1273 1.1 jakllsch if (!v) {
1274 1.1 jakllsch Buffer[0] = '0';
1275 1.1 jakllsch Buffer[1] = 0;
1276 1.1 jakllsch return ;
1277 1.1 jakllsch }
1278 1.1 jakllsch
1279 1.1 jakllsch p1 = str;
1280 1.1 jakllsch p2 = Buffer;
1281 1.1 jakllsch
1282 1.1 jakllsch while (v) {
1283 1.2 jmcneill // Without the cast, the MSVC compiler may insert a reference to __allmull
1284 1.2 jmcneill *(p1++) = Hex[(UINTN)(v & 0xf)];
1285 1.1 jakllsch v = RShiftU64 (v, 4);
1286 1.1 jakllsch }
1287 1.1 jakllsch
1288 1.1 jakllsch while (p1 != str) {
1289 1.1 jakllsch *(p2++) = *(--p1);
1290 1.1 jakllsch }
1291 1.1 jakllsch *p2 = 0;
1292 1.1 jakllsch }
1293 1.1 jakllsch
1294 1.1 jakllsch
1295 1.1 jakllsch VOID
1296 1.1 jakllsch ValueToString (
1297 1.1 jakllsch IN CHAR16 *Buffer,
1298 1.1 jakllsch IN BOOLEAN Comma,
1299 1.1 jakllsch IN INT64 v
1300 1.1 jakllsch )
1301 1.1 jakllsch {
1302 1.1 jakllsch STATIC CHAR8 ca[] = { 3, 1, 2 };
1303 1.1 jakllsch CHAR8 str[40], *p1;
1304 1.1 jakllsch CHAR16 *p2;
1305 1.1 jakllsch UINTN c, r;
1306 1.1 jakllsch
1307 1.1 jakllsch if (!v) {
1308 1.1 jakllsch Buffer[0] = '0';
1309 1.1 jakllsch Buffer[1] = 0;
1310 1.1 jakllsch return ;
1311 1.1 jakllsch }
1312 1.1 jakllsch
1313 1.1 jakllsch p1 = str;
1314 1.1 jakllsch p2 = Buffer;
1315 1.1 jakllsch
1316 1.1 jakllsch if (v < 0) {
1317 1.1 jakllsch *(p2++) = '-';
1318 1.1 jakllsch v = -v;
1319 1.1 jakllsch }
1320 1.1 jakllsch
1321 1.1 jakllsch while (v) {
1322 1.1 jakllsch v = (INT64)DivU64x32 ((UINT64)v, 10, &r);
1323 1.1 jakllsch *(p1++) = (CHAR8)r + '0';
1324 1.1 jakllsch }
1325 1.1 jakllsch
1326 1.1 jakllsch c = (Comma ? ca[(p1 - str) % 3] : 999) + 1;
1327 1.1 jakllsch while (p1 != str) {
1328 1.1 jakllsch
1329 1.1 jakllsch c -= 1;
1330 1.1 jakllsch if (!c) {
1331 1.1 jakllsch *(p2++) = ',';
1332 1.1 jakllsch c = 3;
1333 1.1 jakllsch }
1334 1.1 jakllsch
1335 1.1 jakllsch *(p2++) = *(--p1);
1336 1.1 jakllsch }
1337 1.1 jakllsch *p2 = 0;
1338 1.1 jakllsch }
1339 1.1 jakllsch
1340 1.2 jmcneill #ifndef __NetBSD__
1341 1.2 jmcneill VOID
1342 1.2 jmcneill FloatToString (
1343 1.2 jmcneill IN CHAR16 *Buffer,
1344 1.2 jmcneill IN BOOLEAN Comma,
1345 1.2 jmcneill IN double v
1346 1.2 jmcneill )
1347 1.2 jmcneill {
1348 1.2 jmcneill /*
1349 1.2 jmcneill * Integer part.
1350 1.2 jmcneill */
1351 1.2 jmcneill INTN i = (INTN)v;
1352 1.2 jmcneill ValueToString(Buffer, Comma, i);
1353 1.2 jmcneill
1354 1.2 jmcneill
1355 1.2 jmcneill /*
1356 1.2 jmcneill * Decimal point.
1357 1.2 jmcneill */
1358 1.2 jmcneill UINTN x = StrLen(Buffer);
1359 1.2 jmcneill Buffer[x] = L'.';
1360 1.2 jmcneill x++;
1361 1.2 jmcneill
1362 1.2 jmcneill
1363 1.2 jmcneill /*
1364 1.2 jmcneill * Keep fractional part.
1365 1.2 jmcneill */
1366 1.2 jmcneill float f = (float)(v - i);
1367 1.2 jmcneill if (f < 0) f = -f;
1368 1.2 jmcneill
1369 1.2 jmcneill
1370 1.2 jmcneill /*
1371 1.2 jmcneill * Leading fractional zeroes.
1372 1.2 jmcneill */
1373 1.2 jmcneill f *= 10.0;
1374 1.2 jmcneill while ( (f != 0)
1375 1.2 jmcneill && ((INTN)f == 0))
1376 1.2 jmcneill {
1377 1.2 jmcneill Buffer[x] = L'0';
1378 1.2 jmcneill x++;
1379 1.2 jmcneill f *= 10.0;
1380 1.2 jmcneill }
1381 1.2 jmcneill
1382 1.2 jmcneill
1383 1.2 jmcneill /*
1384 1.2 jmcneill * Fractional digits.
1385 1.2 jmcneill */
1386 1.2 jmcneill while ((float)(INTN)f != f)
1387 1.2 jmcneill {
1388 1.2 jmcneill f *= 10;
1389 1.2 jmcneill }
1390 1.2 jmcneill ValueToString(Buffer + x, FALSE, (INTN)f);
1391 1.2 jmcneill return;
1392 1.2 jmcneill }
1393 1.2 jmcneill #endif
1394 1.2 jmcneill
1395 1.1 jakllsch VOID
1396 1.1 jakllsch TimeToString (
1397 1.1 jakllsch OUT CHAR16 *Buffer,
1398 1.1 jakllsch IN EFI_TIME *Time
1399 1.1 jakllsch )
1400 1.1 jakllsch {
1401 1.1 jakllsch UINTN Hour, Year;
1402 1.1 jakllsch CHAR16 AmPm;
1403 1.1 jakllsch
1404 1.1 jakllsch AmPm = 'a';
1405 1.1 jakllsch Hour = Time->Hour;
1406 1.1 jakllsch if (Time->Hour == 0) {
1407 1.1 jakllsch Hour = 12;
1408 1.1 jakllsch } else if (Time->Hour >= 12) {
1409 1.1 jakllsch AmPm = 'p';
1410 1.1 jakllsch if (Time->Hour >= 13) {
1411 1.1 jakllsch Hour -= 12;
1412 1.1 jakllsch }
1413 1.1 jakllsch }
1414 1.1 jakllsch
1415 1.1 jakllsch Year = Time->Year % 100;
1416 1.2 jmcneill
1417 1.1 jakllsch // bugbug: for now just print it any old way
1418 1.1 jakllsch SPrint (Buffer, 0, L"%02d/%02d/%02d %02d:%02d%c",
1419 1.1 jakllsch Time->Month,
1420 1.1 jakllsch Time->Day,
1421 1.1 jakllsch Year,
1422 1.1 jakllsch Hour,
1423 1.1 jakllsch Time->Minute,
1424 1.1 jakllsch AmPm
1425 1.1 jakllsch );
1426 1.2 jmcneill }
1427 1.1 jakllsch
1428 1.1 jakllsch
1429 1.1 jakllsch
1430 1.1 jakllsch
1431 1.1 jakllsch VOID
1432 1.1 jakllsch DumpHex (
1433 1.1 jakllsch IN UINTN Indent,
1434 1.1 jakllsch IN UINTN Offset,
1435 1.1 jakllsch IN UINTN DataSize,
1436 1.1 jakllsch IN VOID *UserData
1437 1.1 jakllsch )
1438 1.1 jakllsch {
1439 1.1 jakllsch CHAR8 *Data, Val[50], Str[20], c;
1440 1.1 jakllsch UINTN Size, Index;
1441 1.2 jmcneill
1442 1.1 jakllsch UINTN ScreenCount;
1443 1.1 jakllsch UINTN TempColumn;
1444 1.1 jakllsch UINTN ScreenSize;
1445 1.1 jakllsch CHAR16 ReturnStr[1];
1446 1.1 jakllsch
1447 1.1 jakllsch
1448 1.1 jakllsch uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
1449 1.1 jakllsch ScreenCount = 0;
1450 1.1 jakllsch ScreenSize -= 2;
1451 1.1 jakllsch
1452 1.1 jakllsch Data = UserData;
1453 1.1 jakllsch while (DataSize) {
1454 1.1 jakllsch Size = 16;
1455 1.1 jakllsch if (Size > DataSize) {
1456 1.1 jakllsch Size = DataSize;
1457 1.1 jakllsch }
1458 1.1 jakllsch
1459 1.1 jakllsch for (Index=0; Index < Size; Index += 1) {
1460 1.1 jakllsch c = Data[Index];
1461 1.1 jakllsch Val[Index*3+0] = Hex[c>>4];
1462 1.1 jakllsch Val[Index*3+1] = Hex[c&0xF];
1463 1.1 jakllsch Val[Index*3+2] = (Index == 7)?'-':' ';
1464 1.1 jakllsch Str[Index] = (c < ' ' || c > 'z') ? '.' : c;
1465 1.1 jakllsch }
1466 1.1 jakllsch
1467 1.1 jakllsch Val[Index*3] = 0;
1468 1.1 jakllsch Str[Index] = 0;
1469 1.1 jakllsch Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str);
1470 1.1 jakllsch
1471 1.1 jakllsch Data += Size;
1472 1.1 jakllsch Offset += Size;
1473 1.1 jakllsch DataSize -= Size;
1474 1.1 jakllsch
1475 1.1 jakllsch ScreenCount++;
1476 1.1 jakllsch if (ScreenCount >= ScreenSize && ScreenSize != 0) {
1477 1.1 jakllsch //
1478 1.1 jakllsch // If ScreenSize == 0 we have the console redirected so don't
1479 1.1 jakllsch // block updates
1480 1.1 jakllsch //
1481 1.1 jakllsch ScreenCount = 0;
1482 1.1 jakllsch Print (L"Press Enter to continue :");
1483 1.1 jakllsch Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
1484 1.1 jakllsch Print (L"\n");
1485 1.1 jakllsch }
1486 1.1 jakllsch
1487 1.1 jakllsch }
1488 1.1 jakllsch }
1489