aboutsummaryrefslogtreecommitdiff
path: root/src/inc/stdout.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/inc/stdout.c')
-rwxr-xr-xsrc/inc/stdout.c154
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
61void 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
..