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.
This commit is contained in:
Ulrich Drepper 2001-08-09 08:50:50 +00:00
parent 0f78390bd7
commit 40a982a9e1
11 changed files with 152 additions and 23 deletions

View File

@ -1,3 +1,20 @@
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

View File

@ -48,7 +48,7 @@ routines := \
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.
@ -85,6 +85,7 @@ tst-fopenloc-ENV = LOCPATH=$(common-objpfx)localedata \
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

View File

@ -1,4 +1,4 @@
/* 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
@ -44,9 +44,6 @@ ftello (fp)
{
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);

View File

@ -1,4 +1,4 @@
/* 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
@ -45,8 +45,6 @@ ftello64 (fp)
{
if (fp->_mode <= 0)
pos -= fp->_IO_save_end - fp->_IO_save_base;
else
abort ();
}
_IO_funlockfile (fp);
_IO_cleanup_region_end (0);

View File

@ -43,11 +43,8 @@ _IO_new_fgetpos (fp, posp)
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)
{

View File

@ -1,4 +1,4 @@
/* 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
@ -42,7 +42,10 @@ _IO_new_fgetpos64 (fp, posp)
_IO_flockfile (fp);
pos = _IO_seekoff (fp, 0, _IO_seek_cur, 0);
if (_IO_in_backup (fp))
{
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)

View File

@ -1,4 +1,4 @@
/* 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
@ -43,9 +43,6 @@ _IO_ftell (fp)
{
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);

View File

@ -201,6 +201,12 @@ _IO_fwide (fp, mode)
/* 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. */

View File

@ -1,4 +1,4 @@
/* 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
@ -25,6 +25,7 @@
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
@ -58,7 +59,12 @@ _IO_seekoff (fp, offset, dir, mode)
if (mode != 0 && _IO_have_backup (fp))
{
if (dir == _IO_seek_cur && _IO_in_backup (fp))
{
if (fp->_vtable_offset != 0 || fp->_mode <= 0)
offset -= fp->_IO_read_end - fp->_IO_read_ptr;
else
abort ();
}
_IO_free_backup_area (fp);
}

81
libio/tst-ungetwc2.c Normal file
View File

@ -0,0 +1,81 @@
/* 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;
}

View File

@ -458,7 +458,28 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
== fp->_wide_data->_IO_write_ptr));
if (mode == 0)
{
/* 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.
@ -466,7 +487,7 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
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))
@ -509,12 +530,13 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
{
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;
}
@ -651,6 +673,10 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
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;