+2001-08-09 Ulrich Drepper <drepper@redhat.com>
+
+ * libio/wfileops.c (_IO_wfile_seekoff): Don't even try to handle
+ seeking with backup buffer present.
+ Correct determining of internal buffer position.
+ Reset also wide buffers if we reset the internal buffers.
+ * libio/iofwide.c (_IO_fwide): Always determine file offset for wide
+ streams.
+ * libio/ioseekoff.c: Catch one unimplemented case.
+ * libio/ftello.c: Don't abort if the wide stream has backup buffer.
+ * libio/ftello64.c: Likewise.
+ * libio/iofgetpos.c: Likewise.
+ * libio/iofgetpos64.c: Likewise.
+ * libio/ftell.c: Likewise.
+ * libio/Makefile (tests): Add tst-ungetwc2.
+ * libio/tst-ungetwc2.c: New file.
+
2001-08-08 Ulrich Drepper <drepper@redhat.com>
* locale/elem-hash.h (elem_hash): Correct stupid mistake and
tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \
tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-fopenloc \
- tst-fgetws tst-ungetwc1
+ tst-fgetws tst-ungetwc1 tst-ungetwc2
test-srcs = test-freopen
all: # Make this the default target; it will be defined in Rules.
MALLOC_TRACE=$(objpfx)tst-fopenloc.mtrace
tst-fgetws-ENV = LOCPATH=$(common-objpfx)localedata
tst-ungetwc1-ENV = LOCPATH=$(common-objpfx)localedata
+tst-ungetwc2-ENV = LOCPATH=$(common-objpfx)localedata
generated = tst-fopenloc.mtrace tst-fopenloc.check
-/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2000, 2001 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
{
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);
-/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2000, 2001 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
{
if (fp->_mode <= 0)
pos -= fp->_IO_save_end - fp->_IO_save_base;
- else
- abort ();
}
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
if (_IO_in_backup (fp))
{
- if (fp->_vtable_offset != 0 || fp->_mode <= 0)
+ if (fp->_mode <= 0)
pos -= fp->_IO_save_end - fp->_IO_save_base;
- else
- /* XXX For now. */
- abort ();
}
if (pos == _IO_pos_BAD)
{
-/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2000, 2001 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
_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;
+ }
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);
if (pos == _IO_pos_BAD)
-/* Copyright (C) 1993, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1995-2000, 2001 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
{
if (fp->_vtable_offset != 0 || 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);
/* From now on use the wide character callback functions. */
((struct _IO_FILE_plus *) fp)->vtable = fp->_wide_data->_wide_vtable;
+
+ /* One last twist: we get the current stream position. The wide
+ char streams have much more problems with not knowing the
+ current position and so we should disable the optimization
+ which allows the functions without knowing the position. */
+ fp->_offset = _IO_SYSSEEK (fp, 0, 0);
}
/* Set the mode now. */
-/* Copyright (C) 1993, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1993, 1997, 1998, 1999, 2001 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
This exception applies to code released by its copyright holders
in files containing the exception. */
+#include <stdlib.h>
#include <libioP.h>
#include <errno.h>
#ifndef errno
if (mode != 0 && _IO_have_backup (fp))
{
if (dir == _IO_seek_cur && _IO_in_backup (fp))
- offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ {
+ if (fp->_vtable_offset != 0 || fp->_mode <= 0)
+ offset -= fp->_IO_read_end - fp->_IO_read_ptr;
+ else
+ abort ();
+ }
_IO_free_backup_area (fp);
}
--- /dev/null
+/* Taken from the Li18nux base test suite. */
+
+#define _XOPEN_SOURCE 500
+#include <locale.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <wchar.h>
+
+int
+main (void)
+{
+ FILE *fp;
+ char *str = "abcdef";
+ wint_t ret, wc;
+ char fname[] = "/tmp/tst-ungetwc2.out.XXXXXX";
+ int fd;
+ long int pos;
+ int result = 0;
+
+ puts ("This program runs on en_US.UTF-8 locale.");
+ if (setlocale (LC_ALL, "en_US.UTF-8") == NULL)
+ {
+ fprintf (stderr, "Err: Cannot run on the en_US.UTF-8 locale\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Write some characters to `testfile'. */
+ fd = mkstemp (fname);
+ if (fd == -1)
+ {
+ printf ("cannot open temp file: %m\n");
+ exit (EXIT_FAILURE);
+ }
+ if ((fp = fdopen (fd, "w")) == NULL)
+ {
+ fprintf (stderr, "Cannot open 'testfile'.\n");
+ exit (EXIT_FAILURE);
+ }
+ fputs (str, fp);
+ fclose (fp);
+
+ /* Open `testfile'. */
+ if ((fp = fopen (fname, "r")) == NULL)
+ {
+ fprintf (stderr, "Cannot open 'testfile'.");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Get a character. */
+ wc = getwc (fp);
+ pos = ftell (fp);
+ printf ("After get a character: %ld\n", pos);
+ if (pos != 1)
+ result = 1;
+
+ /* Unget a character. */
+ ret = ungetwc (wc, fp);
+ if (ret == WEOF)
+ {
+ fprintf (stderr, "ungetwc() returns NULL.");
+ exit (EXIT_FAILURE);
+ }
+ pos = ftell (fp);
+ printf ("After unget a character: %ld\n", pos);
+ if (pos != 0)
+ result = 1;
+
+ /* Reget a character. */
+ wc = getwc (fp);
+ pos = ftell (fp);
+ printf ("After reget a character: %ld\n", pos);
+ if (pos != 1)
+ result = 1;
+
+ fclose (fp);
+
+ unlink (fname);
+
+ return result;
+}
== fp->_wide_data->_IO_write_ptr));
if (mode == 0)
- dir = _IO_seek_cur, offset = 0; /* Don't move any pointers. */
+ {
+ /* XXX For wide stream with backup store it is not very
+ reasonable to determine the offset. The pushed-back
+ character might require a state change and we need not be
+ able to compute the initial state by reverse transformation
+ since there is no guarantee of symmetry. So we don't even
+ try and return an error. */
+ if (_IO_in_backup (fp))
+ {
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ /* There is no more data in the backup buffer. We can
+ switch back. */
+ _IO_switch_to_main_wget_area (fp);
+ }
+
+ 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.
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. */
+ FIXME: simulate mem-mapped files. */
if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base
|| _IO_in_put_mode (fp))
{
int nread;
- delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_end;
+ delta = fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base;
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;
+ fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
}
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);
+ _IO_wsetg (fp, fp->_wide_data->_IO_buf_base,
+ fp->_wide_data->_IO_buf_base, fp->_wide_data->_IO_buf_base);
+ _IO_wsetp (fp, fp->_wide_data->_IO_buf_base,
+ fp->_wide_data->_IO_buf_base);
}
return result;