OpenCores
URL https://opencores.org/ocsvn/ion/ion/trunk

Subversion Repositories ion

[/] [ion/] [trunk/] [src/] [common/] [libsoc/] [src/] [printf-stdarg.c] - Blame information for rev 178

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 172 ja_rd
/**
2
    @file printf-stdarg.c
3
    @brief Replacement for printf. Limited functionality (e.g. no float format).
4
 
5
    This code relies on external functions getchar and putchar.
6
*/
7
/*
8
        Copyright 2001, 2002 Georges Menie (www.menie.org)
9
        stdarg version contributed by Christian Ettinger
10
 
11
    This program is free software; you can redistribute it and/or modify
12
    it under the terms of the GNU Lesser General Public License as published by
13
    the Free Software Foundation; either version 2 of the License, or
14
    (at your option) any later version.
15
 
16
    This program is distributed in the hope that it will be useful,
17
    but WITHOUT ANY WARRANTY; without even the implied warranty of
18
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
    GNU Lesser General Public License for more details.
20
 
21
    You should have received a copy of the GNU Lesser General Public License
22
    along with this program; if not, write to the Free Software
23
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24
*/
25
 
26
/*
27
        putchar is the only external dependency for this file,
28
        if you have a working putchar, leave it commented out.
29
        If not, uncomment the define below and
30
        replace outbyte(c) by your own function call.
31
 
32
#define putchar(c) outbyte(c)
33
*/
34
 
35
#include <stdarg.h>
36
 
37
/** Prints character to string buffer.
38
    Used by printf, not to be used directly.*/
39
static void printchar(char **str, int c)
40
{
41
        extern int putchar(int c);
42
 
43
        if (str) {
44
                **str = c;
45
                ++(*str);
46
        }
47
        else (void)putchar(c);
48
}
49
 
50
#define PAD_RIGHT (1)   /**<  */
51
#define PAD_ZERO (2)    /**< */
52
 
53
/** Prints formatted string to string buffer.
54
    Used by printf, not to be used directly.*/
55
static int prints(char **out, const char *string, int width, int pad)
56
{
57
        register int pc = 0, padchar = ' ';
58
 
59
        if (width > 0) {
60
                register int len = 0;
61
                register const char *ptr;
62
                for (ptr = string; *ptr; ++ptr) ++len;
63
                if (len >= width) width = 0;
64
                else width -= len;
65
                if (pad & PAD_ZERO) padchar = '0';
66
        }
67
        if (!(pad & PAD_RIGHT)) {
68
                for ( ; width > 0; --width) {
69
                        printchar (out, padchar);
70
                        ++pc;
71
                }
72
        }
73
        for ( ; *string ; ++string) {
74
                printchar (out, *string);
75
                ++pc;
76
        }
77
        for ( ; width > 0; --width) {
78
                printchar (out, padchar);
79
                ++pc;
80
        }
81
 
82
        return pc;
83
}
84
 
85
/** Temporary buffer used to print numbers to */
86
/* the following should be enough for 32 bit int */
87
#define PRINT_BUF_LEN 12
88
 
89
/** Prints formatted integer to string buffer.
90
    Used by printf, not to be used directly.*/
91
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase)
92
{
93
        char print_buf[PRINT_BUF_LEN];
94
        register char *s;
95
        register int t, neg = 0, pc = 0;
96
        register unsigned int u = i;
97
 
98
        if (i == 0) {
99
                print_buf[0] = '0';
100
                print_buf[1] = '\0';
101
                return prints (out, print_buf, width, pad);
102
        }
103
 
104
        if (sg && b == 10 && i < 0) {
105
                neg = 1;
106
                u = -i;
107
        }
108
 
109
        s = print_buf + PRINT_BUF_LEN-1;
110
        *s = '\0';
111
 
112
        while (u) {
113
                t = u % b;
114
                if( t >= 10 )
115
                        t += letbase - '0' - 10;
116
                *--s = t + '0';
117
                u /= b;
118
        }
119
 
120
        if (neg) {
121
                if( width && (pad & PAD_ZERO) ) {
122
                        printchar (out, '-');
123
                        ++pc;
124
                        --width;
125
                }
126
                else {
127
                        *--s = '-';
128
                }
129
        }
130
 
131
        return pc + prints (out, s, width, pad);
132
}
133
 
134
/** Main print function; parses format string and calls aux functions.
135
    Used by printf, not to be used directly.*/
136
static int print( char **out, const char *format, va_list args )
137
{
138
        register int width, pad;
139
        register int pc = 0;
140
        char scr[2];
141
 
142
        for (; *format != 0; ++format) {
143
                if (*format == '%') {
144
                        ++format;
145
                        width = pad = 0;
146
                        if (*format == '\0') break;
147
                        if (*format == '%') goto out;
148
                        if (*format == '-') {
149
                                ++format;
150
                                pad = PAD_RIGHT;
151
                        }
152
                        while (*format == '0') {
153
                                ++format;
154
                                pad |= PAD_ZERO;
155
                        }
156
                        for ( ; *format >= '0' && *format <= '9'; ++format) {
157
                                width *= 10;
158
                                width += *format - '0';
159
                        }
160
                        if( *format == 's' ) {
161
                                register char *s = (char *)va_arg( args, int );
162
                                pc += prints (out, s?s:"(null)", width, pad);
163
                                continue;
164
                        }
165
                        if( *format == 'd' ) {
166
                                pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a');
167
                                continue;
168
                        }
169
                        if( *format == 'x' ) {
170
                                pc += printi (out, va_arg( args, int ), 16, 0, 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 == 'u' ) {
178
                                pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a');
179
                                continue;
180
                        }
181
                        if( *format == 'c' ) {
182
                                /* char are converted to int then pushed on the stack */
183
                                scr[0] = (char)va_arg( args, int );
184
                                scr[1] = '\0';
185
                                pc += prints (out, scr, width, pad);
186
                                continue;
187
                        }
188
                }
189
                else {
190
                out:
191
                        printchar (out, *format);
192
                        ++pc;
193
                }
194
        }
195
        if (out) **out = '\0';
196
        va_end( args );
197
        return pc;
198
}
199
 
200
/** Replacement for standard printf. */
201
int printf(const char *format, ...)
202
{
203
        va_list args;
204
 
205
        va_start( args, format );
206
        return print( 0, format, args );
207
}
208
 
209
/** Replacement for standard sprintf. */
210
int sprintf(char *out, const char *format, ...)
211
{
212
        va_list args;
213
 
214
        va_start( args, format );
215
        return print( &out, format, args );
216
}
217
 
218
/**Replacement for standard snprintf.  */
219
int snprintf( char *buf, unsigned int count, const char *format, ... )
220
{
221
        va_list args;
222
 
223
        ( void ) count;
224
 
225
        va_start( args, format );
226
        return print( &buf, format, args );
227
}
228
 
229
 
230
#ifdef TEST_PRINTF
231
int main(void)
232
{
233
#if 1
234
        char *ptr = "Hello world!";
235
        char *np = 0;
236
        int i = 5;
237
        unsigned int bs = sizeof(int)*8;
238
        int mi;
239
        char buf[80];
240
 
241
        mi = (1 << (bs-1)) + 1;
242
        printf("%s\n", ptr);
243
        printf("printf test\n");
244
        printf("%s is null pointer\n", np);
245
        printf("%d = 5\n", i);
246
        printf("%d = - max int\n", mi);
247
        printf("char %c = 'a'\n", 'a');
248
        printf("hex %x = ff\n", 0xff);
249
        printf("hex %02x = 00\n", 0);
250
        printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3);
251
        printf("%d %s(s)%", 0, "message");
252
        printf("\n");
253
        printf("%d %s(s) with %%\n", 0, "message");
254
        sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf);
255
        sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf);
256
        sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf);
257
        sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf);
258
        sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf);
259
        sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf);
260
        sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf);
261
        sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf);
262
#endif
263
        return 0;
264
}
265
 
266
/*
267
 * if you compile this file with
268
 *   gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c
269
 * you will get a normal warning:
270
 *   printf.c:214: warning: spurious trailing `%' in format
271
 * this line is testing an invalid % at the end of the format string.
272
 *
273
 * this should display (on 32bit int machine) :
274
 *
275
 * Hello world!
276
 * printf test
277
 * (null) is null pointer
278
 * 5 = 5
279
 * -2147483647 = - max int
280
 * char a = 'a'
281
 * hex ff = ff
282
 * hex 00 = 00
283
 * signed -3 = unsigned 4294967293 = hex fffffffd
284
 * 0 message(s)
285
 * 0 message(s) with %
286
 * justif: "left      "
287
 * justif: "     right"
288
 *  3: 0003 zero padded
289
 *  3: 3    left justif.
290
 *  3:    3 right justif.
291
 * -3: -003 zero padded
292
 * -3: -3   left justif.
293
 * -3:   -3 right justif.
294
 */
295
 
296
#endif
297
 
298
 
299
/** Stub function, only used to deceive the linker. */
300
/* To keep linker happy. */
301
int     write( int i, char* c, int n)
302
{
303
        return 0;
304
}
305
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.