001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020 #include <string.h>
021
022 #include "stdarg.h"
023
024
025
026
027 int vsnprintf(char *buff, size_t len, const char * format, va_list ap)
028 {
029 int i, result;
030 int fmt_modifiers = 0;
031 int prefix_long = 0;
032 int prefix_long_long = 0;
033
034 if (!buff || !format || (len < 0))
035 return -1;
036
037 #define PUTCHAR(thechar) \
038 do { \
039 if (result < len-1) \
040 *buff++ = (thechar); \
041 result++; \
042 } while (0)
043
044 result = 0;
045 for(i=0 ; format[i] != '\0' ; i++)
046 {
047 if (!fmt_modifiers && (format[i] != '%'))
048 {
049 PUTCHAR(format[i]);
050 continue;
051 }
052
053 switch (format[i])
054 {
055 case '%':
056 if (fmt_modifiers)
057 {
058 PUTCHAR('%');
059 fmt_modifiers = 0;
060 break;
061 }
062
063 fmt_modifiers = 1;
064 prefix_long = 0;
065 prefix_long_long = 0;
066 break;
067
068 case 'l':
069 if (prefix_long)
070 prefix_long_long = 1;
071 else
072 prefix_long = 1;
073 break;
074
075 case 'u':
076 {
077 if (! prefix_long_long)
078 {
079 unsigned int integer = va_arg(ap,unsigned int);
080 int cpt2 = 0;
081 char buff_int[16];
082
083 do {
084 int m10 = integer%10;
085 buff_int[cpt2++]=(char)('0'+ m10);
086 integer=integer/10;
087 } while(integer!=0);
088
089 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
090 PUTCHAR(buff_int[cpt2]);
091 }
092 else
093 {
094 unsigned long long int integer
095 = va_arg(ap,unsigned long long int);
096 int cpt2 = 0;
097 char buff_int[32];
098
099 do {
100 int m10 = integer%10;
101 buff_int[cpt2++]=(char)('0'+ m10);
102 integer=integer/10;
103 } while(integer!=0);
104
105 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
106 PUTCHAR(buff_int[cpt2]);
107 }
108 }
109 fmt_modifiers = 0;
110 break;
111
112 case 'i':
113 case 'd':
114 {
115 if (! prefix_long_long)
116 {
117 int integer = va_arg(ap,int);
118 int cpt2 = 0;
119 char buff_int[16];
120
121 if (integer<0)
122 PUTCHAR('-');
123
124
125
126 do {
127 int m10 = integer%10;
128 m10 = (m10 < 0)? -m10:m10;
129 buff_int[cpt2++]=(char)('0'+ m10);
130 integer=integer/10;
131 } while(integer!=0);
132
133 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
134 PUTCHAR(buff_int[cpt2]);
135 }
136 else
137 {
138 long long int integer = va_arg(ap,long long int);
139 int cpt2 = 0;
140 char buff_int[32];
141
142 if (integer<0)
143 PUTCHAR('-');
144
145
146
147 do {
148 int m10 = integer%10;
149 m10 = (m10 < 0)? -m10:m10;
150 buff_int[cpt2++]=(char)('0'+ m10);
151 integer=integer/10;
152 } while(integer!=0);
153
154 for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--)
155 PUTCHAR(buff_int[cpt2]);
156 }
157 }
158 fmt_modifiers = 0;
159 break;
160
161 case 'c':
162 {
163 int value = va_arg(ap,int);
164 PUTCHAR((char)value);
165 fmt_modifiers = 0;
166 break;
167 }
168
169 case 's':
170 {
171 char *string = va_arg(ap,char *);
172 if (! string)
173 string = "(null)";
174 for( ; *string != '\0' ; string++)
175 PUTCHAR(*string);
176 fmt_modifiers = 0;
177 break;
178 }
179
180 case 'p':
181 PUTCHAR('0');
182 PUTCHAR('x');
183 case 'x':
184 {
185 unsigned long long int hexa;
186 unsigned long long int nb;
187 int i, had_nonzero = 0;
188
189 if (prefix_long_long)
190 hexa = va_arg(ap,unsigned long long int);
191 else
192 hexa = va_arg(ap,unsigned int);
193
194 for(i=0 ; i < 16 ; i++)
195 {
196 nb = (unsigned long long int)(hexa << (i*4));
197 nb = (nb >> 60) & 0xf;
198
199 if (nb == 0)
200 {
201 if (had_nonzero)
202 PUTCHAR('0');
203 }
204 else
205 {
206 had_nonzero = 1;
207 if (nb < 10)
208 PUTCHAR('0'+nb);
209 else
210 PUTCHAR('a'+(nb-10));
211 }
212 }
213 if (! had_nonzero)
214 PUTCHAR('0');
215 }
216 fmt_modifiers = 0;
217 break;
218
219 default:
220 PUTCHAR('%');
221 if (prefix_long)
222 PUTCHAR('l');
223 if (prefix_long_long)
224 PUTCHAR('l');
225 PUTCHAR(format[i]);
226 fmt_modifiers = 0;
227 }
228 }
229
230 *buff = '\0';
231 return result;
232 }
233
234
235 int snprintf(char * buff, size_t len, const char *format, ...)
236 {
237 va_list ap;
238
239 va_start(ap, format);
240 len = vsnprintf(buff, len, format, ap);
241 va_end(ap);
242
243 return len;
244 }