source: bootcd/isolinux/syslinux-6.03/gnu-efi/gnu-efi-3.0/lib/print.c @ e16e8f2

Last change on this file since e16e8f2 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

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