From 2ef6860d8af25d70b05f61a5f5700e96ecd0cd05 Mon Sep 17 00:00:00 2001 From: bnewbold Date: Sun, 14 Jun 2015 00:31:29 -0700 Subject: WIP on new Print --- wirish/Print.cpp | 283 +++++++++++++----------------------------- wirish/include/wirish/Print.h | 110 ++++++++-------- 2 files changed, 144 insertions(+), 249 deletions(-) diff --git a/wirish/Print.cpp b/wirish/Print.cpp index cf0f74b..ce63373 100644 --- a/wirish/Print.cpp +++ b/wirish/Print.cpp @@ -1,252 +1,143 @@ -/* - * Print.cpp - Base class that provides print() and println() - * Copyright (c) 2008 David A. Mellis. All right reserved. - * Copyright (c) 2011 LeafLabs, LLC. +/****************************************************************************** + * The MIT License * - * 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. + * Copyright (c) 2015 Bryan Newbold * - * 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. + * 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: * - * 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 above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. * - * Modified 23 November 2006 by David A. Mellis - * Modified 12 April 2011 by Marti Bolivar - */ - -#include + * 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. + *****************************************************************************/ -#include -#include - -#ifndef LLONG_MAX /* - * Note: + * Arduino-compatible UART printing implementation. * - * At time of writing (12 April 2011), the limits.h that came with the - * newlib we distributed didn't include LLONG_MAX. Because we're - * staying away from using templates (see /notes/coding_standard.rst, - * "Language Features and Compiler Extensions"), this value was - * copy-pasted from a println() of the value + * This replaces the old copyleft Print class implementation copied from + * Arduino. * - * std::numeric_limits::max(). - */ -#define LLONG_MAX 9223372036854775807LL -#endif - -/* - * Public methods + * This file is a "clean" implementation using only the API documentation + * (for HardwareSerial) without directly copying from the Arduino source. */ -void Print::write(const char *str) { - while (*str) { - write(*str++); - } -} - -void Print::write(const void *buffer, uint32 size) { - uint8 *ch = (uint8*)buffer; - while (size--) { - write(*ch++); - } -} +#include -void Print::print(uint8 b, int base) { - print((uint64)b, base); +void Print::print(unsigned char b) { + this->write(b); } void Print::print(char c) { - write(c); + this->write(c); } -void Print::print(const char str[]) { - write(str); +void Print::print(const char* str) { + this->write(str); } -void Print::print(int n, int base) { - print((long long)n, base); +void Print::print(int n) { + this->print_signed((long)n, DEC); } -void Print::print(unsigned int n, int base) { - print((unsigned long long)n, base); +void Print::print(unsigned int n) { + this->print_unsigned((unsigned long)n, DEC); } -void Print::print(long n, int base) { - print((long long)n, base); -} - -void Print::print(unsigned long n, int base) { - print((unsigned long long)n, base); +void Print::print(long n) { + this->print((long)n, DEC); } -void Print::print(long long n, int base) { - if (base == BYTE) { - write((uint8)n); - return; - } - if (n < 0) { - print('-'); - n = -n; - } - printNumber(n, base); +void Print::print(unsigned long n) { + this->print_unsigned((unsigned long)n, DEC); } -void Print::print(unsigned long long n, int base) { - if (base == BYTE) { - write((uint8)n); - } else { - printNumber(n, base); - } +void Print::print(long n, int base) { + this->print_signed(n, DEC); } -void Print::print(double n, int digits) { - printFloat(n, digits); +void Print::print(double n) { + // XXX } -void Print::println(void) { - print('\r'); - print('\n'); +void Print::println(unsigned char b) { + this->write(b); + this->write(0x0D); // \r + this->write(0x0A); // \n } void Print::println(char c) { - print(c); - println(); + this->print(c); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(const char c[]) { - print(c); - println(); +void Print::println(const char* str) { + this->print(str); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(uint8 b, int base) { - print(b, base); - println(); +void Print::println(int n) { + this->print(n); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(int n, int base) { - print(n, base); - println(); +void Print::println(unsigned int n) { + this->print(n); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(unsigned int n, int base) { - print(n, base); - println(); +void Print::println(long n) { + this->print(n); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(long n, int base) { - print((long long)n, base); - println(); +void Print::println(unsigned long n) { + this->print(n); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(unsigned long n, int base) { - print((unsigned long long)n, base); - println(); +void Print::println(long n, int base) { + this->print(n, base); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(long long n, int base) { - print(n, base); - println(); +void Print::println(double n) { + this->print(n); + this->write(0x0D); // \r + this->write(0x0A); // \n } -void Print::println(unsigned long long n, int base) { - print(n, base); - println(); +void Print::print_unsigned(unsigned long n, int base) { + // XXX: } -void Print::println(double n, int digits) { - print(n, digits); - println(); +void Print::print_signed(long n, int base) { + // XXX: } -/* - * Private methods - */ - -void Print::printNumber(unsigned long long n, uint8 base) { - unsigned char buf[CHAR_BIT * sizeof(long long)]; - 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)); - } +void Print::write(const char* str) { + // XXX: } -/* According to snprintf(), - * - * nextafter((double)numeric_limits::max(), 0.0) ~= 9.22337e+18 - * - * This slightly smaller value was picked semi-arbitrarily. */ -#define LARGE_DOUBLE_TRESHOLD ((double)9.1e18) - -/* THIS FUNCTION SHOULDN'T BE USED IF YOU NEED ACCURATE RESULTS. - * - * This implementation is meant to be simple and not occupy too much - * code size. However, printing floating point values accurately is a - * subtle task, best left to a well-tested library function. - * - * See Steele and White 2003 for more details: - * - * http://kurtstephens.com/files/p372-steele.pdf - */ -void Print::printFloat(double number, uint8 digits) { - // Hackish fail-fast behavior for large-magnitude doubles - if (abs(number) >= LARGE_DOUBLE_TRESHOLD) { - if (number < (double)0.0) { - print('-'); - } - print(""); - return; - } - - // Handle negative numbers - if (number < (double)0.0) { - print('-'); - number = -number; - } - - // Simplistic rounding strategy so that e.g. print(1.999, 2) - // prints as "2.00" - double rounding = (double)0.5; - for (uint8 i = 0; i < digits; i++) { - rounding /= (double)10.0; - } - number += rounding; - - // Extract the integer part of the number and print it - long long int_part = (long long)number; - double remainder = number - int_part; - print(int_part); - - // Print the decimal point, but only if there are digits beyond - if (digits > 0) { - print("."); - } - - // Extract digits from the remainder one at a time - while (digits-- > 0) { - remainder *= (double)10.0; - int to_print = (int)remainder; - print(to_print); - remainder -= to_print; - } +void Print::write(void* buf, unsigned int size) { + // XXX: } diff --git a/wirish/include/wirish/Print.h b/wirish/include/wirish/Print.h index 5fd0b7a..ca3e7e8 100644 --- a/wirish/include/wirish/Print.h +++ b/wirish/include/wirish/Print.h @@ -1,67 +1,71 @@ -/* - * Print.h - Base class that provides print() and println() - * Copyright (c) 2008 David A. Mellis. All right reserved. +/****************************************************************************** + * The MIT License + * + * Copyright (c) 2015 Bryan Newbold * - * 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. + *****************************************************************************/ + +/* + * Arduino-compatible UART printing implementation. * - * 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. + * This replaces the old copyleft Print class implementation copied from + * Arduino. * - * Modified 12 April 2011 by Marti Bolivar + * This file is a "clean" implementation using only the API documentation + * (for HardwareSerial) without directly copying from the Arduino source. */ #ifndef _WIRISH_PRINT_H_ #define _WIRISH_PRINT_H_ -#include - -enum { - BYTE = 0, - BIN = 2, - OCT = 8, - DEC = 10, - HEX = 16 -}; - +/* See HardwareSerial for docs on these functions. */ class Print { public: - virtual void write(uint8 ch) = 0; - virtual void write(const char *str); - virtual void write(const void *buf, uint32 len); - void print(char); - void print(const char[]); - void print(uint8, int=DEC); - void print(int, int=DEC); - void print(unsigned int, int=DEC); - void print(long, int=DEC); - void print(unsigned long, int=DEC); - void print(long long, int=DEC); - void print(unsigned long long, int=DEC); - void print(double, int=2); - void println(void); - void println(char); - void println(const char[]); - void println(uint8, int=DEC); - void println(int, int=DEC); - void println(unsigned int, int=DEC); - void println(long, int=DEC); - void println(unsigned long, int=DEC); - void println(long long, int=DEC); - void println(unsigned long long, int=DEC); - void println(double, int=2); + void print(unsigned char b); + void print(char c); + void print(const char* str); + void print(int n); + void print(unsigned int n); + void print(long n); + void print(unsigned long n); + void print(long n, int base); + void print(double n); + void println(unsigned char b); + void println(char c); + void println(const char* str); + void println(int n); + void println(unsigned int n); + void println(long n); + void println(unsigned long n); + void println(long n, int base); + void println(double n); + void write(const char* str); + void write(void* buf, unsigned int size); + + /* This is the one function that an implementing class needs */ + virtual void write(unsigned char ch); private: - void printNumber(unsigned long long, uint8); - void printFloat(double, uint8); -}; + void print_unsigned(unsigned long n, int base); + void print_signed(long n, int base); +} #endif -- cgit v1.2.3