Changeset 580 for soft/giet_vm/giet_libs/stdio.c
- Timestamp:
- May 28, 2015, 3:34:23 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_libs/stdio.c
r558 r580 142 142 { 143 143 int ret; // return value from the syscall 144 enum TModifiers {NO_MOD, L_MOD, LL_MOD} modifiers; 144 145 145 146 printf_text: … … 164 165 { 165 166 format++; 167 modifiers = NO_MOD; 166 168 goto printf_arguments; 167 169 } … … 173 175 174 176 { 175 char buf[ 20];177 char buf[30]; 176 178 char * pbuf; 177 179 unsigned int len = 0; 178 180 static const char HexaTab[] = "0123456789ABCDEF"; 179 181 unsigned int i; 182 183 /* Ignored fields : width and precision */ 184 for (; *format >= '0' && *format <= '9'; format++); 180 185 181 186 switch (*format++) 182 187 { 188 case ('%'): 183 189 case ('c'): /* char conversion */ 184 190 { 185 191 int val = va_arg( *args, int ); 192 if (modifiers != NO_MOD) goto return_error; //Modifiers have no meaning 193 186 194 len = 1; 187 195 buf[0] = val; … … 189 197 break; 190 198 } 191 case ('d'): /* 32 bitsdecimal signed integer */199 case ('d'): /* decimal signed integer */ 192 200 { 193 201 int val = va_arg( *args, int ); 202 203 if (modifiers == LL_MOD) goto return_error; //64 bits not supported 204 194 205 if (val < 0) 195 206 { … … 211 222 break; 212 223 } 213 case ('u'): /* 32 bitsdecimal unsigned integer */224 case ('u'): /* decimal unsigned integer */ 214 225 { 215 unsigned int val = va_arg( *args, unsigned int ); 216 for(i = 0; i < 10; i++) 217 { 218 buf[9 - i] = HexaTab[val % 10]; 219 if (!(val /= 10)) break; 220 } 221 len = i + 1; 222 pbuf = &buf[9 - i]; 223 break; 226 if (modifiers != LL_MOD) //32 bits integer 227 { 228 unsigned int val = va_arg( *args, unsigned int ); 229 for(i = 0; i < 10; i++) 230 { 231 buf[9 - i] = HexaTab[val % 10]; 232 if (!(val /= 10)) break; 233 } 234 len = i + 1; 235 pbuf = &buf[9 - i]; 236 break; 237 } 238 //64 bits : base 10 unsupported : continue to hexa 224 239 } 225 case ('x'): /* 32 bits hexadecimal integer */ 240 case ('x'): 241 case ('X'): /* hexadecimal integer */ 226 242 { 227 unsigned int val = va_arg( *args, unsigned int ); 228 ret = sys_call(SYSCALL_TTY_WRITE, 229 (unsigned int)"0x", 230 2, 231 channel, 232 0); 233 if (ret != 2) goto return_error; 234 for(i = 0; i < 8; i++) 235 { 236 buf[7 - i] = HexaTab[val % 16]; 237 if (!(val /= 16)) break; 238 } 239 len = i + 1; 240 pbuf = &buf[7 - i]; 241 break; 242 } 243 case ('l'): /* 64 bits hexadecimal unsigned */ 244 { 245 unsigned long long val = va_arg( *args, unsigned long long ); 243 unsigned long long val; 244 int imax; 245 246 if (modifiers == LL_MOD) //64 bits 247 { 248 val = va_arg( *args, unsigned long long); 249 250 if (*(format-1) == 'u' && (!(val & 0xFFFFFFFF00000000))) //if asked to print in base 10, can do only if it fits in 32 bits 251 { 252 unsigned int uintv = (unsigned int) val; 253 254 for(i = 0; i < 10; i++) 255 { 256 buf[9 - i] = HexaTab[uintv % 10]; 257 if (!(uintv /= 10)) break; 258 } 259 len = i + 1; 260 pbuf = &buf[9 - i]; 261 break; 262 } 263 264 imax = 16; 265 } 266 else //32 bits 267 { 268 val = va_arg( *args, unsigned int); 269 imax = 8; 270 } 271 246 272 ret = sys_call(SYSCALL_TTY_WRITE, 247 273 (unsigned int)"0x", … … 250 276 0); 251 277 if (ret != 2) goto return_error; 252 for(i = 0; i < 16; i++) 253 { 254 buf[15 - i] = HexaTab[val % 16]; 278 279 for(i = 0; i < imax; i++) 280 { 281 buf[(imax-1) - i] = HexaTab[val % 16]; 255 282 if (!(val /= 16)) break; 256 283 } 257 284 len = i + 1; 258 pbuf = &buf[ 15- i];285 pbuf = &buf[(imax-1) - i]; 259 286 break; 260 287 } … … 262 289 { 263 290 char* str = va_arg( *args, char* ); 291 292 if (modifiers != NO_MOD) goto return_error; //Modifiers have no meaning 293 264 294 while (str[len]) 265 295 { … … 269 299 break; 270 300 } 301 case ('e'): 302 case ('f'): 303 case ('g'): /* IEEE754 64 bits */ 304 { 305 306 double vald = va_arg( *args, double); 307 308 unsigned long long 309 val = *(unsigned long long*)&vald, //get ieee754 without conversion 310 digits = val & 0xFFFFFFFFFFFFF; //get mantissa 311 312 unsigned int 313 base = (unsigned int)((val & 0x7FF0000000000000) >> 52), //get exposant 314 intp = (unsigned int)vald, //get integer part of the float 315 decp; 316 317 int isvalue = 0; 318 319 if (base == 0x7FF) //special value 320 { 321 if (digits & 0xFFFFFFFFFFFFF) 322 { 323 /* Not a Number */ 324 buf[0] = 'N'; 325 buf[1] = 'a'; 326 buf[2] = 'N'; 327 len = 3; 328 pbuf = buf; 329 } 330 else 331 { 332 /* inf */ 333 buf[0] = (val & 0x8000000000000000) ? '-' : '+'; 334 buf[1] = 'i'; 335 buf[2] = 'n'; 336 buf[3] = 'f'; 337 len = 4; 338 pbuf = buf; 339 } 340 break; 341 } 342 343 if (val & 0x8000000000000000) 344 { 345 /* negative */ 346 ret = sys_call(SYSCALL_TTY_WRITE, 347 (unsigned int)"-", 348 1, 349 channel, 350 0); 351 if (ret != 1) goto return_error; 352 vald = vald * -1; 353 } 354 else 355 { 356 /* positive */ 357 ret = sys_call(SYSCALL_TTY_WRITE, 358 (unsigned int)"+", 359 1, 360 channel, 361 0); 362 if (ret != 1) goto return_error; 363 } 364 365 if (vald > 0xFFFFFFFF) 366 { 367 /* overflow */ 368 buf[0] = 'B'; 369 buf[1] = 'I'; 370 buf[2] = 'G'; 371 len = 3; 372 pbuf = buf; 373 break; 374 } 375 376 vald -= (double)intp; 377 decp = (unsigned int)(vald * 100000000); 378 379 for(i = 0; i < 10; i++) 380 { 381 if ((!isvalue) && (intp % 10)) isvalue = 1; 382 buf[9 - i] = HexaTab[intp % 10]; 383 if (!(intp /= 10)) break; 384 } 385 pbuf = &buf[9 - i]; 386 len = i+11; 387 buf[10] = '.'; 388 389 for(i = 0; i < 9; i++) 390 { 391 if ((!isvalue) && (decp % 10)) isvalue = 1; 392 buf[19 - i] = HexaTab[decp % 10]; 393 decp /= 10; 394 } 395 396 if (!isvalue) 397 { 398 if (vald != 0) 399 { 400 /* underflow */ 401 buf[0] = 'T'; 402 buf[1] = 'I'; 403 buf[2] = 'N'; 404 buf[3] = 'Y'; 405 len = 4; 406 pbuf = buf; 407 } 408 } 409 410 break; 411 } 412 case ('l'): 413 switch (modifiers) 414 { 415 case NO_MOD: 416 modifiers = L_MOD; 417 goto printf_arguments; 418 419 case L_MOD: 420 modifiers = LL_MOD; 421 goto printf_arguments; 422 423 default: 424 goto return_error; 425 } 426 427 /* Ignored fields : width and precision */ 428 case ('.'): goto printf_arguments; 429 271 430 default: 272 431 goto return_error;
Note: See TracChangeset
for help on using the changeset viewer.