print.c revision 1.3 1 1.3 pgoyette /* $NetBSD: print.c,v 1.3 2019/01/27 02:08:43 pgoyette 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.3 pgoyette >>>>>>> 1.1.1.1.34.1
536 1.1 jakllsch
537 1.1 jakllsch CHAR16 *
538 1.1 jakllsch PoolPrint (
539 1.2 jmcneill IN CONST CHAR16 *fmt,
540 1.1 jakllsch ...
541 1.1 jakllsch )
542 1.1 jakllsch /*++
543 1.1 jakllsch
544 1.1 jakllsch Routine Description:
545 1.1 jakllsch
546 1.1 jakllsch Prints a formatted unicode string to allocated pool. The caller
547 1.1 jakllsch must free the resulting buffer.
548 1.1 jakllsch
549 1.1 jakllsch Arguments:
550 1.1 jakllsch
551 1.1 jakllsch fmt - The format string
552 1.1 jakllsch
553 1.1 jakllsch Returns:
554 1.1 jakllsch
555 1.2 jmcneill Allocated buffer with the formatted string printed in it.
556 1.1 jakllsch The caller must free the allocated buffer. The buffer
557 1.1 jakllsch allocation is not packed.
558 1.1 jakllsch
559 1.1 jakllsch --*/
560 1.1 jakllsch {
561 1.2 jmcneill va_list args;
562 1.2 jmcneill CHAR16 *pool;
563 1.1 jakllsch va_start (args, fmt);
564 1.2 jmcneill pool = VPoolPrint(fmt, args);
565 1.1 jakllsch va_end (args);
566 1.2 jmcneill return pool;
567 1.1 jakllsch }
568 1.1 jakllsch
569 1.1 jakllsch CHAR16 *
570 1.1 jakllsch CatPrint (
571 1.1 jakllsch IN OUT POOL_PRINT *Str,
572 1.2 jmcneill IN CONST CHAR16 *fmt,
573 1.1 jakllsch ...
574 1.1 jakllsch )
575 1.1 jakllsch /*++
576 1.1 jakllsch
577 1.1 jakllsch Routine Description:
578 1.1 jakllsch
579 1.2 jmcneill Concatenates a formatted unicode string to allocated pool.
580 1.1 jakllsch The caller must free the resulting buffer.
581 1.1 jakllsch
582 1.1 jakllsch Arguments:
583 1.1 jakllsch
584 1.2 jmcneill Str - Tracks the allocated pool, size in use, and
585 1.1 jakllsch amount of pool allocated.
586 1.1 jakllsch
587 1.1 jakllsch fmt - The format string
588 1.1 jakllsch
589 1.1 jakllsch Returns:
590 1.1 jakllsch
591 1.2 jmcneill Allocated buffer with the formatted string printed in it.
592 1.1 jakllsch The caller must free the allocated buffer. The buffer
593 1.1 jakllsch allocation is not packed.
594 1.1 jakllsch
595 1.1 jakllsch --*/
596 1.1 jakllsch {
597 1.1 jakllsch va_list args;
598 1.1 jakllsch
599 1.1 jakllsch va_start (args, fmt);
600 1.1 jakllsch _PoolCatPrint (fmt, args, Str, _PoolPrint);
601 1.1 jakllsch va_end (args);
602 1.1 jakllsch return Str->str;
603 1.1 jakllsch }
604 1.1 jakllsch
605 1.1 jakllsch
606 1.1 jakllsch
607 1.1 jakllsch UINTN
608 1.1 jakllsch Print (
609 1.2 jmcneill IN CONST CHAR16 *fmt,
610 1.1 jakllsch ...
611 1.1 jakllsch )
612 1.1 jakllsch /*++
613 1.1 jakllsch
614 1.1 jakllsch Routine Description:
615 1.1 jakllsch
616 1.1 jakllsch Prints a formatted unicode string to the default console
617 1.1 jakllsch
618 1.1 jakllsch Arguments:
619 1.1 jakllsch
620 1.1 jakllsch fmt - Format string
621 1.1 jakllsch
622 1.1 jakllsch Returns:
623 1.1 jakllsch
624 1.1 jakllsch Length of string printed to the console
625 1.1 jakllsch
626 1.1 jakllsch --*/
627 1.1 jakllsch {
628 1.1 jakllsch va_list args;
629 1.1 jakllsch UINTN back;
630 1.1 jakllsch
631 1.1 jakllsch va_start (args, fmt);
632 1.1 jakllsch back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
633 1.1 jakllsch va_end (args);
634 1.1 jakllsch return back;
635 1.1 jakllsch }
636 1.1 jakllsch
637 1.1 jakllsch UINTN
638 1.1 jakllsch VPrint (
639 1.2 jmcneill IN CONST CHAR16 *fmt,
640 1.2 jmcneill va_list args
641 1.1 jakllsch )
642 1.1 jakllsch /*++
643 1.1 jakllsch
644 1.1 jakllsch Routine Description:
645 1.1 jakllsch
646 1.1 jakllsch Prints a formatted unicode string to the default console using a va_list
647 1.1 jakllsch
648 1.1 jakllsch Arguments:
649 1.1 jakllsch
650 1.1 jakllsch fmt - Format string
651 1.1 jakllsch args - va_list
652 1.1 jakllsch Returns:
653 1.1 jakllsch
654 1.1 jakllsch Length of string printed to the console
655 1.1 jakllsch
656 1.1 jakllsch --*/
657 1.1 jakllsch {
658 1.1 jakllsch return _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, fmt, NULL, args);
659 1.1 jakllsch }
660 1.1 jakllsch
661 1.1 jakllsch
662 1.1 jakllsch UINTN
663 1.1 jakllsch PrintAt (
664 1.2 jmcneill IN UINTN Column,
665 1.2 jmcneill IN UINTN Row,
666 1.2 jmcneill IN CONST CHAR16 *fmt,
667 1.1 jakllsch ...
668 1.1 jakllsch )
669 1.1 jakllsch /*++
670 1.1 jakllsch
671 1.1 jakllsch Routine Description:
672 1.1 jakllsch
673 1.2 jmcneill Prints a formatted unicode string to the default console, at
674 1.1 jakllsch the supplied cursor position
675 1.1 jakllsch
676 1.1 jakllsch Arguments:
677 1.1 jakllsch
678 1.1 jakllsch Column, Row - The cursor position to print the string at
679 1.1 jakllsch
680 1.1 jakllsch fmt - Format string
681 1.1 jakllsch
682 1.1 jakllsch Returns:
683 1.1 jakllsch
684 1.1 jakllsch Length of string printed to the console
685 1.1 jakllsch
686 1.1 jakllsch --*/
687 1.1 jakllsch {
688 1.1 jakllsch va_list args;
689 1.1 jakllsch UINTN back;
690 1.1 jakllsch
691 1.1 jakllsch va_start (args, fmt);
692 1.1 jakllsch back = _IPrint (Column, Row, ST->ConOut, fmt, NULL, args);
693 1.1 jakllsch va_end (args);
694 1.1 jakllsch return back;
695 1.1 jakllsch }
696 1.1 jakllsch
697 1.1 jakllsch
698 1.1 jakllsch UINTN
699 1.1 jakllsch IPrint (
700 1.1 jakllsch IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
701 1.2 jmcneill IN CONST CHAR16 *fmt,
702 1.1 jakllsch ...
703 1.1 jakllsch )
704 1.1 jakllsch /*++
705 1.1 jakllsch
706 1.1 jakllsch Routine Description:
707 1.1 jakllsch
708 1.1 jakllsch Prints a formatted unicode string to the specified console
709 1.1 jakllsch
710 1.1 jakllsch Arguments:
711 1.1 jakllsch
712 1.1 jakllsch Out - The console to print the string too
713 1.1 jakllsch
714 1.1 jakllsch fmt - Format string
715 1.1 jakllsch
716 1.1 jakllsch Returns:
717 1.1 jakllsch
718 1.1 jakllsch Length of string printed to the console
719 1.1 jakllsch
720 1.1 jakllsch --*/
721 1.1 jakllsch {
722 1.1 jakllsch va_list args;
723 1.1 jakllsch UINTN back;
724 1.1 jakllsch
725 1.1 jakllsch va_start (args, fmt);
726 1.1 jakllsch back = _IPrint ((UINTN) -1, (UINTN) -1, Out, fmt, NULL, args);
727 1.1 jakllsch va_end (args);
728 1.1 jakllsch return back;
729 1.1 jakllsch }
730 1.1 jakllsch
731 1.1 jakllsch
732 1.1 jakllsch UINTN
733 1.1 jakllsch IPrintAt (
734 1.1 jakllsch IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
735 1.1 jakllsch IN UINTN Column,
736 1.1 jakllsch IN UINTN Row,
737 1.2 jmcneill IN CONST CHAR16 *fmt,
738 1.1 jakllsch ...
739 1.1 jakllsch )
740 1.1 jakllsch /*++
741 1.1 jakllsch
742 1.1 jakllsch Routine Description:
743 1.1 jakllsch
744 1.1 jakllsch Prints a formatted unicode string to the specified console, at
745 1.1 jakllsch the supplied cursor position
746 1.1 jakllsch
747 1.1 jakllsch Arguments:
748 1.1 jakllsch
749 1.2 jmcneill Out - The console to print the string to
750 1.1 jakllsch
751 1.1 jakllsch Column, Row - The cursor position to print the string at
752 1.1 jakllsch
753 1.1 jakllsch fmt - Format string
754 1.1 jakllsch
755 1.1 jakllsch Returns:
756 1.1 jakllsch
757 1.1 jakllsch Length of string printed to the console
758 1.1 jakllsch
759 1.1 jakllsch --*/
760 1.1 jakllsch {
761 1.1 jakllsch va_list args;
762 1.1 jakllsch UINTN back;
763 1.1 jakllsch
764 1.1 jakllsch va_start (args, fmt);
765 1.2 jmcneill back = _IPrint (Column, Row, Out, fmt, NULL, args);
766 1.1 jakllsch va_end (args);
767 1.1 jakllsch return back;
768 1.1 jakllsch }
769 1.1 jakllsch
770 1.1 jakllsch
771 1.1 jakllsch UINTN
772 1.1 jakllsch _IPrint (
773 1.1 jakllsch IN UINTN Column,
774 1.1 jakllsch IN UINTN Row,
775 1.1 jakllsch IN SIMPLE_TEXT_OUTPUT_INTERFACE *Out,
776 1.2 jmcneill IN CONST CHAR16 *fmt,
777 1.2 jmcneill IN CONST CHAR8 *fmta,
778 1.1 jakllsch IN va_list args
779 1.1 jakllsch )
780 1.1 jakllsch // Display string worker for: Print, PrintAt, IPrint, IPrintAt
781 1.1 jakllsch {
782 1.1 jakllsch PRINT_STATE ps;
783 1.1 jakllsch UINTN back;
784 1.1 jakllsch
785 1.1 jakllsch ZeroMem (&ps, sizeof(ps));
786 1.1 jakllsch ps.Context = Out;
787 1.2 jmcneill ps.Output = (INTN (EFIAPI *)(VOID *, CHAR16 *)) Out->OutputString;
788 1.2 jmcneill ps.SetAttr = (INTN (EFIAPI *)(VOID *, UINTN)) Out->SetAttribute;
789 1.1 jakllsch ps.Attr = Out->Mode->Attribute;
790 1.2 jmcneill
791 1.1 jakllsch back = (ps.Attr >> 4) & 0xF;
792 1.1 jakllsch ps.AttrNorm = EFI_TEXT_ATTR(EFI_LIGHTGRAY, back);
793 1.1 jakllsch ps.AttrHighlight = EFI_TEXT_ATTR(EFI_WHITE, back);
794 1.1 jakllsch ps.AttrError = EFI_TEXT_ATTR(EFI_YELLOW, back);
795 1.1 jakllsch
796 1.1 jakllsch if (fmt) {
797 1.1 jakllsch ps.fmt.pw = fmt;
798 1.1 jakllsch } else {
799 1.1 jakllsch ps.fmt.Ascii = TRUE;
800 1.1 jakllsch ps.fmt.pc = fmta;
801 1.1 jakllsch }
802 1.1 jakllsch
803 1.1 jakllsch va_copy(ps.args, args);
804 1.1 jakllsch
805 1.1 jakllsch if (Column != (UINTN) -1) {
806 1.1 jakllsch uefi_call_wrapper(Out->SetCursorPosition, 3, Out, Column, Row);
807 1.1 jakllsch }
808 1.1 jakllsch
809 1.1 jakllsch back = _Print (&ps);
810 1.1 jakllsch va_end(ps.args);
811 1.1 jakllsch return back;
812 1.1 jakllsch }
813 1.1 jakllsch
814 1.1 jakllsch
815 1.1 jakllsch UINTN
816 1.1 jakllsch APrint (
817 1.2 jmcneill IN CONST CHAR8 *fmt,
818 1.1 jakllsch ...
819 1.1 jakllsch )
820 1.1 jakllsch /*++
821 1.1 jakllsch
822 1.1 jakllsch Routine Description:
823 1.1 jakllsch
824 1.1 jakllsch For those whom really can't deal with unicode, a print
825 1.1 jakllsch function that takes an ascii format string
826 1.1 jakllsch
827 1.1 jakllsch Arguments:
828 1.1 jakllsch
829 1.1 jakllsch fmt - ascii format string
830 1.1 jakllsch
831 1.1 jakllsch Returns:
832 1.1 jakllsch
833 1.1 jakllsch Length of string printed to the console
834 1.1 jakllsch
835 1.1 jakllsch --*/
836 1.1 jakllsch
837 1.1 jakllsch {
838 1.1 jakllsch va_list args;
839 1.1 jakllsch UINTN back;
840 1.1 jakllsch
841 1.1 jakllsch va_start (args, fmt);
842 1.1 jakllsch back = _IPrint ((UINTN) -1, (UINTN) -1, ST->ConOut, NULL, fmt, args);
843 1.1 jakllsch va_end (args);
844 1.1 jakllsch return back;
845 1.1 jakllsch }
846 1.1 jakllsch
847 1.1 jakllsch
848 1.1 jakllsch STATIC
849 1.1 jakllsch VOID
850 1.1 jakllsch PFLUSH (
851 1.1 jakllsch IN OUT PRINT_STATE *ps
852 1.1 jakllsch )
853 1.1 jakllsch {
854 1.1 jakllsch *ps->Pos = 0;
855 1.1 jakllsch if (IsLocalPrint(ps->Output))
856 1.2 jmcneill ps->Output(ps->Context, ps->Buffer);
857 1.1 jakllsch else
858 1.1 jakllsch uefi_call_wrapper(ps->Output, 2, ps->Context, ps->Buffer);
859 1.1 jakllsch ps->Pos = ps->Buffer;
860 1.1 jakllsch }
861 1.1 jakllsch
862 1.1 jakllsch STATIC
863 1.1 jakllsch VOID
864 1.1 jakllsch PSETATTR (
865 1.1 jakllsch IN OUT PRINT_STATE *ps,
866 1.1 jakllsch IN UINTN Attr
867 1.1 jakllsch )
868 1.1 jakllsch {
869 1.1 jakllsch PFLUSH (ps);
870 1.1 jakllsch
871 1.1 jakllsch ps->RestoreAttr = ps->Attr;
872 1.1 jakllsch if (ps->SetAttr) {
873 1.1 jakllsch uefi_call_wrapper(ps->SetAttr, 2, ps->Context, Attr);
874 1.1 jakllsch }
875 1.1 jakllsch
876 1.1 jakllsch ps->Attr = Attr;
877 1.2 jmcneill }
878 1.1 jakllsch
879 1.1 jakllsch STATIC
880 1.1 jakllsch VOID
881 1.1 jakllsch PPUTC (
882 1.1 jakllsch IN OUT PRINT_STATE *ps,
883 1.1 jakllsch IN CHAR16 c
884 1.1 jakllsch )
885 1.1 jakllsch {
886 1.1 jakllsch // if this is a newline, add a carraige return
887 1.1 jakllsch if (c == '\n') {
888 1.1 jakllsch PPUTC (ps, '\r');
889 1.1 jakllsch }
890 1.1 jakllsch
891 1.1 jakllsch *ps->Pos = c;
892 1.1 jakllsch ps->Pos += 1;
893 1.1 jakllsch ps->Len += 1;
894 1.1 jakllsch
895 1.1 jakllsch // if at the end of the buffer, flush it
896 1.1 jakllsch if (ps->Pos >= ps->End) {
897 1.1 jakllsch PFLUSH(ps);
898 1.1 jakllsch }
899 1.1 jakllsch }
900 1.1 jakllsch
901 1.1 jakllsch
902 1.1 jakllsch STATIC
903 1.1 jakllsch CHAR16
904 1.1 jakllsch PGETC (
905 1.1 jakllsch IN POINTER *p
906 1.1 jakllsch )
907 1.1 jakllsch {
908 1.1 jakllsch CHAR16 c;
909 1.1 jakllsch
910 1.1 jakllsch c = p->Ascii ? p->pc[p->Index] : p->pw[p->Index];
911 1.1 jakllsch p->Index += 1;
912 1.1 jakllsch
913 1.1 jakllsch return c;
914 1.1 jakllsch }
915 1.1 jakllsch
916 1.1 jakllsch
917 1.1 jakllsch STATIC
918 1.1 jakllsch VOID
919 1.1 jakllsch PITEM (
920 1.1 jakllsch IN OUT PRINT_STATE *ps
921 1.1 jakllsch )
922 1.1 jakllsch {
923 1.1 jakllsch UINTN Len, i;
924 1.1 jakllsch PRINT_ITEM *Item;
925 1.1 jakllsch CHAR16 c;
926 1.1 jakllsch
927 1.1 jakllsch // Get the length of the item
928 1.1 jakllsch Item = ps->Item;
929 1.1 jakllsch Item->Item.Index = 0;
930 1.1 jakllsch while (Item->Item.Index < Item->FieldWidth) {
931 1.1 jakllsch c = PGETC(&Item->Item);
932 1.1 jakllsch if (!c) {
933 1.1 jakllsch Item->Item.Index -= 1;
934 1.1 jakllsch break;
935 1.1 jakllsch }
936 1.1 jakllsch }
937 1.1 jakllsch Len = Item->Item.Index;
938 1.1 jakllsch
939 1.1 jakllsch // if there is no item field width, use the items width
940 1.1 jakllsch if (Item->FieldWidth == (UINTN) -1) {
941 1.1 jakllsch Item->FieldWidth = Len;
942 1.1 jakllsch }
943 1.1 jakllsch
944 1.1 jakllsch // if item is larger then width, update width
945 1.1 jakllsch if (Len > Item->Width) {
946 1.1 jakllsch Item->Width = Len;
947 1.1 jakllsch }
948 1.1 jakllsch
949 1.1 jakllsch
950 1.1 jakllsch // if pad field before, add pad char
951 1.1 jakllsch if (Item->PadBefore) {
952 1.1 jakllsch for (i=Item->Width; i < Item->FieldWidth; i+=1) {
953 1.1 jakllsch PPUTC (ps, ' ');
954 1.1 jakllsch }
955 1.1 jakllsch }
956 1.1 jakllsch
957 1.1 jakllsch // pad item
958 1.1 jakllsch for (i=Len; i < Item->Width; i++) {
959 1.1 jakllsch PPUTC (ps, Item->Pad);
960 1.1 jakllsch }
961 1.1 jakllsch
962 1.1 jakllsch // add the item
963 1.2 jmcneill Item->Item.Index=0;
964 1.1 jakllsch while (Item->Item.Index < Len) {
965 1.1 jakllsch PPUTC (ps, PGETC(&Item->Item));
966 1.1 jakllsch }
967 1.1 jakllsch
968 1.1 jakllsch // If pad at the end, add pad char
969 1.1 jakllsch if (!Item->PadBefore) {
970 1.1 jakllsch for (i=Item->Width; i < Item->FieldWidth; i+=1) {
971 1.1 jakllsch PPUTC (ps, ' ');
972 1.1 jakllsch }
973 1.1 jakllsch }
974 1.1 jakllsch }
975 1.1 jakllsch
976 1.1 jakllsch
977 1.1 jakllsch STATIC
978 1.1 jakllsch UINTN
979 1.1 jakllsch _Print (
980 1.1 jakllsch IN PRINT_STATE *ps
981 1.1 jakllsch )
982 1.1 jakllsch /*++
983 1.1 jakllsch
984 1.1 jakllsch Routine Description:
985 1.1 jakllsch
986 1.1 jakllsch %w.lF - w = width
987 1.1 jakllsch l = field width
988 1.1 jakllsch F = format of arg
989 1.1 jakllsch
990 1.1 jakllsch Args F:
991 1.1 jakllsch 0 - pad with zeros
992 1.1 jakllsch - - justify on left (default is on right)
993 1.2 jmcneill , - add comma's to field
994 1.1 jakllsch * - width provided on stack
995 1.1 jakllsch n - Set output attribute to normal (for this field only)
996 1.1 jakllsch h - Set output attribute to highlight (for this field only)
997 1.1 jakllsch e - Set output attribute to error (for this field only)
998 1.1 jakllsch l - Value is 64 bits
999 1.1 jakllsch
1000 1.1 jakllsch a - ascii string
1001 1.1 jakllsch s - unicode string
1002 1.1 jakllsch X - fixed 8 byte value in hex
1003 1.1 jakllsch x - hex value
1004 1.2 jmcneill d - value as signed decimal
1005 1.2 jmcneill u - value as unsigned decimal
1006 1.2 jmcneill f - value as floating point
1007 1.1 jakllsch c - Unicode char
1008 1.1 jakllsch t - EFI time structure
1009 1.1 jakllsch g - Pointer to GUID
1010 1.1 jakllsch r - EFI status code (result code)
1011 1.2 jmcneill D - pointer to Device Path with normal ending.
1012 1.1 jakllsch
1013 1.1 jakllsch N - Set output attribute to normal
1014 1.1 jakllsch H - Set output attribute to highlight
1015 1.1 jakllsch E - Set output attribute to error
1016 1.1 jakllsch % - Print a %
1017 1.2 jmcneill
1018 1.1 jakllsch Arguments:
1019 1.1 jakllsch
1020 1.1 jakllsch SystemTable - The system table
1021 1.1 jakllsch
1022 1.1 jakllsch Returns:
1023 1.1 jakllsch
1024 1.2 jmcneill Number of charactors written
1025 1.1 jakllsch
1026 1.1 jakllsch --*/
1027 1.1 jakllsch {
1028 1.1 jakllsch CHAR16 c;
1029 1.1 jakllsch UINTN Attr;
1030 1.1 jakllsch PRINT_ITEM Item;
1031 1.1 jakllsch CHAR16 Buffer[PRINT_STRING_LEN];
1032 1.1 jakllsch
1033 1.1 jakllsch ps->Len = 0;
1034 1.1 jakllsch ps->Buffer = Buffer;
1035 1.1 jakllsch ps->Pos = Buffer;
1036 1.1 jakllsch ps->End = Buffer + PRINT_STRING_LEN - 1;
1037 1.1 jakllsch ps->Item = &Item;
1038 1.1 jakllsch
1039 1.1 jakllsch ps->fmt.Index = 0;
1040 1.1 jakllsch while ((c = PGETC(&ps->fmt))) {
1041 1.1 jakllsch
1042 1.1 jakllsch if (c != '%') {
1043 1.1 jakllsch PPUTC ( ps, c );
1044 1.2 jmcneill continue;
1045 1.1 jakllsch }
1046 1.1 jakllsch
1047 1.1 jakllsch // setup for new item
1048 1.1 jakllsch Item.FieldWidth = (UINTN) -1;
1049 1.1 jakllsch Item.Width = 0;
1050 1.1 jakllsch Item.WidthParse = &Item.Width;
1051 1.1 jakllsch Item.Pad = ' ';
1052 1.1 jakllsch Item.PadBefore = TRUE;
1053 1.1 jakllsch Item.Comma = FALSE;
1054 1.1 jakllsch Item.Long = FALSE;
1055 1.1 jakllsch Item.Item.Ascii = FALSE;
1056 1.1 jakllsch Item.Item.pw = NULL;
1057 1.1 jakllsch ps->RestoreAttr = 0;
1058 1.1 jakllsch Attr = 0;
1059 1.1 jakllsch
1060 1.1 jakllsch while ((c = PGETC(&ps->fmt))) {
1061 1.1 jakllsch
1062 1.1 jakllsch switch (c) {
1063 1.2 jmcneill
1064 1.1 jakllsch case '%':
1065 1.1 jakllsch //
1066 1.1 jakllsch // %% -> %
1067 1.1 jakllsch //
1068 1.2 jmcneill Item.Scratch[0] = '%';
1069 1.2 jmcneill Item.Scratch[1] = 0;
1070 1.1 jakllsch Item.Item.pw = Item.Scratch;
1071 1.1 jakllsch break;
1072 1.1 jakllsch
1073 1.1 jakllsch case '0':
1074 1.1 jakllsch Item.Pad = '0';
1075 1.1 jakllsch break;
1076 1.1 jakllsch
1077 1.1 jakllsch case '-':
1078 1.1 jakllsch Item.PadBefore = FALSE;
1079 1.1 jakllsch break;
1080 1.1 jakllsch
1081 1.1 jakllsch case ',':
1082 1.1 jakllsch Item.Comma = TRUE;
1083 1.1 jakllsch break;
1084 1.1 jakllsch
1085 1.1 jakllsch case '.':
1086 1.1 jakllsch Item.WidthParse = &Item.FieldWidth;
1087 1.1 jakllsch break;
1088 1.1 jakllsch
1089 1.1 jakllsch case '*':
1090 1.1 jakllsch *Item.WidthParse = va_arg(ps->args, UINTN);
1091 1.1 jakllsch break;
1092 1.2 jmcneill
1093 1.1 jakllsch case '1':
1094 1.1 jakllsch case '2':
1095 1.1 jakllsch case '3':
1096 1.1 jakllsch case '4':
1097 1.1 jakllsch case '5':
1098 1.1 jakllsch case '6':
1099 1.1 jakllsch case '7':
1100 1.1 jakllsch case '8':
1101 1.1 jakllsch case '9':
1102 1.1 jakllsch *Item.WidthParse = 0;
1103 1.1 jakllsch do {
1104 1.1 jakllsch *Item.WidthParse = *Item.WidthParse * 10 + c - '0';
1105 1.1 jakllsch c = PGETC(&ps->fmt);
1106 1.1 jakllsch } while (c >= '0' && c <= '9') ;
1107 1.1 jakllsch ps->fmt.Index -= 1;
1108 1.1 jakllsch break;
1109 1.1 jakllsch
1110 1.1 jakllsch case 'a':
1111 1.1 jakllsch Item.Item.pc = va_arg(ps->args, CHAR8 *);
1112 1.1 jakllsch Item.Item.Ascii = TRUE;
1113 1.1 jakllsch if (!Item.Item.pc) {
1114 1.1 jakllsch Item.Item.pc = (CHAR8 *)"(null)";
1115 1.1 jakllsch }
1116 1.1 jakllsch break;
1117 1.1 jakllsch
1118 1.1 jakllsch case 's':
1119 1.1 jakllsch Item.Item.pw = va_arg(ps->args, CHAR16 *);
1120 1.1 jakllsch if (!Item.Item.pw) {
1121 1.1 jakllsch Item.Item.pw = L"(null)";
1122 1.1 jakllsch }
1123 1.1 jakllsch break;
1124 1.1 jakllsch
1125 1.1 jakllsch case 'c':
1126 1.2 jmcneill Item.Scratch[0] = (CHAR16) va_arg(ps->args, UINTN);
1127 1.2 jmcneill Item.Scratch[1] = 0;
1128 1.1 jakllsch Item.Item.pw = Item.Scratch;
1129 1.1 jakllsch break;
1130 1.1 jakllsch
1131 1.1 jakllsch case 'l':
1132 1.1 jakllsch Item.Long = TRUE;
1133 1.1 jakllsch break;
1134 1.1 jakllsch
1135 1.1 jakllsch case 'X':
1136 1.1 jakllsch Item.Width = Item.Long ? 16 : 8;
1137 1.1 jakllsch Item.Pad = '0';
1138 1.2 jmcneill #if __GNUC__ >= 7
1139 1.2 jmcneill __attribute__ ((fallthrough));
1140 1.2 jmcneill #endif
1141 1.1 jakllsch case 'x':
1142 1.1 jakllsch ValueToHex (
1143 1.2 jmcneill Item.Scratch,
1144 1.1 jakllsch Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
1145 1.1 jakllsch );
1146 1.2 jmcneill Item.Item.pw = Item.Scratch;
1147 1.1 jakllsch
1148 1.1 jakllsch break;
1149 1.2 jmcneill
1150 1.1 jakllsch
1151 1.1 jakllsch case 'g':
1152 1.2 jmcneill GuidToString (Item.Scratch, va_arg(ps->args, EFI_GUID *));
1153 1.2 jmcneill Item.Item.pw = Item.Scratch;
1154 1.2 jmcneill break;
1155 1.2 jmcneill
1156 1.2 jmcneill case 'u':
1157 1.2 jmcneill ValueToString (
1158 1.2 jmcneill Item.Scratch,
1159 1.2 jmcneill Item.Comma,
1160 1.2 jmcneill Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32)
1161 1.2 jmcneill );
1162 1.1 jakllsch Item.Item.pw = Item.Scratch;
1163 1.1 jakllsch break;
1164 1.1 jakllsch
1165 1.1 jakllsch case 'd':
1166 1.2 jmcneill ValueToString (
1167 1.2 jmcneill Item.Scratch,
1168 1.2 jmcneill Item.Comma,
1169 1.2 jmcneill Item.Long ? va_arg(ps->args, INT64) : va_arg(ps->args, INT32)
1170 1.2 jmcneill );
1171 1.2 jmcneill Item.Item.pw = Item.Scratch;
1172 1.2 jmcneill break;
1173 1.2 jmcneill
1174 1.2 jmcneill case 'D':
1175 1.2 jmcneill {
1176 1.2 jmcneill EFI_DEVICE_PATH *dp = va_arg(ps->args, EFI_DEVICE_PATH *);
1177 1.2 jmcneill CHAR16 *dpstr = DevicePathToStr(dp);
1178 1.2 jmcneill StrnCpy(Item.Scratch, dpstr, PRINT_ITEM_BUFFER_LEN);
1179 1.2 jmcneill Item.Scratch[PRINT_ITEM_BUFFER_LEN-1] = L'\0';
1180 1.2 jmcneill FreePool(dpstr);
1181 1.2 jmcneill
1182 1.1 jakllsch Item.Item.pw = Item.Scratch;
1183 1.2 jmcneill break;
1184 1.2 jmcneill }
1185 1.2 jmcneill
1186 1.2 jmcneill #ifndef __NetBSD__
1187 1.2 jmcneill case 'f':
1188 1.2 jmcneill FloatToString (
1189 1.2 jmcneill Item.Scratch,
1190 1.2 jmcneill Item.Comma,
1191 1.2 jmcneill va_arg(ps->args, double)
1192 1.1 jakllsch );
1193 1.2 jmcneill Item.Item.pw = Item.Scratch;
1194 1.2 jmcneill break;
1195 1.2 jmcneill #endif
1196 1.2 jmcneill
1197 1.1 jakllsch case 't':
1198 1.2 jmcneill TimeToString (Item.Scratch, va_arg(ps->args, EFI_TIME *));
1199 1.1 jakllsch Item.Item.pw = Item.Scratch;
1200 1.1 jakllsch break;
1201 1.1 jakllsch
1202 1.1 jakllsch case 'r':
1203 1.2 jmcneill StatusToString (Item.Scratch, va_arg(ps->args, EFI_STATUS));
1204 1.1 jakllsch Item.Item.pw = Item.Scratch;
1205 1.1 jakllsch break;
1206 1.1 jakllsch
1207 1.1 jakllsch case 'n':
1208 1.1 jakllsch PSETATTR(ps, ps->AttrNorm);
1209 1.1 jakllsch break;
1210 1.1 jakllsch
1211 1.1 jakllsch case 'h':
1212 1.1 jakllsch PSETATTR(ps, ps->AttrHighlight);
1213 1.1 jakllsch break;
1214 1.1 jakllsch
1215 1.1 jakllsch case 'e':
1216 1.1 jakllsch PSETATTR(ps, ps->AttrError);
1217 1.1 jakllsch break;
1218 1.1 jakllsch
1219 1.1 jakllsch case 'N':
1220 1.1 jakllsch Attr = ps->AttrNorm;
1221 1.1 jakllsch break;
1222 1.1 jakllsch
1223 1.1 jakllsch case 'H':
1224 1.1 jakllsch Attr = ps->AttrHighlight;
1225 1.1 jakllsch break;
1226 1.1 jakllsch
1227 1.1 jakllsch case 'E':
1228 1.1 jakllsch Attr = ps->AttrError;
1229 1.1 jakllsch break;
1230 1.1 jakllsch
1231 1.1 jakllsch default:
1232 1.2 jmcneill Item.Scratch[0] = '?';
1233 1.2 jmcneill Item.Scratch[1] = 0;
1234 1.1 jakllsch Item.Item.pw = Item.Scratch;
1235 1.1 jakllsch break;
1236 1.1 jakllsch }
1237 1.1 jakllsch
1238 1.1 jakllsch // if we have an Item
1239 1.1 jakllsch if (Item.Item.pw) {
1240 1.1 jakllsch PITEM (ps);
1241 1.1 jakllsch break;
1242 1.1 jakllsch }
1243 1.1 jakllsch
1244 1.1 jakllsch // if we have an Attr set
1245 1.1 jakllsch if (Attr) {
1246 1.1 jakllsch PSETATTR(ps, Attr);
1247 1.1 jakllsch ps->RestoreAttr = 0;
1248 1.1 jakllsch break;
1249 1.1 jakllsch }
1250 1.1 jakllsch }
1251 1.1 jakllsch
1252 1.1 jakllsch if (ps->RestoreAttr) {
1253 1.1 jakllsch PSETATTR(ps, ps->RestoreAttr);
1254 1.1 jakllsch }
1255 1.1 jakllsch }
1256 1.1 jakllsch
1257 1.1 jakllsch // Flush buffer
1258 1.1 jakllsch PFLUSH (ps);
1259 1.1 jakllsch return ps->Len;
1260 1.1 jakllsch }
1261 1.1 jakllsch
1262 1.1 jakllsch STATIC CHAR8 Hex[] = {'0','1','2','3','4','5','6','7',
1263 1.1 jakllsch '8','9','A','B','C','D','E','F'};
1264 1.1 jakllsch
1265 1.1 jakllsch VOID
1266 1.1 jakllsch ValueToHex (
1267 1.1 jakllsch IN CHAR16 *Buffer,
1268 1.1 jakllsch IN UINT64 v
1269 1.1 jakllsch )
1270 1.1 jakllsch {
1271 1.1 jakllsch CHAR8 str[30], *p1;
1272 1.1 jakllsch CHAR16 *p2;
1273 1.1 jakllsch
1274 1.1 jakllsch if (!v) {
1275 1.1 jakllsch Buffer[0] = '0';
1276 1.1 jakllsch Buffer[1] = 0;
1277 1.1 jakllsch return ;
1278 1.1 jakllsch }
1279 1.1 jakllsch
1280 1.1 jakllsch p1 = str;
1281 1.1 jakllsch p2 = Buffer;
1282 1.1 jakllsch
1283 1.1 jakllsch while (v) {
1284 1.2 jmcneill // Without the cast, the MSVC compiler may insert a reference to __allmull
1285 1.2 jmcneill *(p1++) = Hex[(UINTN)(v & 0xf)];
1286 1.1 jakllsch v = RShiftU64 (v, 4);
1287 1.1 jakllsch }
1288 1.1 jakllsch
1289 1.1 jakllsch while (p1 != str) {
1290 1.1 jakllsch *(p2++) = *(--p1);
1291 1.1 jakllsch }
1292 1.1 jakllsch *p2 = 0;
1293 1.1 jakllsch }
1294 1.1 jakllsch
1295 1.1 jakllsch
1296 1.1 jakllsch VOID
1297 1.1 jakllsch ValueToString (
1298 1.1 jakllsch IN CHAR16 *Buffer,
1299 1.1 jakllsch IN BOOLEAN Comma,
1300 1.1 jakllsch IN INT64 v
1301 1.1 jakllsch )
1302 1.1 jakllsch {
1303 1.1 jakllsch STATIC CHAR8 ca[] = { 3, 1, 2 };
1304 1.1 jakllsch CHAR8 str[40], *p1;
1305 1.1 jakllsch CHAR16 *p2;
1306 1.1 jakllsch UINTN c, r;
1307 1.1 jakllsch
1308 1.1 jakllsch if (!v) {
1309 1.1 jakllsch Buffer[0] = '0';
1310 1.1 jakllsch Buffer[1] = 0;
1311 1.1 jakllsch return ;
1312 1.1 jakllsch }
1313 1.1 jakllsch
1314 1.1 jakllsch p1 = str;
1315 1.1 jakllsch p2 = Buffer;
1316 1.1 jakllsch
1317 1.1 jakllsch if (v < 0) {
1318 1.1 jakllsch *(p2++) = '-';
1319 1.1 jakllsch v = -v;
1320 1.1 jakllsch }
1321 1.1 jakllsch
1322 1.1 jakllsch while (v) {
1323 1.1 jakllsch v = (INT64)DivU64x32 ((UINT64)v, 10, &r);
1324 1.1 jakllsch *(p1++) = (CHAR8)r + '0';
1325 1.1 jakllsch }
1326 1.1 jakllsch
1327 1.1 jakllsch c = (Comma ? ca[(p1 - str) % 3] : 999) + 1;
1328 1.1 jakllsch while (p1 != str) {
1329 1.1 jakllsch
1330 1.1 jakllsch c -= 1;
1331 1.1 jakllsch if (!c) {
1332 1.1 jakllsch *(p2++) = ',';
1333 1.1 jakllsch c = 3;
1334 1.1 jakllsch }
1335 1.1 jakllsch
1336 1.1 jakllsch *(p2++) = *(--p1);
1337 1.1 jakllsch }
1338 1.1 jakllsch *p2 = 0;
1339 1.1 jakllsch }
1340 1.1 jakllsch
1341 1.2 jmcneill #ifndef __NetBSD__
1342 1.2 jmcneill VOID
1343 1.2 jmcneill FloatToString (
1344 1.2 jmcneill IN CHAR16 *Buffer,
1345 1.2 jmcneill IN BOOLEAN Comma,
1346 1.2 jmcneill IN double v
1347 1.2 jmcneill )
1348 1.2 jmcneill {
1349 1.2 jmcneill /*
1350 1.2 jmcneill * Integer part.
1351 1.2 jmcneill */
1352 1.2 jmcneill INTN i = (INTN)v;
1353 1.2 jmcneill ValueToString(Buffer, Comma, i);
1354 1.2 jmcneill
1355 1.2 jmcneill
1356 1.2 jmcneill /*
1357 1.2 jmcneill * Decimal point.
1358 1.2 jmcneill */
1359 1.2 jmcneill UINTN x = StrLen(Buffer);
1360 1.2 jmcneill Buffer[x] = L'.';
1361 1.2 jmcneill x++;
1362 1.2 jmcneill
1363 1.2 jmcneill
1364 1.2 jmcneill /*
1365 1.2 jmcneill * Keep fractional part.
1366 1.2 jmcneill */
1367 1.2 jmcneill float f = (float)(v - i);
1368 1.2 jmcneill if (f < 0) f = -f;
1369 1.2 jmcneill
1370 1.2 jmcneill
1371 1.2 jmcneill /*
1372 1.2 jmcneill * Leading fractional zeroes.
1373 1.2 jmcneill */
1374 1.2 jmcneill f *= 10.0;
1375 1.2 jmcneill while ( (f != 0)
1376 1.2 jmcneill && ((INTN)f == 0))
1377 1.2 jmcneill {
1378 1.2 jmcneill Buffer[x] = L'0';
1379 1.2 jmcneill x++;
1380 1.2 jmcneill f *= 10.0;
1381 1.2 jmcneill }
1382 1.2 jmcneill
1383 1.2 jmcneill
1384 1.2 jmcneill /*
1385 1.2 jmcneill * Fractional digits.
1386 1.2 jmcneill */
1387 1.2 jmcneill while ((float)(INTN)f != f)
1388 1.2 jmcneill {
1389 1.2 jmcneill f *= 10;
1390 1.2 jmcneill }
1391 1.2 jmcneill ValueToString(Buffer + x, FALSE, (INTN)f);
1392 1.2 jmcneill return;
1393 1.2 jmcneill }
1394 1.2 jmcneill #endif
1395 1.2 jmcneill
1396 1.1 jakllsch VOID
1397 1.1 jakllsch TimeToString (
1398 1.1 jakllsch OUT CHAR16 *Buffer,
1399 1.1 jakllsch IN EFI_TIME *Time
1400 1.1 jakllsch )
1401 1.1 jakllsch {
1402 1.1 jakllsch UINTN Hour, Year;
1403 1.1 jakllsch CHAR16 AmPm;
1404 1.1 jakllsch
1405 1.1 jakllsch AmPm = 'a';
1406 1.1 jakllsch Hour = Time->Hour;
1407 1.1 jakllsch if (Time->Hour == 0) {
1408 1.1 jakllsch Hour = 12;
1409 1.1 jakllsch } else if (Time->Hour >= 12) {
1410 1.1 jakllsch AmPm = 'p';
1411 1.1 jakllsch if (Time->Hour >= 13) {
1412 1.1 jakllsch Hour -= 12;
1413 1.1 jakllsch }
1414 1.1 jakllsch }
1415 1.1 jakllsch
1416 1.1 jakllsch Year = Time->Year % 100;
1417 1.2 jmcneill
1418 1.1 jakllsch // bugbug: for now just print it any old way
1419 1.1 jakllsch SPrint (Buffer, 0, L"%02d/%02d/%02d %02d:%02d%c",
1420 1.1 jakllsch Time->Month,
1421 1.1 jakllsch Time->Day,
1422 1.1 jakllsch Year,
1423 1.1 jakllsch Hour,
1424 1.1 jakllsch Time->Minute,
1425 1.1 jakllsch AmPm
1426 1.1 jakllsch );
1427 1.2 jmcneill }
1428 1.1 jakllsch
1429 1.1 jakllsch
1430 1.1 jakllsch
1431 1.1 jakllsch
1432 1.1 jakllsch VOID
1433 1.1 jakllsch DumpHex (
1434 1.1 jakllsch IN UINTN Indent,
1435 1.1 jakllsch IN UINTN Offset,
1436 1.1 jakllsch IN UINTN DataSize,
1437 1.1 jakllsch IN VOID *UserData
1438 1.1 jakllsch )
1439 1.1 jakllsch {
1440 1.1 jakllsch CHAR8 *Data, Val[50], Str[20], c;
1441 1.1 jakllsch UINTN Size, Index;
1442 1.2 jmcneill
1443 1.1 jakllsch UINTN ScreenCount;
1444 1.1 jakllsch UINTN TempColumn;
1445 1.1 jakllsch UINTN ScreenSize;
1446 1.1 jakllsch CHAR16 ReturnStr[1];
1447 1.1 jakllsch
1448 1.1 jakllsch
1449 1.1 jakllsch uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut, ST->ConOut->Mode->Mode, &TempColumn, &ScreenSize);
1450 1.1 jakllsch ScreenCount = 0;
1451 1.1 jakllsch ScreenSize -= 2;
1452 1.1 jakllsch
1453 1.1 jakllsch Data = UserData;
1454 1.1 jakllsch while (DataSize) {
1455 1.1 jakllsch Size = 16;
1456 1.1 jakllsch if (Size > DataSize) {
1457 1.1 jakllsch Size = DataSize;
1458 1.1 jakllsch }
1459 1.1 jakllsch
1460 1.1 jakllsch for (Index=0; Index < Size; Index += 1) {
1461 1.1 jakllsch c = Data[Index];
1462 1.1 jakllsch Val[Index*3+0] = Hex[c>>4];
1463 1.1 jakllsch Val[Index*3+1] = Hex[c&0xF];
1464 1.1 jakllsch Val[Index*3+2] = (Index == 7)?'-':' ';
1465 1.1 jakllsch Str[Index] = (c < ' ' || c > 'z') ? '.' : c;
1466 1.1 jakllsch }
1467 1.1 jakllsch
1468 1.1 jakllsch Val[Index*3] = 0;
1469 1.1 jakllsch Str[Index] = 0;
1470 1.1 jakllsch Print (L"%*a%X: %-.48a *%a*\n", Indent, "", Offset, Val, Str);
1471 1.1 jakllsch
1472 1.1 jakllsch Data += Size;
1473 1.1 jakllsch Offset += Size;
1474 1.1 jakllsch DataSize -= Size;
1475 1.1 jakllsch
1476 1.1 jakllsch ScreenCount++;
1477 1.1 jakllsch if (ScreenCount >= ScreenSize && ScreenSize != 0) {
1478 1.1 jakllsch //
1479 1.1 jakllsch // If ScreenSize == 0 we have the console redirected so don't
1480 1.1 jakllsch // block updates
1481 1.1 jakllsch //
1482 1.1 jakllsch ScreenCount = 0;
1483 1.1 jakllsch Print (L"Press Enter to continue :");
1484 1.1 jakllsch Input (L"", ReturnStr, sizeof(ReturnStr)/sizeof(CHAR16));
1485 1.1 jakllsch Print (L"\n");
1486 1.1 jakllsch }
1487 1.1 jakllsch
1488 1.1 jakllsch }
1489 1.1 jakllsch }
1490