#include "stdio.h" #include #include "stdlib.h" #include "string.h" #ifdef OS_ABAOS #include "kernel.h" #endif #ifdef OS_ABAOS console_t *stdio_console = NULL; #endif static void print_string( const char *s ); static void print_char( const char c ); static void print_newline( void ); #ifdef OS_ABAOS static void print_string( const char *s ) { if( stdio_console == NULL ) { kernel_panic( "stdio_console not set!" ); } console_put_string( stdio_console, s ); } static void print_char( const char c ) { if( stdio_console == NULL ) { kernel_panic( "stdio_console not set!" ); } console_put_char( stdio_console, c ); } static void print_newline( void ) { if( stdio_console == NULL ) { kernel_panic( "stdio_console not set!" ); } console_put_newline( stdio_console ); } #endif #ifdef OS_LINUX static void print_string( const char *s ) { syscall3( __NR_write, STDOUT_FILENO, (long)s, strlen( s ) ); } static void print_char( const char c ) { char s[2]; s[0] = c; syscall3( __NR_write, STDOUT_FILENO, (long)s, 1 ); } static void print_newline( void ) { char s[2]; s[0] = '\n'; syscall3( __NR_write, STDOUT_FILENO, (long)s, 1 ); } #endif int puts( const char *s ) { print_string( s ); print_newline( ); return 1; } int printf( const char *format, ... ) { va_list args; va_start( args, format ); int res = vprintf( format, args ); va_end( args ); return res; } int vprintf( const char *format, va_list args ) { const char *s = format; int n = 0; while( *s != '\0' ) { switch( *s ) { case '\n': print_newline( ); n++; break; case '%': s++; if( *s == '\0' ) { print_string( "" ); print_newline( ); return -1; } switch( *s ) { case '%': print_char( '%' ); break; case 'X': { char buf[19]; itoa( va_arg( args, int ), (char *)buf, 16 ); print_string( buf ); n += strlen( buf ); } break; case 'd': { char buf[19]; itoa( va_arg( args, int ), (char *)buf, 10 ); print_string( buf ); n += strlen( buf ); } break; case 'c': print_char( va_arg( args, int ) ); break; case 's': print_string( va_arg( args, const char * ) ); break; default: print_string( "" ); print_newline( ); } break; default: print_char( *s ); n++; } s++; } return n; } int snprintf( char *buf, size_t n, const char *format, ... ) { va_list args; va_start( args, format ); int res = vsnprintf( buf, n, format, args ); va_end( args ); return res; } #define EMIT( x ) if( len < n ) { *buf = ( x ); buf++; *buf = '\0'; len++; } #define APPEND_STRING( s, s2 ) \ strlcat( s, s2, n - len ); \ s += strlen( s2 ); \ len += strlen( s2 ); \ if( len < n ) { \ *s = '\0'; \ } int vsnprintf( char *buf, size_t n, const char *format, va_list args ) { const char *s = format; int len = 0; *buf = '\0'; while( *s != '\0' && len < n ) { switch( *s ) { case '\n': EMIT( '\n' ); break; case '%': s++; if( *s == '\0' ) { strlcpy( buf, "", n - len ); strlcat( buf, "\n", n - len - 1 ); return -1; } switch( *s ) { case '%': EMIT( '%' ); break; case 'X': { char buf2[19]; itoa( va_arg( args, int ), (char *)buf2, 16 ); APPEND_STRING( buf, buf2 ); } break; case 'd': { char buf2[19]; itoa( va_arg( args, int ), (char *)buf2, 10 ); APPEND_STRING( buf, buf2 ); } break; case 'c': { char buf2[2]; buf2[0] = (char)va_arg( args, int ); buf2[1] = '\0'; APPEND_STRING( buf, buf2 ); } break; case 's': { const char *s = va_arg( args, const char * ); APPEND_STRING( buf, s ); } break; default: { APPEND_STRING( buf, "