Changeset 771 for soft/giet_vm/giet_libs/stdio.c
- Timestamp:
- Feb 3, 2016, 9:57:40 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_libs/stdio.c
r767 r771 8 8 #include <stdarg.h> 9 9 #include <stdio.h> 10 #include <stdlib.h> 10 11 #include <giet_config.h> 11 12 /////////////////////////////////////////////////////////////////////////////////////13 // This function is called by both the giet_tty_printf() and14 // the giet_fat_printf() system calls.15 // It analyse the <format> and <args> arguments and returns a byte stream16 // in the <stream> buffer. The TO_STREAM macro checks buffer overflow.17 // It returns number of written bytes in case of success.18 // It returns 0xFFFFFFFF in case of error (illegal format, or buffer overflow).19 /////////////////////////////////////////////////////////////////////////////////////20 21 #define TO_STREAM(x) do { stream[ps] = (x); ps++; if(ps==maxlen) return -1; } while(0);22 23 static unsigned int xprintf( char* stream,24 unsigned int maxlen,25 char* format,26 va_list* args)27 {28 unsigned int ps = 0; // write pointer to the stream buffer29 30 xprintf_text:31 32 while ( *format != 0 )33 {34 35 if (*format == '%') // copy argument to stream36 {37 format++;38 goto xprintf_arguments;39 }40 else // copy one char to stream41 {42 TO_STREAM( *format );43 format++;44 }45 }46 47 return ps;48 49 xprintf_arguments:50 51 {52 char buf[30]; // buffer to display one number53 char * pbuf; // pointer on first char to display54 unsigned int len = 0; // number of char to display55 static const char HexaTab[] = "0123456789ABCDEF";56 unsigned int i;57 58 // Ignore fields width and precision59 for ( ; *format >= '0' && *format <= '9'; format++ );60 61 switch (*format)62 {63 case ('c'): // char conversion64 {65 int val = va_arg( *args, int );66 buf[0] = val;67 pbuf = buf;68 len = 1;69 break;70 }71 case ('d'): // decimal signed integer72 {73 int val = va_arg( *args, int );74 if (val < 0)75 {76 TO_STREAM( '-' );77 val = -val;78 }79 for(i = 0; i < 10; i++)80 {81 82 buf[9 - i] = HexaTab[val % 10];83 if (!(val /= 10)) break;84 }85 len = i + 1;86 pbuf = &buf[9 - i];87 break;88 }89 case ('u'): // decimal unsigned integer90 {91 unsigned int val = va_arg( *args, unsigned int );92 for(i = 0; i < 10; i++)93 {94 buf[9 - i] = HexaTab[val % 10];95 if (!(val /= 10)) break;96 }97 len = i + 1;98 pbuf = &buf[9 - i];99 break;100 }101 case ('x'): // 32 bits hexadecimal102 case ('l'): // 64 bits hexadecimal103 {104 unsigned int imax;105 unsigned long long val;106 107 if ( *format == 'l' ) // 64 bits108 {109 val = va_arg( *args, unsigned long long);110 imax = 16;111 }112 else // 32 bits113 {114 val = va_arg( *args, unsigned int);115 imax = 8;116 }117 118 TO_STREAM( '0' );119 TO_STREAM( 'x' );120 121 for(i = 0; i < imax; i++)122 {123 buf[(imax-1) - i] = HexaTab[val % 16];124 if (!(val /= 16)) break;125 }126 len = i + 1;127 pbuf = &buf[(imax-1) - i];128 break;129 }130 case ('s'): /* string */131 {132 char* str = va_arg( *args, char* );133 while (str[len]) { len++; }134 pbuf = str;135 break;136 }137 case ('e'):138 case ('f'):139 case ('g'): // IEEE754 64 bits140 {141 union142 {143 double d;144 unsigned long long ull;145 } val;146 147 val.d = va_arg( *args, double );148 149 unsigned long long digits;150 digits = val.ull & 0xFFFFFFFFFFFFFULL; // mantisse151 152 unsigned int base;153 base = (unsigned int)((val.ull & 0x7FF0000000000000ULL) >> 52); // exp154 155 unsigned int intp;156 intp = (unsigned int)val.d; // integer part157 158 unsigned int decp; // decimal part159 160 int isvalue = 0;161 162 if (base == 0x7FF) // special values163 {164 if (digits & 0xFFFFFFFFFFFFFULL) // Not a Number165 {166 buf[0] = 'N';167 buf[1] = 'a';168 buf[2] = 'N';169 len = 3;170 pbuf = buf;171 }172 else // infinite173 {174 /* inf */175 buf[0] = (val.ull & 0x8000000000000000ULL) ? '-' : '+';176 buf[1] = 'i';177 buf[2] = 'n';178 buf[3] = 'f';179 len = 4;180 pbuf = buf;181 }182 break;183 }184 185 if (val.ull & 0x8000000000000000ULL) // negative186 {187 TO_STREAM( '-' );188 val.d = val.d * -1;189 }190 else // positive191 {192 TO_STREAM( '+' );193 }194 195 if (val.d > 0xFFFFFFFF) // overflow196 {197 buf[0] = 'B';198 buf[1] = 'I';199 buf[2] = 'G';200 len = 3;201 pbuf = buf;202 break;203 }204 205 val.d -= (double)intp;206 decp = (unsigned int)(val.d * 1000000000);207 208 for(i = 0; i < 10; i++)209 {210 if ((!isvalue) && (intp % 10)) isvalue = 1;211 buf[9 - i] = HexaTab[intp % 10];212 if (!(intp /= 10)) break;213 }214 pbuf = &buf[9 - i];215 len = i+11;216 buf[10] = '.';217 218 for(i = 0; i < 9; i++)219 {220 if ((!isvalue) && (decp % 10)) isvalue = 1;221 buf[19 - i] = HexaTab[decp % 10];222 decp /= 10;223 }224 225 if (!isvalue)226 {227 if (val.d != 0) // underflow228 {229 buf[0] = 'T';230 buf[1] = 'I';231 buf[2] = 'N';232 buf[3] = 'Y';233 len = 4;234 pbuf = buf;235 }236 }237 238 break;239 }240 241 default: // unsupported argument type242 {243 return -1;244 }245 } // end switch on argument type246 247 format++;248 249 // copy argument to stream250 for( i = 0 ; i < len ; i++ )251 {252 TO_STREAM( pbuf[i] );253 }254 255 goto xprintf_text;256 }257 258 } // end xprintf()259 12 260 13 … … 503 256 { 504 257 va_list args; 505 char str eam[4096];258 char string[4096]; 506 259 unsigned int length; 507 260 508 261 va_start( args, format ); 509 length = xprintf( str eam, 4096, format, &args );262 length = xprintf( string , 4096 , format , &args ); 510 263 va_end( args ); 511 264 … … 513 266 514 267 if ( sys_call( SYSCALL_TTY_WRITE, 515 (unsigned int)str eam, // buffer address268 (unsigned int)string, // buffer address 516 269 length, // number of characters 517 270 0xFFFFFFFF, // channel index from thread context … … 1092 845 { 1093 846 va_list args; 1094 char str eam[4096];847 char string[4096]; 1095 848 unsigned int count; 1096 849 1097 850 va_start( args, format ); 1098 1099 count = xprintf( stream, 4096, format, &args ); 851 count = xprintf( string , 4096 , format , &args ); 1100 852 va_end( args ); 1101 853 … … 1104 856 return sys_call( SYSCALL_FAT_WRITE, 1105 857 fd_id, 1106 (unsigned int)str eam,858 (unsigned int)string, 1107 859 count, 1108 860 0 ); // no physical addressing required … … 1143 895 } 1144 896 897 /////////////////////////////////////// 898 int giet_fat_dump( unsigned int type, 899 char* pathname, 900 unsigned int block_id ) 901 { 902 return sys_call( SYSCALL_FAT_DUMP, 903 type, 904 (unsigned int)pathname, 905 block_id, 906 0 ); 907 908 } 909 910 1145 911 ////////////////////////////////////////////////////////////////////////////////// 1146 912 // Miscellaneous system calls
Note: See TracChangeset
for help on using the changeset viewer.