summaryrefslogtreecommitdiff
path: root/src/libc/stdio.c
blob: 1d53f7a063976ee5ecb87d086a7cc6ab5f35c224 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "stdio.h"
#include "stddef.h"
#include "stdlib.h"
#include "string.h"

console_t *global_console = NULL;

int puts( const char *s )
{
	if( global_console == NULL ) {
		return EOF;
	}
	
	console_put_string( global_console, s );
	console_put_newline( global_console );
	
	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;

	if( global_console == NULL ) {
		return -1;
	}
	
	while( *s != '\0' ) {
		switch( *s ) {
			case '\n':
				console_put_newline( global_console );
				n++;
				break;
			
			case '%':
				s++;
				if( *s == '\0' ) {
					console_put_string( global_console, "<truncated % found at end of format string>" );
					console_put_newline( global_console );
					return -1;
				}
				
				switch( *s ) {
					case '%':
						console_put_char( global_console, '%' );
						break;
						
					case 'X': {
						char buf[19];
						itoa( va_arg( args, int ), (char *)buf, 16 );
						console_put_string( global_console, buf );
						n += strlen( buf );
						}
						break;
					
					case 'd': {
						char buf[19];
						itoa( va_arg( args, int ), (char *)buf, 10 );
						console_put_string( global_console, buf );
						n += strlen( buf );
						}
						break;

					case 'c':
						console_put_char( global_console, va_arg( args, int ) );
						break;
						
					case 's':
						console_put_string( global_console, va_arg( args, const char * ) );
						break;

					default:
						console_put_string( global_console, "<illegal format string %" );
						console_put_char( global_console, *s );
						console_put_string( global_console, ">" );
						console_put_newline( global_console );
				}
				
				break;				
			
			default:
				console_put_char( global_console, *s );
				n++;
		}
		s++;
	}
	
	return n;
}

void stdio_set_console( console_t *console )
{
	global_console = console;
}