Changeset 1066 for Whitix/branches/keobject/lib/vsprintf.c
- Timestamp:
- 10/03/08 12:25:17 (3 months ago)
- Files:
-
- 1 modified
-
Whitix/branches/keobject/lib/vsprintf.c (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Whitix/branches/keobject/lib/vsprintf.c
r973 r1066 22 22 #include <string.h> 23 23 #include <typedefs.h> 24 #include <types.h> 24 25 25 26 #define SIGN 1 … … 32 33 33 34 #define is_digit(c) ((c) >= '0' && (c) <= '9') 35 34 36 #define do_div(n,base) ({ \ 35 int __res; \ 36 __asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ 37 __res; }) 37 unsigned long __upper, __low, __high, __mod, __base; \ 38 __base = (base); \ 39 asm("":"=a" (__low), "=d" (__high):"A" (n)); \ 40 __upper = __high; \ 41 if (__high) { \ 42 __upper = __high % (__base); \ 43 __high = __high / (__base); \ 44 } \ 45 asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ 46 asm("":"=A" (n):"a" (__low),"d" (__high)); \ 47 __mod; \ 48 }) 38 49 39 50 int skip_atoi(const char** s) … … 45 56 } 46 57 47 char* number(char* str, intnum,int base,int size,int precision,int type)58 char* number(char* str, char* end, unsigned long long num,int base,int size,int precision,int type) 48 59 { 49 60 char c,sign,tmp[36]; … … 53 64 if (type & SMALL) digits="0123456789abcdefghijklmnopqrstuvwxyz"; 54 65 if (type & LEFT) type &= ~ZEROPAD; 66 55 67 if (base < 2 || base > 36) 56 68 return NULL; 69 57 70 c=(type & ZEROPAD) ? '0' : ' '; 58 if (type & SIGN && num < 0) 71 72 if (type & SIGN && (signed long long)num < 0) 59 73 { 60 74 sign='-'; 61 num=- num;75 num=- (signed long long)num; 62 76 }else 63 77 sign=(type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); 64 if (sign) size--; 78 79 if (sign) 80 size--; 81 65 82 if (type & SPECIAL) 66 83 { … … 76 93 } 77 94 78 if (i>precision) precision=i; 95 if (i>precision) 96 precision=i; 97 79 98 size-=precision; 99 80 100 if (!(type & (ZEROPAD+LEFT))) 81 101 while (size-- > 0) 82 *str++=' '; 102 { 103 if (str < end) 104 *str = ' '; 105 str++; 106 } 83 107 84 108 if (sign) 85 *str++=sign; 86 87 if (type & SPECIAL) 109 { 110 if (str < end) 111 *str = sign; 112 113 str++; 114 } 115 116 if (type & SPECIAL && str < end) 88 117 { 89 118 if (base == 8) 90 *str++='0'; 91 else if (base == 16) 92 { 93 *str++='0'; 94 *str++=digits[33]; 119 { 120 if (str < end) 121 *str = '0'; 122 str++; 123 }else if (base == 16) 124 { 125 if (str < end) 126 *str='0'; 127 str++; 128 129 if (str < end) 130 *str = digits[33]; 131 132 str++; 95 133 } 96 134 } … … 98 136 if (!(type & LEFT)) 99 137 while (size-- > 0) 100 *str++=c; 138 { 139 if (str < end) 140 *str = c; 141 str++; 142 } 101 143 102 144 while (i < precision--) 103 *str++='0'; 145 { 146 if (str < end) 147 *str='0'; 148 149 str++; 150 } 151 104 152 while (i-- > 0) 105 *str++=tmp[i]; 153 { 154 if (str < end) 155 *str = tmp[i]; 156 157 str++; 158 } 159 106 160 while (size-- > 0) 107 *str++=' '; 161 { 162 if (str < end) 163 *str = ' '; 164 165 str++; 166 } 167 108 168 return str; 109 169 } 110 170 111 int vs printf(char* buf,const char* fmt,va_list args)171 int vsnprintf(char* buf, int size, const char* fmt, VaList args) 112 172 { 113 173 char* str=buf; 174 char* end; 114 175 int fieldWidth,precision,qualifier,flags; 176 177 end = buf+size; 178 179 if (end < buf) 180 { 181 end = ((void*)-1); 182 size = end - buf; 183 } 115 184 116 185 for (; *fmt; fmt++) … … 121 190 if (LIKELY(*fmt != '%')) 122 191 { 123 *str++=*fmt; 192 if (str < end) 193 *str = *fmt; 194 195 str++; 124 196 continue; 125 197 } … … 141 213 else if (*fmt == '*') 142 214 { 143 fieldWidth= va_arg(args,int);215 fieldWidth=VaArg(args, int); 144 216 if (fieldWidth < 0) 145 217 { … … 156 228 else if (*fmt == '*') 157 229 { 158 precision= va_arg(args,int);230 precision=VaArg(args,int); 159 231 } 160 232 if (precision < 0) … … 174 246 if (!(flags & LEFT)) 175 247 while (--fieldWidth > 0) 176 *str++=' '; 177 *str++=(unsigned char)va_arg(args,int); 248 { 249 if (str < end) 250 *str=' '; 251 252 ++str; 253 } 254 255 if (str < end) 256 *str=(unsigned char)VaArg(args,int); 257 258 str++; 259 178 260 while (--fieldWidth > 0) 179 *str++=' '; 261 { 262 if (str < end) 263 *str=' '; 264 265 str++; 266 } 180 267 break; 181 268 182 269 case 's': 183 270 { 184 char* s= va_arg(args,char*);271 char* s=VaArg(args,char*); 185 272 if (!s) 186 273 s="<NULL>"; … … 193 280 if (!(flags & LEFT)) 194 281 while (len < fieldWidth--) 195 *str++=' '; 282 { 283 if (str < end) 284 *str=' '; 285 286 str++; 287 } 196 288 int i; 197 289 for (i=0; i<len; i++) 198 *str++=*s++; 290 { 291 if (str < end) 292 *str=*s; 293 294 str++; 295 s++; 296 } 199 297 200 298 while (len < fieldWidth--) 201 *str++=' '; 299 { 300 if (str < end) 301 *str++=' '; 302 } 202 303 break; 203 304 } 204 305 205 306 case 'o': 206 str=number(str, va_arg(args,unsigned long),8,fieldWidth,307 str=number(str, end, VaArg(args,unsigned long),8,fieldWidth, 207 308 precision,flags); 208 309 break; … … 214 315 flags |= ZEROPAD; 215 316 } 216 str=number(str, (unsigned long)va_arg(args,void*),16,fieldWidth,317 str=number(str, end, (unsigned long)VaArg(args,void*),16,fieldWidth, 217 318 precision,flags); 218 319 break; … … 221 322 flags |= SMALL; 222 323 case 'X': 223 str=number(str, va_arg(args,unsigned long),16,fieldWidth,324 str=number(str, end, VaArg(args,unsigned long),16,fieldWidth, 224 325 precision,flags); 225 326 break; … … 228 329 flags |= SIGN; 229 330 case 'u': 230 str=number(str, va_arg(args,unsigned long),10,fieldWidth,331 str=number(str, end, VaArg(args,unsigned long),10,fieldWidth, 231 332 precision,flags); 232 333 break; 233 334 default: 234 if (*fmt != '%') 235 *str++ = '%'; 335 if (str < end) 336 *str = '%'; 337 236 338 if (*fmt) 237 *str++ = *fmt; 238 else 339 { 340 if (str < end) 341 *str = *fmt; 342 ++str; 343 }else 239 344 --fmt; 240 345 break; 241 346 } 242 347 } 243 *str='\0'; 348 349 if (size > 0) 350 { 351 if (str < end) 352 *str = '\0'; 353 else 354 end[-1] = '\0'; 355 } 356 244 357 return (str-buf); 245 358 } 246 359 360 SYMBOL_EXPORT(vsnprintf); 361 362 int vsprintf(char* buf,const char* fmt, VaList args) 363 { 364 return vsnprintf(buf, INT_MAX, fmt, args); 365 } 366 247 367 SYMBOL_EXPORT(vsprintf); 248 368 249 int sprintf(char* buf,const char* fmt,...) 250 { 251 int i; 252 va_list args; 253 254 va_start(args,fmt); 255 i=vsprintf(buf,fmt,args); 256 va_end(args); 257 return i; 258 } 259 260 SYMBOL_EXPORT(sprintf); 369 char* vasprintf(const char* fmt, VaList args) 370 { 371 int length; 372 char* ret; 373 VaList temp; 374 375 VaCopy(temp, args); 376 377 length = vsnprintf(NULL, 0, fmt, temp); 378 379 VaEnd(temp); 380 381 ret = (char*)MemAlloc(length + 1); 382 383 if (!ret) 384 return NULL; 385 386 vsnprintf(ret, length+1, fmt, args); 387 388 return ret; 389 } 390 391 SYMBOL_EXPORT(vasprintf);