-/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2018 Free Software Foundation, Inc.
Contributed by Janne Blomqvist
This file is part of the GNU Fortran runtime library (libgfortran).
#include "fbuf.h"
#include "unix.h"
#include <string.h>
-#include <stdlib.h>
//#define FBUF_DEBUG
void
-fbuf_init (gfc_unit * u, int len)
+fbuf_init (gfc_unit *u, size_t len)
{
if (len == 0)
len = 512; /* Default size. */
- u->fbuf = get_mem (sizeof (struct fbuf));
- u->fbuf->buf = get_mem (len);
+ u->fbuf = xmalloc (sizeof (struct fbuf));
+ u->fbuf->buf = xmalloc (len);
u->fbuf->len = len;
u->fbuf->act = u->fbuf->pos = 0;
}
void
-fbuf_destroy (gfc_unit * u)
+fbuf_destroy (gfc_unit *u)
{
if (u->fbuf == NULL)
return;
- if (u->fbuf->buf)
- free_mem (u->fbuf->buf);
- free_mem (u->fbuf);
+ free (u->fbuf->buf);
+ free (u->fbuf);
u->fbuf = NULL;
}
static void
#ifdef FBUF_DEBUG
-fbuf_debug (gfc_unit * u, const char * format, ...)
+fbuf_debug (gfc_unit *u, const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
- fprintf (stderr, "fbuf_debug pos: %d, act: %d, buf: ''",
- u->fbuf->pos, u->fbuf->act);
- for (int ii = 0; ii < u->fbuf->act; ii++)
+ fprintf (stderr, "fbuf_debug pos: %lu, act: %lu, buf: ''",
+ (long unsigned) u->fbuf->pos, (long unsigned) u->fbuf->act);
+ for (size_t ii = 0; ii < u->fbuf->act; ii++)
{
putc (u->fbuf->buf[ii], stderr);
}
fprintf (stderr, "''\n");
}
#else
-fbuf_debug (gfc_unit * u __attribute__ ((unused)),
- const char * format __attribute__ ((unused)),
+fbuf_debug (gfc_unit *u __attribute__ ((unused)),
+ const char *format __attribute__ ((unused)),
...) {}
#endif
underlying device. Returns how much the physical position was
modified. */
-int
-fbuf_reset (gfc_unit * u)
+ptrdiff_t
+fbuf_reset (gfc_unit *u)
{
- int seekval = 0;
+ ptrdiff_t seekval = 0;
if (!u->fbuf)
return 0;
if (u->mode == READING && u->fbuf->act > u->fbuf->pos)
{
seekval = - (u->fbuf->act - u->fbuf->pos);
- fbuf_debug (u, "fbuf_reset seekval %d, ", seekval);
+ fbuf_debug (u, "fbuf_reset seekval %ld, ", (long) seekval);
}
u->fbuf->act = u->fbuf->pos = 0;
return seekval;
reallocating if necessary. */
char *
-fbuf_alloc (gfc_unit * u, int len)
+fbuf_alloc (gfc_unit *u, size_t len)
{
- int newlen;
+ size_t newlen;
char *dest;
- fbuf_debug (u, "fbuf_alloc len %d, ", len);
+ fbuf_debug (u, "fbuf_alloc len %lu, ", (long unsigned) len);
if (u->fbuf->pos + len > u->fbuf->len)
{
/* Round up to nearest multiple of the current buffer length. */
- newlen = ((u->fbuf->pos + len) / u->fbuf->len + 1) * u->fbuf->len;
- dest = realloc (u->fbuf->buf, newlen);
- if (dest == NULL)
- return NULL;
- u->fbuf->buf = dest;
+ newlen = ((u->fbuf->pos + len) / u->fbuf->len + 1) *u->fbuf->len;
+ u->fbuf->buf = xrealloc (u->fbuf->buf, newlen);
u->fbuf->len = newlen;
}
mode. Return value is 0 for success, -1 on failure. */
int
-fbuf_flush (gfc_unit * u, unit_mode mode)
+fbuf_flush (gfc_unit *u, unit_mode mode)
{
- int nwritten;
-
if (!u->fbuf)
return 0;
{
if (u->fbuf->pos > 0)
{
- nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
+ ptrdiff_t nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
if (nwritten < 0)
return -1;
}
}
+/* The mode argument is LIST_WRITING for write mode and LIST_READING for
+ read. This should only be used for list directed I/O.
+ Return value is 0 for success, -1 on failure. */
+
int
-fbuf_seek (gfc_unit * u, int off, int whence)
+fbuf_flush_list (gfc_unit *u, unit_mode mode)
+{
+ if (!u->fbuf)
+ return 0;
+
+ if (u->fbuf->pos < 524288) /* Upper limit for list writing. */
+ return 0;
+
+ fbuf_debug (u, "fbuf_flush_list with mode %d: ", mode);
+
+ if (mode == LIST_WRITING)
+ {
+ ptrdiff_t nwritten = swrite (u->s, u->fbuf->buf, u->fbuf->pos);
+ if (nwritten < 0)
+ return -1;
+ }
+
+ /* Salvage remaining bytes for both reading and writing. */
+ if (u->fbuf->act > u->fbuf->pos)
+ memmove (u->fbuf->buf, u->fbuf->buf + u->fbuf->pos,
+ u->fbuf->act - u->fbuf->pos);
+
+ u->fbuf->act -= u->fbuf->pos;
+ u->fbuf->pos = 0;
+
+ return 0;
+}
+
+
+ptrdiff_t
+fbuf_seek (gfc_unit *u, ptrdiff_t off, int whence)
{
if (!u->fbuf)
return -1;
return -1;
}
- fbuf_debug (u, "fbuf_seek, off %d ", off);
+ fbuf_debug (u, "fbuf_seek, off %ld ", (long) off);
/* The start of the buffer is always equal to the left tab
limit. Moving to the left past the buffer is illegal in C and
would also imply moving past the left tab limit, which is never
is not possible, in that case the user must make sure to allocate
space with fbuf_alloc(). So return error if that is
attempted. */
- if (off < 0 || off > u->fbuf->act)
+ if (off < 0 || off > (ptrdiff_t) u->fbuf->act)
return -1;
u->fbuf->pos = off;
return off;
of bytes actually processed. */
char *
-fbuf_read (gfc_unit * u, int * len)
+fbuf_read (gfc_unit *u, size_t *len)
{
char *ptr;
- int oldact, oldpos;
- int readlen = 0;
+ size_t oldact, oldpos;
+ ptrdiff_t readlen = 0;
- fbuf_debug (u, "fbuf_read, len %d: ", *len);
+ fbuf_debug (u, "fbuf_read, len %lu: ", (unsigned long) *len);
oldact = u->fbuf->act;
oldpos = u->fbuf->pos;
ptr = fbuf_alloc (u, *len);
u->fbuf->pos = oldpos;
if (oldpos + *len > oldact)
{
- fbuf_debug (u, "reading %d bytes starting at %d ",
- oldpos + *len - oldact, oldact);
+ fbuf_debug (u, "reading %lu bytes starting at %lu ",
+ (long unsigned) oldpos + *len - oldact,
+ (long unsigned) oldact);
readlen = sread (u->s, u->fbuf->buf + oldact, oldpos + *len - oldact);
if (readlen < 0)
return NULL;
reading. Never call this function directly. */
int
-fbuf_getc_refill (gfc_unit * u)
+fbuf_getc_refill (gfc_unit *u)
{
- int nread;
char *p;
fbuf_debug (u, "fbuf_getc_refill ");
between not needing to call the read() syscall all the time and
not having to memmove unnecessary stuff when switching to the
next record. */
- nread = 80;
+ size_t nread = 80;
p = fbuf_read (u, &nread);