summaryrefslogtreecommitdiff
path: root/libio
diff options
context:
space:
mode:
Diffstat (limited to 'libio')
-rw-r--r--libio/Makefile9
-rw-r--r--libio/Versions27
-rw-r--r--libio/fileops.c60
-rw-r--r--libio/fputwc.c45
-rw-r--r--libio/fputwc_u.c40
-rw-r--r--libio/ftello.c14
-rw-r--r--libio/ftello64.c13
-rw-r--r--libio/fwprintf.c36
-rw-r--r--libio/fwscanf.c35
-rw-r--r--libio/genops.c53
-rw-r--r--libio/getwc.c50
-rw-r--r--libio/getwc_u.c39
-rw-r--r--libio/getwchar.c42
-rw-r--r--libio/getwchar_u.c35
-rw-r--r--libio/iofdopen.c5
-rw-r--r--libio/iofgetpos.c16
-rw-r--r--libio/iofgetpos64.c20
-rw-r--r--libio/iofgetws.c63
-rw-r--r--libio/iofgetws_u.c59
-rw-r--r--libio/iofopen.c3
-rw-r--r--libio/iofopen64.c3
-rw-r--r--libio/iofopncook.c6
-rw-r--r--libio/iofputs.c9
-rw-r--r--libio/iofputs_u.c8
-rw-r--r--libio/iofputws.c45
-rw-r--r--libio/iofputws_u.c42
-rw-r--r--libio/iofsetpos.c18
-rw-r--r--libio/iofsetpos64.c18
-rw-r--r--libio/ioftell.c14
-rw-r--r--libio/iofwide.c365
-rw-r--r--libio/iofwrite.c7
-rw-r--r--libio/iofwrite_u.c17
-rw-r--r--libio/iogetwline.c120
-rw-r--r--libio/iolibio.h4
-rw-r--r--libio/iopopen.c28
-rw-r--r--libio/ioputs.c11
-rw-r--r--libio/ioseekoff.c28
-rw-r--r--libio/ioseekpos.c8
-rw-r--r--libio/iosetbuffer.c5
-rw-r--r--libio/iosetvbuf.c6
-rw-r--r--libio/ioungetwc.c44
-rw-r--r--libio/iovdprintf.c5
-rw-r--r--libio/iovsprintf.c4
-rw-r--r--libio/iovsscanf.c4
-rw-r--r--libio/iovswscanf.c48
-rw-r--r--libio/iowpadn.c76
-rw-r--r--libio/libio.h114
-rw-r--r--libio/libioP.h157
-rw-r--r--libio/memstream.c85
-rw-r--r--libio/obprintf.c8
-rw-r--r--libio/oldfileops.c10
-rw-r--r--libio/oldiofgetpos.c61
-rw-r--r--libio/oldiofgetpos64.c66
-rw-r--r--libio/oldiofsetpos.c59
-rw-r--r--libio/oldiofsetpos64.c64
-rw-r--r--libio/oldstdfiles.c7
-rw-r--r--libio/putwc.c35
-rw-r--r--libio/putwc_u.c29
-rw-r--r--libio/putwchar.c34
-rw-r--r--libio/putwchar_u.c28
-rw-r--r--libio/stdfiles.c12
-rw-r--r--libio/strops.c10
-rw-r--r--libio/swprintf.c38
-rw-r--r--libio/swscanf.c37
-rw-r--r--libio/tst_swprintf.c42
-rw-r--r--libio/tst_swscanf.c38
-rw-r--r--libio/tst_wprintf.c10
-rw-r--r--libio/tst_wscanf.c28
-rw-r--r--libio/tst_wscanf.input1
-rw-r--r--libio/vasprintf.c4
-rw-r--r--libio/vsnprintf.c4
-rw-r--r--libio/vswprintf.c144
-rw-r--r--libio/vwprintf.c31
-rw-r--r--libio/vwscanf.c35
-rw-r--r--libio/wfiledoalloc.c105
-rw-r--r--libio/wfileops.c716
-rw-r--r--libio/wgenops.c747
-rw-r--r--libio/wprintf.c35
-rw-r--r--libio/wscanf.c36
-rw-r--r--libio/wstrops.c330
80 files changed, 4568 insertions, 199 deletions
diff --git a/libio/Makefile b/libio/Makefile
index 948556e15c..6fcde40814 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -25,11 +25,16 @@ headers := stdio.h libio.h _G_config.h bits/stdio.h
routines := \
filedoalloc iofclose iofdopen iofflush iofgetpos iofgets iofopen \
- iofopncook iofputs iofread iofsetpos ioftell \
+ iofopncook iofputs iofread iofsetpos ioftell wfiledoalloc \
iofwrite iogetdelim iogetline iogets iopadn iopopen ioputs \
ioseekoff ioseekpos iosetbuffer iosetvbuf iosprintf ioungetc \
iovsprintf iovsscanf \
iofgetpos64 iofopen64 iofsetpos64 \
+ oldiofgetpos oldiofgetpos64 oldiofsetpos oldiofsetpos64 \
+ fputwc fputwc_u getwc getwc_u getwchar getwchar_u iofgetws iofgetws_u \
+ iofputws iofputws_u iogetwline iowpadn ioungetwc putwc putwc_u \
+ putchar putchar_u swprintf vwprintf wprintf wscanf fwscanf vwscanf \
+ vswprintf iovswscanf swscanf wgenops wstrops wfileops iofwide \
\
clearerr feof ferror fileno fputc freopen fseek getc getchar \
memstream pclose putc putchar rewind setbuf setlinebuf vasprintf \
@@ -38,6 +43,8 @@ routines := \
\
libc_fatal
+tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf
+
all: # Make this the default target; it will be defined in Rules.
include ../Makeconfig
diff --git a/libio/Versions b/libio/Versions
index 61b767a2d3..c7a5f668a1 100644
--- a/libio/Versions
+++ b/libio/Versions
@@ -100,4 +100,31 @@ libc {
# p*
pclose; popen;
}
+ GLIBC_2.2 {
+ # functions used in libstdc++
+ _IO_fgetpos; _IO_fgetpos64; _IO_fsetpos; _IO_fsetpos64;
+
+ # f*
+ fgetpos; fgetpos64; fgetwc; fgetwc_unlocked; fgetws; fgetws_unlocked;
+ fputwc; fputwc_unlocked; fputws; fputws_unlocked; fsetpos; fsetpos64;
+ fwide; fwprintf; fwscanf;
+
+ # g*
+ getwc; getwc_unlocked; getwchar; getwchar_unlocked;
+
+ # p*
+ putwc; putwc_unlocked; putwchar; putwchar_unlocked;
+
+ # s*
+ swprintf; swscanf;
+
+ # u*
+ ungetwc;
+
+ # v*
+ vfwprintf; vswprintf; vwprintf; vfwscanf; vswscanf; vwscanf;
+
+ # w*
+ wprintf; wscanf;
+ }
}
diff --git a/libio/fileops.c b/libio/fileops.c
index f5ec0e2b9e..8d480ad08b 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
Written by Per Bothner <bothner@cygnus.com>.
@@ -136,9 +136,18 @@ _IO_new_file_close_it (fp)
close_status = _IO_SYSCLOSE (fp);
/* Free buffer. */
- _IO_setb (fp, NULL, NULL, 0);
- _IO_setg (fp, NULL, NULL, NULL);
- _IO_setp (fp, NULL, NULL);
+ if (fp->_mode <= 0)
+ {
+ _IO_setb (fp, NULL, NULL, 0);
+ _IO_setg (fp, NULL, NULL, NULL);
+ _IO_setp (fp, NULL, NULL);
+ }
+ else
+ {
+ _IO_wsetb (fp, NULL, NULL, 0);
+ _IO_wsetg (fp, NULL, NULL, NULL);
+ _IO_wsetp (fp, NULL, NULL);
+ }
_IO_un_link (fp);
fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
@@ -277,14 +286,14 @@ _IO_new_file_setbuf (fp, p, len)
char *p;
_IO_ssize_t len;
{
- if (_IO_default_setbuf (fp, p, len) == NULL)
- return NULL;
+ if (_IO_default_setbuf (fp, p, len) == NULL)
+ return NULL;
- fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
- = fp->_IO_buf_base;
- _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+ = fp->_IO_buf_base;
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
- return fp;
+ return fp;
}
static int new_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
@@ -319,7 +328,7 @@ new_do_write (fp, data, to_do)
fp->_offset = _IO_pos_BAD;
else if (fp->_IO_read_end != fp->_IO_write_base)
{
- _IO_fpos64_t new_pos
+ _IO_off64_t new_pos
= _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
if (new_pos == _IO_pos_BAD)
return 0;
@@ -330,7 +339,8 @@ new_do_write (fp, data, to_do)
fp->_cur_column = _IO_adjust_column (fp->_cur_column - 1, data, count) + 1;
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
- fp->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+ fp->_IO_write_end = (fp->_mode < 0
+ && (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
? fp->_IO_buf_base : fp->_IO_buf_end);
return count;
}
@@ -410,7 +420,7 @@ _IO_new_file_overflow (f, ch)
return EOF;
}
/* If currently reading or no buffer allocated. */
- if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
+ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == 0)
{
/* Allocate a buffer if needed. */
if (f->_IO_write_base == 0)
@@ -433,18 +443,20 @@ _IO_new_file_overflow (f, ch)
f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end;
f->_flags |= _IO_CURRENTLY_PUTTING;
- if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+ if (f->_mode < 0 && f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
f->_IO_write_end = f->_IO_write_ptr;
}
if (ch == EOF)
- return _IO_do_flush (f);
+ return _IO_new_do_write(f, f->_IO_write_base,
+ f->_IO_write_ptr - f->_IO_write_base);
if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */
if (_IO_do_flush (f) == EOF)
return EOF;
*f->_IO_write_ptr++ = ch;
if ((f->_flags & _IO_UNBUFFERED)
|| ((f->_flags & _IO_LINE_BUF) && ch == '\n'))
- if (_IO_do_flush (f) == EOF)
+ if (_IO_new_do_write(f, f->_IO_write_base,
+ f->_IO_write_ptr - f->_IO_write_base) == EOF)
return EOF;
return (unsigned char) ch;
}
@@ -483,14 +495,14 @@ _IO_new_file_sync (fp)
return retval;
}
-_IO_fpos64_t
+_IO_off64_t
_IO_new_file_seekoff (fp, offset, dir, mode)
_IO_FILE *fp;
_IO_off64_t offset;
int dir;
int mode;
{
- _IO_fpos64_t result;
+ _IO_off64_t result;
_IO_off64_t delta, new_offset;
long count;
/* POSIX.1 8.2.3.7 says that after a call the fflush() the file
@@ -534,7 +546,7 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
if (fp->_offset == _IO_pos_BAD)
goto dumb;
/* Make offset absolute, assuming current pointer is file_ptr(). */
- offset += _IO_pos_as_off (fp->_offset);
+ offset += fp->_offset;
dir = _IO_seek_set;
break;
@@ -563,8 +575,8 @@ _IO_new_file_seekoff (fp, offset, dir, mode)
&& !_IO_in_backup (fp))
{
/* Offset relative to start of main get area. */
- _IO_fpos64_t rel_offset = (offset - fp->_offset
- + (fp->_IO_read_end - fp->_IO_read_base));
+ _IO_off64_t rel_offset = (offset - fp->_offset
+ + (fp->_IO_read_end - fp->_IO_read_base));
if (rel_offset >= 0)
{
#if 0
@@ -678,7 +690,7 @@ _IO_file_read (fp, buf, size)
return read (fp->_fileno, buf, size);
}
-_IO_fpos64_t
+_IO_off64_t
_IO_file_seek (fp, offset, dir)
_IO_FILE *fp;
_IO_off64_t offset;
@@ -720,7 +732,7 @@ _IO_new_file_write (f, data, n)
while (to_do > 0)
{
_IO_ssize_t count = write (f->_fileno, data, to_do);
- if (count == EOF)
+ if (count < 0)
{
f->_flags |= _IO_ERR_SEEN;
break;
@@ -740,7 +752,7 @@ _IO_new_file_xsputn (f, data, n)
const void *data;
_IO_size_t n;
{
- register const char *s = (char *) data;
+ register const char *s = (const char *) data;
_IO_size_t to_do = n;
int must_flush = 0;
_IO_size_t count;
diff --git a/libio/fputwc.c b/libio/fputwc.c
new file mode 100644
index 0000000000..cc8451a98f
--- /dev/null
+++ b/libio/fputwc.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+wint_t
+fputwc (wc, fp)
+ wint_t wc;
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (_IO_fwide (fp, 1) < 0)
+ result = WEOF;
+ else
+ result = _IO_putwc_unlocked (wc, fp);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+}
diff --git a/libio/fputwc_u.c b/libio/fputwc_u.c
new file mode 100644
index 0000000000..343e34d90e
--- /dev/null
+++ b/libio/fputwc_u.c
@@ -0,0 +1,40 @@
+/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+#undef fputwc_unlocked
+
+wint_t
+fputwc_unlocked (wc, fp)
+ wint_t wc;
+ _IO_FILE *fp;
+{
+ CHECK_FILE (fp, EOF);
+ if (_IO_fwide (fp, 1) < 0)
+ return WEOF;
+ return _IO_putwc_unlocked (wc, fp);
+}
diff --git a/libio/ftello.c b/libio/ftello.c
index 2d8a8a7167..ed4ef8b603 100644
--- a/libio/ftello.c
+++ b/libio/ftello.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -32,13 +32,19 @@ off_t
ftello (fp)
_IO_FILE *fp;
{
- _IO_pos_t pos;
+ _IO_off_t pos;
CHECK_FILE (fp, -1L);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
if (_IO_in_backup (fp))
- pos -= fp->_IO_save_end - fp->_IO_save_base;
+ {
+ if (fp->_mode <= 0)
+ pos -= fp->_IO_save_end - fp->_IO_save_base;
+ else
+ /* XXX Not done yet. */
+ abort ();
+ }
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
@@ -49,5 +55,5 @@ ftello (fp)
#endif
return -1L;
}
- return _IO_pos_as_off (pos);
+ return pos;
}
diff --git a/libio/ftello64.c b/libio/ftello64.c
index 621454974e..7cb75626cf 100644
--- a/libio/ftello64.c
+++ b/libio/ftello64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -33,13 +33,18 @@ ftello64 (fp)
_IO_FILE *fp;
{
#ifdef _G_LSEEK64
- _IO_pos_t pos;
+ _IO_off64_t pos;
CHECK_FILE (fp, -1L);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
if (_IO_in_backup (fp))
- pos -= fp->_IO_save_end - fp->_IO_save_base;
+ {
+ if (fp->_mode <= 0)
+ pos -= fp->_IO_save_end - fp->_IO_save_base;
+ else
+ abort ();
+ }
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
@@ -50,7 +55,7 @@ ftello64 (fp)
#endif
return -1L;
}
- return _IO_pos_as_off (pos);
+ return pos;
#else
__set_errno (ENOSYS);
return -1;
diff --git a/libio/fwprintf.c b/libio/fwprintf.c
new file mode 100644
index 0000000000..c26a2ffcd3
--- /dev/null
+++ b/libio/fwprintf.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#include <wchar.h>
+
+
+/* Write formatted output to STREAM from the format string FORMAT. */
+/* VARARGS2 */
+int
+fwprintf (FILE *stream, const wchar_t *format, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+ done = vfwprintf (stream, format, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libio/fwscanf.c b/libio/fwscanf.c
new file mode 100644
index 0000000000..4510fc5b5f
--- /dev/null
+++ b/libio/fwscanf.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#include <wchar.h>
+
+/* Read formatted input from STREAM according to the format string FORMAT. */
+/* VARARGS2 */
+int
+fwscanf (FILE *stream, const wchar_t *format, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+ done = __vfwscanf (stream, format, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libio/genops.c b/libio/genops.c
index 81752e3ccc..a8f34463ad 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -80,9 +80,9 @@ _IO_link_in (fp)
/* Return minimum _pos markers
Assumes the current get area is the main get area. */
-static _IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
+_IO_ssize_t _IO_least_marker __P ((_IO_FILE *fp, char *end_p));
-static _IO_ssize_t
+_IO_ssize_t
_IO_least_marker (fp, end_p)
_IO_FILE *fp;
char *end_p;
@@ -282,6 +282,9 @@ int
__underflow (fp)
_IO_FILE *fp;
{
+ if (_IO_fwide (fp, -1) != -1)
+ return EOF;
+
if (_IO_in_put_mode (fp))
if (_IO_switch_to_get_mode (fp) == EOF)
return EOF;
@@ -307,6 +310,9 @@ int
__uflow (fp)
_IO_FILE *fp;
{
+ if (_IO_fwide (fp, -1) != -1)
+ return EOF;
+
if (_IO_in_put_mode (fp))
if (_IO_switch_to_get_mode (fp) == EOF)
return EOF;
@@ -508,13 +514,13 @@ _IO_default_setbuf (fp, p, len)
return fp;
}
-_IO_fpos64_t
+_IO_off64_t
_IO_default_seekpos (fp, pos, mode)
_IO_FILE *fp;
- _IO_fpos64_t pos;
+ _IO_off64_t pos;
int mode;
{
- return _IO_SEEKOFF (fp, _IO_pos_as_off (pos), 0, mode);
+ return _IO_SEEKOFF (fp, pos, 0, mode);
}
int
@@ -533,6 +539,17 @@ _IO_init (fp, flags)
_IO_FILE *fp;
int flags;
{
+ _IO_no_init (fp, flags, -1, NULL, NULL);
+}
+
+void
+_IO_no_init (fp, flags, orientation, wd, jmp)
+ _IO_FILE *fp;
+ int flags;
+ int orientation;
+ struct _IO_wide_data *wd;
+ struct _IO_jump_t *jmp;
+{
fp->_flags = _IO_MAGIC|flags;
fp->_IO_buf_base = NULL;
fp->_IO_buf_end = NULL;
@@ -555,6 +572,24 @@ _IO_init (fp, flags)
#ifdef _IO_MTSAFE_IO
_IO_lock_init (*fp->_lock);
#endif
+ fp->_mode = orientation;
+ if (orientation >= 0)
+ {
+ fp->_wide_data = wd;
+ fp->_wide_data->_IO_buf_base = NULL;
+ fp->_wide_data->_IO_buf_end = NULL;
+ fp->_wide_data->_IO_read_base = NULL;
+ fp->_wide_data->_IO_read_ptr = NULL;
+ fp->_wide_data->_IO_read_end = NULL;
+ fp->_wide_data->_IO_write_base = NULL;
+ fp->_wide_data->_IO_write_ptr = NULL;
+ fp->_wide_data->_IO_write_end = NULL;
+ fp->_wide_data->_IO_save_base = NULL;
+ fp->_wide_data->_IO_backup_base = NULL;
+ fp->_wide_data->_IO_save_end = NULL;
+
+ fp->_wide_data->_wide_vtable = jmp;
+ }
}
int
@@ -595,7 +630,7 @@ _IO_default_finish (fp, dummy)
_IO_un_link (fp);
}
-_IO_fpos64_t
+_IO_off64_t
_IO_default_seekoff (fp, offset, dir, mode)
_IO_FILE *fp;
_IO_off64_t offset;
@@ -706,7 +741,9 @@ _IO_flush_all ()
int result = 0;
_IO_FILE *fp;
for (fp = _IO_list_all; fp != NULL; fp = fp->_chain)
- if (fp->_IO_write_ptr > fp->_IO_write_base
+ if (((fp->_mode < 0 && fp->_IO_write_ptr > fp->_IO_write_base)
+ || (fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
+ > fp->_wide_data->_IO_write_base)))
&& _IO_OVERFLOW (fp, EOF) == EOF)
result = EOF;
return result;
@@ -941,7 +978,7 @@ _IO_default_pbackfail (fp, c)
return (unsigned char) c;
}
-_IO_fpos64_t
+_IO_off64_t
_IO_default_seek (fp, offset, dir)
_IO_FILE *fp;
_IO_off64_t offset;
diff --git a/libio/getwc.c b/libio/getwc.c
new file mode 100644
index 0000000000..0829ea0248
--- /dev/null
+++ b/libio/getwc.c
@@ -0,0 +1,50 @@
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+#undef _IO_getwc
+
+wint_t
+_IO_getwc (fp)
+ FILE *fp;
+{
+ wint_t result;
+ CHECK_FILE (fp, WEOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_getwc_unlocked (fp);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+}
+
+#undef getwc
+
+#ifdef weak_alias
+weak_alias (_IO_getwc, getwc)
+weak_alias (_IO_getwc, fgetwc)
+#endif
diff --git a/libio/getwc_u.c b/libio/getwc_u.c
new file mode 100644
index 0000000000..606b4d24cc
--- /dev/null
+++ b/libio/getwc_u.c
@@ -0,0 +1,39 @@
+/* Copyright (C) 1993, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+#undef getwc_unlocked
+
+wint_t
+__getwc_unlocked (FILE *fp)
+{
+ CHECK_FILE (fp, EOF);
+ return _IO_getwc_unlocked (fp);
+}
+
+weak_alias (__getwc_unlocked, getwc_unlocked)
+weak_alias (__getwc_unlocked, fgetwc_unlocked)
diff --git a/libio/getwchar.c b/libio/getwchar.c
new file mode 100644
index 0000000000..6ef1f9b552
--- /dev/null
+++ b/libio/getwchar.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+#undef getwchar
+
+wint_t
+getwchar ()
+{
+ wint_t result;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _IO_stdin);
+ _IO_flockfile (_IO_stdin);
+ result = _IO_getwc_unlocked (_IO_stdin);
+ _IO_funlockfile (_IO_stdin);
+ _IO_cleanup_region_end (0);
+ return result;
+}
diff --git a/libio/getwchar_u.c b/libio/getwchar_u.c
new file mode 100644
index 0000000000..18dc2ca158
--- /dev/null
+++ b/libio/getwchar_u.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1993, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+#undef getwchar_unlocked
+
+wint_t
+getwchar_unlocked ()
+{
+ return _IO_getwc_unlocked (_IO_stdin);
+}
diff --git a/libio/iofdopen.c b/libio/iofdopen.c
index 40419bd267..3bfa40c7c6 100644
--- a/libio/iofdopen.c
+++ b/libio/iofdopen.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1994, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -50,6 +50,7 @@ _IO_new_fdopen (fd, mode)
#ifdef _IO_MTSAFE_IO
_IO_lock_t lock;
#endif
+ struct _IO_wide_data wd;
} *new_f;
int fd_flags;
@@ -112,7 +113,7 @@ _IO_new_fdopen (fd, mode)
#ifdef _IO_MTSAFE_IO
new_f->fp.file._lock = &new_f->lock;
#endif
- _IO_init (&new_f->fp.file, 0);
+ _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps);
_IO_JUMPS (&new_f->fp) = &_IO_file_jumps;
_IO_file_init (&new_f->fp.file);
#if !_IO_UNIFIED_JUMPTABLES
diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c
index 27f018d07f..5b8f6a4129 100644
--- a/libio/iofgetpos.c
+++ b/libio/iofgetpos.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -27,11 +27,11 @@
#include <errno.h>
int
-_IO_fgetpos (fp, posp)
+_IO_new_fgetpos (fp, posp)
_IO_FILE *fp;
_IO_fpos_t *posp;
{
- _IO_fpos_t pos;
+ _IO_off_t pos;
CHECK_FILE (fp, EOF);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
@@ -50,10 +50,16 @@ _IO_fgetpos (fp, posp)
#endif
return EOF;
}
- *posp = pos;
+ posp->__pos = pos;
+ if (fp->_mode > 0
+ && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
+ /* This is a stateful encoding, safe the state. */
+ posp->__state = fp->_wide_data->_IO_state;
return 0;
}
#ifdef weak_alias
-weak_alias (_IO_fgetpos, fgetpos)
+strong_alias (_IO_new_fgetpos, __new_fgetpos)
+default_symbol_version (_IO_new_fgetpos, _IO_fgetpos, GLIBC_2.2);
+default_symbol_version (__new_fgetpos, fgetpos, GLIBC_2.2);
#endif
diff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c
index a705e9e91a..cc39a3a9e1 100644
--- a/libio/iofgetpos64.c
+++ b/libio/iofgetpos64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -27,12 +27,12 @@
#include <errno.h>
int
-_IO_fgetpos64 (fp, posp)
+_IO_new_fgetpos64 (fp, posp)
_IO_FILE *fp;
_IO_fpos64_t *posp;
{
#ifdef _G_LSEEK64
- _IO_fpos64_t pos;
+ _IO_off64_t pos;
CHECK_FILE (fp, EOF);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
@@ -45,13 +45,17 @@ _IO_fgetpos64 (fp, posp)
{
/* ANSI explicitly requires setting errno to a positive value on
failure. */
-#ifdef EIO
+# ifdef EIO
if (errno == 0)
__set_errno (EIO);
-#endif
+# endif
return EOF;
}
- *posp = pos;
+ posp->__pos = pos;
+ if (fp->_mode > 0
+ && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
+ /* This is a stateful encoding, safe the state. */
+ posp->__state = fp->_wide_data->_IO_state;
return 0;
#else
__set_errno (ENOSYS);
@@ -60,5 +64,7 @@ _IO_fgetpos64 (fp, posp)
}
#ifdef weak_alias
-weak_alias (_IO_fgetpos64, fgetpos64)
+default_symbol_version (_IO_new_fgetpos64, _IO_fgetpos64, GLIBC_2.2);
+strong_alias (_IO_new_fgetpos64, __new_fgetpos64)
+default_symbol_version (__new_fgetpos64, fgetpos64, GLIBC_2.2);
#endif
diff --git a/libio/iofgetws.c b/libio/iofgetws.c
new file mode 100644
index 0000000000..25ed836560
--- /dev/null
+++ b/libio/iofgetws.c
@@ -0,0 +1,63 @@
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+wchar_t *
+fgetws (buf, n, fp)
+ wchar_t *buf;
+ int n;
+ _IO_FILE *fp;
+{
+ _IO_size_t count;
+ wchar_t *result;
+ int old_error;
+ CHECK_FILE (fp, NULL);
+ if (n <= 0)
+ return NULL;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ /* This is very tricky since a file descriptor may be in the
+ non-blocking mode. The error flag doesn't mean much in this
+ case. We return an error only when there is a new error. */
+ old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
+ fp->_IO_file_flags &= ~_IO_ERR_SEEN;
+ count = _IO_getwline (fp, buf, n - 1, L'\n', 1);
+ /* If we read in some bytes and errno is EAGAIN, that error will
+ be reported for next read. */
+ if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN)
+ && errno != EAGAIN))
+ result = NULL;
+ else
+ {
+ buf[count] = '\0';
+ result = buf;
+ }
+ fp->_IO_file_flags |= old_error;
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+}
diff --git a/libio/iofgetws_u.c b/libio/iofgetws_u.c
new file mode 100644
index 0000000000..951ab80d9d
--- /dev/null
+++ b/libio/iofgetws_u.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+wchar_t *
+fgetws_unlocked (buf, n, fp)
+ wchar_t *buf;
+ int n;
+ _IO_FILE *fp;
+{
+ _IO_size_t count;
+ wchar_t *result;
+ int old_error;
+ CHECK_FILE (fp, NULL);
+ if (n <= 0)
+ return NULL;
+ /* This is very tricky since a file descriptor may be in the
+ non-blocking mode. The error flag doesn't mean much in this
+ case. We return an error only when there is a new error. */
+ old_error = fp->_IO_file_flags & _IO_ERR_SEEN;
+ fp->_IO_file_flags &= ~_IO_ERR_SEEN;
+ count = _IO_getwline (fp, buf, n - 1, L'\n', 1);
+ /* If we read in some bytes and errno is EAGAIN, that error will
+ be reported for next read. */
+ if (count == 0 || ((fp->_IO_file_flags & _IO_ERR_SEEN)
+ && errno != EAGAIN))
+ result = NULL;
+ else
+ {
+ buf[count] = '\0';
+ result = buf;
+ }
+ fp->_IO_file_flags |= old_error;
+ return result;
+}
diff --git a/libio/iofopen.c b/libio/iofopen.c
index 92d58bb133..60b15a00f8 100644
--- a/libio/iofopen.c
+++ b/libio/iofopen.c
@@ -39,6 +39,7 @@ _IO_new_fopen (filename, mode)
#ifdef _IO_MTSAFE_IO
_IO_lock_t lock;
#endif
+ struct _IO_wide_data wd;
} *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
if (new_f == NULL)
@@ -46,7 +47,7 @@ _IO_new_fopen (filename, mode)
#ifdef _IO_MTSAFE_IO
new_f->fp.file._lock = &new_f->lock;
#endif
- _IO_init (&new_f->fp.file, 0);
+ _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps);
_IO_JUMPS (&new_f->fp) = &_IO_file_jumps;
_IO_file_init (&new_f->fp.file);
#if !_IO_UNIFIED_JUMPTABLES
diff --git a/libio/iofopen64.c b/libio/iofopen64.c
index b071a0e160..0dc19b2e1b 100644
--- a/libio/iofopen64.c
+++ b/libio/iofopen64.c
@@ -40,6 +40,7 @@ _IO_fopen64 (filename, mode)
#ifdef _IO_MTSAFE_IO
_IO_lock_t lock;
#endif
+ struct _IO_wide_data wd;
} *new_f = (struct locked_FILE *) malloc (sizeof (struct locked_FILE));
if (new_f == NULL)
@@ -47,7 +48,7 @@ _IO_fopen64 (filename, mode)
#ifdef _IO_MTSAFE_IO
new_f->fp.file._lock = &new_f->lock;
#endif
- _IO_init (&new_f->fp.file, 0);
+ _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps);
_IO_JUMPS (&new_f->fp) = &_IO_file_jumps;
_IO_file_init (&new_f->fp.file);
#if !_IO_UNIFIED_JUMPTABLES
diff --git a/libio/iofopncook.c b/libio/iofopncook.c
index f26744f39d..85ea35c22e 100644
--- a/libio/iofopncook.c
+++ b/libio/iofopncook.c
@@ -33,8 +33,8 @@ static _IO_ssize_t _IO_cookie_read __P ((register _IO_FILE* fp, void* buf,
_IO_ssize_t size));
static _IO_ssize_t _IO_cookie_write __P ((register _IO_FILE* fp,
const void* buf, _IO_ssize_t size));
-static _IO_fpos64_t _IO_cookie_seek __P ((_IO_FILE *fp, _IO_off64_t offset,
- int dir));
+static _IO_off64_t _IO_cookie_seek __P ((_IO_FILE *fp, _IO_off64_t offset,
+ int dir));
static int _IO_cookie_close __P ((_IO_FILE* fp));
@@ -66,7 +66,7 @@ _IO_cookie_write (fp, buf, size)
return cfile->__io_functions.write (cfile->__cookie, buf, size);
}
-static _IO_fpos64_t
+static _IO_off64_t
_IO_cookie_seek (fp, offset, dir)
_IO_FILE *fp;
_IO_off64_t offset;
diff --git a/libio/iofputs.c b/libio/iofputs.c
index 1805387303..ed41d5a49c 100644
--- a/libio/iofputs.c
+++ b/libio/iofputs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -32,13 +32,12 @@ _IO_fputs (str, fp)
_IO_FILE *fp;
{
_IO_size_t len = strlen (str);
- int result;
+ int result = EOF;
CHECK_FILE (fp, EOF);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
- if (_IO_sputn (fp, str, len) != len)
- result = EOF;
- else
+ if (_IO_fwide (fp, -1) == -1
+ && _IO_sputn (fp, str, len) == len)
result = 1;
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
diff --git a/libio/iofputs_u.c b/libio/iofputs_u.c
index dfd91aba7e..556522bad1 100644
--- a/libio/iofputs_u.c
+++ b/libio/iofputs_u.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -33,11 +33,9 @@ fputs_unlocked (str, fp)
_IO_FILE *fp;
{
_IO_size_t len = strlen (str);
- int result;
+ int result = EOF;
CHECK_FILE (fp, EOF);
- if (_IO_sputn (fp, str, len) != len)
- result = EOF;
- else
+ if (_IO_fwide (fp, -1) == -1 && _IO_sputn (fp, str, len) == len)
result = 1;
return result;
}
diff --git a/libio/iofputws.c b/libio/iofputws.c
new file mode 100644
index 0000000000..daad1b9836
--- /dev/null
+++ b/libio/iofputws.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+int
+fputws (str, fp)
+ const wchar_t *str;
+ _IO_FILE *fp;
+{
+ _IO_size_t len = wcslen (str);
+ int result = EOF;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (_IO_fwide (fp, 1) == 1
+ && _IO_sputn (fp, (char *) str, len) == len)
+ result = 1;
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+}
diff --git a/libio/iofputws_u.c b/libio/iofputws_u.c
new file mode 100644
index 0000000000..a5749cdbec
--- /dev/null
+++ b/libio/iofputws_u.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <stdio.h>
+#include <wchar.h>
+
+int
+fputws_unlocked (str, fp)
+ const wchar_t *str;
+ _IO_FILE *fp;
+{
+ _IO_size_t len = wcslen (str);
+ int result = EOF;
+ CHECK_FILE (fp, EOF);
+ if (_IO_fwide (fp, 1) == 1
+ && _IO_sputn (fp, (char *) str, len) == len)
+ result = 1;
+ return result;
+}
diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c
index cbf77347e7..bd49c13a83 100644
--- a/libio/iofsetpos.c
+++ b/libio/iofsetpos.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -27,7 +27,7 @@
#include <errno.h>
int
-_IO_fsetpos (fp, posp)
+_IO_new_fsetpos (fp, posp)
_IO_FILE *fp;
const _IO_fpos_t *posp;
{
@@ -35,7 +35,7 @@ _IO_fsetpos (fp, posp)
CHECK_FILE (fp, EOF);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
- if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
+ if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
{
/* ANSI explicitly requires setting errno to a positive value on
failure. */
@@ -46,12 +46,20 @@ _IO_fsetpos (fp, posp)
result = EOF;
}
else
- result = 0;
+ {
+ result = 0;
+ if (fp->_mode > 0
+ && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
+ /* This is a stateful encoding, restore the state. */
+ fp->_wide_data->_IO_state = posp->__state;
+ }
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
return result;
}
#ifdef weak_alias
-weak_alias (_IO_fsetpos, fsetpos)
+default_symbol_version (_IO_new_fsetpos, _IO_fsetpos, GLIBC_2.2);
+strong_alias (_IO_new_fsetpos, __new_fsetpos)
+default_symbol_version (__new_fsetpos, fsetpos, GLIBC_2.2);
#endif
diff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c
index 13ce0fb3cb..a70d5e215a 100644
--- a/libio/iofsetpos64.c
+++ b/libio/iofsetpos64.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -27,7 +27,7 @@
#include <errno.h>
int
-_IO_fsetpos64 (fp, posp)
+_IO_new_fsetpos64 (fp, posp)
_IO_FILE *fp;
const _IO_fpos64_t *posp;
{
@@ -36,7 +36,7 @@ _IO_fsetpos64 (fp, posp)
CHECK_FILE (fp, EOF);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
- if (_IO_seekpos (fp, *posp, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
+ if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
{
/* ANSI explicitly requires setting errno to a positive value on
failure. */
@@ -47,7 +47,13 @@ _IO_fsetpos64 (fp, posp)
result = EOF;
}
else
- result = 0;
+ {
+ result = 0;
+ if (fp->_mode > 0
+ && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
+ /* This is a stateful encoding, safe the state. */
+ fp->_wide_data->_IO_state = posp->__state;
+ }
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
return result;
@@ -58,5 +64,7 @@ _IO_fsetpos64 (fp, posp)
}
#ifdef weak_alias
-weak_alias (_IO_fsetpos64, fsetpos64)
+default_symbol_version (_IO_new_fsetpos64, _IO_fsetpos64, GLIBC_2.2);
+strong_alias (_IO_new_fsetpos64, __new_fsetpos64)
+default_symbol_version (__new_fsetpos64, fsetpos64, GLIBC_2.2);
#endif
diff --git a/libio/ioftell.c b/libio/ioftell.c
index 3de1ee9c02..1f25b66c2b 100644
--- a/libio/ioftell.c
+++ b/libio/ioftell.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -31,13 +31,19 @@ long int
_IO_ftell (fp)
_IO_FILE *fp;
{
- _IO_pos_t pos;
+ _IO_off_t pos;
CHECK_FILE (fp, -1L);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
if (_IO_in_backup (fp))
- pos -= fp->_IO_save_end - fp->_IO_save_base;
+ {
+ if (fp->_mode < 0)
+ pos -= fp->_IO_save_end - fp->_IO_save_base;
+ else
+ /* XXX For now. */
+ abort ();
+ }
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
@@ -48,7 +54,7 @@ _IO_ftell (fp)
#endif
return -1L;
}
- return _IO_pos_as_off (pos);
+ return pos;
}
#ifdef weak_alias
diff --git a/libio/iofwide.c b/libio/iofwide.c
new file mode 100644
index 0000000000..853920a001
--- /dev/null
+++ b/libio/iofwide.c
@@ -0,0 +1,365 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <libioP.h>
+#ifdef _LIBC
+# include <wchar.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _LIBC
+# include <langinfo.h>
+# include <locale/localeinfo.h>
+# include <wcsmbs/wcsmbsload.h>
+#endif
+
+
+/* Prototypes of libio's codecvt functions. */
+static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
+ __mbstate_t *statep,
+ const wchar_t *from_start,
+ const wchar_t *from_end,
+ const wchar_t **from_stop, char *to_start,
+ char *to_end, char **to_stop);
+static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt,
+ __mbstate_t *statep, char *to_start,
+ char *to_end, char **to_stop);
+static enum __codecvt_result do_in (struct _IO_codecvt *codecvt,
+ __mbstate_t *statep,
+ const char *from_start,
+ const char *from_end,
+ const char **from_stop, wchar_t *to_start,
+ wchar_t *to_end, wchar_t **to_stop);
+static int do_encoding (struct _IO_codecvt *codecvt);
+static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
+ const char *from_start,
+ const char *from_end, _IO_size_t max);
+static int do_max_length (struct _IO_codecvt *codecvt);
+static int do_always_noconv (struct _IO_codecvt *codecvt);
+
+
+/* The functions used in `codecvt' for libio are always the same. */
+static struct _IO_codecvt libio_codecvt =
+{
+ .__codecvt_destr = NULL, /* Destructor, never used. */
+ .__codecvt_do_out = do_out,
+ .__codecvt_do_unshift = do_unshift,
+ .__codecvt_do_in = do_in,
+ .__codecvt_do_encoding = do_encoding,
+ .__codecvt_do_always_noconv = do_always_noconv,
+ .__codecvt_do_length = do_length,
+ .__codecvt_do_max_length = do_max_length
+};
+
+
+/* Return orientation of stream. If mode is nonzero try to change
+ the orientation first. */
+#undef _IO_fwide
+int
+_IO_fwide (fp, mode)
+ _IO_FILE *fp;
+ int mode;
+{
+ /* Normalize the value. */
+ mode = mode < 0 ? -1 : (mode == 0 ? 0 : 1);
+
+ if (mode == 0 || fp->_mode != 0)
+ /* The caller simply wants to know about the current orientation
+ or the orientation already has been determined. */
+ return fp->_mode;
+
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+
+ /* Set the orientation appropriately. */
+ if (mode > 0)
+ {
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
+ fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base;
+
+ /* Clear the state. We start all over again. */
+ memset (&fp->_wide_data->_IO_state, '\0', sizeof (__mbstate_t));
+ memset (&fp->_wide_data->_IO_last_state, '\0', sizeof (__mbstate_t));
+
+ /* Get the character conversion functions based on the currently
+ selected locale for LC_CTYPE. */
+#ifdef _LIBC
+ {
+ struct gconv_fcts fcts;
+ struct _IO_codecvt *cc = &fp->_wide_data->_codecvt;
+
+ __wcsmbs_clone_conv (&fcts);
+
+ /* The functions are always the same. */
+ *cc = libio_codecvt;
+
+ cc->__cd_in.__cd.__nsteps = 1; /* Only one step allowed. */
+ cc->__cd_in.__cd.__steps = fcts.towc;
+
+ cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
+ cc->__cd_in.__cd.__data[0].__internal_use = 1;
+ cc->__cd_in.__cd.__data[0].__is_last = 1;
+ cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
+
+ cc->__cd_out.__cd.__nsteps = 1; /* Only one step allowed. */
+ cc->__cd_out.__cd.__steps = fcts.tomb;
+
+ cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
+ cc->__cd_out.__cd.__data[0].__internal_use = 1;
+ cc->__cd_out.__cd.__data[0].__is_last = 1;
+ cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
+ }
+#else
+# error "somehow determine this from LC_CTYPE"
+#endif
+
+ /* From now on use the wide character callback functions. */
+ ((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
+ }
+
+ /* Set the mode now. */
+ fp->_mode = mode;
+
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+
+ return mode;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_fwide, fwide)
+#endif
+
+
+static enum __codecvt_result
+do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
+ const wchar_t *from_start, const wchar_t *from_end,
+ const wchar_t **from_stop, char *to_start, char *to_end,
+ char **to_stop)
+{
+ enum __codecvt_result result;
+
+#ifdef _LIBC
+ struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
+ int status;
+ size_t written;
+ const unsigned char *from_start_copy = (unsigned char *) from_start;
+
+ codecvt->__cd_out.__cd.__data[0].__outbuf = to_start;
+ codecvt->__cd_out.__cd.__data[0].__outbufend = to_end;
+ codecvt->__cd_out.__cd.__data[0].__statep = statep;
+
+ status = (*gs->__fct) (gs, codecvt->__cd_out.__cd.__data, &from_start_copy,
+ (const unsigned char *) from_end, &written, 0);
+
+ *from_stop = (wchar_t *) from_start_copy;
+ *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf;
+
+ switch (status)
+ {
+ case __GCONV_OK:
+ case __GCONV_EMPTY_INPUT:
+ result = __codecvt_ok;
+ break;
+
+ case __GCONV_FULL_OUTPUT:
+ case __GCONV_INCOMPLETE_INPUT:
+ result = __codecvt_partial;
+ break;
+
+ default:
+ result = __codecvt_error;
+ break;
+ }
+#else
+ /* Decide what to do. */
+ result = __codecvt_error;
+#endif
+
+ return result;
+}
+
+
+static enum __codecvt_result
+do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep,
+ char *to_start, char *to_end, char **to_stop)
+{
+ enum __codecvt_result result;
+
+#ifdef _LIBC
+ struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
+ int status;
+ size_t written;
+
+ codecvt->__cd_out.__cd.__data[0].__outbuf = to_start;
+ codecvt->__cd_out.__cd.__data[0].__outbufend = to_end;
+ codecvt->__cd_out.__cd.__data[0].__statep = statep;
+
+ status = (*gs->__fct) (gs, codecvt->__cd_out.__cd.__data, NULL, NULL,
+ &written, 1);
+
+ *to_stop = codecvt->__cd_out.__cd.__data[0].__outbuf;
+
+ switch (status)
+ {
+ case __GCONV_OK:
+ case __GCONV_EMPTY_INPUT:
+ result = __codecvt_ok;
+ break;
+
+ case __GCONV_FULL_OUTPUT:
+ case __GCONV_INCOMPLETE_INPUT:
+ result = __codecvt_partial;
+ break;
+
+ default:
+ result = __codecvt_error;
+ break;
+ }
+#else
+ /* Decide what to do. */
+ result = __codecvt_error;
+#endif
+
+ return result;
+}
+
+
+static enum __codecvt_result
+do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
+ const char *from_start, const char *from_end, const char **from_stop,
+ wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
+{
+ enum __codecvt_result result;
+
+#ifdef _LIBC
+ struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
+ int status;
+ size_t written;
+ const unsigned char *from_start_copy = (unsigned char *) from_start;
+
+ codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_start;
+ codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) to_end;
+ codecvt->__cd_in.__cd.__data[0].__statep = statep;
+
+ status = (*gs->__fct) (gs, codecvt->__cd_in.__cd.__data, &from_start_copy,
+ from_end, &written, 0);
+
+ *from_stop = from_start_copy;
+ *to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf;
+
+ switch (status)
+ {
+ case __GCONV_OK:
+ case __GCONV_EMPTY_INPUT:
+ result = __codecvt_ok;
+ break;
+
+ case __GCONV_FULL_OUTPUT:
+ case __GCONV_INCOMPLETE_INPUT:
+ result = __codecvt_partial;
+ break;
+
+ default:
+ result = __codecvt_error;
+ break;
+ }
+#else
+ /* Decide what to do. */
+ result = __codecvt_error;
+#endif
+
+ return result;
+}
+
+
+static int
+do_encoding (struct _IO_codecvt *codecvt)
+{
+#ifdef _LIBC
+ /* See whether the encoding is stateful. */
+ if (codecvt->__cd_in.__cd.__steps[0].__stateful)
+ return -1;
+ /* Fortunately not. Now determine the input bytes for the conversion
+ necessary for each wide character. */
+ if (codecvt->__cd_in.__cd.__steps[0].__min_needed_from
+ != codecvt->__cd_in.__cd.__steps[0].__max_needed_from)
+ /* Not a constant value. */
+ return 0;
+
+ return codecvt->__cd_in.__cd.__steps[0].__min_needed_from;
+#else
+ /* Worst case scenario. */
+ return -1;
+#endif
+}
+
+
+static int
+do_always_noconv (struct _IO_codecvt *codecvt)
+{
+ return 0;
+}
+
+
+static int
+do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
+ const char *from_start, const char *from_end, _IO_size_t max)
+{
+ int result;
+#ifdef _LIBC
+ const unsigned char *cp = (const unsigned char *) from_start;
+ wchar_t to_buf[max];
+ struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
+ int status;
+ size_t written;
+
+ codecvt->__cd_in.__cd.__data[0].__outbuf = (char *) to_buf;
+ codecvt->__cd_in.__cd.__data[0].__outbufend = (char *) &to_buf[max];
+ codecvt->__cd_in.__cd.__data[0].__statep = statep;
+
+ status = (*gs->__fct) (gs, codecvt->__cd_in.__cd.__data, &cp, from_end,
+ &written, 0);
+
+ result = cp - (const unsigned char *) from_start;
+#else
+ /* Decide what to do. */
+ result = 0;
+#endif
+
+ return result;
+}
+
+
+static int
+do_max_length (struct _IO_codecvt *codecvt)
+{
+#ifdef _LIBC
+ return codecvt->__cd_in.__cd.__steps[0].__max_needed_from;
+#else
+ return MB_CUR_MAX;
+#endif
+}
diff --git a/libio/iofwrite.c b/libio/iofwrite.c
index d163d29361..886de7ae35 100644
--- a/libio/iofwrite.c
+++ b/libio/iofwrite.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -33,7 +33,7 @@ _IO_fwrite (buf, size, count, fp)
_IO_FILE *fp;
{
_IO_size_t request = size * count;
- _IO_size_t written;
+ _IO_size_t written = 0;
CHECK_FILE (fp, 0);
/* Many traditional implementations return 0 if size==0 && count > 0,
but ANSI requires us to return count in this case. */
@@ -41,7 +41,8 @@ _IO_fwrite (buf, size, count, fp)
return count;
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
_IO_flockfile (fp);
- written = _IO_sputn (fp, (const char *) buf, request);
+ if (_IO_fwide (fp, -1) == -1)
+ written = _IO_sputn (fp, (const char *) buf, request);
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
if (written == request)
diff --git a/libio/iofwrite_u.c b/libio/iofwrite_u.c
index 38d1bd08a3..acb5b2f527 100644
--- a/libio/iofwrite_u.c
+++ b/libio/iofwrite_u.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -36,15 +36,18 @@ fwrite_unlocked (buf, size, count, fp)
_IO_FILE *fp;
{
_IO_size_t request = size * count;
- _IO_size_t written;
+ _IO_size_t written = 0;
CHECK_FILE (fp, 0);
/* Many traditional implementations return 0 if size==0 && count > 0,
but ANSI requires us to return count in this case. */
if (request == 0)
return count;
- written = _IO_sputn (fp, (const char *) buf, request);
- if (written == request)
- return count;
- else
- return written / size;
+ if (_IO_fwide (fp, -1) == -1)
+ {
+ written = _IO_sputn (fp, (const char *) buf, request);
+ if (written == request)
+ return count;
+ }
+
+ return written / size;
}
diff --git a/libio/iogetwline.c b/libio/iogetwline.c
new file mode 100644
index 0000000000..402158a4ef
--- /dev/null
+++ b/libio/iogetwline.c
@@ -0,0 +1,120 @@
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <string.h>
+#include <wchar.h>
+
+#if defined _LIBC || !_G_HAVE_IO_GETLINE_INFO
+
+_IO_size_t
+_IO_getwline (fp, buf, n, delim, extract_delim)
+ _IO_FILE *fp;
+ wchar_t *buf;
+ _IO_size_t n;
+ wint_t delim;
+ int extract_delim;
+{
+ return _IO_getwline_info (fp, buf, n, delim, extract_delim, (wint_t *) 0);
+}
+
+/* Algorithm based on that used by Berkeley pre-4.4 fgets implementation.
+
+ Read chars into buf (of size n), until delim is seen.
+ Return number of chars read (at most n).
+ Does not put a terminating '\0' in buf.
+ If extract_delim < 0, leave delimiter unread.
+ If extract_delim > 0, insert delim in output. */
+
+_IO_size_t
+_IO_getwline_info (fp, buf, n, delim, extract_delim, eof)
+ _IO_FILE *fp;
+ wchar_t *buf;
+ _IO_size_t n;
+ wint_t delim;
+ int extract_delim;
+ wint_t *eof;
+{
+ wchar_t *ptr = buf;
+ if (eof != NULL)
+ *eof = 0;
+ while (n != 0)
+ {
+ _IO_ssize_t len = (fp->_wide_data->_IO_read_end
+ - fp->_wide_data->_IO_read_ptr);
+ if (len <= 0)
+ {
+ wint_t wc = __wuflow (fp);
+ if (wc == WEOF)
+ {
+ if (eof)
+ *eof = wc;
+ break;
+ }
+ if (wc == delim)
+ {
+ if (extract_delim > 0)
+ *ptr++ = wc;
+ else if (extract_delim < 0)
+ _IO_sputbackc (fp, wc);
+ return ptr - buf;
+ if (extract_delim > 0)
+ ++len;
+ }
+ *ptr++ = wc;
+ n--;
+ }
+ else
+ {
+ wchar_t *t;
+ if ((_IO_size_t) len >= n)
+ len = n;
+ t = (wchar_t *) memchr ((void *) fp->_wide_data->_IO_read_ptr,
+ delim, len);
+ if (t != NULL)
+ {
+ _IO_size_t old_len = ptr - buf;
+ len = t - fp->_wide_data->_IO_read_ptr;
+ if (extract_delim >= 0)
+ {
+ ++t;
+ if (extract_delim > 0)
+ ++len;
+ }
+ memcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr,
+ len);
+ fp->_wide_data->_IO_read_ptr = t;
+ return old_len + len;
+ }
+ memcpy ((void *) ptr, (void *) fp->_wide_data->_IO_read_ptr, len);
+ fp->_wide_data->_IO_read_ptr += len;
+ ptr += len;
+ n -= len;
+ }
+ }
+ return ptr - buf;
+}
+
+#endif /* Defined _LIBC || !_G_HAVE_IO_GETLINE_INFO */
diff --git a/libio/iolibio.h b/libio/iolibio.h
index 7b25b40212..92f25cf9f9 100644
--- a/libio/iolibio.h
+++ b/libio/iolibio.h
@@ -41,13 +41,15 @@ extern int _IO_sprintf __P((char *, const char*, ...));
extern int _IO_ungetc __P((int, _IO_FILE*));
extern int _IO_vsscanf __P((const char *, const char *, _IO_va_list));
extern int _IO_vsprintf __P((char*, const char*, _IO_va_list));
+extern int _IO_vswprintf __P((wchar_t*, _IO_size_t, const wchar_t*,
+ _IO_va_list));
struct obstack;
extern int _IO_obstack_vprintf __P ((struct obstack *, const char *,
_IO_va_list));
extern int _IO_obstack_printf __P ((struct obstack *, const char *, ...));
#ifndef _IO_pos_BAD
-#define _IO_pos_BAD ((_IO_fpos64_t)(-1))
+#define _IO_pos_BAD ((_IO_off64_t)(-1))
#endif
#define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN))
#define _IO_fseek(__fp, __offset, __whence) \
diff --git a/libio/iopopen.c b/libio/iopopen.c
index 6b2d7f5328..15c15023f7 100644
--- a/libio/iopopen.c
+++ b/libio/iopopen.c
@@ -101,6 +101,8 @@ struct _IO_proc_file
};
typedef struct _IO_proc_file _IO_proc_file;
+static struct _IO_jump_t _IO_wproc_jumps;
+
static struct _IO_proc_file *proc_file_chain;
_IO_FILE *
@@ -186,6 +188,7 @@ _IO_new_popen (command, mode)
#ifdef _IO_MTSAFE_IO
_IO_lock_t lock;
#endif
+ struct _IO_wide_data wd;
} *new_f;
_IO_FILE *fp;
@@ -196,7 +199,7 @@ _IO_new_popen (command, mode)
new_f->fpx.file.file._lock = &new_f->lock;
#endif
fp = &new_f->fpx.file.file;
- _IO_init (fp, 0);
+ _IO_no_init (fp, 0, 0, &new_f->wd, &_IO_wproc_jumps);
_IO_JUMPS (fp) = &_IO_proc_jumps;
_IO_new_file_init (fp);
#if !_IO_UNIFIED_JUMPTABLES
@@ -273,6 +276,29 @@ struct _IO_jump_t _IO_proc_jumps = {
JUMP_INIT(imbue, _IO_default_imbue)
};
+static struct _IO_jump_t _IO_wproc_jumps = {
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_new_file_finish),
+ JUMP_INIT(overflow, _IO_new_file_overflow),
+ JUMP_INIT(underflow, _IO_new_file_underflow),
+ JUMP_INIT(uflow, _IO_default_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_new_file_xsputn),
+ JUMP_INIT(xsgetn, _IO_default_xsgetn),
+ JUMP_INIT(seekoff, _IO_new_file_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_new_file_setbuf),
+ JUMP_INIT(sync, _IO_new_file_sync),
+ JUMP_INIT(doallocate, _IO_file_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_new_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_new_proc_close),
+ JUMP_INIT(stat, _IO_file_stat),
+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
+ JUMP_INIT(imbue, _IO_default_imbue)
+};
+
#if defined PIC && DO_VERSIONING
strong_alias (_IO_new_popen, __new_popen)
default_symbol_version (_IO_new_popen, _IO_popen, GLIBC_2.1);
diff --git a/libio/ioputs.c b/libio/ioputs.c
index 9ed8fe60a2..954b0f294f 100644
--- a/libio/ioputs.c
+++ b/libio/ioputs.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -30,16 +30,17 @@ int
_IO_puts (str)
const char *str;
{
- int result;
+ int result = EOF;
_IO_size_t len = strlen (str);
_IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
_IO_stdout);
_IO_flockfile (_IO_stdout);
- if (_IO_sputn (_IO_stdout, str, len) == len
+
+ if (_IO_fwide (_IO_stdout, -1) == -1
+ && _IO_sputn (_IO_stdout, str, len) == len
&& _IO_putc_unlocked ('\n', _IO_stdout) != EOF)
result = len + 1;
- else
- result = EOF;
+
_IO_funlockfile (_IO_stdout);
_IO_cleanup_region_end (0);
return result;
diff --git a/libio/ioseekoff.c b/libio/ioseekoff.c
index 4a951dd7c1..4bd1be1e95 100644
--- a/libio/ioseekoff.c
+++ b/libio/ioseekoff.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -24,27 +24,27 @@
General Public License. */
#include <libioP.h>
-#include <errno.h>
-#ifndef errno
-extern int errno;
-#endif
-#ifndef __set_errno
-# define __set_errno(Val) errno = (Val)
-#endif
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+#ifndef __set_errno
+# define __set_errno(Val) errno = (Val)
+#endif
-_IO_fpos64_t
+_IO_off64_t
_IO_seekoff (fp, offset, dir, mode)
_IO_FILE *fp;
_IO_off64_t offset;
int dir;
int mode;
{
- _IO_fpos64_t retval;
+ _IO_off64_t retval;
- if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end)
- {
- __set_errno (EINVAL);
- return EOF;
+ if (dir != _IO_seek_cur && dir != _IO_seek_set && dir != _IO_seek_end)
+ {
+ __set_errno (EINVAL);
+ return EOF;
}
/* If we have a backup buffer, get rid of it, since the __seekoff
diff --git a/libio/ioseekpos.c b/libio/ioseekpos.c
index c81c333676..3e692dae82 100644
--- a/libio/ioseekpos.c
+++ b/libio/ioseekpos.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -25,13 +25,13 @@
#include <libioP.h>
-_IO_fpos64_t
+_IO_off64_t
_IO_seekpos (fp, pos, mode)
_IO_FILE *fp;
- _IO_fpos64_t pos;
+ _IO_off64_t pos;
int mode;
{
- _IO_fpos64_t retval;
+ _IO_off64_t retval;
/* If we have a backup buffer, get rid of it, since the __seekoff
callback may not know to do the right thing about it.
diff --git a/libio/iosetbuffer.c b/libio/iosetbuffer.c
index d615da570c..d119cd0032 100644
--- a/libio/iosetbuffer.c
+++ b/libio/iosetbuffer.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -38,6 +38,9 @@ _IO_setbuffer (fp, buf, size)
if (!buf)
size = 0;
(void) _IO_SETBUF (fp, buf, size);
+ if (fp->_mode == 0)
+ /* We also have to set the buffer using the wide char function. */
+ (*fp->_wide_data->_wide_vtable->__setbuf) (fp, buf, size);
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
}
diff --git a/libio/iosetvbuf.c b/libio/iosetvbuf.c
index 02f4eefb5e..b9ef31a278 100644
--- a/libio/iosetvbuf.c
+++ b/libio/iosetvbuf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -90,6 +90,10 @@ _IO_setvbuf (fp, buf, mode, size)
goto unlock_return;
}
result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;
+ if (result == 0 && fp->_mode > 0)
+ /* We also have to set the buffer using the wide char function. */
+ result = ((*fp->_wide_data->_wide_vtable->__setbuf) (fp, buf, size) == NULL
+ ? EOF : 0);
unlock_return:
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
diff --git a/libio/ioungetwc.c b/libio/ioungetwc.c
new file mode 100644
index 0000000000..88b4162c32
--- /dev/null
+++ b/libio/ioungetwc.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1993, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+wint_t
+ungetwc (c, fp)
+ wint_t c;
+ _IO_FILE *fp;
+{
+ int result;
+ CHECK_FILE (fp, WEOF);
+ if (c == WEOF)
+ return WEOF;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_sputbackwc (fp, c);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+}
diff --git a/libio/iovdprintf.c b/libio/iovdprintf.c
index d95af4742f..b951006975 100644
--- a/libio/iovdprintf.c
+++ b/libio/iovdprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -36,12 +36,13 @@ _IO_vdprintf (d, format, arg)
#ifdef _IO_MTSAFE_IO
_IO_lock_t lock;
#endif
+ struct _IO_wide_data wd;
int done;
#ifdef _IO_MTSAFE_IO
tmpfil.file._lock = &lock;
#endif
- _IO_init (&tmpfil.file, 0);
+ _IO_no_init (&tmpfil.file, 0, 0, &wd, &_IO_wfile_jumps);
_IO_JUMPS (&tmpfil.file) = &_IO_file_jumps;
_IO_file_init (&tmpfil.file);
#if !_IO_UNIFIED_JUMPTABLES
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
index a1ece2da47..84c24d8d59 100644
--- a/libio/iovsprintf.c
+++ b/libio/iovsprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -41,7 +41,7 @@ _IO_vsprintf (string, format, args)
#ifdef _IO_MTSAFE_IO
sf._sbf._f._lock = &lock;
#endif
- _IO_init (&sf._sbf._f, 0);
+ _IO_no_init (&sf._sbf._f, 0, -1, NULL, NULL);
_IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps;
_IO_str_init_static (&sf._sbf._f, string, -1, string);
ret = _IO_vfprintf (&sf._sbf._f, format, args);
diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c
index 923e8290a4..2b1e44dfd8 100644
--- a/libio/iovsscanf.c
+++ b/libio/iovsscanf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -38,7 +38,7 @@ _IO_vsscanf (string, format, args)
_IO_lock_t lock;
sf._sbf._f._lock = &lock;
#endif
- _IO_init (&sf._sbf._f, 0);
+ _IO_no_init (&sf._sbf._f, 0, -1, NULL, NULL);
_IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps;
_IO_str_init_static (&sf._sbf._f, (char*)string, 0, NULL);
ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c
new file mode 100644
index 0000000000..f0ab62a19c
--- /dev/null
+++ b/libio/iovswscanf.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "strfile.h"
+#include <wchar.h>
+
+int
+vswscanf (string, format, args)
+ const wchar_t *string;
+ const wchar_t *format;
+ _IO_va_list args;
+{
+ int ret;
+ _IO_strfile sf;
+ struct _IO_wide_data wd;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+ sf._sbf._f._lock = &lock;
+#endif
+ _IO_no_init (&sf._sbf._f, 0, 1, &wd, &_IO_wstr_jumps);
+ _IO_JUMPS (&sf._sbf._f) = &_IO_str_jumps;
+ _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL);
+ ret = _IO_vfwscanf (&sf._sbf._f, format, args, NULL);
+ return ret;
+}
diff --git a/libio/iowpadn.c b/libio/iowpadn.c
new file mode 100644
index 0000000000..b4904589a2
--- /dev/null
+++ b/libio/iowpadn.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+
+#define PADSIZE 16
+static wchar_t const blanks[PADSIZE] =
+{
+ L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' ',
+ L' ', L' ', L' ', L' ', L' ', L' ', L' ', L' '
+};
+static wchar_t const zeroes[PADSIZE] =
+{
+ L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0',
+ L'0', L'0', L'0', L'0', L'0', L'0', L'0', L'0'
+};
+
+_IO_ssize_t
+_IO_wpadn (fp, pad, count)
+ _IO_FILE *fp;
+ wint_t pad;
+ _IO_ssize_t count;
+{
+ wchar_t padbuf[PADSIZE];
+ const wchar_t *padptr;
+ int i;
+ _IO_size_t written = 0;
+ _IO_size_t w;
+
+ if (pad == L' ')
+ padptr = blanks;
+ else if (pad == L'0')
+ padptr = zeroes;
+ else
+ {
+ for (i = PADSIZE; --i >= 0; )
+ padbuf[i] = pad;
+ padptr = padbuf;
+ }
+ for (i = count; i >= PADSIZE; i -= PADSIZE)
+ {
+ w = _IO_sputn (fp, (char *) padptr, PADSIZE);
+ written += w;
+ if (w != PADSIZE)
+ return written;
+ }
+
+ if (i > 0)
+ {
+ w = _IO_sputn (fp, (char *) padptr, i);
+ written += w;
+ }
+ return written;
+}
diff --git a/libio/libio.h b/libio/libio.h
index b4be610fbd..a3852886fc 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -37,10 +37,12 @@
#define _IO_off64_t _G_off64_t
#define _IO_pid_t _G_pid_t
#define _IO_uid_t _G_uid_t
+#define _IO_iconv_t _G_iconv_t
#define _IO_HAVE_SYS_WAIT _G_HAVE_SYS_WAIT
#define _IO_HAVE_ST_BLKSIZE _G_HAVE_ST_BLKSIZE
#define _IO_BUFSIZ _G_BUFSIZ
#define _IO_va_list _G_va_list
+#define _IO_wint_t _G_wint_t
#ifdef _G_NEED_STDARG_H
/* This define avoids name pollution if we're using GNU stdarg.h */
@@ -186,6 +188,70 @@ struct _IO_marker {
#endif
};
+/* This is the structure from the libstdc++ codecvt class. */
+enum __codecvt_result
+{
+ __codecvt_ok,
+ __codecvt_partial,
+ __codecvt_error,
+ __codecvt_noconv
+};
+
+/* The order of the elements in the following struct must match the order
+ of the virtual functions in the libstdc++ codecvt class. */
+struct _IO_codecvt
+{
+ void (*__codecvt_destr) __P ((struct _IO_codecvt *));
+ enum __codecvt_result (*__codecvt_do_out) __P ((struct _IO_codecvt *,
+ __mbstate_t *,
+ const wchar_t *,
+ const wchar_t *,
+ const wchar_t **, char *,
+ char *, char **));
+ enum __codecvt_result (*__codecvt_do_unshift) __P ((struct _IO_codecvt *,
+ __mbstate_t *, char *,
+ char *, char **));
+ enum __codecvt_result (*__codecvt_do_in) __P ((struct _IO_codecvt *,
+ __mbstate_t *,
+ const char *, const char *,
+ const char **, wchar_t *,
+ wchar_t *, wchar_t **));
+ int (*__codecvt_do_encoding) __P ((struct _IO_codecvt *));
+ int (*__codecvt_do_always_noconv) __P ((struct _IO_codecvt *));
+ int (*__codecvt_do_length) __P ((struct _IO_codecvt *, __mbstate_t *,
+ const char *, const char *, _IO_size_t));
+ int (*__codecvt_do_max_length) __P ((struct _IO_codecvt *));
+
+ _IO_iconv_t __cd_in;
+ _IO_iconv_t __cd_out;
+};
+
+/* Extra data for wide character streams. */
+struct _IO_wide_data
+{
+ wchar_t *_IO_read_ptr; /* Current read pointer */
+ wchar_t *_IO_read_end; /* End of get area. */
+ wchar_t *_IO_read_base; /* Start of putback+get area. */
+ wchar_t *_IO_write_base; /* Start of put area. */
+ wchar_t *_IO_write_ptr; /* Current put pointer. */
+ wchar_t *_IO_write_end; /* End of put area. */
+ wchar_t *_IO_buf_base; /* Start of reserve area. */
+ wchar_t *_IO_buf_end; /* End of reserve area. */
+ /* The following fields are used to support backing up and undo. */
+ wchar_t *_IO_save_base; /* Pointer to start of non-current get area. */
+ wchar_t *_IO_backup_base; /* Pointer to first valid character of
+ backup area */
+ wchar_t *_IO_save_end; /* Pointer to end of non-current get area. */
+
+ __mbstate_t _IO_state;
+ __mbstate_t _IO_last_state;
+ struct _IO_codecvt _codecvt;
+
+ wchar_t _shortbuf[1];
+
+ struct _IO_jump_t *_wide_vtable;
+};
+
struct _IO_FILE {
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags
@@ -231,8 +297,12 @@ struct _IO_FILE_complete
#endif
#if defined _G_IO_IO_FILE_VERSION && _G_IO_IO_FILE_VERSION == 0x20001
_IO_off64_t _offset;
+ /* Wide character stream stuff. */
+ struct _IO_codecvt *_codecvt;
+ struct _IO_wide_data *_wide_data;
+ int _mode;
/* Make sure we don't get into trouble again. */
- int _unused2[16];
+ char _unused2[15 * sizeof (int) - 2 * sizeof (void *)];
#endif
};
@@ -318,6 +388,9 @@ extern "C" {
extern int __underflow __P ((_IO_FILE *));
extern int __uflow __P ((_IO_FILE *));
extern int __overflow __P ((_IO_FILE *, int));
+extern _IO_wint_t __wunderflow __P ((_IO_FILE *));
+extern _IO_wint_t __wuflow __P ((_IO_FILE *));
+extern _IO_wint_t __woverflow __P ((_IO_FILE *, _IO_wint_t));
#define _IO_getc_unlocked(_fp) \
((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end ? __uflow (_fp) \
@@ -331,16 +404,44 @@ extern int __overflow __P ((_IO_FILE *, int));
? __overflow (_fp, (unsigned char) (_ch)) \
: (unsigned char) (*(_fp)->_IO_write_ptr++ = (_ch)))
+#define _IO_getwc_unlocked(_fp) \
+ ((_fp)->_wide_data->_IO_read_ptr >= (_fp)->_wide_data->_IO_read_end \
+ ? __wuflow (_fp) : (_IO_wint_t) *(_fp)->_wide_data->_IO_read_ptr++)
+#define _IO_putwc_unlocked(_wch, _fp) \
+ ((_fp)->_wide_data->_IO_write_ptr >= (_fp)->_wide_data->_IO_write_end \
+ ? __woverflow (_fp, _wch) \
+ : (_IO_wint_t) (*(_fp)->_wide_data->_IO_write_ptr++ = (_wch)))
+
#define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
#define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
extern int _IO_getc __P ((_IO_FILE *__fp));
extern int _IO_putc __P ((int __c, _IO_FILE *__fp));
+extern _IO_wint_t _IO_getwc __P ((_IO_FILE *__fp));
+extern _IO_wint_t _IO_putwc __P ((_IO_wint_t __wc, _IO_FILE *__fp));
extern int _IO_feof __P ((_IO_FILE *__fp));
extern int _IO_ferror __P ((_IO_FILE *__fp));
extern int _IO_peekc_locked __P ((_IO_FILE *__fp));
+extern int _IO_fwide __P ((_IO_FILE *__fp, int __mode));
+#if __GNUC__ >= 2
+/* A special optimized version of the function above. It optimizes the
+ case of initializing an unoriented byte stream. */
+# define _IO_fwide(__fp, __mode) \
+ ({ int __result = (__mode); \
+ if (__result < 0) \
+ { \
+ if ((__fp)->_mode == 0) \
+ /* We know that all we have to do is to set the flag. */ \
+ (__fp)->_mode = -1; \
+ __result = (__fp)->_mode; \
+ } \
+ else \
+ __result = _IO_fwide (__fp, __result); \
+ __result; })
+#endif
+
/* This one is for Emacs. */
#define _IO_PENDING_OUTPUT_COUNT(_fp) \
((_fp)->_IO_write_ptr - (_fp)->_IO_write_base)
@@ -362,15 +463,22 @@ extern int _IO_ftrylockfile __P ((_IO_FILE *));
extern int _IO_vfscanf __P ((_IO_FILE * __restrict, const char * __restrict,
_IO_va_list, int *__restrict));
+extern int _IO_vfwscanf __P ((_IO_FILE * __restrict,
+ const wchar_t * __restrict,
+ _IO_va_list, int *__restrict));
extern int _IO_vfprintf __P ((_IO_FILE *__restrict, const char *__restrict,
_IO_va_list));
+extern int _IO_vfwprintf __P ((_IO_FILE *__restrict, const wchar_t *__restrict,
+ _IO_va_list));
extern _IO_ssize_t _IO_padn __P ((_IO_FILE *, int, _IO_ssize_t));
+extern _IO_ssize_t _IO_wpadn __P ((_IO_FILE *, wint_t, _IO_ssize_t));
extern _IO_size_t _IO_sgetn __P ((_IO_FILE *, void *, _IO_size_t));
-extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
-extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int));
+extern _IO_off64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_off64_t _IO_seekpos __P ((_IO_FILE *, _IO_off64_t, int));
extern void _IO_free_backup_area __P ((_IO_FILE *));
+extern void _IO_free_wbackup_area __P ((_IO_FILE *));
#ifdef __cplusplus
}
diff --git a/libio/libioP.h b/libio/libioP.h
index a9577cec74..6ed79b7169 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -70,6 +70,7 @@ extern "C" {
#endif
#define _IO_JUMPS(THIS) ((struct _IO_FILE_plus *) (THIS))->vtable
+#define _IO_WIDE_JUMPS(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable
#if _IO_JUMPS_OFFSET
# define _IO_JUMPS_FUNC(THIS) \
(*(struct _IO_jump_t **) ((void *) &((struct _IO_FILE_plus *) (THIS))->vtable\
@@ -146,8 +147,8 @@ typedef _IO_size_t (*_IO_xsgetn_t) __PMT ((_IO_FILE *FP, void *DATA,
(MODE==1), or the end of the file (MODE==2).
It matches the streambuf::seekoff virtual function.
It is also used for the ANSI fseek function. */
-typedef _IO_fpos64_t (*_IO_seekoff_t) __PMT ((_IO_FILE *FP, _IO_off64_t OFF,
- int DIR, int MODE));
+typedef _IO_off64_t (*_IO_seekoff_t) __PMT ((_IO_FILE *FP, _IO_off64_t OFF,
+ int DIR, int MODE));
#define _IO_SEEKOFF(FP, OFF, DIR, MODE) JUMP3 (__seekoff, FP, OFF, DIR, MODE)
/* The 'seekpos' hook also moves the stream position,
@@ -155,7 +156,7 @@ typedef _IO_fpos64_t (*_IO_seekoff_t) __PMT ((_IO_FILE *FP, _IO_off64_t OFF,
It matches the streambuf::seekpos virtual function.
It is also used for the ANSI fgetpos and fsetpos functions. */
/* The _IO_seek_cur and _IO_seek_end options are not allowed. */
-typedef _IO_fpos64_t (*_IO_seekpos_t) __PMT ((_IO_FILE *, _IO_fpos64_t, int));
+typedef _IO_off64_t (*_IO_seekpos_t) __PMT ((_IO_FILE *, _IO_off64_t, int));
#define _IO_SEEKPOS(FP, POS, FLAGS) JUMP2 (__seekpos, FP, POS, FLAGS)
/* The 'setbuf' hook gives a buffer to the file.
@@ -205,7 +206,7 @@ typedef _IO_ssize_t (*_IO_write_t) __PMT ((_IO_FILE *, const void *,
It generalizes the Unix lseek(2) function.
It matches the streambuf::sys_seek virtual function, which is
specific to this implementation. */
-typedef _IO_fpos64_t (*_IO_seek_t) __PMT ((_IO_FILE *, _IO_off64_t, int));
+typedef _IO_off64_t (*_IO_seek_t) __PMT ((_IO_FILE *, _IO_off64_t, int));
#define _IO_SYSSEEK(FP, OFFSET, MODE) JUMP2 (__seek, FP, OFFSET, MODE)
/* The 'sysclose' hook is used to finalize (close, finish up) an
@@ -282,9 +283,6 @@ struct _IO_FILE_plus
/* Generic functions */
-extern _IO_fpos64_t _IO_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
-extern _IO_fpos64_t _IO_seekpos __P ((_IO_FILE *, _IO_fpos64_t, int));
-
extern void _IO_switch_to_main_get_area __P ((_IO_FILE *));
extern void _IO_switch_to_backup_area __P ((_IO_FILE *));
extern int _IO_switch_to_get_mode __P ((_IO_FILE *));
@@ -299,56 +297,94 @@ extern void _IO_setb __P ((_IO_FILE *, char *, char *, int));
extern unsigned _IO_adjust_column __P ((unsigned, const char *, int));
#define _IO_sputn(__fp, __s, __n) _IO_XSPUTN (__fp, __s, __n)
+extern void _IO_switch_to_main_wget_area __P ((_IO_FILE *));
+extern void _IO_switch_to_wbackup_area __P ((_IO_FILE *));
+extern int _IO_switch_to_wget_mode __P ((_IO_FILE *));
+extern void _IO_wsetb __P ((_IO_FILE *, wchar_t *, wchar_t *, int));
+extern wint_t _IO_sputbackwc __P ((_IO_FILE *, wint_t));
+extern wint_t _IO_sungetwc __P ((_IO_FILE *));
+extern void _IO_wdoallocbuf __P ((_IO_FILE *));
+extern void _IO_unsave_wmarkers __P ((_IO_FILE *));
+extern void _IO_wsetb __P ((_IO_FILE *, wchar_t *, wchar_t *, int));
+extern unsigned _IO_adjust_wcolumn __P ((unsigned, const wchar_t *, int));
+
/* Marker-related function. */
extern void _IO_init_marker __P ((struct _IO_marker *, _IO_FILE *));
+extern void _IO_init_wmarker __P ((struct _IO_marker *, _IO_FILE *));
extern void _IO_remove_marker __P ((struct _IO_marker *));
extern int _IO_marker_difference __P ((struct _IO_marker *,
struct _IO_marker *));
extern int _IO_marker_delta __P ((struct _IO_marker *));
+extern int _IO_wmarker_delta __P ((struct _IO_marker *));
extern int _IO_seekmark __P ((_IO_FILE *, struct _IO_marker *, int));
+extern int _IO_seekwmark __P ((_IO_FILE *, struct _IO_marker *, int));
/* Default jumptable functions. */
extern int _IO_default_underflow __P ((_IO_FILE *));
extern int _IO_default_uflow __P ((_IO_FILE *));
+extern wint_t _IO_wdefault_uflow __P ((_IO_FILE *));
extern int _IO_default_doallocate __P ((_IO_FILE *));
+extern int _IO_wdefault_doallocate __P ((_IO_FILE *));
extern void _IO_default_finish __P ((_IO_FILE *, int));
+extern void _IO_wdefault_finish __P ((_IO_FILE *, int));
extern int _IO_default_pbackfail __P ((_IO_FILE *, int));
+extern wint_t _IO_wdefault_pbackfail __P ((_IO_FILE *, wint_t));
extern _IO_FILE* _IO_default_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
+extern _IO_FILE* _IO_wdefault_setbuf __P ((_IO_FILE *, wchar_t *,
+ _IO_ssize_t));
extern _IO_size_t _IO_default_xsputn __P ((_IO_FILE *, const void *,
_IO_size_t));
+extern _IO_size_t _IO_wdefault_xsputn __P ((_IO_FILE *, const void *,
+ _IO_size_t));
extern _IO_size_t _IO_default_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
-extern _IO_fpos64_t _IO_default_seekoff __P ((_IO_FILE *,
- _IO_off64_t, int, int));
-extern _IO_fpos64_t _IO_default_seekpos __P ((_IO_FILE *,
- _IO_fpos64_t, int));
+extern _IO_size_t _IO_wdefault_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
+extern _IO_off64_t _IO_default_seekoff __P ((_IO_FILE *,
+ _IO_off64_t, int, int));
+extern _IO_off64_t _IO_default_seekpos __P ((_IO_FILE *, _IO_off64_t, int));
extern _IO_ssize_t _IO_default_write __P ((_IO_FILE *, const void *,
_IO_ssize_t));
extern _IO_ssize_t _IO_default_read __P ((_IO_FILE *, void *, _IO_ssize_t));
extern int _IO_default_stat __P ((_IO_FILE *, void *));
-extern _IO_fpos64_t _IO_default_seek __P ((_IO_FILE *, _IO_off64_t, int));
+extern _IO_off64_t _IO_default_seek __P ((_IO_FILE *, _IO_off64_t, int));
extern int _IO_default_sync __P ((_IO_FILE *));
#define _IO_default_close ((_IO_close_t) _IO_default_sync)
extern int _IO_default_showmanyc __P ((_IO_FILE *));
extern void _IO_default_imbue __P ((_IO_FILE *, void *));
extern struct _IO_jump_t _IO_file_jumps;
+extern struct _IO_jump_t _IO_wfile_jumps;
extern struct _IO_jump_t _IO_old_file_jumps;
extern struct _IO_jump_t _IO_streambuf_jumps;
extern struct _IO_jump_t _IO_proc_jumps;
extern struct _IO_jump_t _IO_old_proc_jumps;
extern struct _IO_jump_t _IO_str_jumps;
+extern struct _IO_jump_t _IO_wstr_jumps;
extern int _IO_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
extern int _IO_new_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
extern int _IO_old_do_write __P ((_IO_FILE *, const char *, _IO_size_t));
+extern int _IO_wdo_write __P ((_IO_FILE *, const wchar_t *, _IO_size_t));
extern int _IO_flush_all __P ((void));
extern int _IO_cleanup __P ((void));
extern void _IO_flush_all_linebuffered __P ((void));
+extern int _IO_new_fgetpos __P ((_IO_FILE *, _IO_fpos_t *));
+extern int _IO_old_fgetpos __P ((_IO_FILE *, _IO_fpos_t *));
+extern int _IO_new_fsetpos __P ((_IO_FILE *, const _IO_fpos_t *));
+extern int _IO_old_fsetpos __P ((_IO_FILE *, const _IO_fpos_t *));
+extern int _IO_new_fgetpos64 __P ((_IO_FILE *, _IO_fpos64_t *));
+extern int _IO_old_fgetpos64 __P ((_IO_FILE *, _IO_fpos64_t *));
+extern int _IO_new_fsetpos64 __P ((_IO_FILE *, const _IO_fpos64_t *));
+extern int _IO_old_fsetpos64 __P ((_IO_FILE *, const _IO_fpos64_t *));
+
#define _IO_do_flush(_f) \
- _IO_do_write(_f, (_f)->_IO_write_base, \
- (_f)->_IO_write_ptr-(_f)->_IO_write_base)
+ ((_f)->_mode <= 0 \
+ ? _IO_do_write(_f, (_f)->_IO_write_base, \
+ (_f)->_IO_write_ptr-(_f)->_IO_write_base) \
+ : _IO_wdo_write(_f, (_f)->_wide_data->_IO_write_base, \
+ ((_f)->_wide_data->_IO_write_ptr \
+ - (_f)->_wide_data->_IO_write_base)))
#define _IO_old_do_flush(_f) \
_IO_old_do_write(_f, (_f)->_IO_write_base, \
(_f)->_IO_write_ptr-(_f)->_IO_write_base)
@@ -357,18 +393,29 @@ extern void _IO_flush_all_linebuffered __P ((void));
((fp)->_flags = ((fp)->_flags & ~(mask)) | ((f) & (mask)))
#define _IO_setg(fp, eb, g, eg) ((fp)->_IO_read_base = (eb),\
(fp)->_IO_read_ptr = (g), (fp)->_IO_read_end = (eg))
+#define _IO_wsetg(fp, eb, g, eg) ((fp)->_wide_data->_IO_read_base = (eb),\
+ (fp)->_wide_data->_IO_read_ptr = (g), \
+ (fp)->_wide_data->_IO_read_end = (eg))
#define _IO_setp(__fp, __p, __ep) \
- ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr = __p, (__fp)->_IO_write_end = (__ep))
+ ((__fp)->_IO_write_base = (__fp)->_IO_write_ptr \
+ = __p, (__fp)->_IO_write_end = (__ep))
+#define _IO_wsetp(__fp, __p, __ep) \
+ ((__fp)->_wide_data->_IO_write_base \
+ = (__fp)->_wide_data->_IO_write_ptr = __p, \
+ (__fp)->_wide_data->_IO_write_end = (__ep))
#define _IO_have_backup(fp) ((fp)->_IO_save_base != NULL)
+#define _IO_have_wbackup(fp) ((fp)->_wide_data->_IO_save_base != NULL)
#define _IO_in_backup(fp) ((fp)->_flags & _IO_IN_BACKUP)
#define _IO_have_markers(fp) ((fp)->_markers != NULL)
#define _IO_blen(fp) ((fp)->_IO_buf_end - (fp)->_IO_buf_base)
+#define _IO_wblen(fp) ((fp)->_wide_data->_IO_buf_end \
+ - (fp)->_wide_data->_IO_buf_base)
/* Jumptable functions for files. */
extern int _IO_file_doallocate __P ((_IO_FILE *));
extern _IO_FILE* _IO_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
-extern _IO_fpos64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_off64_t _IO_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
extern _IO_size_t _IO_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t));
extern _IO_size_t _IO_file_xsgetn __P ((_IO_FILE *, void *, _IO_size_t));
extern int _IO_file_stat __P ((_IO_FILE *, void *));
@@ -387,7 +434,7 @@ extern _IO_ssize_t _IO_file_write __P ((_IO_FILE *, const void *,
extern _IO_ssize_t _IO_file_read __P ((_IO_FILE *, void *, _IO_ssize_t));
extern int _IO_file_sync __P ((_IO_FILE *));
extern int _IO_file_close_it __P ((_IO_FILE *));
-extern _IO_fpos64_t _IO_file_seek __P ((_IO_FILE *, _IO_off64_t, int));
+extern _IO_off64_t _IO_file_seek __P ((_IO_FILE *, _IO_off64_t, int));
extern void _IO_file_finish __P ((_IO_FILE *, int));
extern _IO_FILE* _IO_new_file_attach __P ((_IO_FILE *, int));
@@ -395,19 +442,21 @@ extern int _IO_new_file_close_it __P ((_IO_FILE *));
extern void _IO_new_file_finish __P ((_IO_FILE *, int));
extern _IO_FILE* _IO_new_file_fopen __P ((_IO_FILE *, const char *, const char *,
int));
+extern void _IO_no_init __P ((_IO_FILE *, int, int, struct _IO_wide_data *,
+ struct _IO_jump_t *));
extern void _IO_new_file_init __P ((_IO_FILE *));
extern _IO_FILE* _IO_new_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
extern int _IO_new_file_sync __P ((_IO_FILE *));
extern int _IO_new_file_underflow __P ((_IO_FILE *));
extern int _IO_new_file_overflow __P ((_IO_FILE *, int));
-extern _IO_fpos64_t _IO_new_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_off64_t _IO_new_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
extern _IO_ssize_t _IO_new_file_write __P ((_IO_FILE *, const void *,
_IO_ssize_t));
extern _IO_size_t _IO_new_file_xsputn __P ((_IO_FILE *, const void *, _IO_size_t));
extern _IO_FILE* _IO_old_file_setbuf __P ((_IO_FILE *, char *, _IO_ssize_t));
-extern _IO_fpos64_t _IO_old_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int,
- int));
+extern _IO_off64_t _IO_old_file_seekoff __P ((_IO_FILE *, _IO_off64_t, int,
+ int));
extern _IO_size_t _IO_old_file_xsputn __P ((_IO_FILE *, const void *,
_IO_size_t));
extern int _IO_old_file_underflow __P ((_IO_FILE *));
@@ -422,6 +471,15 @@ extern int _IO_old_file_sync __P ((_IO_FILE *));
extern int _IO_old_file_close_it __P ((_IO_FILE *));
extern void _IO_old_file_finish __P ((_IO_FILE *, int));
+extern int _IO_wfile_doallocate __P ((_IO_FILE *));
+extern _IO_size_t _IO_wfile_xsputn __P ((_IO_FILE *, const void *,
+ _IO_size_t));
+extern _IO_FILE* _IO_wfile_setbuf __P ((_IO_FILE *, wchar_t *, _IO_ssize_t));
+extern wint_t _IO_wfile_sync __P ((_IO_FILE *));
+extern wint_t _IO_wfile_underflow __P ((_IO_FILE *));
+extern wint_t _IO_wfile_overflow __P ((_IO_FILE *, wint_t));
+extern _IO_off64_t _IO_wfile_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+
/* Jumptable functions for proc_files. */
extern _IO_FILE* _IO_proc_open __P ((_IO_FILE *, const char *, const char *));
extern _IO_FILE* _IO_new_proc_open __P ((_IO_FILE *, const char *, const char *));
@@ -434,7 +492,7 @@ extern int _IO_old_proc_close __P ((_IO_FILE *));
extern int _IO_str_underflow __P ((_IO_FILE *));
extern int _IO_str_overflow __P ((_IO_FILE *, int));
extern int _IO_str_pbackfail __P ((_IO_FILE *, int));
-extern _IO_fpos64_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_off64_t _IO_str_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
extern void _IO_str_finish __P ((_IO_FILE *, int));
/* Other strfile functions */
@@ -442,6 +500,16 @@ extern void _IO_str_init_static __P ((_IO_FILE *, char *, int, char *));
extern void _IO_str_init_readonly __P ((_IO_FILE *, const char *, int));
extern _IO_ssize_t _IO_str_count __P ((_IO_FILE *));
+/* And the wide character versions. */
+extern void _IO_wstr_init_static __P ((_IO_FILE *, wchar_t *, int, wchar_t *));
+extern void _IO_wstr_init_readonly __P ((_IO_FILE *, const char *, int));
+extern _IO_ssize_t _IO_wstr_count __P ((_IO_FILE *));
+extern _IO_wint_t _IO_wstr_overflow __P ((_IO_FILE *, _IO_wint_t));
+extern _IO_wint_t _IO_wstr_underflow __P ((_IO_FILE *));
+extern _IO_off64_t _IO_wstr_seekoff __P ((_IO_FILE *, _IO_off64_t, int, int));
+extern _IO_wint_t _IO_wstr_pbackfail __P ((_IO_FILE *, _IO_wint_t));
+extern void _IO_wstr_finish __P ((_IO_FILE *, int));
+
extern int _IO_vasprintf __P ((char **result_ptr, __const char *format,
_IO_va_list args));
extern int _IO_vdprintf __P ((int d, __const char *format, _IO_va_list arg));
@@ -453,6 +521,10 @@ extern _IO_size_t _IO_getline __P ((_IO_FILE *,char *, _IO_size_t, int, int));
extern _IO_size_t _IO_getline_info __P ((_IO_FILE *,char *, _IO_size_t,
int, int, int *));
extern _IO_ssize_t _IO_getdelim __P ((char **, _IO_size_t *, int, _IO_FILE *));
+extern _IO_size_t _IO_getwline __P ((_IO_FILE *,wchar_t *, _IO_size_t, wint_t,
+ int));
+extern _IO_size_t _IO_getwline_info __P ((_IO_FILE *,wchar_t *, _IO_size_t,
+ wint_t, int, wint_t *));
extern double _IO_strtod __P ((const char *, char **));
extern char *_IO_dtoa __P ((double __d, int __mode, int __ndigits,
int *__decpt, int *__sign, char **__rve));
@@ -516,7 +588,15 @@ extern void (*_IO_cleanup_registration_needed) __PMT ((void));
(_B) = (char *) mmap (0, ROUND_TO_PAGE (_S), \
PROT_READ | PROT_WRITE, \
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
- if ((_B) == (char *) -1) \
+ if ((_B) == (char *) MAP_FAILED) \
+ return (_R); \
+ } while (0)
+# define ALLOC_WBUF(_B, _S, _R) \
+ do { \
+ (_B) = (wchar_t *) mmap (0, ROUND_TO_PAGE (_S), \
+ PROT_READ | PROT_WRITE, \
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); \
+ if ((_B) == (wchar_t *) MAP_FAILED) \
return (_R); \
} while (0)
@@ -544,26 +624,17 @@ extern int _IO_close __P ((int));
extern int _IO_fstat __P ((int, struct stat *));
extern int _IO_vscanf __P ((const char *, _IO_va_list));
-/* Operations on _IO_fpos64_t.
- Normally, these are trivial, but we provide hooks for configurations
- where an _IO_fpos64_t is a struct.
- Note that _IO_off64_t must be an integral type. */
-
-/* _IO_pos_BAD is an _IO_fpos64_t value indicating error, unknown, or EOF. */
+/* _IO_pos_BAD is an _IO_off64_t value indicating error, unknown, or EOF. */
#ifndef _IO_pos_BAD
-# define _IO_pos_BAD ((_IO_fpos64_t) -1)
+# define _IO_pos_BAD ((_IO_off64_t) -1)
#endif
-/* _IO_pos_as_off converts an _IO_fpos64_t value to an _IO_off64_t value. */
-#ifndef _IO_pos_as_off
-# define _IO_pos_as_off(__pos) ((_IO_off64_t) (__pos))
-#endif
-/* _IO_pos_adjust adjust an _IO_fpos64_t by some number of bytes. */
+/* _IO_pos_adjust adjust an _IO_off64_t by some number of bytes. */
#ifndef _IO_pos_adjust
-# define _IO_pos_adjust(__pos, __delta) ((__pos) += (__delta))
+# define _IO_pos_adjust(pos, delta) ((pos) += (delta))
#endif
-/* _IO_pos_0 is an _IO_fpos64_t value indicating beginning of file. */
+/* _IO_pos_0 is an _IO_off64_t value indicating beginning of file. */
#ifndef _IO_pos_0
-# define _IO_pos_0 ((_IO_fpos64_t) 0)
+# define _IO_pos_0 ((_IO_off64_t) 0)
#endif
#ifdef __cplusplus
@@ -573,15 +644,16 @@ extern int _IO_vscanf __P ((const char *, _IO_va_list));
#ifdef _IO_MTSAFE_IO
/* check following! */
# ifdef _IO_USE_OLD_IO_FILE
-# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
+# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \
0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock }
# else
-# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
+# define FILEBUF_LITERAL(CHAIN, FLAGS, FD, WDP) \
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \
- 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD }
+ 0, _IO_pos_BAD, 0, 0, { 0 }, &_IO_stdfile_##FD##_lock, _IO_pos_BAD,\
+ NULL, WDP, 0 }
# endif
#else
# ifdef _IO_USE_OLD_IO_FILE
@@ -592,7 +664,8 @@ extern int _IO_vscanf __P ((const char *, _IO_va_list));
# define FILEBUF_LITERAL(CHAIN, FLAGS, FD) \
{ _IO_MAGIC+_IO_LINKED+_IO_IS_FILEBUF+FLAGS, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAIN, FD, \
- 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD }
+ 0, _IO_pos_BAD, 0, 0, { 0 }, 0, _IO_pos_BAD, \
+ NULL, WDP, 0 }
# endif
#endif
diff --git a/libio/memstream.c b/libio/memstream.c
index 71aab2f6ea..840d0e6968 100644
--- a/libio/memstream.c
+++ b/libio/memstream.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -32,9 +32,11 @@ struct _IO_FILE_memstream
static int _IO_mem_sync __P ((_IO_FILE* fp));
static void _IO_mem_finish __P ((_IO_FILE* fp, int));
+static int _IO_wmem_sync __P ((_IO_FILE* fp));
+static void _IO_wmem_finish __P ((_IO_FILE* fp, int));
-static const struct _IO_jump_t _IO_mem_jumps =
+static struct _IO_jump_t _IO_mem_jumps =
{
JUMP_INIT_DUMMY,
JUMP_INIT (finish, _IO_mem_finish),
@@ -58,6 +60,30 @@ static const struct _IO_jump_t _IO_mem_jumps =
JUMP_INIT(imbue, _IO_default_imbue)
};
+static struct _IO_jump_t _IO_wmem_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT (finish, (_IO_finish_t) _IO_wmem_finish),
+ JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
+ JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
+ JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+ JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
+ JUMP_INIT (xsputn, (_IO_xsputn_t) _IO_wdefault_xsputn),
+ JUMP_INIT (xsgetn, (_IO_xsgetn_t) _IO_wdefault_xsgetn),
+ JUMP_INIT (seekoff, _IO_wstr_seekoff),
+ JUMP_INIT (seekpos, _IO_default_seekpos),
+ JUMP_INIT (setbuf, (_IO_setbuf_t) _IO_wdefault_setbuf),
+ JUMP_INIT (sync, (_IO_sync_t) _IO_wmem_sync),
+ JUMP_INIT (doallocate, _IO_wdefault_doallocate),
+ JUMP_INIT (read, _IO_default_read),
+ JUMP_INIT (write, _IO_default_write),
+ JUMP_INIT (seek, _IO_default_seek),
+ JUMP_INIT (close, _IO_default_close),
+ JUMP_INIT (stat, _IO_default_stat),
+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
+ JUMP_INIT(imbue, _IO_default_imbue)
+};
+
/* Open a stream that writes into a malloc'd buffer that is expanded as
necessary. *BUFLOC and *SIZELOC are updated with the buffer's location
and the number of characters written on fflush or fclose. */
@@ -72,6 +98,7 @@ open_memstream (bufloc, sizeloc)
#ifdef _IO_MTSAFE_IO
_IO_lock_t lock;
#endif
+ struct _IO_wide_data wd;
} *new_f;
char *buf;
@@ -85,7 +112,7 @@ open_memstream (bufloc, sizeloc)
buf = malloc (_IO_BUFSIZ);
if (buf == NULL)
return NULL;
- _IO_init (&new_f->fp._sf._sbf._f, 0);
+ _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps);
_IO_JUMPS (&new_f->fp._sf._sbf._f) = &_IO_mem_jumps;
_IO_str_init_static (&new_f->fp._sf._sbf._f, buf, _IO_BUFSIZ, buf);
new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
@@ -144,3 +171,55 @@ _IO_mem_finish (fp, dummy)
_IO_default_finish (fp, 0);
}
+
+
+static int
+_IO_wmem_sync (fp)
+ _IO_FILE* fp;
+{
+ struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
+ int res;
+
+ res = _IO_default_sync (fp);
+ if (res < 0)
+ return res;
+
+ if (fp->_wide_data->_IO_write_ptr == fp->_wide_data->_IO_write_end)
+ {
+ _IO_wstr_overflow (fp, L'\0');
+ --fp->_wide_data->_IO_write_ptr;
+ }
+ else
+ *fp->_wide_data->_IO_write_ptr = '\0';
+
+ *mp->bufloc = (char *) fp->_wide_data->_IO_write_base;
+ *mp->sizeloc = (fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base);
+
+ return 0;
+}
+
+
+static void
+_IO_wmem_finish (fp, dummy)
+ _IO_FILE* fp;
+ int dummy;
+{
+ struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
+
+ *mp->bufloc = (char *) realloc (fp->_wide_data->_IO_write_base,
+ (fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base + 1)
+ * sizeof (wchar_t));
+ if (*mp->bufloc != NULL)
+ {
+ ((wchar_t *) (*mp->bufloc))[fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base] = '\0';
+ *mp->sizeloc = (fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base);
+ }
+
+ fp->_wide_data->_IO_buf_base = NULL;
+
+ _IO_default_finish (fp, 0);
+}
diff --git a/libio/obprintf.c b/libio/obprintf.c
index 0e947b25ad..29e09d4281 100644
--- a/libio/obprintf.c
+++ b/libio/obprintf.c
@@ -127,11 +127,11 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
new_f.ofile.file.file._lock = &new_f.lock;
#endif
- _IO_init (&new_f.ofile.file.file, 0);
- _IO_JUMPS (&new_f.ofile.file.file) = &_IO_obstack_jumps;
+ _IO_no_init (&new_f.ofile.file.file, 0, -1, NULL, NULL);
+ _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps;
_IO_str_init_static (&new_f.ofile.file.file, obstack_base (obstack),
- obstack_object_size (obstack) + obstack_room (obstack),
- obstack_next_free (obstack));
+ (obstack_object_size (obstack) +
+ obstack_room (obstack)), obstack_next_free (obstack));
/* Now allocate the rest of the current chunk. */
obstack_blank_fast (obstack,
(new_f.ofile.file.file._IO_write_end
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index fe29a7965b..d65c272d48 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -285,7 +285,7 @@ old_do_write (fp, data, to_do)
fp->_old_offset = _IO_pos_BAD;
else if (fp->_IO_read_end != fp->_IO_write_base)
{
- _IO_pos_t new_pos
+ _IO_off_t new_pos
= _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
if (new_pos == _IO_pos_BAD)
return 0;
@@ -449,14 +449,14 @@ _IO_old_file_sync (fp)
return retval;
}
-_IO_fpos64_t
+_IO_off64_t
_IO_old_file_seekoff (fp, offset, dir, mode)
_IO_FILE *fp;
_IO_off64_t offset;
int dir;
int mode;
{
- _IO_pos_t result;
+ _IO_off_t result;
_IO_off64_t delta, new_offset;
long count;
/* POSIX.1 8.2.3.7 says that after a call the fflush() the file
@@ -500,7 +500,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode)
if (fp->_old_offset == _IO_pos_BAD)
goto dumb;
/* Make offset absolute, assuming current pointer is file_ptr(). */
- offset += _IO_pos_as_off (fp->_old_offset);
+ offset += fp->_old_offset;
dir = _IO_seek_set;
break;
@@ -529,7 +529,7 @@ _IO_old_file_seekoff (fp, offset, dir, mode)
&& !_IO_in_backup (fp))
{
/* Offset relative to start of main get area. */
- _IO_pos_t rel_offset = (offset - fp->_old_offset
+ _IO_off_t rel_offset = (offset - fp->_old_offset
+ (fp->_IO_read_end - fp->_IO_read_base));
if (rel_offset >= 0)
{
diff --git a/libio/oldiofgetpos.c b/libio/oldiofgetpos.c
new file mode 100644
index 0000000000..2b4d10ad3e
--- /dev/null
+++ b/libio/oldiofgetpos.c
@@ -0,0 +1,61 @@
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <errno.h>
+
+int
+_IO_old_fgetpos (fp, posp)
+ _IO_FILE *fp;
+ _IO_fpos_t *posp;
+{
+ _IO_off_t pos;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
+ if (_IO_in_backup (fp))
+ pos -= fp->_IO_save_end - fp->_IO_save_base;
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ if (pos == _IO_pos_BAD)
+ {
+ /* ANSI explicitly requires setting errno to a positive value on
+ failure. */
+#ifdef EIO
+ if (errno == 0)
+ __set_errno (EIO);
+#endif
+ return EOF;
+ }
+ posp->__pos = pos;
+ return 0;
+}
+
+#ifdef weak_alias
+symbol_version (_IO_old_fgetpos, _IO_fgetpos, GLIBC_2.0);
+strong_alias (_IO_old_fgetpos, __old_fgetpos)
+symbol_version (__old_fgetpos, fgetpos, GLIBC_2.0);
+#endif
diff --git a/libio/oldiofgetpos64.c b/libio/oldiofgetpos64.c
new file mode 100644
index 0000000000..9695c6f53d
--- /dev/null
+++ b/libio/oldiofgetpos64.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 1993, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <errno.h>
+
+int
+_IO_old_fgetpos64 (fp, posp)
+ _IO_FILE *fp;
+ _IO_fpos64_t *posp;
+{
+#ifdef _G_LSEEK64
+ _IO_off64_t pos;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
+ if (_IO_in_backup (fp))
+ pos -= fp->_IO_save_end - fp->_IO_save_base;
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ if (pos == _IO_pos_BAD)
+ {
+ /* ANSI explicitly requires setting errno to a positive value on
+ failure. */
+#ifdef EIO
+ if (errno == 0)
+ __set_errno (EIO);
+#endif
+ return EOF;
+ }
+ posp->__pos = pos;
+ return 0;
+#else
+ __set_errno (ENOSYS);
+ return EOF;
+#endif
+}
+
+#ifdef weak_alias
+symbol_version (_IO_old_fgetpos64, _IO_fgetpos64, GLIBC_2.0);
+strong_alias (_IO_old_fgetpos64, __old_fgetpos64)
+symbol_version (__old_fgetpos64, fgetpos64, GLIBC_2.0);
+#endif
diff --git a/libio/oldiofsetpos.c b/libio/oldiofsetpos.c
new file mode 100644
index 0000000000..87a78d2eea
--- /dev/null
+++ b/libio/oldiofsetpos.c
@@ -0,0 +1,59 @@
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <libioP.h>
+#include <errno.h>
+
+int
+_IO_old_fsetpos (fp, posp)
+ _IO_FILE *fp;
+ const _IO_fpos_t *posp;
+{
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
+ {
+ /* ANSI explicitly requires setting errno to a positive value on
+ failure. */
+#ifdef EIO
+ if (errno == 0)
+ __set_errno (EIO);
+#endif
+ result = EOF;
+ }
+ else
+ result = 0;
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+}
+
+#ifdef weak_alias
+symbol_version (_IO_old_fsetpos, _IO_fsetpos, GLIBC_2.0);
+strong_alias (_IO_old_fsetpos, __old_fsetpos)
+symbol_version (__old_fsetpos, fsetpos, GLIBC_2.0);
+#endif
diff --git a/libio/oldiofsetpos64.c b/libio/oldiofsetpos64.c
new file mode 100644
index 0000000000..9207dd71bd
--- /dev/null
+++ b/libio/oldiofsetpos64.c
@@ -0,0 +1,64 @@
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <libioP.h>
+#include <errno.h>
+
+int
+_IO_old_fsetpos64 (fp, posp)
+ _IO_FILE *fp;
+ const _IO_fpos64_t *posp;
+{
+#ifdef _G_LSEEK64
+ int result;
+ CHECK_FILE (fp, EOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ if (_IO_seekpos (fp, posp->__pos, _IOS_INPUT|_IOS_OUTPUT) == _IO_pos_BAD)
+ {
+ /* ANSI explicitly requires setting errno to a positive value on
+ failure. */
+#ifdef EIO
+ if (errno == 0)
+ __set_errno (EIO);
+#endif
+ result = EOF;
+ }
+ else
+ result = 0;
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+#else
+ __set_errno (ENOSYS);
+ return EOF;
+#endif
+}
+
+#ifdef weak_alias
+symbol_version (_IO_old_fsetpos64, _IO_fsetpos64, GLIBC_2.0);
+strong_alias (_IO_fsetpos64, __old_fsetpos64)
+symbol_version (__old_fsetpos64, _IO_fsetpos64, GLIBC_2.0);
+#endif
diff --git a/libio/oldstdfiles.c b/libio/oldstdfiles.c
index 7781a17449..3629ab8123 100644
--- a/libio/oldstdfiles.c
+++ b/libio/oldstdfiles.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1994, 1996, 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -37,11 +37,12 @@
#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
struct _IO_FILE_plus NAME \
- = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps};
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps};
#else
#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ static struct _IO_wide_data _IO_wide_data_##FD; \
struct _IO_FILE_plus NAME \
- = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_old_file_jumps};
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps};
#endif
DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
diff --git a/libio/putwc.c b/libio/putwc.c
new file mode 100644
index 0000000000..07557ac8c4
--- /dev/null
+++ b/libio/putwc.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+wint_t
+putwc (wc, fp)
+ wint_t wc;
+ _IO_FILE *fp;
+{
+ wint_t result;
+ CHECK_FILE (fp, WEOF);
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile, fp);
+ _IO_flockfile (fp);
+ result = _IO_putwc_unlocked (wc, fp);
+ _IO_funlockfile (fp);
+ _IO_cleanup_region_end (0);
+ return result;
+}
diff --git a/libio/putwc_u.c b/libio/putwc_u.c
new file mode 100644
index 0000000000..3f7a26fad2
--- /dev/null
+++ b/libio/putwc_u.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+wint_t
+putwc_unlocked (wc, fp)
+ wint_t wc;
+ _IO_FILE *fp;
+{
+ CHECK_FILE (fp, WEOF);
+ return _IO_putc_unlocked (wc, fp);
+}
diff --git a/libio/putwchar.c b/libio/putwchar.c
new file mode 100644
index 0000000000..0a2854f16d
--- /dev/null
+++ b/libio/putwchar.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1991, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+wint_t
+putwchar (wc)
+ wint_t wc;
+{
+ wint_t result;
+ _IO_cleanup_region_start ((void (*) __P ((void *))) _IO_funlockfile,
+ _IO_stdout);
+ _IO_flockfile (_IO_stdout);
+ result = _IO_putwc_unlocked (wc, _IO_stdout);
+ _IO_funlockfile (_IO_stdout);
+ _IO_cleanup_region_end (0);
+ return result;
+}
diff --git a/libio/putwchar_u.c b/libio/putwchar_u.c
new file mode 100644
index 0000000000..0da7dcfa30
--- /dev/null
+++ b/libio/putwchar_u.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "libioP.h"
+#include "stdio.h"
+
+wint_t
+putwchar_unlocked (c)
+ wint_t c;
+{
+ CHECK_FILE (stdout, WEOF);
+ return _IO_putwc_unlocked (wc, stdout);
+}
diff --git a/libio/stdfiles.c b/libio/stdfiles.c
index 8c09c2c441..6feff4d392 100644
--- a/libio/stdfiles.c
+++ b/libio/stdfiles.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1994, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1994, 1996, 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -35,12 +35,18 @@
#ifdef _IO_MTSAFE_IO
#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
+ static struct _IO_wide_data _IO_wide_data_##FD \
+ = { ._wide_vtable = &_IO_wfile_jumps }; \
struct _IO_FILE_plus NAME \
- = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps};
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \
+ &_IO_file_jumps};
#else
#define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
+ static struct _IO_wide_data _IO_wide_data_##FD \
+ = { ._wide_vtable = &_IO_wfile_jumps }; \
struct _IO_FILE_plus NAME \
- = {FILEBUF_LITERAL(CHAIN, FLAGS, FD), &_IO_file_jumps};
+ = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \
+ &_IO_file_jumps};
#endif
DEF_STDFILE(_IO_2_1_stdin_, 0, 0, _IO_NO_WRITES);
diff --git a/libio/strops.c b/libio/strops.c
index c3e245f605..83fd794251 100644
--- a/libio/strops.c
+++ b/libio/strops.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1993, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -147,10 +147,10 @@ _IO_str_overflow (fp, c)
/* __ferror(fp) = 1; */
return EOF;
}
- if (fp->_IO_buf_base)
+ if (old_buf)
{
memcpy (new_buf, old_buf, _IO_blen (fp));
- (*((_IO_strfile *) fp)->_s._free_buffer) (fp->_IO_buf_base);
+ (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
/* Make sure _IO_setb won't try to delete _IO_buf_base. */
fp->_IO_buf_base = NULL;
}
@@ -205,14 +205,14 @@ _IO_str_count (fp)
- fp->_IO_read_base);
}
-_IO_fpos64_t
+_IO_off64_t
_IO_str_seekoff (fp, offset, dir, mode)
_IO_FILE *fp;
_IO_off64_t offset;
int dir;
int mode;
{
- _IO_fpos64_t new_pos;
+ _IO_off64_t new_pos;
if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
diff --git a/libio/swprintf.c b/libio/swprintf.c
new file mode 100644
index 0000000000..f0cb637b27
--- /dev/null
+++ b/libio/swprintf.c
@@ -0,0 +1,38 @@
+/* Copyright (C) 1991, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#include <wchar.h>
+
+/* Write formatted output into S, according to the format string FORMAT. */
+/* VARARGS3 */
+int
+swprintf (s, n, format)
+ wchar_t *s;
+ size_t n;
+ const wchar_t *format;
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+ done = vswprintf (s, n, format, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libio/swscanf.c b/libio/swscanf.c
new file mode 100644
index 0000000000..6876d4b793
--- /dev/null
+++ b/libio/swscanf.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 1991, 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#include <wchar.h>
+
+/* Read formatted input from S, according to the format string FORMAT. */
+/* VARARGS2 */
+int
+swscanf (s, format)
+ const wchar_t *s;
+ const wchar_t *format;
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+ done = vswscanf (s, format, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libio/tst_swprintf.c b/libio/tst_swprintf.c
new file mode 100644
index 0000000000..67d10a006d
--- /dev/null
+++ b/libio/tst_swprintf.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <wchar.h>
+
+int
+main (int argc, char *argv[])
+{
+ wchar_t buf[100];
+ int n;
+ int result = 0;
+
+ puts ("test 1");
+ n = swprintf (buf, sizeof (buf) / sizeof (buf[0]), L"Hello %s", "world");
+ if (n != 11)
+ {
+ printf ("incorrect return value: %d instead of 11\n", n);
+ result = 1;
+ }
+
+ if (wcscmp (buf, L"Hello world") != 0)
+ {
+ printf ("incorrect string: L\"%ls\" instead of L\"Hello world\"\n", buf);
+ result = 1;
+ }
+
+ puts ("test 2");
+ n = swprintf (buf, sizeof (buf) / sizeof (buf[0]), L"Is this >%g< 3.1?",
+ 3.1);
+ if (n != 18)
+{
+ printf ("incorrect return value: %d instead of 18\n", n);
+ result = 1;
+ }
+
+ if (wcscmp (buf, L"Is this >3.1< 3.1?") != 0)
+ {
+ printf ("incorrect string: L\"%ls\" instead of L\"Is this >3.1< 3.1?\"\n",
+ buf);
+ result = 1;
+ }
+
+ return result;
+}
diff --git a/libio/tst_swscanf.c b/libio/tst_swscanf.c
new file mode 100644
index 0000000000..ce56144bb0
--- /dev/null
+++ b/libio/tst_swscanf.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <wchar.h>
+
+int
+main (int argc, char *argv[])
+{
+ const wchar_t in[] = L"7 + 35 is 42";
+ size_t n;
+ int a, b, c;
+ int result = 0;
+ char buf1[20];
+ wchar_t wbuf2[20];
+ char buf3[20];
+ char c4;
+ wchar_t wc5;
+
+ puts ("Test 1");
+ a = b = c = 0;
+ n = swscanf (in, L"%d + %d is %d", &a, &b, &c);
+ if (n != 3 || a + b != c || c != 42)
+ {
+ printf ("*** FAILED, n = %Zu, a = %d, b = %d, c = %d\n", n, a, b, c);
+ result = 1;
+ }
+
+ puts ("Test 2");
+ n = swscanf (L"one two three !!", L"%s %S %s %c%C",
+ buf1, wbuf2, buf3, &c4, &wc5);
+ if (n != 5 || strcmp (buf1, "one") != 0 || wcscmp (wbuf2, L"two") != 0
+ || strcmp (buf3, "three") != 0 || c4 != '!' || wc5 != L'!')
+ {
+ printf ("*** FAILED, n = %Zu, buf1 = \"%s\", wbuf2 = L\"%S\", buf3 = \"%s\", c4 = '%c', wc5 = L'%C'\n",
+ n, buf1, wbuf2, buf3, c4, wc5);
+ result = 1;
+ }
+
+ return result;
+}
diff --git a/libio/tst_wprintf.c b/libio/tst_wprintf.c
new file mode 100644
index 0000000000..0838441d2c
--- /dev/null
+++ b/libio/tst_wprintf.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+#include <wchar.h>
+
+int
+main (int argc, char *argv[])
+{
+ fputws (L"Hello world!\n", stdout);
+ wprintf (L"This %s a %ls string: %d\n", "is", L"mixed", 42);
+ return 0;
+}
diff --git a/libio/tst_wscanf.c b/libio/tst_wscanf.c
new file mode 100644
index 0000000000..719f37867e
--- /dev/null
+++ b/libio/tst_wscanf.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <wchar.h>
+
+int
+main (int argc, char *argv[])
+{
+ int n;
+ int result = 0;
+ char buf1[20];
+ wchar_t wbuf2[20];
+ char c3;
+ wchar_t wc4;
+ int d;
+
+ puts ("Test 1");
+
+ n = wscanf (L"%s %S %c%C %d", buf1, wbuf2, &c3, &wc4, &d);
+
+ if (n != 5 || strcmp (buf1, "Hello") != 0 || wcscmp (wbuf2, L"World") != 0
+ || c3 != '!' || wc4 != L'!' || d != 42)
+ {
+ printf ("*** FAILED, n = %d, buf1 = \"%s\", wbuf2 = L\"%S\", c3 = '%c', wc4 = L'%C', d = %d\n",
+ n, buf1, wbuf2, c3, wc4, d);
+ result = 1;
+ }
+
+ return result;
+}
diff --git a/libio/tst_wscanf.input b/libio/tst_wscanf.input
new file mode 100644
index 0000000000..93e1eb55d4
--- /dev/null
+++ b/libio/tst_wscanf.input
@@ -0,0 +1 @@
+Hello World !! 42
diff --git a/libio/vasprintf.c b/libio/vasprintf.c
index 15513d0fca..a656961167 100644
--- a/libio/vasprintf.c
+++ b/libio/vasprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -49,7 +49,7 @@ _IO_vasprintf (result_ptr, format, args)
#ifdef _IO_MTSAFE_IO
sf._sbf._f._lock = &lock;
#endif
- _IO_init ((_IO_FILE *) &sf, 0);
+ _IO_no_init ((_IO_FILE *) &sf, 0, -1, NULL, NULL);
_IO_JUMPS ((_IO_FILE *) &sf) = &_IO_str_jumps;
_IO_str_init_static ((_IO_FILE *) &sf, string, init_string_size, string);
sf._sbf._f._flags &= ~_IO_USER_BUF;
diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c
index e223e5dec2..2b82df5788 100644
--- a/libio/vsnprintf.c
+++ b/libio/vsnprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU IO Library.
This library is free software; you can redistribute it and/or
@@ -122,7 +122,7 @@ _IO_vsnprintf (string, maxlen, format, args)
maxlen = sizeof (sf.overflow_buf);
}
- _IO_init ((_IO_FILE *) &sf, 0);
+ _IO_no_init ((_IO_FILE *) &sf, 0, -1, NULL, NULL);
_IO_JUMPS ((_IO_FILE *) &sf) = &_IO_strn_jumps;
string[0] = '\0';
_IO_str_init_static ((_IO_FILE *) &sf, string, maxlen - 1, string);
diff --git a/libio/vswprintf.c b/libio/vswprintf.c
new file mode 100644
index 0000000000..addf39089c
--- /dev/null
+++ b/libio/vswprintf.c
@@ -0,0 +1,144 @@
+/* Copyright (C) 1994, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include "strfile.h"
+
+
+typedef struct
+{
+ _IO_strfile f;
+ /* This is used for the characters which do not fit in the buffer
+ provided by the user. */
+ wchar_t overflow_buf[64];
+} _IO_strnfile;
+
+
+static wint_t _IO_wstrn_overflow __P ((_IO_FILE *fp, wint_t c));
+
+static wint_t
+_IO_wstrn_overflow (fp, c)
+ _IO_FILE *fp;
+ wint_t c;
+{
+ /* When we come to here this means the user supplied buffer is
+ filled. But since we must return the number of characters which
+ would have been written in total we must provide a buffer for
+ further use. We can do this by writing on and on in the overflow
+ buffer in the _IO_strnfile structure. */
+ _IO_strnfile *snf = (_IO_strnfile *) fp;
+
+ if (fp->_wide_data->_IO_buf_base != snf->overflow_buf)
+ {
+ /* Terminate the string. We know that there is room for at
+ least one more character since we initialized the stream with
+ a size to make this possible. */
+ *fp->_wide_data->_IO_write_ptr = '\0';
+
+ _IO_wsetb (fp, snf->overflow_buf,
+ snf->overflow_buf + (sizeof (snf->overflow_buf)
+ / sizeof (wchar_t)), 0);
+
+ fp->_wide_data->_IO_write_base = snf->overflow_buf;
+ fp->_wide_data->_IO_read_base = snf->overflow_buf;
+ fp->_wide_data->_IO_read_ptr = snf->overflow_buf;
+ fp->_wide_data->_IO_read_end = (snf->overflow_buf
+ + (sizeof (snf->overflow_buf)
+ / sizeof (wchar_t)));
+ }
+
+ fp->_wide_data->_IO_write_ptr = snf->overflow_buf;
+ fp->_wide_data->_IO_write_end = snf->overflow_buf;
+
+ /* Since we are not really interested in storing the characters
+ which do not fit in the buffer we simply ignore it. */
+ return c;
+}
+
+
+static struct _IO_jump_t _IO_wstrn_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_wstr_finish),
+ JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstrn_overflow),
+ JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow),
+ JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+ JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
+ JUMP_INIT(xsputn, _IO_wdefault_xsputn),
+ JUMP_INIT(xsgetn, _IO_wdefault_xsgetn),
+ JUMP_INIT(seekoff, _IO_wstr_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_wdefault_setbuf),
+ JUMP_INIT(sync, _IO_default_sync),
+ JUMP_INIT(doallocate, _IO_wdefault_doallocate),
+ JUMP_INIT(read, _IO_default_read),
+ JUMP_INIT(write, _IO_default_write),
+ JUMP_INIT(seek, _IO_default_seek),
+ JUMP_INIT(close, _IO_default_close),
+ JUMP_INIT(stat, _IO_default_stat),
+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
+ JUMP_INIT(imbue, _IO_default_imbue)
+};
+
+
+int
+_IO_vswprintf (string, maxlen, format, args)
+ wchar_t *string;
+ _IO_size_t maxlen;
+ const wchar_t *format;
+ _IO_va_list args;
+{
+ _IO_strnfile sf;
+ int ret;
+ struct _IO_wide_data wd;
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_t lock;
+ sf.f._sbf._f._lock = &lock;
+#endif
+
+ /* We need to handle the special case where MAXLEN is 0. Use the
+ overflow buffer right from the start. */
+ if (maxlen == 0)
+ {
+ string = sf.overflow_buf;
+ maxlen = sizeof (sf.overflow_buf) / sizeof (wchar_t);
+ }
+
+ _IO_no_init ((_IO_FILE *) &sf, 0, 0, &wd, NULL);
+ _IO_WIDE_JUMPS ((_IO_FILE *) &sf) = &_IO_wstrn_jumps;
+ _IO_fwide (&sf.f._sbf._f, 1);
+ string[0] = L'\0';
+ _IO_wstr_init_static ((_IO_FILE *) &sf, string, maxlen - 1, string);
+ ret = _IO_vfwprintf ((_IO_FILE *) &sf, format, args);
+
+ if (sf.f._sbf._f._wide_data->_IO_buf_base != sf.overflow_buf)
+ *sf.f._sbf._f._wide_data->_IO_write_ptr = '\0';
+ return ret;
+}
+
+#ifdef weak_alias
+weak_alias (_IO_vswprintf, __vswprintf)
+weak_alias (_IO_vswprintf, vswprintf)
+#endif
diff --git a/libio/vwprintf.c b/libio/vwprintf.c
new file mode 100644
index 0000000000..1f3102e4ff
--- /dev/null
+++ b/libio/vwprintf.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991, 1993, 1995, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#undef __OPTIMIZE__ /* Avoid inline `vwprintf' function. */
+#include <stdio.h>
+
+/* Write formatted output to stdout according to the
+ format string FORMAT, using the argument list in ARG. */
+int
+vwprintf (format, arg)
+ const wchar_t *format;
+ __gnuc_va_list arg;
+{
+ return vfwprintf (stdout, format, arg);
+}
diff --git a/libio/vwscanf.c b/libio/vwscanf.c
new file mode 100644
index 0000000000..fb24fc9baa
--- /dev/null
+++ b/libio/vwscanf.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "libioP.h"
+#include <wchar.h>
+
+int
+vwscanf (format, args)
+ const wchar_t *format;
+ _IO_va_list args;
+{
+ return _IO_vfwscanf (_IO_stdin, format, args, NULL);
+}
diff --git a/libio/wfiledoalloc.c b/libio/wfiledoalloc.c
new file mode 100644
index 0000000000..7f5cb7f960
--- /dev/null
+++ b/libio/wfiledoalloc.c
@@ -0,0 +1,105 @@
+/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/*
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Modified for GNU iostream by Per Bothner 1991, 1992. */
+
+#ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+#endif
+#include "libioP.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+
+#ifdef _LIBC
+# undef isatty
+# define isatty(Fd) __isatty (Fd)
+#endif
+
+/*
+ * Allocate a file buffer, or switch to unbuffered I/O.
+ * Per the ANSI C standard, ALL tty devices default to line buffered.
+ *
+ * As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
+ * optimisation) right after the _fstat() that finds the buffer size.
+ */
+
+int
+_IO_wfile_doallocate (fp)
+ _IO_FILE *fp;
+{
+ _IO_size_t size;
+ int couldbetty;
+ wchar_t *p;
+ struct _G_stat64 st;
+
+ /* Allocate room for the external buffer. */
+ _IO_file_doallocate (fp);
+
+ if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0)
+ {
+ couldbetty = 0;
+ size = _IO_BUFSIZ * sizeof (wchar_t);
+#if 0
+ /* do not try to optimise fseek() */
+ fp->_flags |= __SNPT;
+#endif
+ }
+ else
+ {
+ couldbetty = S_ISCHR (st.st_mode);
+#if _IO_HAVE_ST_BLKSIZE
+ size = ((st.st_blksize <= 0 ? _IO_BUFSIZ : st.st_blksize)
+ * sizeof (wchar_t));
+#else
+ size = _IO_BUFSIZ * sizeof (wchar_t);
+#endif
+ }
+ ALLOC_WBUF (p, size, EOF);
+ _IO_wsetb (fp, p, p + size, 1);
+ if (couldbetty && isatty (fp->_fileno))
+ fp->_flags |= _IO_LINE_BUF;
+ return 1;
+}
diff --git a/libio/wfileops.c b/libio/wfileops.c
new file mode 100644
index 0000000000..b040b97491
--- /dev/null
+++ b/libio/wfileops.c
@@ -0,0 +1,716 @@
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+ Written by Ulrich Drepper <drepper@cygnus.com>.
+ Based on the single byte version by Per Bothner <bothner@cygnus.com>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include <assert.h>
+#include <libioP.h>
+#include <wchar.h>
+#include <gconv.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+_IO_FILE *
+_IO_wfile_setbuf (fp, p, len)
+ _IO_FILE *fp;
+ wchar_t *p;
+ _IO_ssize_t len;
+{
+ if (_IO_wdefault_setbuf (fp, p, len) == NULL)
+ return NULL;
+
+ fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr =
+ fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_base;
+ _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base,
+ fp->_wide_data->_IO_buf_base);
+
+ return fp;
+}
+
+
+/* Convert TO_DO wide character from DATA to FP.
+ Then mark FP as having empty buffers. */
+int
+_IO_wdo_write (fp, data, to_do)
+ _IO_FILE *fp;
+ const wchar_t *data;
+ _IO_size_t to_do;
+{
+ struct _IO_codecvt *cc = &fp->_wide_data->_codecvt;
+ _IO_size_t count = 0;
+
+ while (to_do > 0)
+ {
+ enum __codecvt_result result;
+ const wchar_t *new_data;
+
+ if (fp->_IO_write_end == fp->_IO_write_ptr)
+ {
+ _IO_new_file_overflow (fp, EOF);
+ assert (fp->_IO_write_end > fp->_IO_write_ptr);
+ }
+
+ /* Now convert from the internal format into the external buffer. */
+ result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state,
+ data, data + to_do, &new_data,
+ fp->_IO_write_ptr,
+ fp->_IO_write_end,
+ &fp->_IO_write_ptr);
+
+ /* Write out what we produced so far. */
+ if (_IO_new_do_write (fp, fp->_IO_write_base,
+ fp->_IO_write_ptr - fp->_IO_write_base) == EOF)
+ /* Something went wrong. */
+ return EOF;
+
+ count += new_data - data;
+ to_do -= new_data - data;
+ data = new_data;
+
+ /* Next see whether we had problems during the conversion. If yes,
+ we cannot go on. */
+ if (result != __codecvt_ok)
+ break;
+ }
+
+ _IO_wsetg (fp, fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base,
+ fp->_wide_data->_IO_buf_base);
+ fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
+ = fp->_wide_data->_IO_buf_base;
+ fp->_wide_data->_IO_write_end = ((fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+ ? fp->_wide_data->_IO_buf_base
+ : fp->_wide_data->_IO_buf_end);
+
+ return count;
+}
+
+
+wint_t
+_IO_wfile_underflow (fp)
+ _IO_FILE *fp;
+{
+ struct _IO_codecvt *cd;
+ enum __codecvt_result status;
+ _IO_ssize_t count;
+ int tries;
+ const char *read_ptr_copy;
+
+ if (fp->_flags & _IO_NO_READS)
+ {
+ __set_errno (EBADF);
+ return WEOF;
+ }
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr;
+
+ cd = &fp->_wide_data->_codecvt;
+
+ /* Maybe there is something left in the external buffer. */
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ {
+ /* Convert it. */
+ size_t avail_bytes = fp->_IO_read_end - fp->_IO_read_ptr;
+
+ if (avail_bytes >= (*cd->__codecvt_do_max_length) (cd))
+ {
+ /* There is more in the external. */
+ const char *read_stop = (const char *) fp->_IO_read_ptr;
+
+ fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+ status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
+ fp->_IO_read_ptr, fp->_IO_read_end,
+ &read_stop,
+ fp->_wide_data->_IO_read_end,
+ fp->_wide_data->_IO_buf_end,
+ &fp->_wide_data->_IO_read_end);
+
+ fp->_IO_read_ptr = (char *) read_stop;
+
+ /* If we managed to generate some text return the next character. */
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr;
+
+ if (status == __codecvt_error)
+ {
+ __set_errno (EILSEQ);
+ fp->_flags |= _IO_ERR_SEEN;
+ return WEOF;
+ }
+ }
+
+ /* Move the remaining content of the read buffer to the beginning. */
+ memmove (fp->_IO_buf_base, fp->_IO_read_ptr,
+ fp->_IO_read_end - fp->_IO_read_ptr);
+ fp->_IO_read_end = (fp->_IO_buf_base
+ + (fp->_IO_read_end - fp->_IO_read_ptr));
+ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
+ }
+ else
+ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end =
+ fp->_IO_buf_base;
+
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end =
+ fp->_IO_buf_base;
+
+ if (fp->_IO_buf_base == NULL)
+ {
+ /* Maybe we already have a push back pointer. */
+ if (fp->_IO_save_base != NULL)
+ {
+ free (fp->_IO_save_base);
+ fp->_flags &= ~_IO_IN_BACKUP;
+ }
+ _IO_doallocbuf (fp);
+ }
+
+ if (fp->_wide_data->_IO_buf_base == NULL)
+ {
+ /* Maybe we already have a push back pointer. */
+ if (fp->_wide_data->_IO_save_base != NULL)
+ {
+ free (fp->_wide_data->_IO_save_base);
+ fp->_flags &= ~_IO_IN_BACKUP;
+ }
+ _IO_wdoallocbuf (fp);
+ }
+
+ /* Flush all line buffered files before reading. */
+ /* FIXME This can/should be moved to genops ?? */
+ if (fp->_flags & (_IO_LINE_BUF|_IO_UNBUFFERED))
+ _IO_flush_all_linebuffered ();
+
+ _IO_switch_to_get_mode (fp);
+
+ fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_buf_base;
+ fp->_IO_read_end = fp->_IO_buf_base;
+ fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end
+ = fp->_IO_buf_base;
+
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
+ fp->_wide_data->_IO_buf_base;
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_buf_base;
+ fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr =
+ fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_base;
+
+ tries = 0;
+ again:
+ count = _IO_SYSREAD (fp, fp->_IO_read_end,
+ fp->_IO_buf_end - fp->_IO_read_end);
+ if (count <= 0)
+ {
+ if (count == 0 && tries == 0)
+ fp->_flags |= _IO_EOF_SEEN;
+ else
+ fp->_flags |= _IO_ERR_SEEN, count = 0;
+ }
+ fp->_IO_read_end += count;
+ if (count == 0)
+ {
+ if (tries != 0)
+ /* There are some bytes in the external buffer but they don't
+ convert to anything. */
+ __set_errno (EILSEQ);
+ return WEOF;
+ }
+ if (fp->_offset != _IO_pos_BAD)
+ _IO_pos_adjust (fp->_offset, count);
+
+ /* Now convert the read input. */
+ fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+ fp->_IO_read_base = fp->_IO_read_ptr;
+ status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
+ fp->_IO_read_ptr, fp->_IO_read_end,
+ &read_ptr_copy,
+ fp->_wide_data->_IO_read_end,
+ fp->_wide_data->_IO_buf_end,
+ &fp->_wide_data->_IO_read_end);
+
+ fp->_IO_read_ptr = (char *) read_ptr_copy;
+ if (fp->_wide_data->_IO_read_end == fp->_wide_data->_IO_buf_base)
+ {
+ if (status == __codecvt_error || fp->_IO_read_end == fp->_IO_buf_end)
+ {
+ __set_errno (EILSEQ);
+ fp->_flags |= _IO_ERR_SEEN;
+ return WEOF;
+ }
+
+ /* The read bytes make no complete character. Try reading again. */
+ assert (status == __codecvt_partial);
+ ++tries;
+ goto again;
+ }
+
+ return *fp->_wide_data->_IO_read_ptr;
+}
+
+
+wint_t
+_IO_wfile_overflow (f, wch)
+ _IO_FILE *f;
+ wint_t wch;
+{
+ if (f->_flags & _IO_NO_WRITES) /* SET ERROR */
+ {
+ f->_flags |= _IO_ERR_SEEN;
+ __set_errno (EBADF);
+ return WEOF;
+ }
+ /* If currently reading or no buffer allocated. */
+ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0)
+ {
+ /* Allocate a buffer if needed. */
+ if (f->_wide_data->_IO_write_base == 0)
+ {
+ _IO_wdoallocbuf (f);
+ _IO_wsetg (f, f->_wide_data->_IO_buf_base,
+ f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base);
+ }
+ else
+ {
+ /* Otherwise must be currently reading. If _IO_read_ptr
+ (and hence also _IO_read_end) is at the buffer end,
+ logically slide the buffer forwards one block (by setting
+ the read pointers to all point at the beginning of the
+ block). This makes room for subsequent output.
+ Otherwise, set the read pointers to _IO_read_end (leaving
+ that alone, so it can continue to correspond to the
+ external position). */
+ if (f->_wide_data->_IO_read_ptr == f->_wide_data->_IO_buf_end)
+ {
+ f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base;
+ f->_wide_data->_IO_read_end = f->_wide_data->_IO_read_ptr =
+ f->_wide_data->_IO_buf_base;
+ }
+ }
+ f->_wide_data->_IO_write_ptr = f->_wide_data->_IO_read_ptr;
+ f->_wide_data->_IO_write_base = f->_wide_data->_IO_write_ptr;
+ f->_wide_data->_IO_write_end = f->_wide_data->_IO_buf_end;
+ f->_wide_data->_IO_read_base = f->_wide_data->_IO_read_ptr =
+ f->_wide_data->_IO_read_end;
+
+ f->_flags |= _IO_CURRENTLY_PUTTING;
+ if (f->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
+ f->_wide_data->_IO_write_end = f->_wide_data->_IO_write_ptr;
+ }
+ if (wch == WEOF)
+ return _IO_do_flush (f);
+ if (f->_wide_data->_IO_write_ptr == f->_wide_data->_IO_buf_end )
+ /* Buffer is really full */
+ if (_IO_do_flush (f) == WEOF)
+ return WEOF;
+ *f->_wide_data->_IO_write_ptr++ = wch;
+ if ((f->_flags & _IO_UNBUFFERED)
+ || ((f->_flags & _IO_LINE_BUF) && wch == L'\n'))
+ if (_IO_do_flush (f) == WEOF)
+ return WEOF;
+ return wch;
+}
+
+wint_t
+_IO_wfile_sync (fp)
+ _IO_FILE *fp;
+{
+ _IO_ssize_t delta;
+ wint_t retval = 0;
+
+ /* char* ptr = cur_ptr(); */
+ if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
+ if (_IO_do_flush (fp))
+ return WEOF;
+ delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
+ if (delta != 0)
+ {
+ /* We have to find out how many bytes we have to go back in the
+ external buffer. */
+ struct _IO_codecvt *cv = &fp->_wide_data->_codecvt;
+ _IO_off64_t new_pos;
+
+ int clen = (*cv->__codecvt_do_encoding) (cv);
+
+ if (clen > 0)
+ /* It is easy, a fixed number of input bytes are used for each
+ wide character. */
+ delta *= clen;
+ else
+ {
+ /* We have to find out the hard way how much to back off.
+ To do this we determine how much input we needed to
+ generate the wide characters up to the current reading
+ position. */
+ int nread;
+
+ fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
+ nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
+ fp->_IO_read_base,
+ fp->_IO_read_end, delta);
+ fp->_IO_read_ptr = fp->_IO_read_base + nread;
+ delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
+ }
+
+ new_pos = _IO_SYSSEEK (fp, delta, 1);
+ if (new_pos != (_IO_off64_t) EOF)
+ {
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
+ fp->_IO_read_end = fp->_IO_read_ptr;
+ }
+#ifdef ESPIPE
+ else if (errno == ESPIPE)
+ ; /* Ignore error from unseekable devices. */
+#endif
+ else
+ retval = WEOF;
+ }
+ if (retval != WEOF)
+ fp->_offset = _IO_pos_BAD;
+ /* FIXME: Cleanup - can this be shared? */
+ /* setg(base(), ptr, ptr); */
+ return retval;
+}
+
+_IO_off64_t
+_IO_wfile_seekoff (fp, offset, dir, mode)
+ _IO_FILE *fp;
+ _IO_off64_t offset;
+ int dir;
+ int mode;
+{
+ _IO_off64_t result;
+ _IO_off64_t delta, new_offset;
+ long int count;
+ /* POSIX.1 8.2.3.7 says that after a call the fflush() the file
+ offset of the underlying file must be exact. */
+ int must_be_exact = ((fp->_wide_data->_IO_read_base
+ == fp->_wide_data->_IO_read_end)
+ && (fp->_wide_data->_IO_write_base
+ == fp->_wide_data->_IO_write_ptr));
+
+ if (mode == 0)
+ dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+
+ /* Flush unwritten characters.
+ (This may do an unneeded write if we seek within the buffer.
+ But to be able to switch to reading, we would need to set
+ egptr to ptr. That can't be done in the current design,
+ which assumes file_ptr() is eGptr. Anyway, since we probably
+ end up flushing when we close(), it doesn't make much difference.)
+ FIXME: simulate mem-papped files. */
+
+ if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
+ || _IO_in_put_mode (fp))
+ if (_IO_switch_to_get_mode (fp))
+ return WEOF;
+
+ if (fp->_wide_data->_IO_buf_base == NULL)
+ {
+ /* It could be that we already have a pushback buffer. */
+ if (fp->_wide_data->_IO_read_base != NULL)
+ {
+ free (fp->_wide_data->_IO_read_base);
+ fp->_flags &= ~_IO_IN_BACKUP;
+ }
+ _IO_doallocbuf (fp);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
+ fp->_wide_data->_IO_buf_base);
+ _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
+ fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
+ }
+
+ switch (dir)
+ {
+ struct _IO_codecvt *cv;
+ int clen;
+
+ case _IO_seek_cur:
+ /* Adjust for read-ahead (bytes is buffer). To do this we must
+ find out which position in the external buffer corresponds to
+ the current position in the internal buffer. */
+ cv = &fp->_wide_data->_codecvt;
+ clen = (*cv->__codecvt_do_encoding) (cv);
+
+ if (clen > 0)
+ offset -= (fp->_wide_data->_IO_read_end
+ - fp->_wide_data->_IO_read_ptr) * clen;
+ else
+ {
+ int nread;
+
+ delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
+ fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
+ nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
+ fp->_IO_read_base,
+ fp->_IO_read_end, delta);
+ fp->_IO_read_ptr = fp->_IO_read_base + nread;
+ offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
+ }
+
+ if (fp->_offset == _IO_pos_BAD)
+ goto dumb;
+ /* Make offset absolute, assuming current pointer is file_ptr(). */
+ offset += fp->_offset;
+
+ dir = _IO_seek_set;
+ break;
+ case _IO_seek_set:
+ break;
+ case _IO_seek_end:
+ {
+ struct _G_stat64 st;
+ if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode))
+ {
+ offset += st.st_size;
+ dir = _IO_seek_set;
+ }
+ else
+ goto dumb;
+ }
+ }
+ /* At this point, dir==_IO_seek_set. */
+
+ /* If we are only interested in the current position we've found it now. */
+ if (mode == 0)
+ return offset;
+
+ /* If destination is within current buffer, optimize: */
+ if (fp->_offset != _IO_pos_BAD && fp->_IO_read_base != NULL
+ && !_IO_in_backup (fp))
+ {
+ /* Offset relative to start of main get area. */
+ _IO_off64_t rel_offset = (offset - fp->_offset
+ + (fp->_IO_read_end - fp->_IO_read_base));
+ if (rel_offset >= 0)
+ {
+#if 0
+ if (_IO_in_backup (fp))
+ _IO_switch_to_main_get_area (fp);
+#endif
+ if (rel_offset <= fp->_IO_read_end - fp->_IO_read_base)
+ {
+ fp->_IO_read_ptr = fp->_IO_read_base + rel_offset;
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+
+ /* Now set the pointer for the internal buffer. This
+ might be an iterative process. Though the read
+ pointer is somewhere in the current external buffer
+ this does not mean we can convert this whole buffer
+ at once fitting in the internal buffer. */
+ do
+ {
+
+ }
+ while (0);
+
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ goto resync;
+ }
+#ifdef TODO
+ /* If we have streammarkers, seek forward by reading ahead. */
+ if (_IO_have_markers (fp))
+ {
+ int to_skip = rel_offset
+ - (fp->_IO_read_ptr - fp->_IO_read_base);
+ if (ignore (to_skip) != to_skip)
+ goto dumb;
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ goto resync;
+ }
+#endif
+ }
+#ifdef TODO
+ if (rel_offset < 0 && rel_offset >= Bbase () - Bptr ())
+ {
+ if (!_IO_in_backup (fp))
+ _IO_switch_to_backup_area (fp);
+ gbump (fp->_IO_read_end + rel_offset - fp->_IO_read_ptr);
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ goto resync;
+ }
+#endif
+ }
+
+#ifdef TODO
+ _IO_unsave_markers (fp);
+#endif
+
+ if (fp->_flags & _IO_NO_READS)
+ goto dumb;
+
+ /* Try to seek to a block boundary, to improve kernel page management. */
+ new_offset = offset & ~(fp->_IO_buf_end - fp->_IO_buf_base - 1);
+ delta = offset - new_offset;
+ if (delta > fp->_IO_buf_end - fp->_IO_buf_base)
+ {
+ new_offset = offset;
+ delta = 0;
+ }
+ result = _IO_SYSSEEK (fp, new_offset, 0);
+ if (result < 0)
+ return EOF;
+ if (delta == 0)
+ count = 0;
+ else
+ {
+ count = _IO_SYSREAD (fp, fp->_IO_buf_base,
+ (must_be_exact
+ ? delta : fp->_IO_buf_end - fp->_IO_buf_base));
+ if (count < delta)
+ {
+ /* We weren't allowed to read, but try to seek the remainder. */
+ offset = count == EOF ? delta : delta-count;
+ dir = _IO_seek_cur;
+ goto dumb;
+ }
+ }
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base + delta,
+ fp->_IO_buf_base + count);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ fp->_offset = result + count;
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ return offset;
+ dumb:
+
+ _IO_unsave_markers (fp);
+ result = _IO_SYSSEEK (fp, offset, dir);
+ if (result != EOF)
+ {
+ _IO_mask_flags (fp, 0, _IO_EOF_SEEN);
+ fp->_offset = result;
+ _IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
+ _IO_setp (fp, fp->_IO_buf_base, fp->_IO_buf_base);
+ }
+ return result;
+
+resync:
+ /* We need to do it since it is possible that the file offset in
+ the kernel may be changed behind our back. It may happen when
+ we fopen a file and then do a fork. One process may access the
+ the file and the kernel file offset will be changed. */
+ if (fp->_offset >= 0)
+ _IO_SYSSEEK (fp, fp->_offset, 0);
+
+ return offset;
+}
+
+
+_IO_size_t
+_IO_wfile_xsputn (f, data, n)
+ _IO_FILE *f;
+ const void *data;
+ _IO_size_t n;
+{
+ register const wchar_t *s = (const wchar_t *) data;
+ _IO_size_t to_do = n;
+ int must_flush = 0;
+ _IO_size_t count;
+
+ if (n <= 0)
+ return 0;
+ /* This is an optimized implementation.
+ If the amount to be written straddles a block boundary
+ (or the filebuf is unbuffered), use sys_write directly. */
+
+ /* First figure out how much space is available in the buffer. */
+ count = f->_wide_data->_IO_write_end - f->_wide_data->_IO_write_ptr;
+ if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ count = f->_wide_data->_IO_buf_end - f->_wide_data->_IO_write_ptr;
+ if (count >= n)
+ {
+ register const wchar_t *p;
+ for (p = s + n; p > s; )
+ {
+ if (*--p == L'\n')
+ {
+ count = p - s + 1;
+ must_flush = 1;
+ break;
+ }
+ }
+ }
+ }
+ /* Then fill the buffer. */
+ if (count > 0)
+ {
+ if (count > to_do)
+ count = to_do;
+ if (count > 20)
+ {
+#ifdef _LIBC
+ f->_wide_data->_IO_write_ptr =
+ __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
+#else
+ wmemcpy (f->_wide_data->_IO_write_ptr, s, count);
+ f->_wide_data->_IO_write_ptr += count;
+#endif
+ s += count;
+ }
+ else
+ {
+ register wchar_t *p = f->_wide_data->_IO_write_ptr;
+ register int i = (int) count;
+ while (--i >= 0)
+ *p++ = *s++;
+ f->_wide_data->_IO_write_ptr = p;
+ }
+ to_do -= count;
+ }
+ if (to_do > 0)
+ to_do -= _IO_wdefault_xsputn (f, s, to_do);
+ if (must_flush
+ && f->_wide_data->_IO_write_ptr != f->_wide_data->_IO_write_base)
+ _IO_wdo_write (f, f->_wide_data->_IO_write_base,
+ f->_wide_data->_IO_write_ptr
+ - f->_wide_data->_IO_write_base);
+
+ return n - to_do;
+}
+
+
+struct _IO_jump_t _IO_wfile_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_new_file_finish),
+ JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
+ JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow),
+ JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+ JUMP_INIT(pbackfail, _IO_default_pbackfail),
+ JUMP_INIT(xsputn, _IO_wfile_xsputn),
+ JUMP_INIT(xsgetn, _IO_file_xsgetn),
+ JUMP_INIT(seekoff, _IO_wfile_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_new_file_setbuf),
+ JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
+ JUMP_INIT(doallocate, _IO_wfile_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_new_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_file_close),
+ JUMP_INIT(stat, _IO_file_stat),
+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
+ JUMP_INIT(imbue, _IO_default_imbue)
+};
diff --git a/libio/wgenops.c b/libio/wgenops.c
new file mode 100644
index 0000000000..496d080014
--- /dev/null
+++ b/libio/wgenops.c
@@ -0,0 +1,747 @@
+/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+ Written by Ulrich Drepper <drepper@cygnus.com>.
+ Based on the single byte version by Per Bothner <bothner@cygnus.com>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+/* Generic or default I/O operations. */
+
+#include "libioP.h"
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <wchar.h>
+
+
+
+static int save_for_wbackup __P ((_IO_FILE *fp, wchar_t *end_p))
+#ifdef _LIBC
+ internal_function
+#endif
+ ;
+
+/* Return minimum _pos markers
+ Assumes the current get area is the main get area. */
+_IO_ssize_t _IO_least_wmarker __P ((_IO_FILE *fp, wchar_t *end_p));
+
+_IO_ssize_t
+_IO_least_wmarker (fp, end_p)
+ _IO_FILE *fp;
+ wchar_t *end_p;
+{
+ _IO_ssize_t least_so_far = end_p - fp->_wide_data->_IO_read_base;
+ struct _IO_marker *mark;
+ for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+ if (mark->_pos < least_so_far)
+ least_so_far = mark->_pos;
+ return least_so_far;
+}
+
+/* Switch current get area from backup buffer to (start of) main get area. */
+void
+_IO_switch_to_main_wget_area (fp)
+ _IO_FILE *fp;
+{
+ wchar_t *tmp;
+ fp->_flags &= ~_IO_IN_BACKUP;
+ /* Swap _IO_read_end and _IO_save_end. */
+ tmp = fp->_wide_data->_IO_read_end;
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
+ fp->_wide_data->_IO_save_end= tmp;
+ /* Swap _IO_read_base and _IO_save_base. */
+ tmp = fp->_wide_data->_IO_read_base;
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
+ fp->_wide_data->_IO_save_base = tmp;
+ /* Set _IO_read_ptr. */
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_base;
+}
+
+
+/* Switch current get area from main get area to (end of) backup area. */
+void
+_IO_switch_to_wbackup_area (fp)
+ _IO_FILE *fp;
+{
+ wchar_t *tmp;
+ fp->_flags |= _IO_IN_BACKUP;
+ /* Swap _IO_read_end and _IO_save_end. */
+ tmp = fp->_wide_data->_IO_read_end;
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_save_end;
+ fp->_wide_data->_IO_save_end = tmp;
+ /* Swap _IO_read_base and _IO_save_base. */
+ tmp = fp->_wide_data->_IO_read_base;
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_save_base;
+ fp->_wide_data->_IO_save_base = tmp;
+ /* Set _IO_read_ptr. */
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
+}
+
+
+void
+_IO_wsetb (f, b, eb, a)
+ _IO_FILE *f;
+ wchar_t *b;
+ wchar_t *eb;
+ int a;
+{
+ if (f->_wide_data->_IO_buf_base && !(f->_flags & _IO_USER_BUF))
+ FREE_BUF (f->_wide_data->_IO_buf_base, _IO_wblen (f));
+ f->_wide_data->_IO_buf_base = b;
+ f->_wide_data->_IO_buf_end = eb;
+ if (a)
+ f->_flags &= ~_IO_USER_BUF;
+ else
+ f->_flags |= _IO_USER_BUF;
+}
+
+
+wint_t
+_IO_wdefault_pbackfail (fp, c)
+ _IO_FILE *fp;
+ wint_t c;
+{
+ if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
+ && !_IO_in_backup (fp)
+ && (wint_t) fp->_IO_read_ptr[-1] == c)
+ --fp->_IO_read_ptr;
+ else
+ {
+ /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/
+ if (!_IO_in_backup (fp))
+ {
+ /* We need to keep the invariant that the main get area
+ logically follows the backup area. */
+ if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
+ && _IO_have_wbackup (fp))
+ {
+ if (save_for_wbackup (fp, fp->_wide_data->_IO_read_ptr))
+ return WEOF;
+ }
+ else if (!_IO_have_wbackup (fp))
+ {
+ /* No backup buffer: allocate one. */
+ /* Use nshort buffer, if unused? (probably not) FIXME */
+ int backup_size = 128;
+ wchar_t *bbuf = (wchar_t *) malloc (backup_size
+ * sizeof (wchar_t));
+ if (bbuf == NULL)
+ return WEOF;
+ fp->_wide_data->_IO_save_base = bbuf;
+ fp->_wide_data->_IO_save_end = (fp->_wide_data->_IO_save_base
+ + backup_size);
+ fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_end;
+ }
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr;
+ _IO_switch_to_wbackup_area (fp);
+ }
+ else if (fp->_wide_data->_IO_read_ptr <= fp->_wide_data->_IO_read_base)
+ {
+ /* Increase size of existing backup buffer. */
+ _IO_size_t new_size;
+ _IO_size_t old_size = (fp->_wide_data->_IO_read_end
+ - fp->_wide_data->_IO_read_base);
+ wchar_t *new_buf;
+ new_size = 2 * old_size;
+ new_buf = (wchar_t *) malloc (new_size * sizeof (wchar_t));
+ if (new_buf == NULL)
+ return WEOF;
+ __wmemcpy (new_buf + (new_size - old_size),
+ fp->_wide_data->_IO_read_base, old_size);
+ free (fp->_wide_data->_IO_read_base);
+ _IO_wsetg (fp, new_buf, new_buf + (new_size - old_size),
+ new_buf + new_size);
+ fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_read_ptr;
+ }
+
+ *--fp->_wide_data->_IO_read_ptr = c;
+ }
+ return c;
+}
+
+
+void
+_IO_wdefault_finish (fp, dummy)
+ _IO_FILE *fp;
+ int dummy;
+{
+ struct _IO_marker *mark;
+ if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+ {
+ FREE_BUF (fp->_wide_data->_IO_buf_base,
+ _IO_wblen (fp) * sizeof (wchar_t));
+ fp->_wide_data->_IO_buf_base = fp->_wide_data->_IO_buf_end = NULL;
+ }
+
+ for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+ mark->_sbuf = NULL;
+
+ if (fp->_IO_save_base)
+ {
+ free (fp->_wide_data->_IO_save_base);
+ fp->_IO_save_base = NULL;
+ }
+
+#ifdef _IO_MTSAFE_IO
+ _IO_lock_fini (*fp->_lock);
+#endif
+
+ _IO_un_link (fp);
+}
+
+
+wint_t
+_IO_wdefault_uflow (fp)
+ _IO_FILE *fp;
+{
+ wint_t wch;
+ wch = _IO_UNDERFLOW (fp);
+ if (wch == WEOF)
+ return WEOF;
+ return *fp->_wide_data->_IO_read_ptr++;
+}
+
+
+wint_t
+__woverflow (f, wch)
+ _IO_FILE *f;
+ wint_t wch;
+{
+ if (f->_mode == 0)
+ _IO_fwide (f, 1);
+ return _IO_OVERFLOW (f, wch);
+}
+
+
+wint_t
+__wuflow (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
+ return EOF;
+
+ if (fp->_mode == 0)
+ _IO_fwide (fp, 1);
+ if (_IO_in_put_mode (fp))
+ if (_IO_switch_to_get_mode (fp) == EOF)
+ return WEOF;
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr++;
+ if (_IO_in_backup (fp))
+ {
+ _IO_switch_to_main_wget_area (fp);
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr++;
+ }
+ if (_IO_have_markers (fp))
+ {
+ if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
+ return WEOF;
+ }
+ else if (_IO_have_wbackup (fp))
+ _IO_free_wbackup_area (fp);
+ return _IO_UFLOW (fp);
+}
+
+
+wint_t
+__wunderflow (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1))
+ return EOF;
+
+ if (_IO_in_put_mode (fp))
+ if (_IO_switch_to_wget_mode (fp) == WEOF)
+ return WEOF;
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr;
+ if (_IO_in_backup (fp))
+ {
+ _IO_switch_to_main_wget_area (fp);
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr;
+ }
+ if (_IO_have_markers (fp))
+ {
+ if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end))
+ return EOF;
+ }
+ else if (_IO_have_backup (fp))
+ _IO_free_wbackup_area (fp);
+ return _IO_UNDERFLOW (fp);
+}
+
+
+_IO_size_t
+_IO_wdefault_xsputn (f, data, n)
+ _IO_FILE *f;
+ const void *data;
+ _IO_size_t n;
+{
+ const wchar_t *s = (const wchar_t *) data;
+ _IO_size_t more = n;
+ if (more <= 0)
+ return 0;
+ for (;;)
+ {
+ /* Space available. */
+ _IO_ssize_t count = (f->_wide_data->_IO_write_end
+ - f->_wide_data->_IO_write_ptr);
+ if (count > 0)
+ {
+ if ((_IO_size_t) count > more)
+ count = more;
+ if (count > 20)
+ {
+#ifdef _LIBC
+ f->_wide_data->_IO_write_ptr =
+ __wmempcpy (f->_wide_data->_IO_write_ptr, s, count);
+#else
+ memcpy (f->_wide_data->_IO_write_ptr, s, count);
+ f->_wide_data->_IO_write_ptr += count;
+#endif
+ s += count;
+ }
+ else if (count <= 0)
+ count = 0;
+ else
+ {
+ wchar_t *p = f->_wide_data->_IO_write_ptr;
+ _IO_ssize_t i;
+ for (i = count; --i >= 0; )
+ *p++ = *s++;
+ f->_wide_data->_IO_write_ptr = p;
+ }
+ more -= count;
+ }
+ if (more == 0 || __woverflow (f, *s++) == WEOF)
+ break;
+ more--;
+ }
+ return n - more;
+}
+
+
+_IO_size_t
+_IO_wdefault_xsgetn (fp, data, n)
+ _IO_FILE *fp;
+ void *data;
+ _IO_size_t n;
+{
+ _IO_size_t more = n;
+ wchar_t *s = (wchar_t*) data;
+ for (;;)
+ {
+ /* Data available. */
+ _IO_ssize_t count = (fp->_wide_data->_IO_read_end
+ - fp->_wide_data->_IO_read_ptr);
+ if (count > 0)
+ {
+ if ((_IO_size_t) count > more)
+ count = more;
+ if (count > 20)
+ {
+#ifdef _LIBC
+ s = __wmempcpy (s, fp->_wide_data->_IO_read_ptr, count);
+#else
+ memcpy (s, fp->_wide_data->_IO_read_ptr, count);
+ s += count;
+#endif
+ fp->_wide_data->_IO_read_ptr += count;
+ }
+ else if (count <= 0)
+ count = 0;
+ else
+ {
+ wchar_t *p = fp->_wide_data->_IO_read_ptr;
+ int i = (int) count;
+ while (--i >= 0)
+ *s++ = *p++;
+ fp->_wide_data->_IO_read_ptr = p;
+ }
+ more -= count;
+ }
+ if (more == 0 || __wunderflow (fp) == WEOF)
+ break;
+ }
+ return n - more;
+}
+
+
+void
+_IO_wdoallocbuf (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_wide_data->_IO_buf_base)
+ return;
+ if (!(fp->_flags & _IO_UNBUFFERED))
+ if (_IO_DOALLOCATE (fp) != WEOF)
+ return;
+ _IO_wsetb (fp, fp->_wide_data->_shortbuf, fp->_wide_data->_shortbuf + 1, 0);
+}
+
+
+_IO_FILE *
+_IO_wdefault_setbuf (fp, p, len)
+ _IO_FILE *fp;
+ wchar_t *p;
+ _IO_ssize_t len;
+{
+ if (_IO_SYNC (fp) == EOF)
+ return NULL;
+ if (p == NULL || len == 0)
+ {
+ fp->_flags |= _IO_UNBUFFERED;
+ _IO_wsetb (fp, fp->_wide_data->_shortbuf, fp->_wide_data->_shortbuf + 1,
+ 0);
+ }
+ else
+ {
+ fp->_flags &= ~_IO_UNBUFFERED;
+ _IO_wsetb (fp, p, p + len, 0);
+ }
+ fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
+ = fp->_wide_data->_IO_write_end = 0;
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr
+ = fp->_wide_data->_IO_read_end = 0;
+ return fp;
+}
+
+
+int
+_IO_wdefault_doallocate (fp)
+ _IO_FILE *fp;
+{
+ wchar_t *buf;
+
+ ALLOC_WBUF (buf, _IO_BUFSIZ, EOF);
+ _IO_wsetb (fp, buf, buf + _IO_BUFSIZ, 1);
+ return 1;
+}
+
+
+int
+_IO_switch_to_wget_mode (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base)
+ if (_IO_OVERFLOW (fp, EOF) == EOF)
+ return EOF;
+ if (_IO_in_backup (fp))
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_backup_base;
+ else
+ {
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_buf_base;
+ if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
+ }
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
+
+ fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_write_ptr
+ = fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_read_ptr;
+
+ fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+ return 0;
+}
+
+void
+_IO_free_wbackup_area (fp)
+ _IO_FILE *fp;
+{
+ if (_IO_in_backup (fp))
+ _IO_switch_to_main_wget_area (fp); /* Just in case. */
+ free (fp->_wide_data->_IO_save_base);
+ fp->_wide_data->_IO_save_base = NULL;
+ fp->_wide_data->_IO_save_end = NULL;
+ fp->_wide_data->_IO_backup_base = NULL;
+}
+
+#if 0
+int
+_IO_switch_to_wput_mode (fp)
+ _IO_FILE *fp;
+{
+ fp->_wide_data->_IO_write_base = fp->_wide_data->_IO_read_ptr;
+ fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
+ /* Following is wrong if line- or un-buffered? */
+ fp->_wide_data->_IO_write_end = (fp->_flags & _IO_IN_BACKUP
+ ? fp->_wide_data->_IO_read_end
+ : fp->_wide_data->_IO_buf_end);
+
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_end;
+
+ fp->_flags |= _IO_CURRENTLY_PUTTING;
+ return 0;
+}
+#endif
+
+
+static int
+#ifdef _LIBC
+internal_function
+#endif
+save_for_wbackup (fp, end_p)
+ _IO_FILE *fp;
+ wchar_t *end_p;
+{
+ /* Append [_IO_read_base..end_p] to backup area. */
+ _IO_ssize_t least_mark = _IO_least_wmarker (fp, end_p);
+ /* needed_size is how much space we need in the backup area. */
+ _IO_size_t needed_size = ((end_p - fp->_wide_data->_IO_read_base)
+ - least_mark);
+ /* FIXME: Dubious arithmetic if pointers are NULL */
+ _IO_size_t current_Bsize = (fp->_wide_data->_IO_save_end
+ - fp->_wide_data->_IO_save_base);
+ _IO_size_t avail; /* Extra space available for future expansion. */
+ _IO_ssize_t delta;
+ struct _IO_marker *mark;
+ if (needed_size > current_Bsize)
+ {
+ wchar_t *new_buffer;
+ avail = 100;
+ new_buffer = (wchar_t *) malloc ((avail + needed_size)
+ * sizeof (wchar_t));
+ if (new_buffer == NULL)
+ return EOF; /* FIXME */
+ if (least_mark < 0)
+ {
+#ifdef _LIBC
+ __wmempcpy (__wmempcpy (new_buffer + avail,
+ fp->_wide_data->_IO_save_end + least_mark,
+ -least_mark),
+ fp->_wide_data->_IO_read_base,
+ end_p - fp->_wide_data->_IO_read_base);
+#else
+ memcpy (new_buffer + avail,
+ fp->_wide_data->_IO_save_end + least_mark,
+ -least_mark * sizeof (wchar_t));
+ memcpy (new_buffer + avail - least_mark,
+ fp->_wide_data->_IO_read_base,
+ (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
+#endif
+ }
+ else
+ {
+#ifdef _LIBC
+ __wmemcpy (new_buffer + avail,
+ fp->_wide_data->_IO_read_base + least_mark,
+ needed_size);
+#else
+ memcpy (new_buffer + avail,
+ fp->_wide_data->_IO_read_base + least_mark,
+ needed_size * sizeof (wchar_t));
+#endif
+ }
+ if (fp->_wide_data->_IO_save_base)
+ free (fp->_wide_data->_IO_save_base);
+ fp->_wide_data->_IO_save_base = new_buffer;
+ fp->_wide_data->_IO_save_end = new_buffer + avail + needed_size;
+ }
+ else
+ {
+ avail = current_Bsize - needed_size;
+ if (least_mark < 0)
+ {
+#ifdef _LIBC
+ __wmemmove (fp->_wide_data->_IO_save_base + avail,
+ fp->_wide_data->_IO_save_end + least_mark,
+ -least_mark);
+ __wmemcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
+ fp->_wide_data->_IO_read_base,
+ end_p - fp->_wide_data->_IO_read_base);
+#else
+ memmove (fp->_wide_data->_IO_save_base + avail,
+ fp->_wide_data->_IO_save_end + least_mark,
+ -least_mark * sizeof (wchar_t));
+ memcpy (fp->_wide_data->_IO_save_base + avail - least_mark,
+ fp->_wide_data->_IO_read_base,
+ (end_p - fp->_wide_data->_IO_read_base) * sizeof (wchar_t));
+#endif
+ }
+ else if (needed_size > 0)
+#ifdef _LIBC
+ __wmemcpy (fp->_wide_data->_IO_save_base + avail,
+ fp->_wide_data->_IO_read_base + least_mark,
+ needed_size);
+#else
+ memcpy (fp->_wide_data->_IO_save_base + avail,
+ fp->_wide_data->_IO_read_base + least_mark,
+ needed_size * sizeof (wchar_t));
+#endif
+ }
+ fp->_wide_data->_IO_backup_base = fp->_wide_data->_IO_save_base + avail;
+ /* Adjust all the streammarkers. */
+ delta = end_p - fp->_wide_data->_IO_read_base;
+ for (mark = fp->_markers; mark != NULL; mark = mark->_next)
+ mark->_pos -= delta;
+ return 0;
+}
+
+wint_t
+_IO_sputbackwc (fp, c)
+ _IO_FILE *fp;
+ wint_t c;
+{
+ wint_t result;
+
+ if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base
+ && (wchar_t)fp->_wide_data->_IO_read_ptr[-1] == (wchar_t) c)
+ {
+ fp->_wide_data->_IO_read_ptr--;
+ result = c;
+ }
+ else
+ result = _IO_PBACKFAIL (fp, c);
+
+ if (result != EOF)
+ fp->_flags &= ~_IO_EOF_SEEN;
+
+ return result;
+}
+
+wint_t
+_IO_sungetwc (fp)
+ _IO_FILE *fp;
+{
+ int result;
+
+ if (fp->_wide_data->_IO_read_ptr > fp->_wide_data->_IO_read_base)
+ {
+ fp->_wide_data->_IO_read_ptr--;
+ result = *fp->_wide_data->_IO_read_ptr;
+ }
+ else
+ result = _IO_PBACKFAIL (fp, EOF);
+
+ if (result != WEOF)
+ fp->_flags &= ~_IO_EOF_SEEN;
+
+ return result;
+}
+
+
+unsigned
+_IO_adjust_wcolumn (start, line, count)
+ unsigned start;
+ const wchar_t *line;
+ int count;
+{
+ const wchar_t *ptr = line + count;
+ while (ptr > line)
+ if (*--ptr == L'\n')
+ return line + count - ptr - 1;
+ return start + count;
+}
+
+void
+_IO_init_wmarker (marker, fp)
+ struct _IO_marker *marker;
+ _IO_FILE *fp;
+{
+ marker->_sbuf = fp;
+ if (_IO_in_put_mode (fp))
+ _IO_switch_to_get_mode (fp);
+ if (_IO_in_backup (fp))
+ marker->_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
+ else
+ marker->_pos = (fp->_wide_data->_IO_read_ptr
+ - fp->_wide_data->_IO_read_base);
+
+ /* Should perhaps sort the chain? */
+ marker->_next = fp->_markers;
+ fp->_markers = marker;
+}
+
+#define BAD_DELTA EOF
+
+/* Return difference between MARK and current position of MARK's stream. */
+int
+_IO_wmarker_delta (mark)
+ struct _IO_marker *mark;
+{
+ int cur_pos;
+ if (mark->_sbuf == NULL)
+ return BAD_DELTA;
+ if (_IO_in_backup (mark->_sbuf))
+ cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
+ - mark->_sbuf->_wide_data->_IO_read_end);
+ else
+ cur_pos = (mark->_sbuf->_wide_data->_IO_read_ptr
+ - mark->_sbuf->_wide_data->_IO_read_base);
+ return mark->_pos - cur_pos;
+}
+
+int
+_IO_seekwmark (fp, mark, delta)
+ _IO_FILE *fp;
+ struct _IO_marker *mark;
+ int delta;
+{
+ if (mark->_sbuf != fp)
+ return EOF;
+ if (mark->_pos >= 0)
+ {
+ if (_IO_in_backup (fp))
+ _IO_switch_to_main_wget_area (fp);
+ fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
+ + mark->_pos);
+ }
+ else
+ {
+ if (!_IO_in_backup (fp))
+ _IO_switch_to_wbackup_area (fp);
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end + mark->_pos;
+ }
+ return 0;
+}
+
+void
+_IO_unsave_wmarkers (fp)
+ _IO_FILE *fp;
+{
+ struct _IO_marker *mark = fp->_markers;
+ if (mark)
+ {
+#ifdef TODO
+ streampos offset = seekoff (0, ios::cur, ios::in);
+ if (offset != EOF)
+ {
+ offset += eGptr () - Gbase ();
+ for ( ; mark != NULL; mark = mark->_next)
+ mark->set_streampos (mark->_pos + offset);
+ }
+ else
+ {
+ for ( ; mark != NULL; mark = mark->_next)
+ mark->set_streampos (EOF);
+ }
+#endif
+ fp->_markers = 0;
+ }
+
+ if (_IO_have_backup (fp))
+ _IO_free_wbackup_area (fp);
+}
diff --git a/libio/wprintf.c b/libio/wprintf.c
new file mode 100644
index 0000000000..6fb6c32554
--- /dev/null
+++ b/libio/wprintf.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+/* Write formatted output to stdout from the format string FORMAT. */
+/* VARARGS1 */
+int
+wprintf (const wchar_t *format, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+ done = vfwprintf (stdout, format, arg);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libio/wscanf.c b/libio/wscanf.c
new file mode 100644
index 0000000000..a530d6fcfa
--- /dev/null
+++ b/libio/wscanf.c
@@ -0,0 +1,36 @@
+/* Copyright (C) 1991, 1995, 1996, 1997, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+
+/* Read formatted input from stdin according to the format string FORMAT. */
+/* VARARGS1 */
+int
+wscanf (const wchar_t *format, ...)
+{
+ va_list arg;
+ int done;
+
+ va_start (arg, format);
+ done = _IO_vfwscanf (stdin, format, arg, NULL);
+ va_end (arg);
+
+ return done;
+}
diff --git a/libio/wstrops.c b/libio/wstrops.c
new file mode 100644
index 0000000000..af2c957b05
--- /dev/null
+++ b/libio/wstrops.c
@@ -0,0 +1,330 @@
+/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
+ This file is part of the GNU IO Library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+ MA 02111-1307, USA.
+
+ As a special exception, if you link this library with files
+ compiled with a GNU compiler to produce an executable, this does
+ not cause the resulting executable to be covered by the GNU General
+ Public License. This exception does not however invalidate any
+ other reasons why the executable file might be covered by the GNU
+ General Public License. */
+
+#include "strfile.h"
+#include "libioP.h"
+#include <string.h>
+#include <wchar.h>
+
+#if 0
+/* The following definitions are for exposition only.
+ They map the terminology used in the ANSI/ISO C++ draft standard
+ to the implementation. */
+
+/* allocated: set when a dynamic array object has been allocated, and
+ hence should be freed by the destructor for the strstreambuf object. */
+#define ALLOCATED(FP) ((FP)->_f._IO_buf_base && DYNAMIC(FP))
+
+/* constant: set when the array object has const elements,
+ so the output sequence cannot be written. */
+#define CONSTANT(FP) ((FP)->_f._IO_file_flags & _IO_NO_WRITES)
+
+/* alsize: the suggested minimum size for a dynamic array object. */
+#define ALSIZE(FP) ??? /* not stored */
+
+/* palloc: points to the function to call to allocate a dynamic array object.*/
+#define PALLOC(FP) \
+ ((FP)->_s._allocate_buffer == default_alloc ? 0 : (FP)->_s._allocate_buffer)
+
+/* pfree: points to the function to call to free a dynamic array object. */
+#define PFREE(FP) \
+ ((FP)->_s._free_buffer == default_free ? 0 : (FP)->_s._free_buffer)
+
+#endif
+
+#ifdef TODO
+/* An "unbounded buffer" is when a buffer is supplied, but with no
+ specified length. An example is the buffer argument to sprintf.
+ */
+#endif
+
+void
+_IO_wstr_init_static (fp, ptr, size, pstart)
+ _IO_FILE *fp;
+ wchar_t *ptr;
+ int size;
+ wchar_t *pstart;
+{
+ if (size == 0)
+ size = __wcslen (ptr);
+ else if (size < 0)
+ {
+ /* If size is negative 'the characters are assumed to
+ continue indefinitely.' This is kind of messy ... */
+ int s;
+ size = 512;
+ /* Try increasing powers of 2, as long as we don't wrap around. */
+ for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
+ size = s;
+ /* Try increasing size as much as we can without wrapping around. */
+ for (s = size >> 1; s > 0; s >>= 1)
+ {
+ if (ptr + size + s > ptr)
+ size += s;
+ }
+ }
+ _IO_wsetb (fp, ptr, ptr + size, 0);
+
+ fp->_wide_data->_IO_write_base = ptr;
+ fp->_wide_data->_IO_read_base = ptr;
+ fp->_wide_data->_IO_read_ptr = ptr;
+ if (pstart)
+ {
+ fp->_wide_data->_IO_write_ptr = pstart;
+ fp->_wide_data->_IO_write_end = ptr + size;
+ fp->_wide_data->_IO_read_end = pstart;
+ }
+ else
+ {
+ fp->_wide_data->_IO_write_ptr = ptr;
+ fp->_wide_data->_IO_write_end = ptr;
+ fp->_wide_data->_IO_read_end = ptr + size;
+ }
+ /* A null _allocate_buffer function flags the strfile as being static. */
+ (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0;
+}
+
+void
+_IO_wstr_init_readonly (fp, ptr, size)
+ _IO_FILE *fp;
+ const char *ptr;
+ int size;
+{
+ _IO_wstr_init_static (fp, (wchar_t *) ptr, size, NULL);
+ fp->_IO_file_flags |= _IO_NO_WRITES;
+}
+
+_IO_wint_t
+_IO_wstr_overflow (fp, c)
+ _IO_FILE *fp;
+ _IO_wint_t c;
+{
+ int flush_only = c == WEOF;
+ _IO_size_t pos;
+ if (fp->_flags & _IO_NO_WRITES)
+ return flush_only ? 0 : WEOF;
+ if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ fp->_flags |= _IO_CURRENTLY_PUTTING;
+ fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr;
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end;
+ }
+ pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base;
+ if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only))
+ {
+ if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */
+ return WEOF;
+ else
+ {
+ wchar_t *new_buf;
+ wchar_t *old_buf = fp->_wide_data->_IO_buf_base;
+ _IO_size_t new_size = 2 * _IO_wblen (fp) + 100;
+ new_buf
+ = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size
+ * sizeof (wchar_t));
+ if (new_buf == NULL)
+ {
+ /* __ferror(fp) = 1; */
+ return WEOF;
+ }
+ if (old_buf)
+ {
+ __wmemcpy (new_buf, old_buf, _IO_wblen (fp));
+ (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf);
+ /* Make sure _IO_setb won't try to delete _IO_buf_base. */
+ fp->_wide_data->_IO_buf_base = NULL;
+ }
+ _IO_wsetb (fp, new_buf, new_buf + new_size, 1);
+ fp->_wide_data->_IO_read_base =
+ new_buf + (fp->_wide_data->_IO_read_base - old_buf);
+ fp->_wide_data->_IO_read_ptr =
+ new_buf + (fp->_wide_data->_IO_read_ptr - old_buf);
+ fp->_wide_data->_IO_read_end =
+ new_buf + (fp->_wide_data->_IO_read_end - old_buf);
+ fp->_wide_data->_IO_write_ptr =
+ new_buf + (fp->_wide_data->_IO_write_ptr - old_buf);
+
+ fp->_wide_data->_IO_write_base = new_buf;
+ fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_end;
+ }
+ }
+
+ if (!flush_only)
+ *fp->_wide_data->_IO_write_ptr++ = c;
+ if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
+ return c;
+}
+
+_IO_wint_t
+_IO_wstr_underflow (fp)
+ _IO_FILE *fp;
+{
+ if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end)
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr;
+ if ((fp->_flags & _IO_TIED_PUT_GET) && (fp->_flags & _IO_CURRENTLY_PUTTING))
+ {
+ fp->_flags &= ~_IO_CURRENTLY_PUTTING;
+ fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_write_ptr;
+ fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_end;
+ }
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr;
+ else
+ return WEOF;
+}
+
+/* The size of the valid part of the buffer. */
+
+_IO_ssize_t
+_IO_wstr_count (fp)
+ _IO_FILE *fp;
+{
+ return ((fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end
+ ? fp->_wide_data->_IO_write_ptr : fp->_wide_data->_IO_read_end)
+ - fp->_wide_data->_IO_read_base);
+}
+
+_IO_off64_t
+_IO_wstr_seekoff (fp, offset, dir, mode)
+ _IO_FILE *fp;
+ _IO_off64_t offset;
+ int dir;
+ int mode;
+{
+ _IO_off64_t new_pos;
+
+ if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET))
+ mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT);
+
+ if (mode == 0)
+ {
+ /* Don't move any pointers. But there is no clear indication what
+ mode FP is in. Let's guess. */
+ if (fp->_IO_file_flags & _IO_NO_WRITES)
+ new_pos = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base;
+ else
+ new_pos = (fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base);
+ }
+ else
+ {
+ _IO_ssize_t cur_size = _IO_wstr_count (fp);
+ new_pos = EOF;
+
+ /* Move the get pointer, if requested. */
+ if (mode & _IOS_INPUT)
+ {
+ switch (dir)
+ {
+ case _IO_seek_end:
+ offset += cur_size;
+ break;
+ case _IO_seek_cur:
+ offset += (fp->_wide_data->_IO_read_ptr
+ - fp->_wide_data->_IO_read_base);
+ break;
+ default: /* case _IO_seek_set: */
+ break;
+ }
+ if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+ return EOF;
+ fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base
+ + offset);
+ fp->_wide_data->_IO_read_end = (fp->_wide_data->_IO_read_base
+ + cur_size);
+ new_pos = offset;
+ }
+
+ /* Move the put pointer, if requested. */
+ if (mode & _IOS_OUTPUT)
+ {
+ switch (dir)
+ {
+ case _IO_seek_end:
+ offset += cur_size;
+ break;
+ case _IO_seek_cur:
+ offset += (fp->_wide_data->_IO_write_ptr
+ - fp->_wide_data->_IO_write_base);
+ break;
+ default: /* case _IO_seek_set: */
+ break;
+ }
+ if (offset < 0 || (_IO_ssize_t) offset > cur_size)
+ return EOF;
+ fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base
+ + offset);
+ new_pos = offset;
+ }
+ }
+ return new_pos;
+}
+
+_IO_wint_t
+_IO_wstr_pbackfail (fp, c)
+ _IO_FILE *fp;
+ _IO_wint_t c;
+{
+ if ((fp->_flags & _IO_NO_WRITES) && c != EOF)
+ return WEOF;
+ return _IO_wdefault_pbackfail (fp, c);
+}
+
+void
+_IO_wstr_finish (fp, dummy)
+ _IO_FILE *fp;
+ int dummy;
+{
+ if (fp->_wide_data->_IO_buf_base && !(fp->_flags & _IO_USER_BUF))
+ (((_IO_strfile *) fp)->_s._free_buffer) (fp->_wide_data->_IO_buf_base);
+ fp->_wide_data->_IO_buf_base = NULL;
+
+ _IO_wdefault_finish (fp, 0);
+}
+
+struct _IO_jump_t _IO_wstr_jumps =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_wstr_finish),
+ JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstr_overflow),
+ JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow),
+ JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+ JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
+ JUMP_INIT(xsputn, _IO_wdefault_xsputn),
+ JUMP_INIT(xsgetn, _IO_wdefault_xsgetn),
+ JUMP_INIT(seekoff, _IO_wstr_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_wdefault_setbuf),
+ JUMP_INIT(sync, _IO_default_sync),
+ JUMP_INIT(doallocate, _IO_wdefault_doallocate),
+ JUMP_INIT(read, _IO_default_read),
+ JUMP_INIT(write, _IO_default_write),
+ JUMP_INIT(seek, _IO_default_seek),
+ JUMP_INIT(close, _IO_default_close),
+ JUMP_INIT(stat, _IO_default_stat),
+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
+ JUMP_INIT(imbue, _IO_default_imbue)
+};