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