Subversion Repositories freemyipod

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
881 theseven 1
#include "global.h"
2
#include "lib/printf/printf.h"
3
 
4
static const char printf_hexdigit[] = "0123456789ABCDEF";
5
 
6
int printf_format(int (*push)(void *userp, unsigned char data), void *userp, const char *fmt, va_list ap)
7
{
8
    char *str;
9
    char tmpbuf[12], pad;
10
    int ch, width, val, sign, precision;
11
    long lval, lsign;
12
    unsigned int uval;
13
    unsigned long ulval;
14
    bool ok = true;
15
 
16
    tmpbuf[sizeof tmpbuf - 1] = '\0';
17
 
18
    while ((ch = *fmt++) != '\0' && ok)
19
    {
20
        if (ch == '%')
21
        {
22
            ch = *fmt++;
23
            pad = ' ';
24
            if (ch == '0')
25
            pad = '0';
26
 
27
            width = 0;
28
            while (ch >= '0' && ch <= '9')
29
            {
30
                width = 10 * width + ch - '0';
31
                ch = *fmt++;
32
            }
33
 
34
            precision = 0;
35
            if (ch == '.')
36
            {
37
                ch = *fmt++;
38
                while (ch >= '0' && ch <= '9')
39
                {
40
                    precision = 10 * precision + ch - '0';
41
                    ch = *fmt++;
42
                }
43
            }
44
            else precision = 12;
45
 
46
            str = tmpbuf + sizeof tmpbuf - 1;
47
            switch (ch)
48
            {
49
            case 'c':
50
                *--str = va_arg(ap, int);
51
                break;
52
 
53
            case 's':
54
                str = va_arg(ap, char*);
55
                break;
56
 
57
            case 'd':
58
                val = sign = va_arg(ap, int);
59
                if (val < 0) val = -val;
60
                do
61
                {
62
                    *--str = (val % 10) + '0';
63
                    val /= 10;
64
                }
65
                while (val > 0);
66
                if (sign < 0) *--str = '-';
67
                break;
68
 
69
            case 'u':
70
                uval = va_arg(ap, unsigned int);
71
                do
72
                {
73
                    *--str = (uval % 10) + '0';
74
                    uval /= 10;
75
                }
76
                while (uval > 0);
77
                break;
78
 
79
            case 'x':
80
            case 'X':
81
                pad='0';
82
                uval = va_arg(ap, int);
83
                do
84
                {
85
                    *--str = printf_hexdigit[uval & 0xf];
86
                    uval >>= 4;
87
                }
88
                while (uval);
89
                break;
90
 
91
            case 'l':
92
            case 'z':
93
                ch = *fmt++;
94
                switch(ch)
95
                {
96
                case 'x':
97
                case 'X':
98
                    pad='0';
99
                    ulval = va_arg(ap, long);
100
                    do
101
                    {
102
                        *--str = printf_hexdigit[ulval & 0xf];
103
                        ulval >>= 4;
104
                    }
105
                    while (ulval);
106
                    break;
107
                case 'd':
108
                    lval = lsign = va_arg(ap, long);
109
                    if (lval < 0) lval = -lval;
110
                    do
111
                    {
112
                        *--str = (lval % 10) + '0';
113
                        lval /= 10;
114
                    }
115
                    while (lval > 0);
116
                    if (lsign < 0) *--str = '-';
117
                    break;
118
 
119
                case 'u':
120
                    ulval = va_arg(ap, unsigned long);
121
                    do
122
                    {
123
                        *--str = (ulval % 10) + '0';
124
                        ulval /= 10;
125
                    }
126
                    while (ulval > 0);
127
                    break;
128
 
129
                default:
130
                    *--str = 'l';
131
                    *--str = ch;
132
                    break;
133
                }
134
                break;
135
 
136
            default:
137
                *--str = ch;
138
                break;
139
            }
140
 
141
            if (width > 0)
142
            {
143
                const char* p = str;
144
                while (*p++) width--;
145
                while (width-- > 0 && ok) ok = push(userp, pad);
146
            }
147
            while (*str != '\0' && ok && precision--) ok = push(userp, *str++);
148
    }
149
    else
150
        ok = push(userp, ch);
151
    }
152
    return ok;
153
}