diff options
author | Ulrich Drepper <drepper@redhat.com> | 2000-07-20 08:56:12 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2000-07-20 08:56:12 +0000 |
commit | 9c38a6899957746cbf2c0c04d110626a9271d51a (patch) | |
tree | 7baeb90b3aff1cf0acf63fed32577f3a9ad17764 /libio | |
parent | 4e8286acfa4224ac9ccfb07e90b8fd70fab1467e (diff) | |
download | glibc-9c38a6899957746cbf2c0c04d110626a9271d51a.tar.gz glibc-9c38a6899957746cbf2c0c04d110626a9271d51a.tar.xz glibc-9c38a6899957746cbf2c0c04d110626a9271d51a.zip |
Update.
2000-07-20 Ulrich Drepper <drepper@redhat.com> * libio/Makefile (tests): Add tst_wprintf2. (tst_wprintf2-ARGS): Define. * libio/tst_wprintf2.c: New file. Based on a test case by Yoshito Kawada <KAWADA@jp.ibm.com>. * libio/wfiledoalloc.c: Only allocate external buffer if this hasn't happened yet. * libio/wfileops.c (_IO_wdo_write): Overflow only if there is really something in the buffer. gconv call can write up to end of the buffer, not only _IO_write_end. (_IO_wfile_overflow): Allocate also external buffer. * stdio-common/vfprintf.c (process_string_arg): Handle multibyte strings with precision in vfwprintf correctly. * stdio-common/vfprintf.c: Fix completely broken handling of unbuffered wide character streams. Reported by Yoshito Kawada <KAWADA@jp.ibm.com>.
Diffstat (limited to 'libio')
-rw-r--r-- | libio/Makefile | 5 | ||||
-rw-r--r-- | libio/tst_wprintf2.c | 104 | ||||
-rw-r--r-- | libio/wfiledoalloc.c | 5 | ||||
-rw-r--r-- | libio/wfileops.c | 20 |
4 files changed, 127 insertions, 7 deletions
diff --git a/libio/Makefile b/libio/Makefile index e636c19c82..ffc6958ae9 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -43,7 +43,8 @@ routines := \ \ libc_fatal -tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc +tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ + tst_wprintf2 all: # Make this the default target; it will be defined in Rules. @@ -65,6 +66,8 @@ endif CFLAGS-tst_putwc.c = -DOBJPFX=\"$(objpfx)\" +tst_wprintf2-ARGS = "Some Text" + aux := fileops genops stdfiles stdio strops ifeq ($(versioning),yes) diff --git a/libio/tst_wprintf2.c b/libio/tst_wprintf2.c new file mode 100644 index 0000000000..be0f29f53f --- /dev/null +++ b/libio/tst_wprintf2.c @@ -0,0 +1,104 @@ +/* Test case by Yoshito Kawada <KAWADA@jp.ibm.com>. */ +#include <errno.h> +#include <error.h> +#include <fcntl.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> + +int +main (int argc, char *argv[]) +{ + int a = 3; + int fd; + char name[] = "/tmp/wprintf.out.XXXXXX"; + FILE *fp; + char buf[100]; + size_t len; + int res = 0; + + fd = mkstemp (name); + if (fd == -1) + error (EXIT_FAILURE, errno, "cannot open temporary file"); + + unlink (name); + + setlocale (LC_ALL, ""); + + fp = fdopen (dup (fd), "w"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "fdopen(,\"w\")"); + + fwprintf (fp, L"test start"); + fwprintf (fp, L" int %d\n", a); + + /* String with precision. */ + fwprintf (fp, L"1[%6.3s]\n", argv[1]); + + fclose (fp); + + fp = fdopen (dup (fd), "a"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "fdopen(,\"a\")"); + + setvbuf (fp, NULL, _IONBF, 0); + + /* fwprintf to unbuffered stream. */ + fwprintf (fp, L"hello.\n"); + + fclose (fp); + + + /* Now read it back in. This time using multibyte functions. */ + lseek (fd, SEEK_SET, 0); + fp = fdopen (fd, "r"); + if (fp == NULL) + error (EXIT_FAILURE, errno, "fdopen(,\"r\")"); + + if (fgets (buf, sizeof buf, fp) != buf) + error (EXIT_FAILURE, errno, "first fgets"); + len = strlen (buf); + if (buf[len - 1] == '\n') + --len; + else + { + puts ("newline missing after first line"); + res = 1; + } + printf ("1st line: \"%.*s\" -> %s\n", (int) len, buf, + strncmp (buf, "test start int 3", len) == 0 ? "OK" : "FAIL"); + res |= strncmp (buf, "test start int 3", len) != 0; + + if (fgets (buf, sizeof buf, fp) != buf) + error (EXIT_FAILURE, errno, "second fgets"); + len = strlen (buf); + if (buf[len - 1] == '\n') + --len; + else + { + puts ("newline missing after second line"); + res = 1; + } + printf ("2nd line: \"%.*s\" -> %s\n", (int) len, buf, + strncmp (buf, "1[ Som]", len) == 0 ? "OK" : "FAIL"); + res |= strncmp (buf, "1[ Som]", len) != 0; + + if (fgets (buf, sizeof buf, fp) != buf) + error (EXIT_FAILURE, errno, "third fgets"); + len = strlen (buf); + if (buf[len - 1] == '\n') + --len; + else + { + puts ("newline missing after third line"); + res = 1; + } + printf ("3rd line: \"%.*s\" -> %s\n", (int) len, buf, + strncmp (buf, "hello.", len) == 0 ? "OK" : "FAIL"); + res |= strncmp (buf, "hello.", len) != 0; + + return res; +} diff --git a/libio/wfiledoalloc.c b/libio/wfiledoalloc.c index 7f5cb7f960..76226e9846 100644 --- a/libio/wfiledoalloc.c +++ b/libio/wfiledoalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1997, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1993, 1997, 1999, 2000 Free Software Foundation, Inc. This file is part of the GNU IO Library. This library is free software; you can redistribute it and/or @@ -76,7 +76,8 @@ _IO_wfile_doallocate (fp) struct _G_stat64 st; /* Allocate room for the external buffer. */ - _IO_file_doallocate (fp); + if (fp->_IO_buf_base == NULL) + _IO_file_doallocate (fp); if (fp->_fileno < 0 || _IO_SYSSTAT (fp, &st) < 0) { diff --git a/libio/wfileops.c b/libio/wfileops.c index 3489b36fb1..94c14c9151 100644 --- a/libio/wfileops.c +++ b/libio/wfileops.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1993, 95, 97, 98, 99, 2000 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>. @@ -67,7 +67,8 @@ _IO_wdo_write (fp, data, to_do) enum __codecvt_result result; const wchar_t *new_data; - if (fp->_IO_write_end == fp->_IO_write_ptr) + if (fp->_IO_write_end == fp->_IO_write_ptr + && fp->_IO_write_end != fp->_IO_write_base) { _IO_new_file_overflow (fp, EOF); assert (fp->_IO_write_end > fp->_IO_write_ptr); @@ -77,7 +78,7 @@ _IO_wdo_write (fp, data, to_do) 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_buf_end, &fp->_IO_write_ptr); /* Write out what we produced so far. */ @@ -289,6 +290,12 @@ _IO_wfile_overflow (f, wch) _IO_wdoallocbuf (f); _IO_wsetg (f, f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base, f->_wide_data->_IO_buf_base); + + if (f->_IO_write_base == NULL) + { + _IO_doallocbuf (f); + _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); + } } else { @@ -313,13 +320,18 @@ _IO_wfile_overflow (f, wch) f->_wide_data->_IO_read_base = f->_wide_data->_IO_read_ptr = f->_wide_data->_IO_read_end; + f->_IO_write_ptr = f->_IO_read_ptr; + f->_IO_write_base = f->_IO_write_ptr; + f->_IO_write_end = f->_IO_buf_end; + 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)) 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 ) + 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; |