diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2007-07-29 20:01:45 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2007-07-29 20:01:45 +0000 |
commit | d8163f5cc068347dfd74cb03c9e7b6cfcd3a8460 (patch) | |
tree | 05a77906359d7bd336aba3bd8c097b7414e1f63a /libgfortran/io/unix.c | |
parent | 6a56381bf7e8825e08ec3a47bc14230528c82462 (diff) | |
download | gcc-d8163f5cc068347dfd74cb03c9e7b6cfcd3a8460.zip gcc-d8163f5cc068347dfd74cb03c9e7b6cfcd3a8460.tar.gz gcc-d8163f5cc068347dfd74cb03c9e7b6cfcd3a8460.tar.bz2 |
re PR libfortran/32858 (printf-capabilities for runtime_error())
2007-07-29 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libfortran/32858
PR libfortran/30814
* configure.ac: Added checks for presence of stdio.h and
stdarg.h. Test presence of vsnprintf().
* configure: Regenerated.
* config.h.in: Regenerated.
* libgfortran.h: Include <stdio.h>. Add printf attribute to
prototype of runtime_error. Remove prototype for st_sprintf.
Add prototype for st_vprintf.
* runtime/main.c (store_exec_path): Replace st_sprintf by sprintf.
* runtime/error.c (st_sprintf): Remove.
(runtime_error): Rewrite as a variadic function. Call
st_vprintf().
* intrinsics/pack_generic.c: Output extents of LHS and RHS for
bounds error.
* io/open.c (new_unit): Replace st_sprintf by sprintf.
* io/list_read.c (convert_integer): Likewise.
(parse_repeat): Likewise.
(read_logical): Likewise.
(read_character): Likewise.
(parse_real): Likewise.
(read_real): Likewise.
(check_type): Likewise.
(nml_parse_qualifyer): Likewise.
(nml_read_obj): Likewise.
(nml_get_ojb_data): Likewise.
* io/unix.c (init_error_stream): Remove.
(tempfile): Replace st_sprintf by sprintf.
(st_vprintf): New function.
(st_printf): Rewrite to call st_vprintf.
* io/transfer.c (require_type): Replace st_sprintf by sprintf.
* io/format.c (format_error): Likewise.
* io/write.c (nml_write_obj): Likewise.
2007-07-29 Thomas Koenig <tkoenig@gcc.gnu.org>
PR libfortran/32858
PR libfortran/30814
* gfortran.dg/pack_bounds_1.f90: Adjust to new error message.
From-SVN: r127049
Diffstat (limited to 'libgfortran/io/unix.c')
-rw-r--r-- | libgfortran/io/unix.c | 140 |
1 files changed, 29 insertions, 111 deletions
diff --git a/libgfortran/io/unix.c b/libgfortran/io/unix.c index 87d001e..e9ad164 100644 --- a/libgfortran/io/unix.c +++ b/libgfortran/io/unix.c @@ -142,10 +142,6 @@ typedef struct } int_stream; -extern stream *init_error_stream (unix_stream *); -internal_proto(init_error_stream); - - /* This implementation of stream I/O is based on the paper: * * "Exploiting the advantages of mapped files for stream I/O", @@ -1155,7 +1151,7 @@ tempfile (st_parameter_open *opp) template = get_mem (strlen (tempdir) + 20); - st_sprintf (template, "%s/gfortrantmpXXXXXX", tempdir); + sprintf (template, "%s/gfortrantmpXXXXXX", tempdir); #ifdef HAVE_MKSTEMP @@ -1385,122 +1381,44 @@ error_stream (void) return fd_to_stream (STDERR_FILENO, PROT_WRITE); } -/* init_error_stream()-- Return a pointer to the error stream. This - * subroutine is called when the stream is needed, rather than at - * initialization. We want to work even if memory has been seriously - * corrupted. */ -stream * -init_error_stream (unix_stream *error) -{ - memset (error, '\0', sizeof (*error)); +/* st_vprintf()-- vprintf function for error output. To avoid buffer + overruns, we limit the length of the buffer to ST_VPRINTF_SIZE. 2k + is big enough to completely fill a 80x25 terminal, so it shuld be + OK. We use a direct write() because it is simpler and least likely + to be clobbered by memory corruption. */ - error->fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO; +#define ST_VPRINTF_SIZE 2048 - error->st.alloc_w_at = (void *) fd_alloc_w_at; - error->st.sfree = (void *) fd_sfree; - - error->unbuffered = 1; - error->buffer = error->small_buffer; +int +st_vprintf (const char *format, va_list ap) +{ + static char buffer[ST_VPRINTF_SIZE]; + int written; + int fd; - return (stream *) error; + fd = options.use_stderr ? STDERR_FILENO : STDOUT_FILENO; +#ifdef HAVE_VSNPRINTF + written = vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap); +#else + written = __builtin_vsnprintf(buffer, ST_VPRINTF_SIZE, format, ap); +#endif + written = write (fd, buffer, written); + return written; } -/* st_printf()-- simple printf() function for streams that handles the - * formats %d, %s and %c. This function handles printing of error - * messages that originate within the library itself, not from a user - * program. */ +/* st_printf()-- printf() function for error output. This just calls + st_vprintf() to do the actual work. */ int st_printf (const char *format, ...) { - int count, total; - va_list arg; - char *p; - const char *q; - stream *s; - char itoa_buf[GFC_ITOA_BUF_SIZE]; - unix_stream err_stream; - - total = 0; - s = init_error_stream (&err_stream); - va_start (arg, format); - - for (;;) - { - count = 0; - - while (format[count] != '%' && format[count] != '\0') - count++; - - if (count != 0) - { - p = salloc_w (s, &count); - memmove (p, format, count); - sfree (s); - } - - total += count; - format += count; - if (*format++ == '\0') - break; - - switch (*format) - { - case 'c': - count = 1; - - p = salloc_w (s, &count); - *p = (char) va_arg (arg, int); - - sfree (s); - break; - - case 'd': - q = gfc_itoa (va_arg (arg, int), itoa_buf, sizeof (itoa_buf)); - count = strlen (q); - - p = salloc_w (s, &count); - memmove (p, q, count); - sfree (s); - break; - - case 'x': - q = xtoa (va_arg (arg, unsigned), itoa_buf, sizeof (itoa_buf)); - count = strlen (q); - - p = salloc_w (s, &count); - memmove (p, q, count); - sfree (s); - break; - - case 's': - q = va_arg (arg, char *); - count = strlen (q); - - p = salloc_w (s, &count); - memmove (p, q, count); - sfree (s); - break; - - case '\0': - return total; - - default: - count = 2; - p = salloc_w (s, &count); - p[0] = format[-1]; - p[1] = format[0]; - sfree (s); - break; - } - - total += count; - format++; - } - - va_end (arg); - return total; + int written; + va_list ap; + va_start (ap, format); + written = st_vprintf(format, ap); + va_end (ap); + return written; } |