2005-02-17  Theodore A. Roth  <troth@openavr.org>

	* include/stdio.h (fdevopen): Change the __get() and __put() function
	pointers so that they take the stream as an argument.
	(fdev_set_udata): Add prototype.
	(fdev_get_udata): Add prototype.
	* libc/stdio/Makefile.am (lib_a_c_sources): Add fdevdata.c.
	* libc/stdio/fdevopen.c (fdevopen): Update dox for new get and put
	argument types.
	Change the get() and put() function pointers so that they take the
	stream as an argument.
	* libc/stdio/fgetc.c (fgetc): Pass stream to get() method.
	* libc/stdio/fputc.c (fputc): Pass stream to put() method.
	* libc/stdio/fputs.c (fputs): Ditto.
	* libc/stdio/fputs_p.c (fputs_P): Ditto.
	* libc/stdio/fwrite.c (fwrite): Ditto.
	* libc/stdio/puts.c (puts): Ditto.
	* libc/stdio/puts_p.c (puts_P): Ditto.
	* libc/stdio/stdio_private.h (struct __file::put): Add stream argument.
	(struct __file::get): Add stream argument.
	(struct __file::udata): New field.
	* libc/stdio/fdevdata.c: New file.

Index: include/stdio.h
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/include/stdio.h,v
retrieving revision 1.17
diff -u -p -p -r1.17 stdio.h
--- include/stdio.h	18 Jan 2005 16:22:04 -0000	1.17
+++ include/stdio.h	18 Feb 2005 00:52:30 -0000
@@ -138,7 +138,7 @@
 
     \code
     int
-    uart_putchar(char c)
+    uart_putchar(FILE *fp, char c)
     {
 
       if (c == '\n')
@@ -217,7 +217,11 @@ extern "C" {
 
 extern struct __file *__iob[];
 
-extern FILE	*fdevopen(int (*__put)(char), int (*__get)(void), int __opts);
+extern FILE	*fdevopen(int (*__put)(FILE *, char), int (*__get)(FILE *),
+                      int __opts);
+
+extern void fdev_set_udata(FILE *stream, void *udata);
+extern void *fdev_get_udata(FILE *stream);
 
 #endif /* not DOXYGEN */
 
Index: libc/stdio/Makefile.am
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/Makefile.am,v
retrieving revision 1.12
diff -u -p -p -r1.12 Makefile.am
--- libc/stdio/Makefile.am	9 Feb 2005 00:22:31 -0000	1.12
+++ libc/stdio/Makefile.am	18 Feb 2005 00:52:30 -0000
@@ -36,6 +36,7 @@ lib_a_c_sources =	\
 	clearerr.c	\
 	fclose.c	\
 	fdevopen.c	\
+	fdevdata.c	\
 	feof.c		\
 	ferror.c	\
 	fgetc.c		\
Index: libc/stdio/fdevopen.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/fdevopen.c,v
retrieving revision 1.4
diff -u -p -p -r1.4 fdevopen.c
--- libc/stdio/fdevopen.c	22 Dec 2004 22:08:23 -0000	1.4
+++ libc/stdio/fdevopen.c	18 Feb 2005 00:52:30 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, Joerg Wunsch
+/* Copyright (c) 2002, 2004, 2005  Joerg Wunsch
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -49,16 +49,17 @@ FILE *__iob[3];			/* stdin, stdout, stde
    insufficient dynamic memory is available to establish a new stream.
 
    If the \c put function pointer is provided, the stream is opened
-   with write intent.  The function passed as \c put shall take one
-   character to write to the device as argument , and shall return 0
+   with write intent.  The function passed as \c put shall take two
+   arguments, the first a pointer to FILE and the second a character to
+   write to the device as argument, and shall return 0
    if the output was successful, and a nonzero value if the character
    could not be sent to the device.
 
    If the \c get function pointer is provided, the stream is opened
-   with read intent.  The function passed as \c get shall take no
-   arguments, and return one character from the device, passed as an
-   \c int type.  If an error occurs when trying to read from the
-   device, it shall return \c -1.
+   with read intent.  The function passed as \c get shall take a pointer
+   to FILE as it's single argument, and return one character from the
+   device, passed as an \c int type.  If an error occurs when trying to
+   read from the device, it shall return \c -1.
 
    If both functions are provided, the stream is opened with read
    and write intent.
@@ -75,7 +76,8 @@ FILE *__iob[3];			/* stdin, stdout, stde
 */
 
 FILE *
-fdevopen(int (*put)(char), int (*get)(void), int opts __attribute__((unused)))
+fdevopen(int (*put)(FILE *, char), int (*get)(FILE *),
+         int opts __attribute__((unused)))
 {
 	FILE *s;
 
Index: libc/stdio/fgetc.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/fgetc.c,v
retrieving revision 1.3
diff -u -p -p -r1.3 fgetc.c
--- libc/stdio/fgetc.c	7 Jan 2003 22:17:24 -0000	1.3
+++ libc/stdio/fgetc.c	18 Feb 2005 00:52:30 -0000
@@ -54,7 +54,7 @@ fgetc(FILE *stream)
 			return EOF;
 		}
 	} else {
-		rv = stream->get();
+		rv = stream->get(stream);
 		if (rv == -1) {
 			stream->flags |= __SERR;
 			return EOF;
Index: libc/stdio/fputc.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/fputc.c,v
retrieving revision 1.2
diff -u -p -p -r1.2 fputc.c
--- libc/stdio/fputc.c	26 Dec 2002 21:48:13 -0000	1.2
+++ libc/stdio/fputc.c	18 Feb 2005 00:52:30 -0000
@@ -46,7 +46,7 @@ fputc(int c, FILE *stream)
 		stream->len++;
 		return c;
 	} else {
-		if (stream->put(c) == 0) {
+		if (stream->put(stream, c) == 0) {
 			stream->len++;
 			return c;
 		} else
Index: libc/stdio/fputs.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/fputs.c,v
retrieving revision 1.2
diff -u -p -p -r1.2 fputs.c
--- libc/stdio/fputs.c	26 Dec 2002 21:48:13 -0000	1.2
+++ libc/stdio/fputs.c	18 Feb 2005 00:52:30 -0000
@@ -43,7 +43,7 @@ fputs(const char *str, FILE *stream)
 		return EOF;
 
 	while ((c = *str++) != '\0')
-		if (stream->put(c) != 0)
+		if (stream->put(stream, c) != 0)
 			rv = EOF;
 
 	return rv;
Index: libc/stdio/fputs_p.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/fputs_p.c,v
retrieving revision 1.4
diff -u -p -p -r1.4 fputs_p.c
--- libc/stdio/fputs_p.c	21 Jul 2004 22:11:59 -0000	1.4
+++ libc/stdio/fputs_p.c	18 Feb 2005 00:52:30 -0000
@@ -48,7 +48,7 @@ fputs_P(const char *str, FILE *stream)
 	 * macro, so it could evaluate its argument more than once.
 	 */
 	while ((c = pgm_read_byte(str)) != '\0') {
-		if (stream->put(c) != 0)
+		if (stream->put(stream, c) != 0)
 			rv = EOF;
 		str++;
 	}
Index: libc/stdio/fwrite.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/fwrite.c,v
retrieving revision 1.1
diff -u -p -p -r1.1 fwrite.c
--- libc/stdio/fwrite.c	28 Dec 2002 20:46:04 -0000	1.1
+++ libc/stdio/fwrite.c	18 Feb 2005 00:52:30 -0000
@@ -44,7 +44,7 @@ fwrite(const void *ptr, size_t size, siz
 
 	for (i = 0, cp = (const uint8_t *)ptr; i < nmemb; i++)
 		for (j = 0; j < size; j++)
-			if (stream->put(*cp++) != 0)
+			if (stream->put(stream, *cp++) != 0)
 				return i;
 
 	return i;
Index: libc/stdio/puts.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/puts.c,v
retrieving revision 1.2
diff -u -p -p -r1.2 puts.c
--- libc/stdio/puts.c	26 Dec 2002 21:48:13 -0000	1.2
+++ libc/stdio/puts.c	18 Feb 2005 00:52:30 -0000
@@ -43,9 +43,9 @@ puts(const char *str)
 		return EOF;
 
 	while ((c = *str++) != '\0')
-		if (stdout->put(c) != 0)
+		if (stdout->put(stdout, c) != 0)
 			rv = EOF;
-	if (stdout->put('\n') != 0)
+	if (stdout->put(stdout, '\n') != 0)
 		rv = EOF;
 
 	return rv;
Index: libc/stdio/puts_p.c
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/puts_p.c,v
retrieving revision 1.4
diff -u -p -p -r1.4 puts_p.c
--- libc/stdio/puts_p.c	21 Jul 2004 22:11:59 -0000	1.4
+++ libc/stdio/puts_p.c	18 Feb 2005 00:52:30 -0000
@@ -48,11 +48,11 @@ puts_P(const char *str)
 	 * macro, so it could evaluate its argument more than once.
 	 */
 	while ((c = pgm_read_byte(str)) != '\0') {
-		if (stdout->put(c) != 0)
+		if (stdout->put(stdout, c) != 0)
 			rv = EOF;
 		str++;
 	}
-	if (stdout->put('\n') != 0)
+	if (stdout->put(stdout, '\n') != 0)
 		rv = EOF;
 
 	return rv;
Index: libc/stdio/stdio_private.h
===================================================================
RCS file: /cvsroot/avr-libc/avr-libc/libc/stdio/stdio_private.h,v
retrieving revision 1.7
diff -u -p -p -r1.7 stdio_private.h
--- libc/stdio/stdio_private.h	30 Sep 2003 23:05:18 -0000	1.7
+++ libc/stdio/stdio_private.h	18 Feb 2005 00:52:30 -0000
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, Joerg Wunsch
+/* Copyright (c) 2002, 2003, 2005 Joerg Wunsch
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,11 @@ struct __file {
 #endif
 	int	size;		/* size of buffer */
 	int	len;		/* characters read or written so far */
-	int	(*put)(char);	/* function to write one char to device */
-	int	(*get)(void);	/* function to read one char from device */
+	int	(*put)(struct __file *, char); /* function to write one char to
+						  device */
+	int	(*get)(struct __file *);       /* function to read one char
+						  from device */
+	void    *udata;		/* User defined and accessible data. */
 };
 
 #endif /* not DOXYGEN */
Index: libc/stdio/fdevdata.c
===================================================================
--- /dev/null	2004-10-09 11:37:42.000000000 -0700
+++ libc/stdio/fdevdata.c	2005-02-17 08:51:15.000000000 -0800
@@ -0,0 +1,60 @@
+/* Copyright (c) 2005  Theodore A. Roth
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "stdio_private.h"
+
+/** \ingroup avr_stdio 
+
+    This function inserts a pointer to user defined data into a FILE stream
+    object.
+
+    The user data can be useful for tracking state in the put and get
+    functions supplied to the fdevopen() function. */
+
+void
+fdev_set_udata(FILE *stream, void *udata)
+{
+    stream->udata = udata;
+}
+
+/** \ingroup avr_stdio 
+
+    This function inserts a pointer to user defined data into a FILE stream
+    object. */
+
+void *
+fdev_get_udata(FILE *stream)
+{
+    return stream->udata;
+}
