diff options
Diffstat (limited to 'src/inc/stdout.c')
-rwxr-xr-x | src/inc/stdout.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/src/inc/stdout.c b/src/inc/stdout.c new file mode 100755 index 0000000..0160e0b --- /dev/null +++ b/src/inc/stdout.c | |||
@@ -0,0 +1,154 @@ | |||
1 | #include "stdout.h" | ||
2 | |||
3 | #ifdef STDOUT_put_string | ||
4 | void stdout_put_string(void (*putc)(char c), const char* s) | ||
5 | { | ||
6 | register unsigned char c; | ||
7 | while ((c=*s++)) | ||
8 | putc(c); | ||
9 | } | ||
10 | #endif | ||
11 | |||
12 | #ifdef STDOUT_put_uint | ||
13 | void stdout_put_uint(void (*putc)(const char c), int n) | ||
14 | { | ||
15 | unsigned char i; | ||
16 | for(i=0; _devisor_ten[i]>n; i++); | ||
17 | int c=0; | ||
18 | for(; i<sizeof(_devisor_ten) / sizeof(int); i++) | ||
19 | { | ||
20 | for(c=0; (n - _devisor_ten[i]) < n; c++) | ||
21 | n -= _devisor_ten[i]; | ||
22 | putc('0' + c); | ||
23 | } | ||
24 | /// // if processor has can devide this might be better: | ||
25 | /// register unsigned int d=1; | ||
26 | /// for(; d<n; d*=10); | ||
27 | /// for(d /= 10; d>0; n %= d, d /= 10) | ||
28 | /// putc('0' + (n / d)); | ||
29 | } | ||
30 | #endif | ||
31 | |||
32 | #ifdef STDOUT_reverse_bits | ||
33 | char stdout_reverse_bits(unsigned char v) | ||
34 | { | ||
35 | unsigned char s = sizeof(v) * CHAR_BIT; // bit size; must be power of 2 | ||
36 | unsigned char mask = ~0; | ||
37 | while ((s >>= 1) > 0) | ||
38 | { | ||
39 | mask ^= (mask << s); | ||
40 | v = ((v >> s) & mask) | ((v << s) & ~mask); | ||
41 | } | ||
42 | return v; | ||
43 | } | ||
44 | #endif | ||
45 | |||
46 | #ifdef STDOUT_put_binary | ||
47 | void stdout_put_binary(void (*putc)(const char c), const unsigned char data) | ||
48 | { | ||
49 | char i; | ||
50 | for(i=CHAR_BIT-1; i>=0; i--) | ||
51 | { | ||
52 | if(data & (1<<i)) | ||
53 | putc('1'); | ||
54 | else | ||
55 | putc('0'); | ||
56 | } | ||
57 | } | ||
58 | #endif | ||
59 | |||
60 | #ifdef STDOUT_putf | ||
61 | void stdout_putf(void (*putc)(const char c), const char* format, ...) | ||
62 | { | ||
63 | va_list vl; | ||
64 | va_start(vl, format); | ||
65 | |||
66 | typedef union | ||
67 | { | ||
68 | char as_char : (sizeof(char) * CHAR_BIT); | ||
69 | int as_int : (sizeof(int) * CHAR_BIT); | ||
70 | uint32_t as_uint : (sizeof(int) * CHAR_BIT); | ||
71 | } va_data; | ||
72 | va_data data; | ||
73 | |||
74 | do | ||
75 | { | ||
76 | if(format[0] != '%') | ||
77 | putc(format[0]); | ||
78 | else | ||
79 | { | ||
80 | char f = '\0'; // fill-char for fixed width numbers (\0 means OFF) | ||
81 | switch((++format)[0]) | ||
82 | { | ||
83 | case '%': | ||
84 | putc('%'); | ||
85 | break; | ||
86 | case 'c': | ||
87 | putc(va_arg(vl, int)); | ||
88 | break; | ||
89 | case '0': | ||
90 | if(f == '\0') | ||
91 | f = '0'; | ||
92 | case '-': | ||
93 | if(f == '\0') | ||
94 | f = ' '; | ||
95 | case ' ': | ||
96 | case 'd': | ||
97 | { | ||
98 | int width = 0; | ||
99 | data.as_int = va_arg(vl, unsigned int); | ||
100 | |||
101 | if(data.as_int < 0) | ||
102 | { | ||
103 | putc('-'); | ||
104 | width = -1; | ||
105 | data.as_int *= -1; | ||
106 | } | ||
107 | else if(format[0] == ' ') | ||
108 | putc(' '); | ||
109 | |||
110 | if(f != '\0') | ||
111 | { | ||
112 | // translate string with user-requested fixed length... | ||
113 | static const int _potences[] = {1, 10, 100, 1000}; | ||
114 | |||
115 | int s = 0; | ||
116 | while((++format)[1] !='d' && format[0] >='0' && format[0] <='9') | ||
117 | s++; | ||
118 | for(; s>=0; --s) | ||
119 | width += _potences[sizeof(_potences) - s] * (format[-s] - '0'); | ||
120 | |||
121 | // count numbers width in decimal-system... | ||
122 | for(s=10; s<data.as_int; s*=10, --width); | ||
123 | |||
124 | // remove trailing numbers and append spacechar if wanted... | ||
125 | for(; width>1; width--, putc(f)); // prepend whitespace-character[space] | ||
126 | } | ||
127 | |||
128 | stdout_put_uint(putc, data.as_uint); | ||
129 | if(format[0] != 'd') | ||
130 | ++format; | ||
131 | } | ||
132 | break; | ||
133 | case 's': | ||
134 | #ifdef STDOUT_put_string | ||
135 | stdout_put_string(putc, va_arg(vl, char*)); | ||
136 | #else | ||
137 | va_arg(vl, int); // remove next argument | ||
138 | #endif | ||
139 | break; | ||
140 | case 'b': | ||
141 | #ifdef STDOUT_put_binary | ||
142 | data.as_int = va_arg(vl, int); | ||
143 | stdout_put_binary(putc, data.as_uint); | ||
144 | #else | ||
145 | va_arg(vl, int); // remove next argument | ||
146 | #endif | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | while((++format)[0] != '\0'); | ||
152 | return; | ||
153 | } | ||
154 | #endif | ||