]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Update.
authorUlrich Drepper <drepper@redhat.com>
Thu, 9 Aug 2001 08:50:50 +0000 (08:50 +0000)
committerUlrich Drepper <drepper@redhat.com>
Thu, 9 Aug 2001 08:50:50 +0000 (08:50 +0000)
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.

ChangeLog
libio/Makefile
libio/ftello.c
libio/ftello64.c
libio/iofgetpos.c
libio/iofgetpos64.c
libio/ioftell.c
libio/iofwide.c
libio/ioseekoff.c
libio/tst-ungetwc2.c [new file with mode: 0644]
libio/wfileops.c

index 10d448bb8d3e00dbd2ff59775d6a40603f1fb965..95645471274e9d313af839d07ca58f44f90e69a8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 97a8f73e1328a98950d8d97f9c42f2b1794d066b..14eaefcf9089c99549a10ede7ac505d0fe894ca1 100644 (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
 
index 1d030511dd68bfd5baaec25aa893142d5175e58f..6c1f1a670fd5406442ac7122e639b8ec95204533 100644 (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);
index adc1385e1bc743b4745582225deeb69db8ac65f0..cd0670f1f4fa2b0f62065a2a3d592f0422c3b33b 100644 (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);
index b8b2f874a3b70709ec0a1c8ffe9a2b52ae2b84bb..cc7d9e9755d81d86d2b846a40c4188841110b1de 100644 (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)
     {
index 3f29337c7daf510dc4759b987ee820ab10059c0e..179071894e572cd5608b7475a4187dd98aad77db 100644 (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))
-    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)
index 59c8288043902e928f552135b1303659bdc3f8e7..f2abd62ad82b6b3757d58050753ea746db47510c 100644 (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);
index aa314fe6719603105302b543867bd752cfe4a357..88d2d5e56315844e798e89b28e5605672d561a91 100644 (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.  */
index 60249694c09a7437ada016c8955ab283d328b7fe..2111bec7450717a2b230dc79eb0a49320127cb30 100644 (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))
-       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);
     }
 
diff --git a/libio/tst-ungetwc2.c b/libio/tst-ungetwc2.c
new file mode 100644 (file)
index 0000000..9064427
--- /dev/null
@@ -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;
+}
index e88c0654e5453529f6f3e807d1cbbfddc2ea34f6..92d1a08190f0a58c9070d3d09ea998f2ade8c4e1 100644 (file)
@@ -458,7 +458,28 @@ _IO_wfile_seekoff (fp, offset, dir, mode)
                           == 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.
@@ -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;