Subversion Repositories HelenOS

Rev

Rev 2726 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2726 Rev 2782
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