aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/source/lang/api/serial.rst35
-rw-r--r--docs/source/lang/api/serialusb.rst35
-rw-r--r--wirish/Print.cpp245
-rw-r--r--wirish/Print.h87
4 files changed, 167 insertions, 235 deletions
diff --git a/docs/source/lang/api/serial.rst b/docs/source/lang/api/serial.rst
index 29c70a2..fadac34 100644
--- a/docs/source/lang/api/serial.rst
+++ b/docs/source/lang/api/serial.rst
@@ -116,34 +116,25 @@ means that you can use any of these functions on any of ``Serial1``,
Print the argument's digits over the USART, in decimal format.
-.. cpp:function:: HardwareSerial::print(long long n)
+.. cpp:function:: HardwareSerial::print(long n)
Print the argument's digits over the USART, in decimal format.
Negative values will be prefixed with a ``'-'`` character.
-.. cpp:function:: HardwareSerial::print(unsigned long long n)
+.. cpp:function:: HardwareSerial::print(unsigned long n)
Print the argument's digits over the USART, in decimal format.
-.. _lang-serial-print-n-base:
+.. cpp:function:: HardwareSerial::print(long n, int base)
-.. cpp:function:: HardwareSerial::print(int n, int base)
-
- Print the digits of ``n`` over the USART, in base ``base``. The
- ``base`` value 2 corresponds to binary, 8 to octal, 10 to decimal,
- and 16 to hexadecimal (you can also use the symbolic constants
- ``BIN``, ``OCT``, ``DEC``, ``HEX``). If ``base`` is 10, negative
- values will be prefixed with a ``'-'`` character (otherwise, ``n``
- will be interpreted as an unsigned quantity).
-
-.. cpp:function:: HardwareSerial::print(long long n, int base)
-
- Same behavior as the above :ref:`print(int n, int base)
- <lang-serial-print-n-base>`, except with 64-bit values.
+ Print the digits of ``n`` over the USART, in base ``base`` (which
+ may be between 2 and 16). The ``base`` value 2 corresponds to
+ binary, 8 to octal, 10 to decimal, and 16 to hexadecimal. Negative
+ values will be prefixed with a ``'-'`` character.
.. cpp:function:: HardwareSerial::print(double n)
- Print ``n``, accurate to 6 digits after the decimal point.
+ Print ``n``, accurate to 2 digits after the decimal point.
.. _lang-serial-println:
@@ -167,19 +158,15 @@ means that you can use any of these functions on any of ``Serial1``,
Like ``print(n)``, followed by ``"\r\n"``.
-.. cpp:function:: HardwareSerial::println(long long n)
+.. cpp:function:: HardwareSerial::println(long n)
Like ``print(n)``, followed by ``"\r\n"``.
-.. cpp:function:: HardwareSerial::println(unsigned long long n)
+.. cpp:function:: HardwareSerial::println(unsigned long n)
Like ``print(n)``, followed by ``"\r\n"``.
-.. cpp:function:: HardwareSerial::println(int n, int base)
-
- Like ``print(n, b)``, followed by ``"\r\n"``.
-
-.. cpp:function:: HardwareSerial::println(long long n, int base)
+.. cpp:function:: HardwareSerial::println(long n, int base)
Like ``print(n, b)``, followed by ``"\r\n"``.
diff --git a/docs/source/lang/api/serialusb.rst b/docs/source/lang/api/serialusb.rst
index 4ddfa4a..ee7146e 100644
--- a/docs/source/lang/api/serialusb.rst
+++ b/docs/source/lang/api/serialusb.rst
@@ -109,35 +109,26 @@ world!")``.
Print the argument's digits over the USB connection, in decimal format.
-.. cpp:function:: USBSerial::print(long long n)
+.. cpp:function:: USBSerial::print(long n)
Print the argument's digits over the USB connection, in decimal
format. Negative values will be prefixed with a ``'-'`` character.
-.. cpp:function:: USBSerial::print(unsigned long long n)
+.. cpp:function:: USBSerial::print(unsigned long n)
Print the argument's digits over the USB connection, in decimal
format.
-.. _lang-serial-print-n-base:
+.. cpp:function:: USBSerial::print(long n, int base)
-.. cpp:function:: USBSerial::print(int n, int base)
-
- Print the digits of ``n`` over USB, in base ``base``. The ``base``
- value 2 corresponds to binary, 8 to octal, 10 to decimal, and 16 to
- hexadecimal (you can also use the symbolic constants ``BIN``,
- ``OCT``, ``DEC``, ``HEX``). If ``base`` is 10, negative values
- will be prefixed with a ``'-'`` character (otherwise, ``n`` will be
- interpreted as an unsigned quantity).
-
-.. cpp:function:: HardwareSerial::print(long long n, int base)
-
- Same behavior as the above :ref:`print(int n, int base)
- <lang-serialusb-print-n-base>`, except with 64-bit values.
+ Print the digits of ``n`` over the USB connection, in base ``base``
+ (which may be between 2 and 16). The ``base`` value 2 corresponds
+ to binary, 8 to octal, 10 to decimal, and 16 to hexadecimal.
+ Negative values will be prefixed with a ``'-'`` character.
.. cpp:function:: USBSerial::print(double n)
- Print ``n``, accurate to 6 digits after the decimal point.
+ Print ``n``, accurate to 2 digits after the decimal point.
.. _lang-serialusb-println:
@@ -161,19 +152,15 @@ world!")``.
Like ``print(n)``, followed by ``"\r\n"``.
-.. cpp:function:: USBSerial::println(long long n)
+.. cpp:function:: USBSerial::println(long n)
Like ``print(n)``, followed by ``"\r\n"``.
-.. cpp:function:: USBSerial::println(unsigned long long n)
+.. cpp:function:: USBSerial::println(unsigned long n)
Like ``print(n)``, followed by ``"\r\n"``.
-.. cpp:function:: USBSerial::println(int n, int base)
-
- Like ``print(n, b)``, followed by ``"\r\n"``.
-
-.. cpp:function:: USBSerial::println(long long n, int base)
+.. cpp:function:: USBSerial::println(long n, int base)
Like ``print(n, b)``, followed by ``"\r\n"``.
diff --git a/wirish/Print.cpp b/wirish/Print.cpp
index 9c52321..c66ca61 100644
--- a/wirish/Print.cpp
+++ b/wirish/Print.cpp
@@ -1,127 +1,91 @@
-/******************************************************************************
- * The MIT License
+/*
+ * Print.cpp - Base class that provides print() and println()
+ * Copyright (c) 2008 David A. Mellis. All right reserved.
*
- * Copyright (c) 2011 LeafLabs, LLC.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
*
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *****************************************************************************/
+ * Modified 23 November 2006 by David A. Mellis
+ */
+#include "wirish.h"
#include "Print.h"
-#include <cstdio>
-#include <climits>
-#include <cstring>
-
-// We'll allocate character buffers of size INT_BUF_SIZE to hold the
-// string representations of numbers; this value ensures that they're
-// big enough to accomodate the biggest integral value + null byte.
-//
-// E.g., consider -(2^63-1) = -9223372036854775807, which is 20
-// characters long, including the minus sign. The other edge cases
-// are similar.
-//
-// (Nonetheless, use snprintf everywhere, just in case of error).
-#define INT_BUF_SIZE 21
-
-// An IEEE-754 double buys you about 16 digits of precision; there's
-// the possibility of minus signs, a decimal point, 'e+'/'e-', etc.
-// While the Right Thing is to follow Steele and White, I'm just going
-// to double what I consider a safe number of bytes and hope for the
-// best.
-#define DOUBLE_BUF_SIZE 40
-
-static void fillBase(char *buf, int buf_size, int64 n,
- uint8 n_real_bits, int base);
-static void fillBinary(char *buf, int64 n, int start_bit);
-static char baseToFmtSpec(int base);
+//------------------------------ Public Methods -------------------------------
void Print::write(const char *str) {
- for (const char *c = str; *c != '\0'; c++) {
- write(*c);
- }
+ while (*str)
+ write(*str++);
}
void Print::write(void *buffer, uint32 size) {
- for (uint32 i = 0; i < size; i++) {
- write(*((uint8*)buffer + i));
+ uint8 *ch = (uint8*)buffer;
+ while (size--) {
+ write(*ch++);
}
}
+void Print::print(uint8 b) {
+ this->write(b);
+}
+
void Print::print(char c) {
- print((uint8) c);
+ print((byte) c);
}
void Print::print(const char str[]) {
write(str);
}
-void Print::print(uint8 b) {
- write(b);
-}
-
-void Print::print(int32 n) {
- print(n, DEC);
+void Print::print(int n) {
+ print((long) n);
}
-void Print::print(uint32 n) {
- print((uint64) n);
+void Print::print(unsigned int n) {
+ print((unsigned long) n);
}
-void Print::print(int64 n) {
- print(n, DEC);
-}
-
-void Print::print(uint64 n) {
- char buf[INT_BUF_SIZE];
- snprintf(buf, INT_BUF_SIZE, "%llu", n);
- write(buf);
+void Print::print(long n) {
+ if (n < 0) {
+ print('-');
+ n = -n;
+ }
+ printNumber(n, 10);
}
-void Print::print(int32 n, int base) {
- // Worst case: sign bit set && base == BIN: 32 bytes for digits +
- // 1 null (base == BIN means no minus sign).
- char buf[33];
- fillBase(buf, sizeof(buf), (int64)n, 32, base);
- write(buf);
+void Print::print(unsigned long n) {
+ printNumber(n, 10);
}
-void Print::print(int64 n, int base) {
- // As above, but now 64 bytes for bits + 1 null
- char buf[65];
- fillBase(buf, sizeof(buf), n, 64, base);
- write(buf);
+void Print::print(long n, int base) {
+ if (base == 0) {
+ print((char) n);
+ } else if (base == 10) {
+ print(n);
+ } else {
+ printNumber(n, base);
+ }
}
void Print::print(double n) {
- char buf[DOUBLE_BUF_SIZE];
- // This breaks strict compliance with the Arduino library behavior
- // (which is equivalent to using "%.2f"), but that's really not
- // enough. According to Stroustrup, "%f" without precision is
- // equivalent to ".6f", which is much better.
- snprintf(buf, DOUBLE_BUF_SIZE, "%f", n);
- write(buf);
+ printFloat(n, 2);
}
void Print::println(void) {
- print("\r\n");
+ print('\r');
+ print('\n');
}
void Print::println(char c) {
@@ -139,32 +103,27 @@ void Print::println(uint8 b) {
println();
}
-void Print::println(int32 n) {
+void Print::println(int n) {
print(n);
println();
}
-void Print::println(uint32 n) {
+void Print::println(unsigned int n) {
print(n);
println();
}
-void Print::println(int64 n) {
+void Print::println(long n) {
print(n);
println();
}
-void Print::println(uint64 n) {
+void Print::println(unsigned long n) {
print(n);
println();
}
-void Print::println(int32 n, int base) {
- print(n, base);
- println();
-}
-
-void Print::println(int64 n, int base) {
+void Print::println(long n, int base) {
print(n, base);
println();
}
@@ -174,54 +133,58 @@ void Print::println(double n) {
println();
}
-// -- Auxiliary functions -----------------------------------------------------
+//------------------------------ Private Methods ------------------------------
-static void fillBase(char *buf, int buf_size, int64 n,
- uint8 n_real_bits, int base) {
- if (base == BIN) {
- fillBinary(buf, n, n_real_bits - 1);
- } else {
- char spec = baseToFmtSpec(base);
- char fmt[5];
-
- if (base == BYTE)
- n = (uint8)n;
-
- if (n_real_bits == 32) {
- snprintf(fmt, sizeof(fmt), "%%l%c", spec);
- snprintf(buf, buf_size, fmt, (int32)n);
- } else {
- snprintf(fmt, sizeof(fmt), "%%ll%c", spec);
- snprintf(buf, buf_size, fmt, n);
- }
+void Print::printNumber(unsigned long n, uint8 base) {
+ unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
+ unsigned long i = 0;
+
+ if (n == 0) {
+ print('0');
+ return;
}
+
+ while (n > 0) {
+ buf[i++] = n % base;
+ n /= base;
+ }
+
+ for (; i > 0; i--)
+ print((char) (buf[i - 1] < 10 ?
+ '0' + buf[i - 1] :
+ 'A' + buf[i - 1] - 10));
}
-// Assumes sizeof(buf) > start_bit.
-static void fillBinary(char *buf, int64 n, int start_bit) {
- int b = 0; // position in buf
- int i = start_bit; // position in n's bits
- while(!(n & (1 << i))) {
- i--;
+void Print::printFloat(double number, uint8 digits) {
+ // Handle negative numbers
+ if (number < 0.0) {
+ print('-');
+ number = -number;
}
- for(; i >= 0; i--) {
- buf[b++] = '0' + ((n >> i) & 0x1);
+
+ // Round correctly so that print(1.999, 2) prints as "2.00"
+ double rounding = 0.5;
+ for (uint8 i=0; i<digits; ++i) {
+ rounding /= 10.0;
+ }
+
+ number += rounding;
+
+ // Extract the integer part of the number and print it
+ unsigned long int_part = (unsigned long)number;
+ double remainder = number - (double)int_part;
+ print(int_part);
+
+ // Print the decimal point, but only if there are digits beyond
+ if (digits > 0) {
+ print(".");
}
- buf[b] = '\0';
-}
-
-static char baseToFmtSpec(int base) {
- switch (base) {
- case DEC:
- return 'd';
- case HEX:
- return 'x';
- case OCT:
- return 'o';
- case BYTE:
- return 'd';
- default:
- // Shouldn't happen, but give a sensible default
- return 'd';
+
+ // Extract digits from the remainder one at a time
+ while (digits-- > 0) {
+ remainder *= 10.0;
+ int toPrint = int(remainder);
+ print(toPrint);
+ remainder -= toPrint;
}
}
diff --git a/wirish/Print.h b/wirish/Print.h
index 4527948..dc21183 100644
--- a/wirish/Print.h
+++ b/wirish/Print.h
@@ -1,67 +1,62 @@
-/******************************************************************************
- * The MIT License
+/*
+ * Print.h - Base class that provides print() and println()
+ * Copyright (c) 2008 David A. Mellis. All right reserved.
*
- * Copyright (c) 2011 LeafLabs, LLC.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
*
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *****************************************************************************/
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
-#ifndef _PRINT_H_
-#define _PRINT_H_
+#ifndef Print_h
+#define Print_h
-#include "libmaple_types.h"
+#include <libmaple_types.h>
+#include <stdio.h> // for size_t
-#define DEC 10
-#define HEX 16
-#define OCT 8
-#define BIN 2
-#define BYTE 0 // yuck
+#define DEC 10
+#define HEX 16
+#define OCT 8
+#define BIN 2
+#define BYTE 0
-class Print {
+class Print
+{
+ private:
+ void printNumber(unsigned long, uint8);
+ void printFloat(double, uint8);
public:
virtual void write(uint8) = 0;
virtual void write(const char *str);
- virtual void write(void *buf, uint32 size);
-
+ virtual void write(void *, uint32);
void print(char);
void print(const char[]);
void print(uint8);
- void print(int32);
- void print(uint32);
- void print(int64);
- void print(uint64);
- void print(int32, int);
- void print(int64, int);
+ void print(int);
+ void print(unsigned int);
+ void print(long);
+ void print(unsigned long);
+ void print(long, int);
void print(double);
-
void println(void);
void println(char);
void println(const char[]);
void println(uint8);
- void println(int32);
- void println(uint32);
- void println(int64);
- void println(uint64);
- void println(int32, int);
- void println(int64, int);
+ void println(int);
+ void println(unsigned int);
+ void println(long);
+ void println(unsigned long);
+ void println(long, int);
void println(double);
};