Subversion Repositories DashDisplay

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
26 mjames 1
/*
2
        Copyright 2001, 2002 Georges Menie (www.menie.org)
3
        stdarg version contributed by Christian Ettinger
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU Lesser General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU Lesser General Public License for more details.
14
 
15
    You should have received a copy of the GNU Lesser General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
*/
19
 
20
/* Includes */
21
 
22
 
23
#include "../../small_printf/Inc/small_printf.h"
24
 
25
#include <stdarg.h>
26
#include <stdio.h>
27
#include <string.h>
28
 
29
/*
30
        putchar is the only external dependency for this file,
31
        if you have a working putchar, leave it commented out.
32
        If not, uncomment the define below and
33
        replace outbyte(c) by your own function call.
34
*/
35
 
36
 
37
 
38
static void printchar(char **str, int c)
39
{
40
 
41
 
42
        if (str) {
43
                **str = c;
44
                ++(*str);
45
        }
46
        else (void)PutCharSerial(c);
47
}
48
 
49
#define PAD_RIGHT 1
50
#define PAD_ZERO 2
51
 
52
static int prints(char **out, const char *string, int width, int pad)
53
{
54
        register int pc = 0, padchar = ' ';
55
 
56
        if (width > 0) {
57
                register int len = 0;
58
                register const char *ptr;
59
                for (ptr = string; *ptr; ++ptr) ++len;
60
                if (len >= width) width = 0;
61
                else width -= len;
62
                if (pad & PAD_ZERO) padchar = '0';
63
        }
64
        if (!(pad & PAD_RIGHT)) {
65
                for ( ; width > 0; --width) {
66
                        printchar (out, padchar);
67
                        ++pc;
68
                }
69
        }
70
        for ( ; *string ; ++string) {
71
                printchar (out, *string);
72
                ++pc;
73
        }
74
        for ( ; width > 0; --width) {
75
                printchar (out, padchar);
76
                ++pc;
77
        }
78
 
79
        return pc;
80
}
81
 
82
/* the following should be enough for 32 bit int */
83
#define PRINT_BUF_LEN 12
84
 
85
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
86
{
87
        char print_buf[PRINT_BUF_LEN];
88
        register char *s;
89
        register int t, neg = 0, pc = 0;
90
        register unsigned int u = i;
91
 
92
        if (i == 0) {
93
                print_buf[0] = '0';
94
                print_buf[1] = '\0';
95
                return prints (out, print_buf, width, pad);
96
        }
97
 
98
        if (sg && b == 10 && i < 0) {
99
                neg = 1;
100
                u = -i;
101
        }
102
 
103
        s = print_buf + PRINT_BUF_LEN-1;
104
        *s = '\0';
105
 
106
        while (u) {
107
                t = u % b;
108
                if( t >= 10 )
109
                        t += letbase - '0' - 10;
110
                *--s = t + '0';
111
                u /= b;
112
        }
113
 
114
        if (neg) {
115
                if( width && (pad & PAD_ZERO) ) {
116
                        printchar (out, '-');
117
                        ++pc;
118
                        --width;
119
                }
120
                else {
121
                        *--s = '-';
122
                }
123
        }
124
 
125
        return pc + prints (out, s, width, pad);
126
}
127
 
128
static int small_print(char **out, const char *format, va_list args )
129
{
130
        register int width, pad;
131
        register int pc = 0;
132
        char scr[2];
133
 
134
        for (; *format != 0; ++format) {
135
                if (*format == '%') {
136
                        ++format;
137
                        width = pad = 0;
138
                        if (*format == '\0') break;
139
                        if (*format == '%') goto out;
140
                        if (*format == '-') {
141
                                ++format;
142
                                pad = PAD_RIGHT;
143
                        }
144
                        while (*format == '0') {
145
                                ++format;
146
                                pad |= PAD_ZERO;
147
                        }
148
                        if ('*' == *format)
149
                        {
150
                                width = va_arg( args, int );    // get width from next argument
151
                                format++;
152
                        }
153
                        else
154
                        {
155
                                for ( ; *format >= '0' && *format <= '9'; ++format)
156
                                {
157
                                        width *= 10;
158
                                        width += *format - '0';
159
                                }
160
                        }
161
                        if( *format == 'l') { /* skip l in ld etc */
162
                                format++;
163
                        }
164
                        if( *format == 's' ) {
165
                                register char *s = (char *)va_arg( args, int );
166
                                pc += prints (out, s?s:"(null)", width, pad);
167
                                continue;
168
                        }
169
                        if( *format == 'd' ) {
170
                                pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
171
                                continue;
172
                        }
173
                        if( *format == 'x' ) {
174
                                pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a');
175
                                continue;
176
                        }
177
                        if( *format == 'X' ) {
178
                                pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A');
179
                                continue;
180
                        }
181
                        if( *format == 'u' ) {
182
                                pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
183
                                continue;
184
                        }
185
                        if( *format == 'c' ) {
186
                                /* char are converted to int then pushed on the stack */
187
                                scr[0] = (char)va_arg( args, int );
188
                                scr[1] = '\0';
189
                                pc += prints (out, scr, width, pad);
190
                                continue;
191
                        }
192
                        if( *format == 'n' )
193
                        {       /* convert number printed so far and store in *va_arg( args, int)... */
194
                                int *dp = va_arg( args, int );
195
                                *dp = pc;
196
                                continue;
197
                        }
198
                }
199
                else {
200
                out:
201
                        /* deal with LF -> CRLF mapping */
202
                        if(*format == '\n')
203
                        {
204
                                printchar(out,'\r');
205
                        }
206
                        printchar (out, *format);
207
                        ++pc;
208
                }
209
        }
210
        if (out) **out = '\0';
211
        return pc;
212
}
213
 
214
 
215
int small_printf(const char *format, ...)
216
{
217
        int result = 0;
218
        va_list args;
219
 
220
        va_start( args, format );
221
        result = small_print( 0, format, args );
222
        va_end(args);
223
        return result;
224
}
225
 
226
int small_sprintf(char *out, const char *format, ...)
227
{
228
    int result = 0;
229
                va_list args;
230
        va_start( args, format );
231
        result = small_print( &out, format, args );
232
        va_end(args);
233
        return result;
234
}
235