From 31ff05504fd862a3dfeace691027cc69af213c1d Mon Sep 17 00:00:00 2001
From: "David A. Mellis" <d.mellis@arduino.cc>
Date: Wed, 17 Aug 2011 13:53:49 -0400
Subject: Integrating Stream searching & parsing (Michael Margolis)

This from Michael's TextFinder library, incorporated into the Stream class: find(), findUntil(), parseInt(), parseFloat(), readChars(), readCharsUntil(), readCharsBetween(), setTimeout().
---
 cores/arduino/Stream.cpp | 244 +++++++++++++++++++++++++++++++++++++++++++++++
 cores/arduino/Stream.h   |  64 +++++++++++++
 2 files changed, 308 insertions(+)
 create mode 100644 cores/arduino/Stream.cpp

(limited to 'cores/arduino')

diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp
new file mode 100644
index 0000000..dea0aff
--- /dev/null
+++ b/cores/arduino/Stream.cpp
@@ -0,0 +1,244 @@
+/*
+ Stream.cpp - adds parsing methods to Stream class
+ Copyright (c) 2008 David A. Mellis.  All right reserved.
+
+ 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.
+
+ 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.
+
+ 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
+
+ Created July 2011
+ parsing functions based on TextFinder library by Michael Margolis
+ */
+
+#include "Arduino.h"
+#include "Stream.h"
+
+#define PARSE_TIMEOUT 5  // default number of seconds to wait
+#define NO_SKIP_CHAR  1  // a magic char not found in a valid ASCII numeric field
+
+// private method to read stream with timeout
+int Stream::timedRead()
+{
+  //Serial.println(_timeout);
+  this->_startMillis = millis();
+  while(millis() - this->_startMillis < (this->_timeout * 1000L))
+  {
+    if (this->available() > 0) {
+      return this->read();
+    }
+  }
+  return -1;     // -1 indicates timeout
+}
+
+// returns the next digit in the stream or -1 if timeout
+// discards non-numeric characters
+int Stream::getNextDigit()
+{
+  int c;
+  do{
+    c = timedRead();
+    if( c < 0)
+      return c;  // timeout
+  }
+  while( c != '-' && (c < '0' || c > '9') ) ;
+
+return c;
+}
+
+// Public Methods
+//////////////////////////////////////////////////////////////
+
+void Stream::setTimeout( long timeout)  // sets the maximum number of seconds to wait
+{
+   this->_timeout = timeout;
+}
+
+ // find returns true if the target string is found
+bool  Stream::find(char *target)
+{
+  return findUntil(target, NULL);
+}
+
+// reads data from the stream until the target string of given length is found
+// returns true if target string is found, false if timed out
+bool Stream::find(char *target, size_t length)
+{
+  return findUntil(target, length, NULL, 0);
+}
+
+// as find but search ends if the terminator string is found
+bool  Stream::findUntil(char *target, char *terminator)
+{
+  return findUntil(target, strlen(target), terminator, strlen(terminator));
+}
+
+// reads data from the stream until the target string of the given length is found
+// search terminated if the terminator string is found
+// returns true if target string is found, false if terminated or timed out
+bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
+{
+  size_t index = 0;  // maximum target string length is 64k bytes!
+  size_t termIndex = 0;
+  int c;
+
+  if( *target == 0)
+     return true;   // return true if target is a null string
+  while( (c = timedRead()) > 0){
+    if( c == target[index]){
+    //////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
+      if(++index >= targetLen){ // return true if all chars in the target match
+        return true;
+      }
+    }
+    else{
+      index = 0;  // reset index if any char does not match
+    }
+    if(termLen > 0 && c == terminator[termIndex]){
+       if(++termIndex >= termLen)
+         return false;       // return false if terminate string found before target string
+    }
+    else
+        termIndex = 0;
+  }
+  return false;
+}
+
+
+// returns the first valid (long) integer value from the current position.
+// initial characters that are not digits (or the minus sign) are skipped
+// function is terminated by the first character that is not a digit.
+long Stream::parseInt()
+{
+  return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
+}
+
+// as above but a given skipChar is ignored
+// this allows format characters (typically commas) in values to be ignored
+long Stream::parseInt(char skipChar)
+{
+  boolean isNegative = false;
+  long value = 0;
+  int c;
+
+  c = getNextDigit();
+  // ignore non numeric leading characters
+  if(c < 0)
+    return 0; // zero returned if timeout
+
+  do{
+    if(c == skipChar)
+      ; // ignore this charactor
+    else if(c == '-')
+      isNegative = true;
+    else if(c >= '0' && c <= '9')        // is c a digit?
+      value = value * 10 + c - '0';
+    c = timedRead();
+  }
+  while( (c >= '0' && c <= '9')  || c == skipChar );
+
+  if(isNegative)
+    value = -value;
+  return value;
+}
+
+
+// as parseInt but returns a floating point value
+float Stream::parseFloat()
+{
+  parseFloat(NO_SKIP_CHAR);
+}
+
+// as above but the given skipChar is ignored
+// this allows format characters (typically commas) in values to be ignored
+float Stream::parseFloat(char skipChar){
+  boolean isNegative = false;
+  boolean isFraction = false;
+  long value = 0;
+  float fValue;
+  char c;
+  float fraction = 1.0;
+
+  c = getNextDigit();
+    // ignore non numeric leading characters
+  if(c < 0)
+    return 0; // zero returned if timeout
+
+  do{
+    if(c == skipChar)
+      ; // ignore
+    else if(c == '-')
+      isNegative = true;
+    else if (c == '.')
+      isFraction = true;
+    else if(c >= '0' && c <= '9')  {      // is c a digit?
+      value = value * 10 + c - '0';
+      if(isFraction)
+         fraction *= 0.1;
+    }
+    c = timedRead();
+  }
+  while( (c >= '0' && c <= '9')  || c == '.' || c == skipChar );
+
+  if(isNegative)
+    value = -value;
+  if(isFraction)
+    return value * fraction;
+  else
+    return value;
+}
+
+// read characters from stream into buffer
+// terminates if length characters have been read, null is detected or timeout (see setTimeout)
+// returns the number of characters placed in the buffer (0 means no valid data found)
+int Stream::readChars( char *buffer, size_t length)
+{
+   return readCharsUntil( 0, buffer, length);
+}
+
+
+// as readChars with terminator character
+// terminates if length characters have been read, timeout, or if the terminator character  detected
+// returns the number of characters placed in the buffer (0 means no valid data found)
+
+int Stream::readCharsUntil( char terminator, char *buffer, size_t length)
+{
+ int index = 0;
+    *buffer = 0;
+    while(index < length ){
+      int c = timedRead();
+      if( c <= 0 ){
+        return 0;   // timeout returns 0 !
+      }
+      else if( c == terminator){
+        buffer[index] = 0; // terminate the string
+        return index;               // data got successfully
+      }
+      else{
+        buffer[index++] = (char)c;
+      }
+    }
+    buffer[index] = 0;
+    return index; // here if buffer is full before detecting the terminator
+}
+
+
+// read characters found between pre_string and terminator into a buffer
+// terminated when the terminator character is matched or the buffer is full
+// returns the number of bytes placed in the buffer (0 means no valid data found)
+int Stream::readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length)
+{
+  if( find( pre_string) ){
+    return readCharsUntil(terminator, buffer, length);
+  }
+  return 0;    //failed to find the prestring
+}
diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h
index 93d8275..3f76392 100644
--- a/cores/arduino/Stream.h
+++ b/cores/arduino/Stream.h
@@ -15,6 +15,8 @@
   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
+
+  parsing functions based on TextFinder library by Michael Margolis
 */
 
 #ifndef Stream_h
@@ -23,13 +25,75 @@
 #include <inttypes.h>
 #include "Print.h"
 
+// compatability macros for testing
+/*
+#define   getInt()            parseInt()
+#define   getInt(skipChar)    parseInt(skipchar)
+#define   getFloat()          parseFloat()
+#define   getFloat(skipChar)  parseFloat(skipChar)
+#define   getString( pre_string, post_string, buffer, length)
+readBytesBetween( pre_string, terminator, buffer, length)
+*/
+
 class Stream : public Print
 {
+  private:
+    long _timeout;      // number of seconds to wait for the next char before aborting timed read
+    long _startMillis;  // used for timeout measurement
+    int timedRead();    // private method to read stream with timeout
+    int getNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
+
   public:
     virtual int available() = 0;
     virtual int read() = 0;
     virtual int peek() = 0;
     virtual void flush() = 0;
+
+    Stream() {_timeout=5;}
+
+// parsing methods
+
+  void setTimeout(long timeout);  // sets maximum seconds to wait for stream data, default is 5 seconds
+
+  bool find(char *target);   // reads data from the stream until the target string is found
+  // returns true if target string is found, false if timed out (see setTimeout)
+
+  bool find(char *target, size_t length);   // reads data from the stream until the target string of given length is found
+  // returns true if target string is found, false if timed out
+
+  bool findUntil(char *target, char *terminator);   // as find but search ends if the terminator string is found
+
+  bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);   // as above but search ends if the terminate string is found
+
+
+  long parseInt(); // returns the first valid (long) integer value from the current position.
+  // initial characters that are not digits (or the minus sign) are skipped
+  // integer is terminated by the first character that is not a digit.
+
+  long parseInt(char skipChar); // as above but the given skipChar is ignored
+  // as above but the given skipChar is ignored
+  // this allows format characters (typically commas) in values to be ignored
+
+  float parseFloat();               // float version of parseInt
+
+  float parseFloat(char skipChar);  // as above but the given skipChar is ignored
+
+  int readChars( char *buffer, size_t length); // read chars from stream into buffer
+  // terminates if length characters have been read or timeout (see setTimeout)
+  // returns the number of characters placed in the buffer (0 means no valid data found)
+
+  int readCharsUntil( char terminator, char *buffer, size_t length); // as readChars with terminator character
+  // terminates if length characters have been read, timeout, or if the terminator character  detected
+  // returns the number of characters placed in the buffer (0 means no valid data found)
+
+   int readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length);
+  // read characters found between pre_string and terminator into a buffer
+  // terminated when the terminator character is matched or the buffer is full
+  // returns the number of bytes placed in the buffer (0 means no valid data found)
+
+
+  // Arduino String functions to be added here
+
 };
 
 #endif
-- 
cgit v1.2.3-18-g5258


From 8dd6a40334613ce1c0c575a93bcd86ee1b109be6 Mon Sep 17 00:00:00 2001
From: "David A. Mellis" <d.mellis@arduino.cc>
Date: Wed, 17 Aug 2011 14:16:47 -0400
Subject: A few API changes to new Stream parsing functions.

Renamed readChars() -> readBytes(), readCharsUntil() -> readBytesUntil().
Changed timeouts to milliseconds from seconds; default from 5 to 1 seconds.
Removed readCharsBetween().
---
 cores/arduino/Stream.cpp | 25 +++++++------------------
 cores/arduino/Stream.h   | 16 +++++-----------
 2 files changed, 12 insertions(+), 29 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp
index dea0aff..bf8304f 100644
--- a/cores/arduino/Stream.cpp
+++ b/cores/arduino/Stream.cpp
@@ -23,7 +23,7 @@
 #include "Arduino.h"
 #include "Stream.h"
 
-#define PARSE_TIMEOUT 5  // default number of seconds to wait
+#define PARSE_TIMEOUT 1000  // default number of milli-seconds to wait
 #define NO_SKIP_CHAR  1  // a magic char not found in a valid ASCII numeric field
 
 // private method to read stream with timeout
@@ -31,7 +31,7 @@ int Stream::timedRead()
 {
   //Serial.println(_timeout);
   this->_startMillis = millis();
-  while(millis() - this->_startMillis < (this->_timeout * 1000L))
+  while(millis() - this->_startMillis < this->_timeout)
   {
     if (this->available() > 0) {
       return this->read();
@@ -58,7 +58,7 @@ return c;
 // Public Methods
 //////////////////////////////////////////////////////////////
 
-void Stream::setTimeout( long timeout)  // sets the maximum number of seconds to wait
+void Stream::setTimeout( long timeout)  // sets the maximum number of milliseconds to wait
 {
    this->_timeout = timeout;
 }
@@ -200,17 +200,17 @@ float Stream::parseFloat(char skipChar){
 // read characters from stream into buffer
 // terminates if length characters have been read, null is detected or timeout (see setTimeout)
 // returns the number of characters placed in the buffer (0 means no valid data found)
-int Stream::readChars( char *buffer, size_t length)
+int Stream::readBytes( char *buffer, size_t length)
 {
-   return readCharsUntil( 0, buffer, length);
+   return readBytesUntil( 0, buffer, length);
 }
 
 
-// as readChars with terminator character
+// as readBytes with terminator character
 // terminates if length characters have been read, timeout, or if the terminator character  detected
 // returns the number of characters placed in the buffer (0 means no valid data found)
 
-int Stream::readCharsUntil( char terminator, char *buffer, size_t length)
+int Stream::readBytesUntil( char terminator, char *buffer, size_t length)
 {
  int index = 0;
     *buffer = 0;
@@ -231,14 +231,3 @@ int Stream::readCharsUntil( char terminator, char *buffer, size_t length)
     return index; // here if buffer is full before detecting the terminator
 }
 
-
-// read characters found between pre_string and terminator into a buffer
-// terminated when the terminator character is matched or the buffer is full
-// returns the number of bytes placed in the buffer (0 means no valid data found)
-int Stream::readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length)
-{
-  if( find( pre_string) ){
-    return readCharsUntil(terminator, buffer, length);
-  }
-  return 0;    //failed to find the prestring
-}
diff --git a/cores/arduino/Stream.h b/cores/arduino/Stream.h
index 3f76392..1633f15 100644
--- a/cores/arduino/Stream.h
+++ b/cores/arduino/Stream.h
@@ -38,7 +38,7 @@ readBytesBetween( pre_string, terminator, buffer, length)
 class Stream : public Print
 {
   private:
-    long _timeout;      // number of seconds to wait for the next char before aborting timed read
+    long _timeout;      // number of milliseconds to wait for the next char before aborting timed read
     long _startMillis;  // used for timeout measurement
     int timedRead();    // private method to read stream with timeout
     int getNextDigit(); // returns the next numeric digit in the stream or -1 if timeout
@@ -49,11 +49,11 @@ class Stream : public Print
     virtual int peek() = 0;
     virtual void flush() = 0;
 
-    Stream() {_timeout=5;}
+    Stream() {_timeout=1000;}
 
 // parsing methods
 
-  void setTimeout(long timeout);  // sets maximum seconds to wait for stream data, default is 5 seconds
+  void setTimeout(long timeout);  // sets maximum milliseconds to wait for stream data, default is 1 second
 
   bool find(char *target);   // reads data from the stream until the target string is found
   // returns true if target string is found, false if timed out (see setTimeout)
@@ -78,20 +78,14 @@ class Stream : public Print
 
   float parseFloat(char skipChar);  // as above but the given skipChar is ignored
 
-  int readChars( char *buffer, size_t length); // read chars from stream into buffer
+  int readBytes( char *buffer, size_t length); // read chars from stream into buffer
   // terminates if length characters have been read or timeout (see setTimeout)
   // returns the number of characters placed in the buffer (0 means no valid data found)
 
-  int readCharsUntil( char terminator, char *buffer, size_t length); // as readChars with terminator character
+  int readBytesUntil( char terminator, char *buffer, size_t length); // as readBytes with terminator character
   // terminates if length characters have been read, timeout, or if the terminator character  detected
   // returns the number of characters placed in the buffer (0 means no valid data found)
 
-   int readCharsBetween( char *pre_string, char terminator, char *buffer, size_t length);
-  // read characters found between pre_string and terminator into a buffer
-  // terminated when the terminator character is matched or the buffer is full
-  // returns the number of bytes placed in the buffer (0 means no valid data found)
-
-
   // Arduino String functions to be added here
 
 };
-- 
cgit v1.2.3-18-g5258


From 9bc7be0d9a52edf77cf65554bce8a43123953107 Mon Sep 17 00:00:00 2001
From: "David A. Mellis" <d.mellis@arduino.cc>
Date: Thu, 18 Aug 2011 15:13:47 -0400
Subject: Stream.readBytesUntil() now writes null terminator within length.

---
 cores/arduino/Stream.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/Stream.cpp b/cores/arduino/Stream.cpp
index bf8304f..d267bf0 100644
--- a/cores/arduino/Stream.cpp
+++ b/cores/arduino/Stream.cpp
@@ -214,7 +214,7 @@ int Stream::readBytesUntil( char terminator, char *buffer, size_t length)
 {
  int index = 0;
     *buffer = 0;
-    while(index < length ){
+    while(index < length-1 ){
       int c = timedRead();
       if( c <= 0 ){
         return 0;   // timeout returns 0 !
-- 
cgit v1.2.3-18-g5258


From f282cbaf968f7142ef5abb68a92e970c3d5eea35 Mon Sep 17 00:00:00 2001
From: "David A. Mellis" <d.mellis@arduino.cc>
Date: Tue, 23 Aug 2011 19:12:03 -0400
Subject: write(), print(), and println() now return number of bytes written.

The type is long, and negative values indicate errors.  Needs more testing.
http://code.google.com/p/arduino/issues/detail?id=551
---
 cores/arduino/HardwareSerial.cpp |   5 +-
 cores/arduino/HardwareSerial.h   |   2 +-
 cores/arduino/Print.cpp          | 194 +++++++++++++++++++++++----------------
 cores/arduino/Print.h            |  56 +++++------
 cores/arduino/Printable.h        |   2 +-
 5 files changed, 151 insertions(+), 108 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
index db6b149..a200da5 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -352,12 +352,13 @@ void HardwareSerial::flush()
     ;
 }
 
-void HardwareSerial::write(uint8_t c)
+long HardwareSerial::write(uint8_t c)
 {
   int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
 	
   // If the output buffer is full, there's nothing for it other than to 
   // wait for the interrupt handler to empty it a bit
+  // ???: return 0 here instead?
   while (i == _tx_buffer->tail)
     ;
 	
@@ -365,6 +366,8 @@ void HardwareSerial::write(uint8_t c)
   _tx_buffer->head = i;
 	
   sbi(*_ucsrb, _udrie);
+  
+  return 1;
 }
 
 // Preinstantiate Objects //////////////////////////////////////////////////////
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
index eefdcbe..4af8c59 100644
--- a/cores/arduino/HardwareSerial.h
+++ b/cores/arduino/HardwareSerial.h
@@ -55,7 +55,7 @@ class HardwareSerial : public Stream
     virtual int peek(void);
     virtual int read(void);
     virtual void flush(void);
-    virtual void write(uint8_t);
+    virtual long write(uint8_t);
     using Print::write; // pull in write(str) and write(buf, size) from Print
 };
 
diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp
index 06ac52a..58b1032 100755
--- a/cores/arduino/Print.cpp
+++ b/cores/arduino/Print.cpp
@@ -30,167 +30,196 @@
 // Public Methods //////////////////////////////////////////////////////////////
 
 /* default implementation: may be overridden */
-void Print::write(const char *str)
+long Print::write(const char *str)
 {
-  while (*str)
-    write(*str++);
+  long n = 0;
+  while (*str) {
+    if (write(*str++) <= 0) break;
+    n++;
+  }
+  return n;
 }
 
 /* default implementation: may be overridden */
-void Print::write(const uint8_t *buffer, size_t size)
+long Print::write(const uint8_t *buffer, size_t size)
 {
-  while (size--)
-    write(*buffer++);
+  long n = 0;
+  while (size--) {
+    if (write(*buffer++) <= 0) break;
+    n++;
+  }
+  return n;
 }
 
-void Print::print(const __FlashStringHelper *ifsh)
+long Print::print(const __FlashStringHelper *ifsh)
 {
   const prog_char *p = (const prog_char *)ifsh;
+  long n = 0;
   while (1) {
     unsigned char c = pgm_read_byte(p++);
-    if (c == 0) return;
-    write(c);
+    if (c == 0) break;
+    if (write(c) <= 0) break;
+    n++;
   }
+  return n;
 }
 
-void Print::print(const String &s)
+long Print::print(const String &s)
 {
+  long n = 0;
   for (int i = 0; i < s.length(); i++) {
-    write(s[i]);
+    if (write(s[i]) < 0) break;
+    n++;
   }
+  return n;
 }
 
-void Print::print(const char str[])
+long Print::print(const char str[])
 {
-  write(str);
+  return write(str);
 }
 
-void Print::print(char c)
+long Print::print(char c)
 {
-  write(c);
+  return write(c);
 }
 
-void Print::print(unsigned char b, int base)
+long Print::print(unsigned char b, int base)
 {
-  print((unsigned long) b, base);
+  return print((unsigned long) b, base);
 }
 
-void Print::print(int n, int base)
+long Print::print(int n, int base)
 {
-  print((long) n, base);
+  return print((long) n, base);
 }
 
-void Print::print(unsigned int n, int base)
+long Print::print(unsigned int n, int base)
 {
-  print((unsigned long) n, base);
+  return print((unsigned long) n, base);
 }
 
-void Print::print(long n, int base)
+long Print::print(long n, int base)
 {
   if (base == 0) {
-    write(n);
+    return write(n);
   } else if (base == 10) {
     if (n < 0) {
-      print('-');
+      long t = print('-');
+      if (t <= 0) return t;
       n = -n;
+      return printNumber(n, 10) + 1;
     }
-    printNumber(n, 10);
+    return printNumber(n, 10);
   } else {
-    printNumber(n, base);
+    return printNumber(n, base);
   }
 }
 
-void Print::print(unsigned long n, int base)
+long Print::print(unsigned long n, int base)
 {
-  if (base == 0) write(n);
-  else printNumber(n, base);
+  if (base == 0) return write(n);
+  else return printNumber(n, base);
 }
 
-void Print::print(double n, int digits)
+long Print::print(double n, int digits)
 {
-  printFloat(n, digits);
+  return printFloat(n, digits);
 }
 
-void Print::println(const __FlashStringHelper *ifsh)
+long Print::println(const __FlashStringHelper *ifsh)
 {
-  print(ifsh);
-  println();
+  long n = print(ifsh);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::print(const Printable& x)
+long Print::print(const Printable& x)
 {
-  x.printTo(*this);
+  return x.printTo(*this);
 }
 
-void Print::println(void)
+long Print::println(void)
 {
-  print('\r');
-  print('\n');
+  long t = print('\r');
+  if (t <= 0) return t;
+  if (print('\n') <= 0) return 1;
+  return 2;
 }
 
-void Print::println(const String &s)
+long Print::println(const String &s)
 {
-  print(s);
-  println();
+  long n = print(s);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(const char c[])
+long Print::println(const char c[])
 {
-  print(c);
-  println();
+  long n = print(c);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(char c)
+long Print::println(char c)
 {
-  print(c);
-  println();
+  long n = print(c);
+  if (n > 0) n += println();
+  return n;
 }
 
-void Print::println(unsigned char b, int base)
+long Print::println(unsigned char b, int base)
 {
-  print(b, base);
-  println();
+  long n = print(b, base);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(int n, int base)
+long Print::println(int num, int base)
 {
-  print(n, base);
-  println();
+  long n = print(num, base);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(unsigned int n, int base)
+long Print::println(unsigned int num, int base)
 {
-  print(n, base);
-  println();
+  long n = print(num, base);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(long n, int base)
+long Print::println(long num, int base)
 {
-  print(n, base);
-  println();
+  long n = print(num, base);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(unsigned long n, int base)
+long Print::println(unsigned long num, int base)
 {
-  print(n, base);
-  println();
+  long n = print(num, base);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(double n, int digits)
+long Print::println(double num, int digits)
 {
-  print(n, digits);
-  println();
+  long n = print(num, digits);
+  if (n >= 0) n += println();
+  return n;
 }
 
-void Print::println(const Printable& x)
+long Print::println(const Printable& x)
 {
-  print(x);
-  println();
+  long n = print(x);
+  if (n >= 0) n += println();
+  return n;
 }
 
 // Private Methods /////////////////////////////////////////////////////////////
 
-void Print::printNumber(unsigned long n, uint8_t base) {
+long Print::printNumber(unsigned long n, uint8_t base) {
   char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
   char *str = &buf[sizeof(buf) - 1];
 
@@ -206,15 +235,17 @@ void Print::printNumber(unsigned long n, uint8_t base) {
     *--str = c < 10 ? c + '0' : c + 'A' - 10;
   } while(n);
 
-  write(str);
+  return write(str);
 }
 
-void Print::printFloat(double number, uint8_t digits) 
+long Print::printFloat(double number, uint8_t digits) 
 { 
+  long n = 0, t;
+  
   // Handle negative numbers
   if (number < 0.0)
   {
-     print('-');
+     if ((n = print('-')) <= 0) return n;
      number = -number;
   }
 
@@ -228,18 +259,27 @@ void Print::printFloat(double number, uint8_t digits)
   // 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);
+  if ((t = print(int_part)) < 0) return n;
+  
+  n += t;
 
   // Print the decimal point, but only if there are digits beyond
-  if (digits > 0)
-    print("."); 
+  if (digits > 0) {
+    t = print("."); 
+    if (t <= 0) return n;
+    n += t;
+  }
 
   // Extract digits from the remainder one at a time
   while (digits-- > 0)
   {
     remainder *= 10.0;
     int toPrint = int(remainder);
-    print(toPrint);
+    t = print(toPrint);
+    if (t <= 0) return n;
+    n += t;
     remainder -= toPrint; 
   } 
+  
+  return n;
 }
diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h
index bf10b14..d5b02ff 100755
--- a/cores/arduino/Print.h
+++ b/cores/arduino/Print.h
@@ -34,37 +34,37 @@
 class Print
 {
   private:
-    void printNumber(unsigned long, uint8_t);
-    void printFloat(double, uint8_t);
+    long printNumber(unsigned long, uint8_t);
+    long printFloat(double, uint8_t);
   public:
-    virtual void write(uint8_t) = 0;
-    virtual void write(const char *str);
-    virtual void write(const uint8_t *buffer, size_t size);
+    virtual long write(uint8_t) = 0;
+    virtual long write(const char *str);
+    virtual long write(const uint8_t *buffer, size_t size);
     
-    void print(const __FlashStringHelper *);
-    void print(const String &);
-    void print(const char[]);
-    void print(char);
-    void print(unsigned char, 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(double, int = 2);
-    void print(const Printable&);
+    long print(const __FlashStringHelper *);
+    long print(const String &);
+    long print(const char[]);
+    long print(char);
+    long print(unsigned char, int = DEC);
+    long print(int, int = DEC);
+    long print(unsigned int, int = DEC);
+    long print(long, int = DEC);
+    long print(unsigned long, int = DEC);
+    long print(double, int = 2);
+    long print(const Printable&);
 
-    void println(const __FlashStringHelper *);
-    void println(const String &s);
-    void println(const char[]);
-    void println(char);
-    void println(unsigned char, 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(double, int = 2);
-    void println(const Printable&);
-    void println(void);
+    long println(const __FlashStringHelper *);
+    long println(const String &s);
+    long println(const char[]);
+    long println(char);
+    long println(unsigned char, int = DEC);
+    long println(int, int = DEC);
+    long println(unsigned int, int = DEC);
+    long println(long, int = DEC);
+    long println(unsigned long, int = DEC);
+    long println(double, int = 2);
+    long println(const Printable&);
+    long println(void);
 };
 
 #endif
diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h
index d332aad..6814ee4 100644
--- a/cores/arduino/Printable.h
+++ b/cores/arduino/Printable.h
@@ -30,7 +30,7 @@ class Print;
 class Printable
 {
   public:
-    virtual void printTo(Print& p) const = 0;
+    virtual long printTo(Print& p) const = 0;
 };
 
 #endif
-- 
cgit v1.2.3-18-g5258


From 0635790dd111e91e5c488acc599cc404dc707abd Mon Sep 17 00:00:00 2001
From: "David A. Mellis" <d.mellis@arduino.cc>
Date: Fri, 26 Aug 2011 14:20:41 -0400
Subject: Changing from long to ssize_t (int) for write(), print(), println()
 return.

---
 cores/arduino/HardwareSerial.cpp |  2 +-
 cores/arduino/HardwareSerial.h   |  2 +-
 cores/arduino/Print.cpp          | 90 ++++++++++++++++++++--------------------
 cores/arduino/Print.h            | 58 +++++++++++++-------------
 cores/arduino/Printable.h        |  2 +-
 5 files changed, 78 insertions(+), 76 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
index a200da5..641c973 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -352,7 +352,7 @@ void HardwareSerial::flush()
     ;
 }
 
-long HardwareSerial::write(uint8_t c)
+ssize_t HardwareSerial::write(uint8_t c)
 {
   int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
 	
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
index 4af8c59..960d3f5 100644
--- a/cores/arduino/HardwareSerial.h
+++ b/cores/arduino/HardwareSerial.h
@@ -55,7 +55,7 @@ class HardwareSerial : public Stream
     virtual int peek(void);
     virtual int read(void);
     virtual void flush(void);
-    virtual long write(uint8_t);
+    virtual ssize_t write(uint8_t);
     using Print::write; // pull in write(str) and write(buf, size) from Print
 };
 
diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp
index 58b1032..192d9a3 100755
--- a/cores/arduino/Print.cpp
+++ b/cores/arduino/Print.cpp
@@ -30,9 +30,9 @@
 // Public Methods //////////////////////////////////////////////////////////////
 
 /* default implementation: may be overridden */
-long Print::write(const char *str)
+ssize_t Print::write(const char *str)
 {
-  long n = 0;
+  ssize_t n = 0;
   while (*str) {
     if (write(*str++) <= 0) break;
     n++;
@@ -41,9 +41,9 @@ long Print::write(const char *str)
 }
 
 /* default implementation: may be overridden */
-long Print::write(const uint8_t *buffer, size_t size)
+ssize_t Print::write(const uint8_t *buffer, size_t size)
 {
-  long n = 0;
+  ssize_t n = 0;
   while (size--) {
     if (write(*buffer++) <= 0) break;
     n++;
@@ -51,10 +51,10 @@ long Print::write(const uint8_t *buffer, size_t size)
   return n;
 }
 
-long Print::print(const __FlashStringHelper *ifsh)
+ssize_t Print::print(const __FlashStringHelper *ifsh)
 {
   const prog_char *p = (const prog_char *)ifsh;
-  long n = 0;
+  ssize_t n = 0;
   while (1) {
     unsigned char c = pgm_read_byte(p++);
     if (c == 0) break;
@@ -64,9 +64,9 @@ long Print::print(const __FlashStringHelper *ifsh)
   return n;
 }
 
-long Print::print(const String &s)
+ssize_t Print::print(const String &s)
 {
-  long n = 0;
+  ssize_t n = 0;
   for (int i = 0; i < s.length(); i++) {
     if (write(s[i]) < 0) break;
     n++;
@@ -74,38 +74,38 @@ long Print::print(const String &s)
   return n;
 }
 
-long Print::print(const char str[])
+ssize_t Print::print(const char str[])
 {
   return write(str);
 }
 
-long Print::print(char c)
+ssize_t Print::print(char c)
 {
   return write(c);
 }
 
-long Print::print(unsigned char b, int base)
+ssize_t Print::print(unsigned char b, int base)
 {
   return print((unsigned long) b, base);
 }
 
-long Print::print(int n, int base)
+ssize_t Print::print(int n, int base)
 {
   return print((long) n, base);
 }
 
-long Print::print(unsigned int n, int base)
+ssize_t Print::print(unsigned int n, int base)
 {
   return print((unsigned long) n, base);
 }
 
-long Print::print(long n, int base)
+ssize_t Print::print(long n, int base)
 {
   if (base == 0) {
     return write(n);
   } else if (base == 10) {
     if (n < 0) {
-      long t = print('-');
+      int t = print('-');
       if (t <= 0) return t;
       n = -n;
       return printNumber(n, 10) + 1;
@@ -116,110 +116,110 @@ long Print::print(long n, int base)
   }
 }
 
-long Print::print(unsigned long n, int base)
+ssize_t Print::print(unsigned long n, int base)
 {
   if (base == 0) return write(n);
   else return printNumber(n, base);
 }
 
-long Print::print(double n, int digits)
+ssize_t Print::print(double n, int digits)
 {
   return printFloat(n, digits);
 }
 
-long Print::println(const __FlashStringHelper *ifsh)
+ssize_t Print::println(const __FlashStringHelper *ifsh)
 {
-  long n = print(ifsh);
+  ssize_t n = print(ifsh);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::print(const Printable& x)
+ssize_t Print::print(const Printable& x)
 {
   return x.printTo(*this);
 }
 
-long Print::println(void)
+ssize_t Print::println(void)
 {
-  long t = print('\r');
+  ssize_t t = print('\r');
   if (t <= 0) return t;
   if (print('\n') <= 0) return 1;
   return 2;
 }
 
-long Print::println(const String &s)
+ssize_t Print::println(const String &s)
 {
-  long n = print(s);
+  ssize_t n = print(s);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(const char c[])
+ssize_t Print::println(const char c[])
 {
-  long n = print(c);
+  ssize_t n = print(c);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(char c)
+ssize_t Print::println(char c)
 {
-  long n = print(c);
+  ssize_t n = print(c);
   if (n > 0) n += println();
   return n;
 }
 
-long Print::println(unsigned char b, int base)
+ssize_t Print::println(unsigned char b, int base)
 {
-  long n = print(b, base);
+  ssize_t n = print(b, base);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(int num, int base)
+ssize_t Print::println(int num, int base)
 {
-  long n = print(num, base);
+  ssize_t n = print(num, base);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(unsigned int num, int base)
+ssize_t Print::println(unsigned int num, int base)
 {
-  long n = print(num, base);
+  ssize_t n = print(num, base);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(long num, int base)
+ssize_t Print::println(long num, int base)
 {
-  long n = print(num, base);
+  ssize_t n = print(num, base);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(unsigned long num, int base)
+ssize_t Print::println(unsigned long num, int base)
 {
-  long n = print(num, base);
+  ssize_t n = print(num, base);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(double num, int digits)
+ssize_t Print::println(double num, int digits)
 {
-  long n = print(num, digits);
+  ssize_t n = print(num, digits);
   if (n >= 0) n += println();
   return n;
 }
 
-long Print::println(const Printable& x)
+ssize_t Print::println(const Printable& x)
 {
-  long n = print(x);
+  ssize_t n = print(x);
   if (n >= 0) n += println();
   return n;
 }
 
 // Private Methods /////////////////////////////////////////////////////////////
 
-long Print::printNumber(unsigned long n, uint8_t base) {
+ssize_t Print::printNumber(unsigned long n, uint8_t base) {
   char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
   char *str = &buf[sizeof(buf) - 1];
 
@@ -238,9 +238,9 @@ long Print::printNumber(unsigned long n, uint8_t base) {
   return write(str);
 }
 
-long Print::printFloat(double number, uint8_t digits) 
+ssize_t Print::printFloat(double number, uint8_t digits) 
 { 
-  long n = 0, t;
+  ssize_t n = 0, t;
   
   // Handle negative numbers
   if (number < 0.0)
diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h
index d5b02ff..3f303f3 100755
--- a/cores/arduino/Print.h
+++ b/cores/arduino/Print.h
@@ -23,6 +23,8 @@
 #include <inttypes.h>
 #include <stdio.h> // for size_t
 
+typedef int ssize_t;
+
 #include "WString.h"
 #include "Printable.h"
 
@@ -34,37 +36,37 @@
 class Print
 {
   private:
-    long printNumber(unsigned long, uint8_t);
-    long printFloat(double, uint8_t);
+    ssize_t printNumber(unsigned long, uint8_t);
+    ssize_t printFloat(double, uint8_t);
   public:
-    virtual long write(uint8_t) = 0;
-    virtual long write(const char *str);
-    virtual long write(const uint8_t *buffer, size_t size);
+    virtual ssize_t write(uint8_t) = 0;
+    virtual ssize_t write(const char *str);
+    virtual ssize_t write(const uint8_t *buffer, size_t size);
     
-    long print(const __FlashStringHelper *);
-    long print(const String &);
-    long print(const char[]);
-    long print(char);
-    long print(unsigned char, int = DEC);
-    long print(int, int = DEC);
-    long print(unsigned int, int = DEC);
-    long print(long, int = DEC);
-    long print(unsigned long, int = DEC);
-    long print(double, int = 2);
-    long print(const Printable&);
+    ssize_t print(const __FlashStringHelper *);
+    ssize_t print(const String &);
+    ssize_t print(const char[]);
+    ssize_t print(char);
+    ssize_t print(unsigned char, int = DEC);
+    ssize_t print(int, int = DEC);
+    ssize_t print(unsigned int, int = DEC);
+    ssize_t print(long, int = DEC);
+    ssize_t print(unsigned long, int = DEC);
+    ssize_t print(double, int = 2);
+    ssize_t print(const Printable&);
 
-    long println(const __FlashStringHelper *);
-    long println(const String &s);
-    long println(const char[]);
-    long println(char);
-    long println(unsigned char, int = DEC);
-    long println(int, int = DEC);
-    long println(unsigned int, int = DEC);
-    long println(long, int = DEC);
-    long println(unsigned long, int = DEC);
-    long println(double, int = 2);
-    long println(const Printable&);
-    long println(void);
+    ssize_t println(const __FlashStringHelper *);
+    ssize_t println(const String &s);
+    ssize_t println(const char[]);
+    ssize_t println(char);
+    ssize_t println(unsigned char, int = DEC);
+    ssize_t println(int, int = DEC);
+    ssize_t println(unsigned int, int = DEC);
+    ssize_t println(long, int = DEC);
+    ssize_t println(unsigned long, int = DEC);
+    ssize_t println(double, int = 2);
+    ssize_t println(const Printable&);
+    ssize_t println(void);
 };
 
 #endif
diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h
index 6814ee4..9065904 100644
--- a/cores/arduino/Printable.h
+++ b/cores/arduino/Printable.h
@@ -30,7 +30,7 @@ class Print;
 class Printable
 {
   public:
-    virtual long printTo(Print& p) const = 0;
+    virtual ssize_t printTo(Print& p) const = 0;
 };
 
 #endif
-- 
cgit v1.2.3-18-g5258


From 5130a1329462aa36d5f18e31851d3d9d5086e411 Mon Sep 17 00:00:00 2001
From: "David A. Mellis" <d.mellis@arduino.cc>
Date: Fri, 26 Aug 2011 16:08:14 -0400
Subject: Moving write errors out of return value into separate API methods.

write(), print(), println() now return size_t (and don't use negative values to signal errors).
Print adds writeError() for checking for write errors, clearWriteError() to reset the flag to false, and a protected setWriteError() for signalling errors.

http://code.google.com/p/arduino/issues/detail?id=598
---
 cores/arduino/HardwareSerial.cpp |   2 +-
 cores/arduino/HardwareSerial.h   |   2 +-
 cores/arduino/Print.cpp          | 144 ++++++++++++++++++---------------------
 cores/arduino/Print.h            |  66 ++++++++++--------
 cores/arduino/Printable.h        |   2 +-
 5 files changed, 105 insertions(+), 111 deletions(-)

(limited to 'cores/arduino')

diff --git a/cores/arduino/HardwareSerial.cpp b/cores/arduino/HardwareSerial.cpp
index 641c973..d6be218 100644
--- a/cores/arduino/HardwareSerial.cpp
+++ b/cores/arduino/HardwareSerial.cpp
@@ -352,7 +352,7 @@ void HardwareSerial::flush()
     ;
 }
 
-ssize_t HardwareSerial::write(uint8_t c)
+size_t HardwareSerial::write(uint8_t c)
 {
   int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
 	
diff --git a/cores/arduino/HardwareSerial.h b/cores/arduino/HardwareSerial.h
index 960d3f5..1895f08 100644
--- a/cores/arduino/HardwareSerial.h
+++ b/cores/arduino/HardwareSerial.h
@@ -55,7 +55,7 @@ class HardwareSerial : public Stream
     virtual int peek(void);
     virtual int read(void);
     virtual void flush(void);
-    virtual ssize_t write(uint8_t);
+    virtual size_t write(uint8_t);
     using Print::write; // pull in write(str) and write(buf, size) from Print
 };
 
diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp
index 192d9a3..8190d4f 100755
--- a/cores/arduino/Print.cpp
+++ b/cores/arduino/Print.cpp
@@ -30,85 +30,80 @@
 // Public Methods //////////////////////////////////////////////////////////////
 
 /* default implementation: may be overridden */
-ssize_t Print::write(const char *str)
+size_t Print::write(const char *str)
 {
-  ssize_t n = 0;
+  size_t n = 0;
   while (*str) {
-    if (write(*str++) <= 0) break;
-    n++;
+    n += write(*str++);
   }
   return n;
 }
 
 /* default implementation: may be overridden */
-ssize_t Print::write(const uint8_t *buffer, size_t size)
+size_t Print::write(const uint8_t *buffer, size_t size)
 {
-  ssize_t n = 0;
+  size_t n = 0;
   while (size--) {
-    if (write(*buffer++) <= 0) break;
-    n++;
+    n += write(*buffer++);
   }
   return n;
 }
 
-ssize_t Print::print(const __FlashStringHelper *ifsh)
+size_t Print::print(const __FlashStringHelper *ifsh)
 {
   const prog_char *p = (const prog_char *)ifsh;
-  ssize_t n = 0;
+  size_t n = 0;
   while (1) {
     unsigned char c = pgm_read_byte(p++);
     if (c == 0) break;
-    if (write(c) <= 0) break;
-    n++;
+    n += write(c);
   }
   return n;
 }
 
-ssize_t Print::print(const String &s)
+size_t Print::print(const String &s)
 {
-  ssize_t n = 0;
+  size_t n = 0;
   for (int i = 0; i < s.length(); i++) {
-    if (write(s[i]) < 0) break;
-    n++;
+    n += write(s[i]);
   }
   return n;
 }
 
-ssize_t Print::print(const char str[])
+size_t Print::print(const char str[])
 {
   return write(str);
 }
 
-ssize_t Print::print(char c)
+size_t Print::print(char c)
 {
   return write(c);
 }
 
-ssize_t Print::print(unsigned char b, int base)
+size_t Print::print(unsigned char b, int base)
 {
   return print((unsigned long) b, base);
 }
 
-ssize_t Print::print(int n, int base)
+size_t Print::print(int n, int base)
 {
   return print((long) n, base);
 }
 
-ssize_t Print::print(unsigned int n, int base)
+size_t Print::print(unsigned int n, int base)
 {
   return print((unsigned long) n, base);
 }
 
-ssize_t Print::print(long n, int base)
+size_t Print::print(long n, int base)
 {
   if (base == 0) {
     return write(n);
   } else if (base == 10) {
     if (n < 0) {
       int t = print('-');
-      if (t <= 0) return t;
       n = -n;
-      return printNumber(n, 10) + 1;
+      return printNumber(n, 10) + t;
     }
     return printNumber(n, 10);
   } else {
@@ -116,110 +111,109 @@ ssize_t Print::print(long n, int base)
   }
 }
 
-ssize_t Print::print(unsigned long n, int base)
+size_t Print::print(unsigned long n, int base)
 {
   if (base == 0) return write(n);
   else return printNumber(n, base);
 }
 
-ssize_t Print::print(double n, int digits)
+size_t Print::print(double n, int digits)
 {
   return printFloat(n, digits);
 }
 
-ssize_t Print::println(const __FlashStringHelper *ifsh)
+size_t Print::println(const __FlashStringHelper *ifsh)
 {
-  ssize_t n = print(ifsh);
-  if (n >= 0) n += println();
+  size_t n = print(ifsh);
+  n += println();
   return n;
 }
 
-ssize_t Print::print(const Printable& x)
+size_t Print::print(const Printable& x)
 {
   return x.printTo(*this);
 }
 
-ssize_t Print::println(void)
+size_t Print::println(void)
 {
-  ssize_t t = print('\r');
-  if (t <= 0) return t;
-  if (print('\n') <= 0) return 1;
-  return 2;
+  size_t n = print('\r');
+  n += print('\n');
+  return n;
 }
 
-ssize_t Print::println(const String &s)
+size_t Print::println(const String &s)
 {
-  ssize_t n = print(s);
-  if (n >= 0) n += println();
+  size_t n = print(s);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(const char c[])
+size_t Print::println(const char c[])
 {
-  ssize_t n = print(c);
-  if (n >= 0) n += println();
+  size_t n = print(c);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(char c)
+size_t Print::println(char c)
 {
-  ssize_t n = print(c);
-  if (n > 0) n += println();
+  size_t n = print(c);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(unsigned char b, int base)
+size_t Print::println(unsigned char b, int base)
 {
-  ssize_t n = print(b, base);
-  if (n >= 0) n += println();
+  size_t n = print(b, base);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(int num, int base)
+size_t Print::println(int num, int base)
 {
-  ssize_t n = print(num, base);
-  if (n >= 0) n += println();
+  size_t n = print(num, base);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(unsigned int num, int base)
+size_t Print::println(unsigned int num, int base)
 {
-  ssize_t n = print(num, base);
-  if (n >= 0) n += println();
+  size_t n = print(num, base);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(long num, int base)
+size_t Print::println(long num, int base)
 {
-  ssize_t n = print(num, base);
-  if (n >= 0) n += println();
+  size_t n = print(num, base);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(unsigned long num, int base)
+size_t Print::println(unsigned long num, int base)
 {
-  ssize_t n = print(num, base);
-  if (n >= 0) n += println();
+  size_t n = print(num, base);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(double num, int digits)
+size_t Print::println(double num, int digits)
 {
-  ssize_t n = print(num, digits);
-  if (n >= 0) n += println();
+  size_t n = print(num, digits);
+  n += println();
   return n;
 }
 
-ssize_t Print::println(const Printable& x)
+size_t Print::println(const Printable& x)
 {
-  ssize_t n = print(x);
-  if (n >= 0) n += println();
+  size_t n = print(x);
+  n += println();
   return n;
 }
 
 // Private Methods /////////////////////////////////////////////////////////////
 
-ssize_t Print::printNumber(unsigned long n, uint8_t base) {
+size_t Print::printNumber(unsigned long n, uint8_t base) {
   char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
   char *str = &buf[sizeof(buf) - 1];
 
@@ -238,14 +232,14 @@ ssize_t Print::printNumber(unsigned long n, uint8_t base) {
   return write(str);
 }
 
-ssize_t Print::printFloat(double number, uint8_t digits) 
+size_t Print::printFloat(double number, uint8_t digits) 
 { 
-  ssize_t n = 0, t;
+  size_t n = 0;
   
   // Handle negative numbers
   if (number < 0.0)
   {
-     if ((n = print('-')) <= 0) return n;
+     n += print('-');
      number = -number;
   }
 
@@ -259,15 +253,11 @@ ssize_t Print::printFloat(double number, uint8_t digits)
   // Extract the integer part of the number and print it
   unsigned long int_part = (unsigned long)number;
   double remainder = number - (double)int_part;
-  if ((t = print(int_part)) < 0) return n;
-  
-  n += t;
+  n += print(int_part);
 
   // Print the decimal point, but only if there are digits beyond
   if (digits > 0) {
-    t = print("."); 
-    if (t <= 0) return n;
-    n += t;
+    n += print("."); 
   }
 
   // Extract digits from the remainder one at a time
@@ -275,9 +265,7 @@ ssize_t Print::printFloat(double number, uint8_t digits)
   {
     remainder *= 10.0;
     int toPrint = int(remainder);
-    t = print(toPrint);
-    if (t <= 0) return n;
-    n += t;
+    n += print(toPrint);
     remainder -= toPrint; 
   } 
   
diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h
index 3f303f3..fce302e 100755
--- a/cores/arduino/Print.h
+++ b/cores/arduino/Print.h
@@ -23,8 +23,6 @@
 #include <inttypes.h>
 #include <stdio.h> // for size_t
 
-typedef int ssize_t;
-
 #include "WString.h"
 #include "Printable.h"
 
@@ -36,37 +34,45 @@ typedef int ssize_t;
 class Print
 {
   private:
-    ssize_t printNumber(unsigned long, uint8_t);
-    ssize_t printFloat(double, uint8_t);
+    int write_error;
+    size_t printNumber(unsigned long, uint8_t);
+    size_t printFloat(double, uint8_t);
+  protected:
+    void setWriteError(int err = 1) { write_error = err; }
   public:
-    virtual ssize_t write(uint8_t) = 0;
-    virtual ssize_t write(const char *str);
-    virtual ssize_t write(const uint8_t *buffer, size_t size);
+    Print() : write_error(0) {}
+  
+    int writeError() { return write_error; }
+    void clearWriteError() { setWriteError(0); }
+  
+    virtual size_t write(uint8_t) = 0;
+    virtual size_t write(const char *str);
+    virtual size_t write(const uint8_t *buffer, size_t size);
     
-    ssize_t print(const __FlashStringHelper *);
-    ssize_t print(const String &);
-    ssize_t print(const char[]);
-    ssize_t print(char);
-    ssize_t print(unsigned char, int = DEC);
-    ssize_t print(int, int = DEC);
-    ssize_t print(unsigned int, int = DEC);
-    ssize_t print(long, int = DEC);
-    ssize_t print(unsigned long, int = DEC);
-    ssize_t print(double, int = 2);
-    ssize_t print(const Printable&);
+    size_t print(const __FlashStringHelper *);
+    size_t print(const String &);
+    size_t print(const char[]);
+    size_t print(char);
+    size_t print(unsigned char, int = DEC);
+    size_t print(int, int = DEC);
+    size_t print(unsigned int, int = DEC);
+    size_t print(long, int = DEC);
+    size_t print(unsigned long, int = DEC);
+    size_t print(double, int = 2);
+    size_t print(const Printable&);
 
-    ssize_t println(const __FlashStringHelper *);
-    ssize_t println(const String &s);
-    ssize_t println(const char[]);
-    ssize_t println(char);
-    ssize_t println(unsigned char, int = DEC);
-    ssize_t println(int, int = DEC);
-    ssize_t println(unsigned int, int = DEC);
-    ssize_t println(long, int = DEC);
-    ssize_t println(unsigned long, int = DEC);
-    ssize_t println(double, int = 2);
-    ssize_t println(const Printable&);
-    ssize_t println(void);
+    size_t println(const __FlashStringHelper *);
+    size_t println(const String &s);
+    size_t println(const char[]);
+    size_t println(char);
+    size_t println(unsigned char, int = DEC);
+    size_t println(int, int = DEC);
+    size_t println(unsigned int, int = DEC);
+    size_t println(long, int = DEC);
+    size_t println(unsigned long, int = DEC);
+    size_t println(double, int = 2);
+    size_t println(const Printable&);
+    size_t println(void);
 };
 
 #endif
diff --git a/cores/arduino/Printable.h b/cores/arduino/Printable.h
index 9065904..e22e87e 100644
--- a/cores/arduino/Printable.h
+++ b/cores/arduino/Printable.h
@@ -30,7 +30,7 @@ class Print;
 class Printable
 {
   public:
-    virtual ssize_t printTo(Print& p) const = 0;
+    virtual size_t printTo(Print& p) const = 0;
 };
 
 #endif
-- 
cgit v1.2.3-18-g5258