Changeset 444 for trunk/libs/mini-libc/stdio.c
- Timestamp:
- May 16, 2018, 8:31:35 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/libs/mini-libc/stdio.c
r443 r444 22 22 */ 23 23 24 #include <shared_syscalls.h>25 #include <hal_user.h>26 24 #include <stdio.h> 27 #include <stdlib.h> 28 29 #define reg_t int 30 31 ///////////// POSIX standard system calls //////////////////////////////////// 32 33 /////////////////////// 34 void exit( int status ) 35 { 36 hal_user_syscall( SYS_EXIT, 37 (reg_t)status, 0, 0, 0 ); 25 #include <stdarg.h> 26 #include <unistd.h> 27 #include <almos-mkh.h> 28 ////////////////////////////////////////// 29 static int xprintf( char * string, 30 unsigned int length, 31 const char * format, 32 va_list * args ) 33 { 34 unsigned int ps = 0; // write index to the string buffer 35 36 #define TO_STREAM(x) do { string[ps] = (x); ps++; if(ps==length) return -1; } while(0); 37 38 xprintf_text: 39 40 while ( *format != 0 ) 41 { 42 43 if (*format == '%') // copy argument to string 44 { 45 format++; 46 goto xprintf_arguments; 47 } 48 else // copy one char to string 49 { 50 TO_STREAM( *format ); 51 format++; 52 } 53 } 54 55 return ps; 56 57 xprintf_arguments: 58 59 { 60 char buf[30]; // buffer to display one number 61 char * pbuf; // pointer on first char to display 62 unsigned int len = 0; // number of char to display 63 static const char HexaTab[] = "0123456789ABCDEF"; 64 unsigned int i; 65 66 // Ignore fields width and precision 67 for ( ; (*format >= '0' && *format <= '9') || (*format == '.') ; format++ ); 68 69 switch (*format) 70 { 71 case ('c'): // char conversion 72 { 73 int val = va_arg( *args, int ); 74 buf[0] = val; 75 pbuf = buf; 76 len = 1; 77 break; 78 } 79 case ('d'): // decimal signed integer 80 { 81 int val = va_arg( *args, int ); 82 if (val < 0) 83 { 84 TO_STREAM( '-' ); 85 val = -val; 86 } 87 for(i = 0; i < 10; i++) 88 { 89 90 buf[9 - i] = HexaTab[val % 10]; 91 if (!(val /= 10)) break; 92 } 93 len = i + 1; 94 pbuf = &buf[9 - i]; 95 break; 96 } 97 case ('u'): // decimal unsigned integer 98 { 99 unsigned int val = va_arg( *args, unsigned int ); 100 for(i = 0; i < 10; i++) 101 { 102 buf[9 - i] = HexaTab[val % 10]; 103 if (!(val /= 10)) break; 104 } 105 len = i + 1; 106 pbuf = &buf[9 - i]; 107 break; 108 } 109 case ('x'): // 32 bits hexadecimal 110 case ('l'): // 64 bits hexadecimal 111 { 112 unsigned int imax; 113 unsigned long long val; 114 115 if ( *format == 'l' ) // 64 bits 116 { 117 val = va_arg( *args, unsigned long long); 118 imax = 16; 119 } 120 else // 32 bits 121 { 122 val = va_arg( *args, unsigned int); 123 imax = 8; 124 } 125 126 TO_STREAM( '0' ); 127 TO_STREAM( 'x' ); 128 129 for(i = 0; i < imax; i++) 130 { 131 buf[(imax-1) - i] = HexaTab[val % 16]; 132 if (!(val /= 16)) break; 133 } 134 len = i + 1; 135 pbuf = &buf[(imax-1) - i]; 136 break; 137 } 138 case ('s'): /* string */ 139 { 140 char* str = va_arg( *args, char* ); 141 while (str[len]) { len++; } 142 pbuf = str; 143 break; 144 } 145 /* 146 case ('f'): // IEEE754 64 bits 147 // integer part : up to 10 decimal digits 148 // decimal part : 9 decimal digits 149 { 150 union 151 { 152 double d; 153 unsigned long long ull; 154 } val; 155 156 val.d = va_arg( *args, double ); 157 158 unsigned long long mantisse; 159 mantisse = val.ull & 0xFFFFFFFFFFFFFULL; // mantisse 160 161 unsigned int exp; 162 exp = (unsigned int)((val.ull & 0x7FF0000000000000ULL) >> 52); // exp 163 164 if (exp == 0x7FF) // special values 165 { 166 if (mantisse & 0xFFFFFFFFFFFFFULL) // Not a Number 167 { 168 buf[0] = 'N'; 169 buf[1] = 'a'; 170 buf[2] = 'N'; 171 len = 3; 172 pbuf = buf; 173 } 174 else // infinite 175 { 176 // inf 177 buf[0] = (val.ull & 0x8000000000000000ULL) ? '-' : '+'; 178 buf[1] = 'i'; 179 buf[2] = 'n'; 180 buf[3] = 'f'; 181 len = 4; 182 pbuf = buf; 183 } 184 break; 185 } 186 187 // display sign & analyse overflow 188 unsigned int overflow = 0; 189 if (val.ull & 0x8000000000000000ULL) // negative 190 { 191 TO_STREAM( '-' ); 192 val.d = val.d * -1; 193 if( val.d < -9999999999.0) overflow = 1; 194 } 195 else // positive 196 { 197 TO_STREAM( '+' ); 198 if( val.d > 9999999999.0) overflow = 1; 199 } 200 201 // check overflow caused by the 10.9 format 202 if ( overflow ) 203 { 204 buf[0] = 'o'; 205 buf[1] = 'v'; 206 buf[2] = 'r'; 207 len = 3; 208 pbuf = buf; 209 break; 210 } 211 212 // compute integer & decimal parts 213 unsigned int intp; // integer part 214 unsigned int decp; // decimal part 215 intp = (unsigned int)val.d; 216 val.d -= (double)intp; 217 decp = (unsigned int)(val.d * 1000000000); 218 219 // display decimal value in 10.9 format 220 for(i = 0; i < 10; i++) 221 { 222 buf[9 - i] = HexaTab[intp % 10]; 223 if (!(intp /= 10)) break; 224 } 225 pbuf = &buf[9 - i]; 226 len = i+11; 227 buf[10] = '.'; 228 for(i = 0; i < 9; i++) 229 { 230 buf[19 - i] = HexaTab[decp % 10]; 231 decp /= 10; 232 } 233 break; 234 } 235 */ 236 default: // unsupported argument type 237 { 238 return -1; 239 } 240 } // end switch on argument type 241 242 format++; 243 244 // copy argument to string 245 for( i = 0 ; i < len ; i++ ) 246 { 247 TO_STREAM( pbuf[i] ); 248 } 249 250 goto xprintf_text; 251 } 252 } // end xprintf() 253 254 ////////////////////////////////////// 255 int printf( const char * format, ... ) 256 { 257 char string[4096]; 258 va_list args; 259 int count; 260 261 va_start( args, format ); 262 count = xprintf( string , 4095 , format , &args ); 263 va_end( args ); 264 265 if ( count == -1 ) 266 { 267 display_string( "stdlib : xprintf failure" ); 268 return -1; 269 } 270 else 271 { 272 string[count] = 0; 273 return write( 1 , &string , count + 1 ); 274 } 38 275 } 39 276 40 ///////////// ////////////////////41 int munmap( void * addr,42 unsigned int size ) 43 { 44 return hal_user_syscall( SYS_MUNMAP, 45 (reg_t)addr,46 (reg_t)size, 0, 0 );277 ///////////// 278 int getchar() 279 { 280 char byte; 281 282 if ( read( 0 , &byte , 1 ) != 1 ) return 0; 283 else return (int)byte; 47 284 } 48 285 49 //////////////////////////////// 50 int open( const char * pathname, 51 int flags, 52 int mode ) 53 { 54 return hal_user_syscall( SYS_OPEN, 55 (reg_t)pathname, 56 (reg_t)flags, 57 (reg_t)mode, 0 ); 286 //////////////////// 287 int putchar( int c ) 288 { 289 char byte = (char)c; 290 291 if( write( 1 , &byte , 1 ) != 1 ) return 0; 292 else return c; 58 293 } 59 294 60 /////////////////////////////// 61 void * mmap( void * addr, 62 unsigned int length, 63 int prot, 64 int flags, 65 int fd, 66 unsigned int offset ) 67 { 68 mmap_attr_t attr; 69 attr.addr = addr; 70 attr.length = length; 71 attr.prot = prot; 72 attr.flags = flags; 73 attr.fdid = fd; 74 attr.offset = offset; 75 76 if( hal_user_syscall( SYS_MMAP, 77 (reg_t)&attr, 0, 0, 0 ) ) return NULL; 78 else return attr.addr; 295 /////////////////////////////////////// 296 int snprintf( char * string, 297 unsigned int length, 298 const char * format, ... ) 299 { 300 va_list args; 301 int count; 302 303 va_start( args, format ); 304 count = xprintf( string , length , format , &args ); 305 va_end( args ); 306 307 if( count < length ) string[count] = 0; 308 309 return count; 79 310 } 80 311 81 ////////////////////////// 82 int read( int fd, 83 void * buf, 84 unsigned int count ) 85 { 86 return hal_user_syscall( SYS_READ, 87 (reg_t)fd, 88 (reg_t)buf, 89 (reg_t)count, 0 ); 90 } 91 92 /////////////////////////// 93 int write( int fd, 94 const void * buf, 95 unsigned int count ) 96 { 97 return hal_user_syscall( SYS_WRITE, 98 (reg_t)fd, 99 (reg_t)buf, 100 (reg_t)count, 0 ); 101 } 102 103 /////////////////////////// 104 int lseek( int fd, 105 unsigned int offset, 106 int whence ) 107 { 108 return hal_user_syscall( SYS_LSEEK, 109 (reg_t)fd, 110 (reg_t)offset, 111 (reg_t)whence, 0 ); 112 } 113 114 /////////////////// 115 int close( int fd ) 116 { 117 return hal_user_syscall( SYS_CLOSE, 118 (reg_t)fd, 0, 0, 0 ); 119 } 120 121 /////////////////////////////////// 122 int unlink( const char * pathname ) 123 { 124 return hal_user_syscall( SYS_UNLINK, 125 (reg_t)pathname, 0, 0, 0 ); 126 } 127 128 ///////////////////// 129 int pipe( int fd[2] ) 130 { 131 return -1; 132 } 133 134 ////////////////////////////////// 135 int chdir( const char * pathname ) 136 { 137 return hal_user_syscall( SYS_CHDIR, 138 (reg_t)pathname, 0, 0, 0 ); 139 } 140 141 ///////////////////////////////// 142 int mkdir( const char * pathname, 143 int mode ) 144 { 145 return hal_user_syscall( SYS_MKDIR, 146 (reg_t)pathname, 147 (reg_t)mode, 0, 0 ); 148 } 149 150 ////////////////////////////////// 151 int mkfifo( const char * pathname, 152 int mode ) 153 { 154 return hal_user_syscall( SYS_MKFIFO, 155 (reg_t)pathname, 156 (reg_t)mode, 0, 0 ); 157 } 158 159 ////////////////////////////////////// 160 DIR * opendir( const char * pathname ) 161 { 162 DIR * dirp; 163 int error; 164 error = hal_user_syscall( SYS_OPENDIR, 165 (reg_t)pathname, 166 (reg_t)&dirp, 0, 0 ); 167 if( error ) return NULL; 168 else return dirp; 169 } 170 171 ///////////////////////////////////// 172 struct dirent * readdir( DIR * dirp ) 173 { 174 struct dirent * dentp; 175 int error; 176 error = hal_user_syscall( SYS_READDIR, 177 (reg_t)dirp, 178 (reg_t)&dentp, 0, 0 ); 179 if( error ) return NULL; 180 else return dentp; 181 } 182 183 ////////////////////////// 184 int closedir( DIR * dirp ) 185 { 186 return hal_user_syscall( SYS_CLOSEDIR, 187 (reg_t)dirp, 0, 0, 0 ); 188 } 189 190 ///////////////////////////// 191 int getcwd( char * buf, 192 unsigned int bytes ) 193 { 194 return hal_user_syscall( SYS_GETCWD, 195 (reg_t)buf, 196 (reg_t)bytes, 0, 0 ); 197 } 198 199 //////////////////////////// 200 int rmdir( char * pathname ) 201 { 202 return hal_user_syscall( SYS_RMDIR, 203 (reg_t)pathname, 0, 0, 0 ); 204 } 205 206 ///////////////////////////////// 207 int utls( unsigned int operation, 208 unsigned int value ) 209 { 210 return hal_user_syscall( SYS_UTLS, 211 (reg_t)operation, 212 (reg_t)value, 0, 0 ); 213 } 214 215 /////////////////////////////// 216 int chmod( char * pathname, 217 unsigned int rights ) 218 { 219 return hal_user_syscall( SYS_CHMOD, 220 (reg_t)pathname, 221 (reg_t)rights, 0, 0 ); 222 } 223 224 ///////////////////////////////// 225 int signal( unsigned int sigid, 226 void * handler ) 227 { 228 return hal_user_syscall( SYS_SIGNAL, 229 (reg_t)sigid, 230 (reg_t)handler, 0, 0 ); 231 } 232 233 /////////////////////////////////////// 234 int gettimeofday( struct timeval * tv, 235 struct timezone * tz ) 236 { 237 return hal_user_syscall( SYS_SIGNAL, 238 (reg_t)tv, 239 (reg_t)tz, 0, 0 ); 240 } 241 242 /////////////////////////// 243 int kill( unsigned int pid, 244 unsigned int sig_id ) 245 { 246 return hal_user_syscall( SYS_KILL, 247 (reg_t)pid, 248 (reg_t)sig_id, 0, 0 ); 249 } 250 251 //////////// 252 int getpid() 253 { 254 return hal_user_syscall( SYS_GETPID, 0, 0, 0, 0 ); 255 } 256 257 ////////// 258 int fork() 259 { 260 return hal_user_syscall( SYS_FORK, 0, 0, 0, 0 ); 261 } 262 263 /////////////////////////// 264 int exec( char * pathname, 265 char ** argv, 266 char ** envp ) 267 { 268 return hal_user_syscall( SYS_EXEC, 269 (reg_t)pathname, 270 (reg_t)argv, 271 (reg_t)envp, 0 ); 272 } 273 274 ///////////////////////////////// 275 int stat( const char * pathname, 276 struct stat * stat ) 277 { 278 return hal_user_syscall( SYS_STAT, 279 (reg_t)pathname, 280 (reg_t)stat, 0, 0 ); 281 } 282 283 //////////////////////// 284 int wait( int * status ) 285 { 286 return hal_user_syscall( SYS_WAIT, 287 (reg_t)status, 0, 0, 0 ); 288 } 289 290 291 292 ///////////// Non standard system calls //////////////////////////////////// 293 294 295 ////////////////////////// 296 int fg( unsigned int pid ) 297 { 298 return hal_user_syscall( SYS_FG, 299 (reg_t)pid, 0, 0, 0 ); 300 } 301 302 ////////////////////////////////////// 303 int get_config( unsigned int * x_size, 304 unsigned int * y_size, 305 unsigned int * ncores ) 306 { 307 return hal_user_syscall( SYS_GET_CONFIG, 308 (reg_t)x_size, 309 (reg_t)y_size, 310 (reg_t)ncores, 0 ); 311 } 312 313 ///////////////////////////////// 314 int get_core( unsigned int * cxy, 315 unsigned int * lid ) 316 { 317 return hal_user_syscall( SYS_GET_CORE, 318 (reg_t)cxy, 319 (reg_t)lid, 0, 0 ); 320 } 321 322 //////////////////////////////////// 323 void display_string( char * string ) 324 { 325 hal_user_syscall( SYS_DISPLAY, 326 DISPLAY_STRING, 327 (reg_t)string, 0, 0 ); 328 } 329 330 ////////////////////////////////// 331 int display_vmm( unsigned int cxy, 332 unsigned int pid ) 333 { 334 return hal_user_syscall( SYS_DISPLAY, 335 DISPLAY_VMM, 336 (reg_t)cxy, 337 (reg_t)pid, 0 ); 338 } 339 340 //////////////////////////////////// 341 int display_sched( unsigned int cxy, 342 unsigned int lid ) 343 { 344 return hal_user_syscall( SYS_DISPLAY, 345 DISPLAY_SCHED, 346 (reg_t)cxy, 347 (reg_t)lid, 0 ); 348 } 349 350 ///////////////////////////////////////////////// 351 int display_cluster_processes( unsigned int cxy ) 352 { 353 return hal_user_syscall( SYS_DISPLAY, 354 DISPLAY_CLUSTER_PROCESSES, 355 (reg_t)cxy, 0, 0 ); 356 } 357 358 /////////////////// 359 int display_chdev() 360 { 361 return hal_user_syscall( SYS_DISPLAY, 362 DISPLAY_CHDEV, 0, 0, 0 ); 363 } 364 365 ///////////////// 366 int display_vfs() 367 { 368 return hal_user_syscall( SYS_DISPLAY, 369 DISPLAY_VFS, 0, 0, 0 ); 370 } 371 372 //////////////////////////////////////////////// 373 int display_txt_processes( unsigned int txt_id ) 374 { 375 return hal_user_syscall( SYS_DISPLAY, 376 DISPLAY_TXT_PROCESSES, 377 (reg_t)txt_id, 0, 0 ); 378 } 379 380 /////////////////////////////////////////// 381 int get_cycle( unsigned long long * cycle ) 382 { 383 return hal_user_syscall( SYS_GET_CYCLE, 384 (reg_t)cycle, 0, 0, 0 ); 385 } 386 387 /////////////////////////////// 388 int trace( unsigned int active, 389 unsigned int cxy, 390 unsigned int lid ) 391 { 392 return hal_user_syscall( SYS_TRACE, 393 (reg_t)active, 394 (reg_t)cxy, 395 (reg_t)lid, 0 ); 396 } 397 398 312 313 314 315
Note: See TracChangeset
for help on using the changeset viewer.