-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuffer_printf.c
155 lines (141 loc) · 3.49 KB
/
buffer_printf.c
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* buffer_printf.c
*
* Created on: Mar 11, 2014
* Author: Michael
*/
#include "buffer.h"
#include "buffer_printf.h"
#include <stdarg.h>
#define ESC 0x1B
void Push_printf(buffer_t * buf, char * str,...) {
// variable argument list type
va_list vars;
// initialize the variable argument list pointer by specifying the
// input argument immediately preceding the variable list
va_start(vars, str);
Push_vprintf(buf, str, vars);
va_end(vars);
}
void Push_vprintf(buffer_t * buf, char * str, va_list vars) {
char escape = 0;
while(*str != 0) {
if(*str == '%' && !escape) {
switch(*(str+1)) {
case 0:
str++;
continue;
case 'c': // char
// to be implemented by everyone else
Push(buf, va_arg(vars, char));
str+=2;
continue;
case 'd':
// Capo
// use va_arg to ge the next variable of length int
Push_int16(buf,va_arg(vars, int));
str+=2;
continue;
case 'e':
case 'f':
case 'g': // scientific notation of float
// Jehandad
PushFloat(buf, va_arg(vars, double));
str+=2;
continue;
case 's': // string
// Cecere / Paterson
PushStr(buf, va_arg(vars, char *));
str+=2;
continue;
case 'u':
// use va_arg to ge the next variable of length int
Push_uint16(buf,va_arg(vars, unsigned int));
str+=2;
continue;
case 'x': // hex
// Jake
PushHex(buf,va_arg(vars, int));
str+=2;
continue;
default:
// if the character following the % was not "special"
// then we will print the % and whatever follows it
break;
}
}
escape = (*str == '\\') ? 1 : 0;
Push(buf,*str++);
}
}
void Push_uint16(buffer_t * buf, uint16_t x) {
char num[6];
unsigned int i = 0;
do {
num[i] = (x % 10) + '0';
x /= 10;
i++;
} while (x);
do {
Push(buf, num[--i]);
} while (i);
}
void Push_int16(buffer_t * buf, int16_t x) {
if (x < 0) {
Push(buf, '-');
x = -x;
}
Push_uint16(buf, x);
}
void Push_int32(buffer_t * buf, int32_t x) {
if (x < 0) {
Push(buf, '-');
x = -x;
}
Push_uint32(buf, x);
}
void Push_uint32(buffer_t * buf, uint32_t x) {
char num[10];
unsigned int i = 0;
do {
num[i] = (x % 10) + '0';
x /= 10;
i++;
} while (x);
do {
Push(buf, num[--i]);
} while (i);
}
void PushStr(buffer_t * buf, char * str){
do{
Push(buf, *str);
} while( *str++ != 0);
}
void PushHex(buffer_t *buf, uint16_t x)
{
volatile unsigned int y;
char num[4];
unsigned int i = 0;
do {
y = x - ((x >> 4) << 4); // x % 16
num[i++] = (y >= 10) ? (y + 0x37) : (y + 0x30);
x >>= 4; // x / 16
} while(x);
do {
Push(buf, num[--i]);
} while (i);
}
void PushFloat(buffer_t * buf, float x) {
int i;
long l;
// for now just print 0.000 format
i = x;
Push_int16(buf, i);
l = (x * 1000);
l = l - i * 1000;
Push(buf, '.');
if(l < 100) Push(buf, '0');
if(l < 10) Push(buf, '0');
if(l == 0) Push(buf, '0');
else Push_uint16(buf, l & 0xFFFF);
}