|
@@ -1,23 +1,24 @@
|
1
|
|
-/*
|
2
|
|
- Print.cpp - Base class that provides print() and println()
|
3
|
|
- Copyright (c) 2008 David A. Mellis. All right reserved.
|
4
|
|
-
|
5
|
|
- This library is free software; you can redistribute it and/or
|
6
|
|
- modify it under the terms of the GNU Lesser General Public
|
7
|
|
- License as published by the Free Software Foundation; either
|
8
|
|
- version 2.1 of the License, or (at your option) any later version.
|
9
|
|
-
|
10
|
|
- This library is distributed in the hope that it will be useful,
|
11
|
|
- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
|
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
|
- Lesser General Public License for more details.
|
14
|
|
-
|
15
|
|
- You should have received a copy of the GNU Lesser General Public
|
16
|
|
- License along with this library; if not, write to the Free Software
|
17
|
|
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
|
-
|
19
|
|
- Modified 23 November 2006 by David A. Mellis
|
20
|
|
- Modified 03 August 2015 by Chuck Todd
|
|
1
|
+/**
|
|
2
|
+ * Print.cpp - Base class that provides print() and println()
|
|
3
|
+ * Copyright (c) 2008 David A. Mellis. All right reserved.
|
|
4
|
+ *
|
|
5
|
+ * This library is free software; you can redistribute it and/or
|
|
6
|
+ * modify it under the terms of the GNU Lesser General Public
|
|
7
|
+ * License as published by the Free Software Foundation; either
|
|
8
|
+ * version 2.1 of the License, or (at your option) any later version.
|
|
9
|
+ *
|
|
10
|
+ * This library is distributed in the hope that it will be useful,
|
|
11
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+ * Lesser General Public License for more details.
|
|
14
|
+ *
|
|
15
|
+ * You should have received a copy of the GNU Lesser General Public
|
|
16
|
+ * License along with this library; if not, write to the Free Software
|
|
17
|
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
18
|
+ *
|
|
19
|
+ * Modified 23 November 2006 by David A. Mellis
|
|
20
|
+ * Modified 03 August 2015 by Chuck Todd
|
|
21
|
+ * Modified 03 February 2018 by Scott Lahteine
|
21
|
22
|
*/
|
22
|
23
|
|
23
|
24
|
#include <stdlib.h>
|
|
@@ -28,16 +29,12 @@
|
28
|
29
|
#include "Print.h"
|
29
|
30
|
#include <stdarg.h>
|
30
|
31
|
|
31
|
|
-#define PrintfEnable 1
|
32
|
|
-typedef signed short sint16_t;
|
33
|
|
-typedef signed long sint32_t;
|
|
32
|
+#define ENABLE_PRINTF
|
34
|
33
|
|
35
|
34
|
// Public Methods //////////////////////////////////////////////////////////////
|
36
|
35
|
|
37
|
36
|
/* default implementation: may be overridden */
|
38
|
|
-size_t Print::write(const uint8_t *buffer, size_t size)
|
39
|
|
-{
|
40
|
|
-
|
|
37
|
+size_t Print::write(const uint8_t *buffer, size_t size) {
|
41
|
38
|
size_t n = 0;
|
42
|
39
|
while (size--) {
|
43
|
40
|
if (write(*buffer++)) n++;
|
|
@@ -46,133 +43,46 @@ size_t Print::write(const uint8_t *buffer, size_t size)
|
46
|
43
|
return n;
|
47
|
44
|
}
|
48
|
45
|
|
|
46
|
+size_t Print::print(const char str[]) { return write(str); }
|
|
47
|
+size_t Print::print(char c) { return write(c); }
|
|
48
|
+size_t Print::print(unsigned char b, int base) { return print((unsigned long) b, base); }
|
|
49
|
+size_t Print::print(int n, int base) { return print((long) n, base); }
|
|
50
|
+size_t Print::print(unsigned int n, int base) { return print((unsigned long) n, base); }
|
|
51
|
+size_t Print::print(double n, int digits) { return printFloat(n, digits); }
|
|
52
|
+size_t Print::print(const Printable& x) { return x.printTo(*this); }
|
|
53
|
+size_t Print::println(void) { return write("\r\n"); }
|
49
|
54
|
|
50
|
|
-size_t Print::print(const char str[])
|
51
|
|
-{
|
52
|
|
-
|
53
|
|
- //while(1);
|
54
|
|
- return write(str);
|
55
|
|
-}
|
56
|
|
-
|
57
|
|
-size_t Print::print(char c)
|
58
|
|
-{
|
59
|
|
- return write(c);
|
60
|
|
-}
|
61
|
|
-
|
62
|
|
-size_t Print::print(unsigned char b, int base)
|
63
|
|
-{
|
64
|
|
- return print((unsigned long) b, base);
|
65
|
|
-}
|
66
|
|
-
|
67
|
|
-size_t Print::print(int n, int base)
|
68
|
|
-{
|
69
|
|
- return print((long) n, base);
|
70
|
|
-}
|
71
|
|
-
|
72
|
|
-size_t Print::print(unsigned int n, int base)
|
73
|
|
-{
|
74
|
|
- return print((unsigned long) n, base);
|
75
|
|
-}
|
76
|
|
-
|
77
|
|
-size_t Print::print(long n, int base)
|
78
|
|
-{
|
79
|
|
- if (base == 0) {
|
80
|
|
- return write(n);
|
81
|
|
- } else if (base == 10) {
|
|
55
|
+size_t Print::print(long n, int base) {
|
|
56
|
+ if (base == 0) return write(n);
|
|
57
|
+ if (base == 10) {
|
82
|
58
|
if (n < 0) {
|
83
|
|
- int t = print('-');
|
84
|
|
- n = -n;
|
85
|
|
- return printNumber(n, 10) + t;
|
|
59
|
+ const int t = print('-');
|
|
60
|
+ return printNumber(-n, 10) + t;
|
86
|
61
|
}
|
87
|
|
- return printNumber(n, 10);
|
88
|
|
- } else {
|
89
|
|
- return printNumber(n, base);
|
90
|
62
|
}
|
|
63
|
+ return printNumber(n, base);
|
91
|
64
|
}
|
92
|
65
|
|
93
|
|
-size_t Print::print(unsigned long n, int base)
|
94
|
|
-{
|
|
66
|
+size_t Print::print(unsigned long n, int base) {
|
95
|
67
|
if (base == 0) return write(n);
|
96
|
|
- else return printNumber(n, base);
|
97
|
|
-}
|
98
|
|
-
|
99
|
|
-size_t Print::print(double n, int digits)
|
100
|
|
-{
|
101
|
|
- return printFloat(n, digits);
|
102
|
|
-}
|
103
|
|
-
|
104
|
|
-size_t Print::print(const Printable& x)
|
105
|
|
-{
|
106
|
|
- return x.printTo(*this);
|
107
|
|
-}
|
108
|
|
-
|
109
|
|
-size_t Print::println(void)
|
110
|
|
-{
|
111
|
|
- return write("\r\n");
|
|
68
|
+ return printNumber(n, base);
|
112
|
69
|
}
|
113
|
70
|
|
114
|
|
-size_t Print::println(const char c[])
|
115
|
|
-{
|
116
|
|
- size_t n = print(c);
|
117
|
|
- n += println();
|
118
|
|
- return n;
|
119
|
|
-}
|
120
|
|
-
|
121
|
|
-size_t Print::println(char c)
|
122
|
|
-{
|
123
|
|
- size_t n = print(c);
|
124
|
|
- n += println();
|
125
|
|
- return n;
|
126
|
|
-}
|
|
71
|
+#define PRINTLN(...) do{ \
|
|
72
|
+ size_t n = print(__VA_ARGS__); \
|
|
73
|
+ n += println(); \
|
|
74
|
+ return n; \
|
|
75
|
+}while(0)
|
127
|
76
|
|
128
|
|
-size_t Print::println(unsigned char b, int base)
|
129
|
|
-{
|
130
|
|
- size_t n = print(b, base);
|
131
|
|
- n += println();
|
132
|
|
- return n;
|
133
|
|
-}
|
134
|
|
-
|
135
|
|
-size_t Print::println(int num, int base)
|
136
|
|
-{
|
137
|
|
- size_t n = print(num, base);
|
138
|
|
- n += println();
|
139
|
|
- return n;
|
140
|
|
-}
|
141
|
|
-
|
142
|
|
-size_t Print::println(unsigned int num, int base)
|
143
|
|
-{
|
144
|
|
- size_t n = print(num, base);
|
145
|
|
- n += println();
|
146
|
|
- return n;
|
147
|
|
-}
|
148
|
|
-
|
149
|
|
-size_t Print::println(long num, int base)
|
150
|
|
-{
|
151
|
|
- size_t n = print(num, base);
|
152
|
|
- n += println();
|
153
|
|
- return n;
|
154
|
|
-}
|
155
|
|
-
|
156
|
|
-size_t Print::println(unsigned long num, int base)
|
157
|
|
-{
|
158
|
|
- size_t n = print(num, base);
|
159
|
|
- n += println();
|
160
|
|
- return n;
|
161
|
|
-}
|
162
|
|
-
|
163
|
|
-size_t Print::println(double num, int digits)
|
164
|
|
-{
|
165
|
|
- size_t n = print(num, digits);
|
166
|
|
- n += println();
|
167
|
|
- return n;
|
168
|
|
-}
|
169
|
|
-
|
170
|
|
-size_t Print::println(const Printable& x)
|
171
|
|
-{
|
172
|
|
- size_t n = print(x);
|
173
|
|
- n += println();
|
174
|
|
- return n;
|
175
|
|
-}
|
|
77
|
+size_t Print::println(const char c[]) { PRINTLN(c); }
|
|
78
|
+size_t Print::println(char c) { PRINTLN(c); }
|
|
79
|
+size_t Print::println(unsigned char b, int base) { PRINTLN(b, base); }
|
|
80
|
+size_t Print::println(int num, int base) { PRINTLN(num, base); }
|
|
81
|
+size_t Print::println(unsigned int num, int base) { PRINTLN(num, base); }
|
|
82
|
+size_t Print::println(long num, int base) { PRINTLN(num, base); }
|
|
83
|
+size_t Print::println(unsigned long num, int base) { PRINTLN(num, base); }
|
|
84
|
+size_t Print::println(double num, int digits) { PRINTLN(num, digits); }
|
|
85
|
+size_t Print::println(const Printable& x) { PRINTLN(x); }
|
176
|
86
|
|
177
|
87
|
// Private Methods /////////////////////////////////////////////////////////////
|
178
|
88
|
|
|
@@ -195,8 +105,7 @@ size_t Print::printNumber(unsigned long n, uint8_t base) {
|
195
|
105
|
return write(str);
|
196
|
106
|
}
|
197
|
107
|
|
198
|
|
-size_t Print::printFloat(double number, uint8_t digits)
|
199
|
|
-{
|
|
108
|
+size_t Print::printFloat(double number, uint8_t digits) {
|
200
|
109
|
size_t n = 0;
|
201
|
110
|
|
202
|
111
|
if (isnan(number)) return print("nan");
|
|
@@ -205,34 +114,29 @@ size_t Print::printFloat(double number, uint8_t digits)
|
205
|
114
|
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
|
206
|
115
|
|
207
|
116
|
// Handle negative numbers
|
208
|
|
- if (number < 0.0)
|
209
|
|
- {
|
210
|
|
- n += print('-');
|
211
|
|
- number = -number;
|
|
117
|
+ if (number < 0.0) {
|
|
118
|
+ n += print('-');
|
|
119
|
+ number = -number;
|
212
|
120
|
}
|
213
|
121
|
|
214
|
122
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
215
|
123
|
double rounding = 0.5;
|
216
|
|
- for (uint8_t i=0; i<digits; ++i)
|
217
|
|
- rounding /= 10.0;
|
|
124
|
+ for (uint8_t i = 0; i < digits; ++i) rounding /= 10.0;
|
218
|
125
|
|
219
|
126
|
number += rounding;
|
220
|
127
|
|
221
|
128
|
// Extract the integer part of the number and print it
|
222
|
|
- unsigned long int_part = (unsigned long)number;
|
|
129
|
+ uint32_t int_part = (uint32_t)number;
|
223
|
130
|
double remainder = number - (double)int_part;
|
224
|
131
|
n += print(int_part);
|
225
|
132
|
|
226
|
133
|
// Print the decimal point, but only if there are digits beyond
|
227
|
|
- if (digits > 0) {
|
228
|
|
- n += print(".");
|
229
|
|
- }
|
|
134
|
+ if (digits > 0) n += print('.');
|
230
|
135
|
|
231
|
136
|
// Extract digits from the remainder one at a time
|
232
|
|
- while (digits-- > 0)
|
233
|
|
- {
|
|
137
|
+ while (digits-- > 0) {
|
234
|
138
|
remainder *= 10.0;
|
235
|
|
- int toPrint = int(remainder);
|
|
139
|
+ const int toPrint = int(remainder);
|
236
|
140
|
n += print(toPrint);
|
237
|
141
|
remainder -= toPrint;
|
238
|
142
|
}
|
|
@@ -240,15 +144,14 @@ size_t Print::printFloat(double number, uint8_t digits)
|
240
|
144
|
return n;
|
241
|
145
|
}
|
242
|
146
|
|
|
147
|
+#ifdef ENABLE_PRINTF
|
243
|
148
|
|
244
|
|
-#if (PrintfEnable == 1)
|
245
|
|
-size_t Print::printf(const char *argList, ...)
|
246
|
|
-{
|
|
149
|
+ size_t Print::printf(const char *argList, ...) {
|
247
|
150
|
const char *ptr;
|
248
|
151
|
double floatNum_f32;
|
249
|
152
|
va_list argp;
|
250
|
|
- sint16_t num_s16;
|
251
|
|
- sint32_t num_s32;
|
|
153
|
+ int16_t num_s16;
|
|
154
|
+ int32_t num_s32;
|
252
|
155
|
uint16_t num_u16;
|
253
|
156
|
uint32_t num_u32;
|
254
|
157
|
char *str;
|
|
@@ -257,103 +160,76 @@ size_t Print::printf(const char *argList, ...)
|
257
|
160
|
|
258
|
161
|
va_start(argp, argList);
|
259
|
162
|
|
260
|
|
- /* Loop through the list to extract all the input arguments */
|
261
|
|
- for(ptr = argList; *ptr != '\0'; ptr++)
|
262
|
|
- {
|
263
|
|
-
|
264
|
|
- ch= *ptr;
|
265
|
|
- if(ch == '%') /*Check for '%' as there will be format specifier after it */
|
266
|
|
- {
|
|
163
|
+ // Loop through the list to extract all the input arguments
|
|
164
|
+ for (ptr = argList; (ch = *ptr); ptr++) {
|
|
165
|
+ if (ch == '%') { //Check for '%' as there will be format specifier after it
|
|
166
|
+ ptr++;
|
|
167
|
+ ch = *ptr;
|
|
168
|
+ if (ch >= '0' && ch <= '9') {
|
|
169
|
+ numOfDigits = 0;
|
|
170
|
+ while (ch >= '0' && ch <= '9') {
|
|
171
|
+ numOfDigits = numOfDigits * 10 + ch - '0';
|
267
|
172
|
ptr++;
|
268
|
173
|
ch = *ptr;
|
269
|
|
- if((ch>=0x30) && (ch<=0x39))
|
270
|
|
- {
|
271
|
|
- numOfDigits = 0;
|
272
|
|
- while((ch>=0x30) && (ch<=0x39))
|
273
|
|
- {
|
274
|
|
- numOfDigits = (numOfDigits * 10) + (ch-0x30);
|
275
|
|
- ptr++;
|
276
|
|
- ch = *ptr;
|
277
|
|
- }
|
278
|
|
- }
|
279
|
|
- else
|
280
|
|
- {
|
281
|
|
- numOfDigits = 0xff;
|
282
|
|
- }
|
283
|
|
-
|
284
|
|
-
|
285
|
|
- switch(ch) /* Decode the type of the argument */
|
286
|
|
- {
|
287
|
|
-
|
288
|
|
- case 'C':
|
289
|
|
- case 'c': /* Argument type is of char, hence read char data from the argp */
|
290
|
|
- ch = va_arg(argp, int);
|
291
|
|
- print(ch);
|
292
|
|
- break;
|
293
|
|
-
|
294
|
|
-
|
295
|
|
-
|
296
|
|
- case 'd': /* Argument type is of signed integer, hence read 16bit data from the argp */
|
297
|
|
- case 'D':
|
298
|
|
- num_s32 = va_arg(argp, int);
|
299
|
|
- print(num_s32, 10);
|
300
|
|
- break;
|
301
|
|
-
|
302
|
|
-
|
303
|
|
- case 'u':
|
304
|
|
- case 'U': /* Argument type is of integer, hence read 32bit unsigend data */
|
305
|
|
- num_u32 = va_arg(argp, uint32_t);
|
306
|
|
- print(num_u32, 10);
|
307
|
|
- break;
|
308
|
|
-
|
309
|
|
-
|
310
|
|
-
|
311
|
|
-
|
312
|
|
- case 'x':
|
313
|
|
- case 'X': /* Argument type is of hex, hence hexadecimal data from the argp */
|
314
|
|
- num_u32 = va_arg(argp, uint32_t);
|
315
|
|
- print(num_u32, 16);
|
316
|
|
- break;
|
317
|
|
-
|
318
|
|
-
|
319
|
|
- case 'b':
|
320
|
|
- case 'B': /* Argument type is of binary,Read int and convert to binary */
|
321
|
|
- num_u32 = va_arg(argp, uint32_t);
|
322
|
|
- print(num_u32, 2);
|
323
|
|
- break;
|
324
|
|
-
|
325
|
|
-
|
326
|
|
-
|
327
|
|
- case 'F':
|
328
|
|
- case 'f': /* Argument type is of float, hence read double data from the argp */
|
329
|
|
- floatNum_f32 = va_arg(argp, double);
|
330
|
|
- printFloat(floatNum_f32,10);
|
331
|
|
- break;
|
332
|
|
-
|
333
|
|
-
|
334
|
|
-
|
335
|
|
- case 'S':
|
336
|
|
- case 's': /* Argument type is of string, hence get the pointer to sting passed */
|
337
|
|
- str = va_arg(argp, char *);
|
338
|
|
- print(str);
|
339
|
|
- break;
|
340
|
|
-
|
341
|
|
-
|
342
|
|
-
|
343
|
|
- case '%':
|
344
|
|
- print('%');
|
345
|
|
- break;
|
346
|
|
- }
|
|
174
|
+ }
|
347
|
175
|
}
|
348
|
176
|
else
|
349
|
|
- {
|
350
|
|
- /* As '%' is not detected transmit the char passed */
|
|
177
|
+ numOfDigits = 0xFF;
|
|
178
|
+
|
|
179
|
+ switch(ch) { // Decode the type of the argument
|
|
180
|
+
|
|
181
|
+ case 'C':
|
|
182
|
+ case 'c': // Argument type is of char, hence read char data from the argp
|
|
183
|
+ ch = va_arg(argp, int);
|
351
|
184
|
print(ch);
|
|
185
|
+ break;
|
|
186
|
+
|
|
187
|
+ case 'd': // Argument type is of signed integer, hence read 16bit data from the argp
|
|
188
|
+ case 'D':
|
|
189
|
+ num_s32 = va_arg(argp, int);
|
|
190
|
+ print(num_s32, 10);
|
|
191
|
+ break;
|
|
192
|
+
|
|
193
|
+ case 'u':
|
|
194
|
+ case 'U': // Argument type is of integer, hence read 32bit unsigend data
|
|
195
|
+ num_u32 = va_arg(argp, uint32_t);
|
|
196
|
+ print(num_u32, 10);
|
|
197
|
+ break;
|
|
198
|
+
|
|
199
|
+ case 'x':
|
|
200
|
+ case 'X': // Argument type is of hex, hence hexadecimal data from the argp
|
|
201
|
+ num_u32 = va_arg(argp, uint32_t);
|
|
202
|
+ print(num_u32, 16);
|
|
203
|
+ break;
|
|
204
|
+
|
|
205
|
+ case 'b':
|
|
206
|
+ case 'B': // Argument type is of binary,Read int and convert to binary
|
|
207
|
+ num_u32 = va_arg(argp, uint32_t);
|
|
208
|
+ print(num_u32, 2);
|
|
209
|
+ break;
|
|
210
|
+
|
|
211
|
+ case 'F':
|
|
212
|
+ case 'f': // Argument type is of float, hence read double data from the argp
|
|
213
|
+ floatNum_f32 = va_arg(argp, double);
|
|
214
|
+ printFloat(floatNum_f32, 10);
|
|
215
|
+ break;
|
|
216
|
+
|
|
217
|
+ case 'S':
|
|
218
|
+ case 's': // Argument type is of string, hence get the pointer to sting passed
|
|
219
|
+ str = va_arg(argp, char *);
|
|
220
|
+ print(str);
|
|
221
|
+ break;
|
|
222
|
+
|
|
223
|
+ case '%':
|
|
224
|
+ print('%');
|
|
225
|
+ break;
|
352
|
226
|
}
|
|
227
|
+ }
|
|
228
|
+ else
|
|
229
|
+ print(ch); // As '%' is not detected transmit the char passed
|
353
|
230
|
}
|
354
|
231
|
|
355
|
232
|
va_end(argp);
|
356
|
|
-}
|
357
|
|
-
|
|
233
|
+ }
|
358
|
234
|
|
359
|
|
-#endif
|
|
235
|
+#endif // ENABLE_PRINTF
|