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