Changeset 771 for soft/giet_vm/giet_libs/stdlib.c
- Timestamp:
- Feb 3, 2016, 9:57:40 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_libs/stdlib.c
r647 r771 7 7 8 8 #include <stdlib.h> 9 #include <stdio.h> 10 #include <stdarg.h> 9 11 10 12 ///////////////////////// … … 147 149 } 148 150 151 152 ////////////////////////////////////////// 153 unsigned int xprintf( char* string, 154 unsigned int length, 155 char* format, 156 va_list* args ) 157 { 158 unsigned int ps = 0; // write pointer to the string buffer 159 160 #define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0); 161 162 xprintf_text: 163 164 while ( *format != 0 ) 165 { 166 167 if (*format == '%') // copy argument to string 168 { 169 format++; 170 goto xprintf_arguments; 171 } 172 else // copy one char to string 173 { 174 TO_STREAM( *format ); 175 format++; 176 } 177 } 178 179 return ps; 180 181 xprintf_arguments: 182 183 { 184 char buf[30]; // buffer to display one number 185 char * pbuf; // pointer on first char to display 186 unsigned int len = 0; // number of char to display 187 static const char HexaTab[] = "0123456789ABCDEF"; 188 unsigned int i; 189 190 // Ignore fields width and precision 191 for ( ; *format >= '0' && *format <= '9'; format++ ); 192 193 switch (*format) 194 { 195 case ('c'): // char conversion 196 { 197 int val = va_arg( *args, int ); 198 buf[0] = val; 199 pbuf = buf; 200 len = 1; 201 break; 202 } 203 case ('d'): // decimal signed integer 204 { 205 int val = va_arg( *args, int ); 206 if (val < 0) 207 { 208 TO_STREAM( '-' ); 209 val = -val; 210 } 211 for(i = 0; i < 10; i++) 212 { 213 214 buf[9 - i] = HexaTab[val % 10]; 215 if (!(val /= 10)) break; 216 } 217 len = i + 1; 218 pbuf = &buf[9 - i]; 219 break; 220 } 221 case ('u'): // decimal unsigned integer 222 { 223 unsigned int val = va_arg( *args, unsigned int ); 224 for(i = 0; i < 10; i++) 225 { 226 buf[9 - i] = HexaTab[val % 10]; 227 if (!(val /= 10)) break; 228 } 229 len = i + 1; 230 pbuf = &buf[9 - i]; 231 break; 232 } 233 case ('x'): // 32 bits hexadecimal 234 case ('l'): // 64 bits hexadecimal 235 { 236 unsigned int imax; 237 unsigned long long val; 238 239 if ( *format == 'l' ) // 64 bits 240 { 241 val = va_arg( *args, unsigned long long); 242 imax = 16; 243 } 244 else // 32 bits 245 { 246 val = va_arg( *args, unsigned int); 247 imax = 8; 248 } 249 250 TO_STREAM( '0' ); 251 TO_STREAM( 'x' ); 252 253 for(i = 0; i < imax; i++) 254 { 255 buf[(imax-1) - i] = HexaTab[val % 16]; 256 if (!(val /= 16)) break; 257 } 258 len = i + 1; 259 pbuf = &buf[(imax-1) - i]; 260 break; 261 } 262 case ('s'): /* string */ 263 { 264 char* str = va_arg( *args, char* ); 265 while (str[len]) { len++; } 266 pbuf = str; 267 break; 268 } 269 case ('e'): 270 case ('f'): 271 case ('g'): // IEEE754 64 bits 272 { 273 union 274 { 275 double d; 276 unsigned long long ull; 277 } val; 278 279 val.d = va_arg( *args, double ); 280 281 unsigned long long digits; 282 digits = val.ull & 0xFFFFFFFFFFFFFULL; // mantisse 283 284 unsigned int base; 285 base = (unsigned int)((val.ull & 0x7FF0000000000000ULL) >> 52); // exp 286 287 unsigned int intp; 288 intp = (unsigned int)val.d; // integer part 289 290 unsigned int decp; // decimal part 291 292 int isvalue = 0; 293 294 if (base == 0x7FF) // special values 295 { 296 if (digits & 0xFFFFFFFFFFFFFULL) // Not a Number 297 { 298 buf[0] = 'N'; 299 buf[1] = 'a'; 300 buf[2] = 'N'; 301 len = 3; 302 pbuf = buf; 303 } 304 else // infinite 305 { 306 /* inf */ 307 buf[0] = (val.ull & 0x8000000000000000ULL) ? '-' : '+'; 308 buf[1] = 'i'; 309 buf[2] = 'n'; 310 buf[3] = 'f'; 311 len = 4; 312 pbuf = buf; 313 } 314 break; 315 } 316 317 if (val.ull & 0x8000000000000000ULL) // negative 318 { 319 TO_STREAM( '-' ); 320 val.d = val.d * -1; 321 } 322 else // positive 323 { 324 TO_STREAM( '+' ); 325 } 326 327 if (val.d > 0xFFFFFFFF) // overflow 328 { 329 buf[0] = 'B'; 330 buf[1] = 'I'; 331 buf[2] = 'G'; 332 len = 3; 333 pbuf = buf; 334 break; 335 } 336 337 val.d -= (double)intp; 338 decp = (unsigned int)(val.d * 1000000000); 339 340 for(i = 0; i < 10; i++) 341 { 342 if ((!isvalue) && (intp % 10)) isvalue = 1; 343 buf[9 - i] = HexaTab[intp % 10]; 344 if (!(intp /= 10)) break; 345 } 346 pbuf = &buf[9 - i]; 347 len = i+11; 348 buf[10] = '.'; 349 350 for(i = 0; i < 9; i++) 351 { 352 if ((!isvalue) && (decp % 10)) isvalue = 1; 353 buf[19 - i] = HexaTab[decp % 10]; 354 decp /= 10; 355 } 356 357 if (!isvalue) 358 { 359 if (val.d != 0) // underflow 360 { 361 buf[0] = 'T'; 362 buf[1] = 'I'; 363 buf[2] = 'N'; 364 buf[3] = 'Y'; 365 len = 4; 366 pbuf = buf; 367 } 368 } 369 370 break; 371 } 372 373 default: // unsupported argument type 374 { 375 return -1; 376 } 377 } // end switch on argument type 378 379 format++; 380 381 // copy argument to string 382 for( i = 0 ; i < len ; i++ ) 383 { 384 TO_STREAM( pbuf[i] ); 385 } 386 387 goto xprintf_text; 388 } 389 } // end xprintf() 390 391 /////////////////////////////////////////// 392 unsigned int snprintf( char* string, 393 unsigned int length, 394 char* format, ... ) 395 { 396 va_list args; 397 unsigned int count; 398 399 va_start( args, format ); 400 count = xprintf( string , length , format , &args ); 401 va_end( args ); 402 403 if ( count == 0xFFFFFFFF ) giet_pthread_exit("error in snprintf()"); 404 else string[count] = 0; 405 406 return count; 407 } 149 408 // Local Variables: 150 409 // tab-width: 4
Note: See TracChangeset
for help on using the changeset viewer.