From cdd7bb7a13442160fea29e10ddc61402f56f4bd1 Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Tue, 12 Apr 2011 01:07:59 -0400 Subject: Reverting "Rewrote Print class." This reverts commit 8bd3cebbee62e2dd7e961b149cc8bb0e980eaf88. --- docs/source/lang/api/serial.rst | 35 ++---- docs/source/lang/api/serialusb.rst | 35 ++---- wirish/Print.cpp | 245 ++++++++++++++++--------------------- wirish/Print.h | 87 +++++++------ 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) - `, 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) - `, 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 -#include -#include - -// 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 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 +#include // 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); }; -- cgit v1.2.3