Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
#include <ll/i386/stdlib.h>
23
#include <ll/i386/string.h>
24
#include <ll/i386/limits.h>
25
#include <ll/i386/float.h>
26
#include <ll/i386/mem.h>
27
#include <ll/stdarg.h>
28
#include <ll/ctype.h>
29
#include <ll/math.h>
30
#include "sprintf.h"
31
 
32
FILE(sprintf);
33
 
34
#define STD_SIZE        0
35
#define SHORT_SIZE      1
36
#define LONG_SIZE       2
37
 
38
int vsprintf(char *buf,char *fmt,va_list parms)
39
{
40
    int scanned = 0,w = 0,prec = 0,l = 0,size = 0;
41
    int n1 = 0;
42
    unsigned n2 = 0,parsing = 0,flag = 0;
43
    double n3 = 0.0;
44
    char *base = buf;
45
    char *sp = NULL;
46
    void *fp = NULL;
47
    while (*fmt != 0) {
48
        if (*fmt != '%' && !parsing) {
49
            /* No token detected */
50
            *buf++ = *fmt++;
51
            scanned++;
52
        }
53
        else {     
54
            /* We need to make a conversion */
55
            if (*fmt == '%') {
56
                fmt++;
57
                parsing = 1;
58
                w = 10;
59
                prec = 4;
60
                size = STD_SIZE;
61
                flag = 0;
62
            }
63
            /* Parse token */
64
            switch(*fmt) {
65
                case '%' : *buf++ = '%';
66
                           scanned++;
67
                           parsing = 0;
68
                           break;
69
                case 'c' : *buf++ = va_arg(parms, char);
70
                           scanned++;
71
                           parsing = 0;
72
                           break;
73
                case 'i' :
74
                case 'd' : switch (size) {
75
                                case STD_SIZE : n1 = va_arg(parms, int);
76
                                                break;
77
                                case LONG_SIZE : n1 = va_arg(parms, long int);
78
                                                 break;
79
                                case SHORT_SIZE : n1 = va_arg(parms, short int);
80
                                                  break;
81
                           }
82
                           l = dcvt(n1,buf,10,w,flag);
83
                           scanned += l;
84
                           buf += l;
85
                           parsing = 0;
86
                           break;
87
                case 'u' : switch (size) {
88
                                case STD_SIZE : n2 = va_arg(parms, unsigned);
89
                                                break;
90
                                case LONG_SIZE : n2 = va_arg(parms, unsigned long);
91
                                                 break;
92
                                case SHORT_SIZE : n2 = va_arg(parms, unsigned short);
93
                                                  break;
94
                           }
95
                           l = ucvt(n2,buf,10,w,flag);
96
                           scanned += l;
97
                           buf += l;
98
                           parsing = 0;
99
                           break;
100
                case 'x' : switch (size) {
101
                                case STD_SIZE : n2 = va_arg(parms, unsigned);
102
                                                break;
103
                                case LONG_SIZE : n2 = va_arg(parms, unsigned long);
104
                                                 break;
105
                                case SHORT_SIZE : n2 = va_arg(parms, unsigned short);
106
                                                  break;
107
                           }
108
                           l = ucvt(n2,buf,16,w,flag);
109
                           scanned += l;
110
                           buf += l;
111
                           parsing = 0;
112
                           break;
113
                case 'p' : fp = va_arg(parms, void *);
114
                           n2 = (unsigned long)(fp);
115
                           l = ucvt(n2,buf,16,w,0);
116
                           scanned += l;
117
                           buf += l;
118
                           parsing = 0;
119
                           break;
120
                case 's' : sp = va_arg(parms, char *);
121
                           while (*sp != 0) {
122
                               *buf++ = *sp++;
123
                               l++;
124
                           }
125
                           scanned += l;
126
                           parsing = 0;
127
                           break;
128
                case 'f' : switch (size) {
129
                                case STD_SIZE : n3 = va_arg(parms, double);
130
                                                break;
131
                                case LONG_SIZE : n3 = va_arg(parms, double);
132
                                                 break;
133
                                /*
134
                                It seems that the compilers push a float as
135
                                a double ... Need to check!
136
                                */
137
                                case SHORT_SIZE : n3 = va_arg(parms, double);
138
                                                  break;
139
                           }
140
                           l = fcvt(n3,buf,w,prec,flag);
141
                           scanned += l;
142
                           buf += l;
143
                           parsing = 0;
144
                           break;
145
                case 'e' : switch (size) {
146
                                case STD_SIZE : n3 = va_arg(parms, double);
147
                                                break;
148
                                case LONG_SIZE : n3 = va_arg(parms, double);
149
                                                 break;
150
                                /*
151
                                It seems that the compilers push a float as
152
                                a double ... Need to check!
153
                                */
154
                                case SHORT_SIZE : n3 = va_arg(parms, double);
155
                                                  break;
156
                           }
157
                           l = ecvt(n3,buf,w,prec,flag);
158
                           scanned += l;
159
                           buf += l;
160
                           parsing = 0;
161
                           break;                          
162
                case 'g' : switch (size) {
163
                                case STD_SIZE : n3 = va_arg(parms, double);
164
                                                break;
165
                                case LONG_SIZE : n3 = va_arg(parms, double);
166
                                                 break;
167
                                /*
168
                                It seems that the compilers push a float as
169
                                a double ... Need to check!
170
                                */
171
                                case SHORT_SIZE : n3 = va_arg(parms, double);
172
                                                  break;
173
                           }
174
                           l = gcvt(n3,buf,w,prec,flag);
175
                           scanned += l;
176
                           buf += l;
177
                           parsing = 0;
178
                           break;
179
                case 'l' : size = LONG_SIZE;
180
                           break;
181
                case 'n' :
182
                case 'h' : size = SHORT_SIZE;
183
                           break;
184
                case '+' : flag |= ADD_PLUS;
185
                           break;
186
                case '-' : flag |= LEFT_PAD;
187
                           break;
188
                case '.' : parsing = 2;
189
                           flag |= RESPECT_WIDTH;
190
                           break;
191
                case '1' :
192
                case '2' :
193
                case '3' :
194
                case '4' :
195
                case '5' :
196
                case '6' :
197
                case '7' :
198
                case '8' :
199
                case '9' :
200
                case '0' : if (parsing == 1) {
201
                              w = strtou(fmt,10,&base);
202
                              /* MG */
203
                              /* if the first numeral is zero a ZERO pad is */
204
                              /* required */
205
                              /* but not if LEFT_PAD is set*/
206
                              if (*fmt!='0'||flag&LEFT_PAD)
207
                                  flag |= SPACE_PAD ;
208
                              else
209
                                  flag |= ZERO_PAD ;
210
                              fmt = base-1;
211
                           } else if (parsing == 2) {
212
                               prec = strtou(fmt,10,&base);
213
                               fmt = base-1;
214
                               parsing = 1;
215
                           }
216
                           break;
217
                default :  parsing = 0;
218
                           break;
219
            }
220
            fmt++;
221
        }
222
    }
223
    *buf = 0;
224
    return(scanned);
225
}
226
 
227
int sprintf(char *buf,char *fmt,...)
228
{
229
    va_list parms;
230
    int result;
231
    va_start(parms,fmt);
232
    result = vsprintf(buf,fmt,parms);
233
    va_end(parms);
234
    return(result);
235
}