Subversion Repositories HelenOS

Rev

Rev 3022 | Rev 4201 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3022 Rev 4055
Line 38... Line 38...
38
#include <printf/printf_core.h>
38
#include <printf/printf_core.h>
39
#include <putchar.h>
39
#include <putchar.h>
40
#include <print.h>
40
#include <print.h>
41
#include <arch/arg.h>
41
#include <arch/arg.h>
42
#include <macros.h>
42
#include <macros.h>
43
#include <func.h>
43
#include <string.h>
44
#include <arch.h>
44
#include <arch.h>
45
 
45
 
46
/** show prefixes 0x or 0 */
46
/** show prefixes 0x or 0 */
47
#define __PRINTF_FLAG_PREFIX        0x00000001
47
#define __PRINTF_FLAG_PREFIX        0x00000001
48
/** signed / unsigned number */
48
/** signed / unsigned number */
Line 73... Line 73...
73
    PrintfQualifierByte = 0,
73
    PrintfQualifierByte = 0,
74
    PrintfQualifierShort,
74
    PrintfQualifierShort,
75
    PrintfQualifierInt,
75
    PrintfQualifierInt,
76
    PrintfQualifierLong,
76
    PrintfQualifierLong,
77
    PrintfQualifierLongLong,
77
    PrintfQualifierLongLong,
78
    PrintfQualifierNative,
-
 
79
    PrintfQualifierPointer
78
    PrintfQualifierPointer
80
} qualifier_t;
79
} qualifier_t;
81
 
80
 
82
static char digits_small[] = "0123456789abcdef";
81
static char digits_small[] = "0123456789abcdef";
83
static char digits_big[] = "0123456789ABCDEF";
82
static char digits_big[] = "0123456789ABCDEF";
Line 430... Line 429...
430
 *  - "hh"  Signed or unsigned char.@n
429
 *  - "hh"  Signed or unsigned char.@n
431
 *  - "h"   Signed or unsigned short.@n
430
 *  - "h"   Signed or unsigned short.@n
432
 *  - ""    Signed or unsigned int (default value).@n
431
 *  - ""    Signed or unsigned int (default value).@n
433
 *  - "l"   Signed or unsigned long int.@n
432
 *  - "l"   Signed or unsigned long int.@n
434
 *  - "ll"  Signed or unsigned long long int.@n
433
 *  - "ll"  Signed or unsigned long long int.@n
435
 *  - "z"   unative_t (non-standard extension).@n
-
 
436
 *
434
 *
437
 *
435
 *
438
 * CONVERSION:@n
436
 * CONVERSION:@n
439
 *  - % Print percentile character itself.
437
 *  - % Print percentile character itself.
440
 *
438
 *
Line 484... Line 482...
484
   
482
   
485
    counter = 0;
483
    counter = 0;
486
       
484
       
487
    while ((c = fmt[i])) {
485
    while ((c = fmt[i])) {
488
        /* control character */
486
        /* control character */
489
        if (c == '%' ) {
487
        if (c == '%') {
490
            /* print common characters if any processed */ 
488
            /* print common characters if any processed */ 
491
            if (i > j) {
489
            if (i > j) {
492
                if ((retval = printf_putnchars(&fmt[j],
490
                if ((retval = printf_putnchars(&fmt[j],
493
                    (size_t)(i - j), ps)) < 0) { /* error */
491
                    (size_t)(i - j), ps)) < 0) { /* error */
494
                    counter = -counter;
492
                    counter = -counter;
Line 534... Line 532...
534
                    width += fmt[i++] - '0';
532
                    width += fmt[i++] - '0';
535
                }
533
                }
536
            } else if (fmt[i] == '*') {
534
            } else if (fmt[i] == '*') {
537
                /* get width value from argument list */
535
                /* get width value from argument list */
538
                i++;
536
                i++;
539
                width = (int)va_arg(ap, int);
537
                width = (int) va_arg(ap, int);
540
                if (width < 0) {
538
                if (width < 0) {
541
                    /* negative width sets '-' flag */
539
                    /* negative width sets '-' flag */
542
                    width *= -1;
540
                    width *= -1;
543
                    flags |= __PRINTF_FLAG_LEFTALIGNED;
541
                    flags |= __PRINTF_FLAG_LEFTALIGNED;
544
                }
542
                }
Line 557... Line 555...
557
                    /*
555
                    /*
558
                     * Get precision value from the argument
556
                     * Get precision value from the argument
559
                     * list.
557
                     * list.
560
                     */
558
                     */
561
                    i++;
559
                    i++;
562
                    precision = (int)va_arg(ap, int);
560
                    precision = (int) va_arg(ap, int);
563
                    if (precision < 0) {
561
                    if (precision < 0) {
564
                        /* ignore negative precision */
562
                        /* ignore negative precision */
565
                        precision = 0;
563
                        precision = 0;
566
                    }
564
                    }
567
                }
565
                }
Line 583... Line 581...
583
                if (fmt[i] == 'l') {
581
                if (fmt[i] == 'l') {
584
                    i++;
582
                    i++;
585
                    qualifier = PrintfQualifierLongLong;
583
                    qualifier = PrintfQualifierLongLong;
586
                }
584
                }
587
                break;
585
                break;
588
            case 'z':   /* unative_t */
-
 
589
                qualifier = PrintfQualifierNative;
-
 
590
                break;
-
 
591
            default:
586
            default:
592
                /* default type */
587
                /* default type */
593
                qualifier = PrintfQualifierInt;
588
                qualifier = PrintfQualifierInt;
594
                --i;
589
                --i;
595
            }  
590
            }  
Line 625... Line 620...
625
 
620
 
626
            /*
621
            /*
627
             * Integer values
622
             * Integer values
628
             */
623
             */
629
            case 'P': /* pointer */
624
            case 'P': /* pointer */
630
                    flags |= __PRINTF_FLAG_BIGCHARS;
625
                flags |= __PRINTF_FLAG_BIGCHARS;
631
            case 'p':
626
            case 'p':
632
                flags |= __PRINTF_FLAG_PREFIX;
627
                flags |= __PRINTF_FLAG_PREFIX;
633
                base = 16;
628
                base = 16;
634
                qualifier = PrintfQualifierPointer;
629
                qualifier = PrintfQualifierPointer;
635
                break; 
630
                break; 
Line 668... Line 663...
668
        /* Print integers */
663
        /* Print integers */
669
            /* print number */
664
            /* print number */
670
            switch (qualifier) {
665
            switch (qualifier) {
671
            case PrintfQualifierByte:
666
            case PrintfQualifierByte:
672
                size = sizeof(unsigned char);
667
                size = sizeof(unsigned char);
673
                number = (uint64_t)va_arg(ap, unsigned int);
668
                number = (uint64_t) va_arg(ap, unsigned int);
674
                break;
669
                break;
675
            case PrintfQualifierShort:
670
            case PrintfQualifierShort:
676
                size = sizeof(unsigned short);
671
                size = sizeof(unsigned short);
677
                number = (uint64_t)va_arg(ap, unsigned int);
672
                number = (uint64_t) va_arg(ap, unsigned int);
678
                break;
673
                break;
679
            case PrintfQualifierInt:
674
            case PrintfQualifierInt:
680
                size = sizeof(unsigned int);
675
                size = sizeof(unsigned int);
681
                number = (uint64_t)va_arg(ap, unsigned int);
676
                number = (uint64_t) va_arg(ap, unsigned int);
682
                break;
677
                break;
683
            case PrintfQualifierLong:
678
            case PrintfQualifierLong:
684
                size = sizeof(unsigned long);
679
                size = sizeof(unsigned long);
685
                number = (uint64_t)va_arg(ap, unsigned long);
680
                number = (uint64_t) va_arg(ap, unsigned long);
686
                break;
681
                break;
687
            case PrintfQualifierLongLong:
682
            case PrintfQualifierLongLong:
688
                size = sizeof(unsigned long long);
683
                size = sizeof(unsigned long long);
689
                number = (uint64_t)va_arg(ap,
684
                number = (uint64_t) va_arg(ap, unsigned long long);
690
                    unsigned long long);
-
 
691
                break;
685
                break;
692
            case PrintfQualifierPointer:
686
            case PrintfQualifierPointer:
693
                size = sizeof(void *);
687
                size = sizeof(void *);
694
                number = (uint64_t)(unsigned long)va_arg(ap,
688
                number = (uint64_t) (unsigned long) va_arg(ap, void *);
695
                    void *);
-
 
696
                break;
-
 
697
            case PrintfQualifierNative:
-
 
698
                size = sizeof(unative_t);
-
 
699
                number = (uint64_t)va_arg(ap, unative_t);
-
 
700
                break;
689
                break;
701
            default: /* Unknown qualifier */
690
            default: /* Unknown qualifier */
702
                counter = -counter;
691
                counter = -counter;
703
                goto out;
692
                goto out;
704
            }
693
            }
Line 706... Line 695...
706
            if (flags & __PRINTF_FLAG_SIGNED) {
695
            if (flags & __PRINTF_FLAG_SIGNED) {
707
                if (number & (0x1 << (size * 8 - 1))) {
696
                if (number & (0x1 << (size * 8 - 1))) {
708
                    flags |= __PRINTF_FLAG_NEGATIVE;
697
                    flags |= __PRINTF_FLAG_NEGATIVE;
709
               
698
               
710
                    if (size == sizeof(uint64_t)) {
699
                    if (size == sizeof(uint64_t)) {
711
                        number = -((int64_t)number);
700
                        number = -((int64_t) number);
712
                    } else {
701
                    } else {
713
                        number = ~number;
702
                        number = ~number;
714
                        number &=
703
                        number &=
715
                            ~(0xFFFFFFFFFFFFFFFFll <<
704
                            ~(0xFFFFFFFFFFFFFFFFll <<
716
                            (size * 8));
705
                            (size * 8));
Line 732... Line 721...
732
           
721
           
733
        ++i;
722
        ++i;
734
    }
723
    }
735
   
724
   
736
    if (i > j) {
725
    if (i > j) {
737
        if ((retval = printf_putnchars(&fmt[j], (unative_t)(i - j),
726
        if ((retval = printf_putnchars(&fmt[j], (unative_t) (i - j),
738
            ps)) < 0) { /* error */
727
            ps)) < 0) { /* error */
739
            counter = -counter;
728
            counter = -counter;
740
            goto out;
729
            goto out;
741
           
730
           
742
        }
731
        }
743
        counter += retval;
732
        counter += retval;
744
    }
733
    }
745
 
734
 
746
out:
735
out:
747
   
-
 
748
    return counter;
736
    return counter;
749
}
737
}
750
 
738
 
751
/** @}
739
/** @}
752
 */
740
 */