Mercurial > hg > octave-nkf > gnulib-hg
view lib/read-file.c @ 6848:2a11dd9faacd
2006-06-19 Paul Eggert <eggert@cs.ucla.edu>
* read-file.c (fread_file): Start with buffer allocation of
0 bytes rather than 1 byte; this simplifies the code.
Don't invoke feof; it's not needed. Refactor to avoid duplicate
code to free buffer and save/restore errno.
(internal_read_file): Remove unused local.
author | Simon Josefsson <simon@josefsson.org> |
---|---|
date | Wed, 21 Jun 2006 08:02:40 +0000 |
parents | 19c37b3f23b1 |
children | a88f85e4728f |
line wrap: on
line source
/* read-file.c -- read file contents into a string Copyright (C) 2006 Free Software Foundation, Inc. Written by Simon Josefsson and Bruno Haible. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H # include <config.h> #endif #include "read-file.h" /* Get realloc, free. */ #include <stdlib.h> /* Get errno. */ #include <errno.h> /* Read a STREAM and return a newly allocated string with the content, and set *LENGTH to the length of the string. The string is zero-terminated, but the terminating zero byte is not counted in *LENGTH. On errors, *LENGTH is undefined, errno preserves the values set by system functions (if any), and NULL is returned. */ char * fread_file (FILE * stream, size_t * length) { char *buf = NULL; size_t alloc = 0; size_t size = 0; int save_errno; for (;;) { size_t count; size_t requested; if (size + BUFSIZ + 1 > alloc) { char *new_buf; alloc += alloc / 2; if (alloc < size + BUFSIZ + 1) alloc = size + BUFSIZ + 1; new_buf = realloc (buf, alloc); if (!new_buf) { save_errno = errno; break; } buf = new_buf; } requested = alloc - size - 1; count = fread (buf + size, 1, requested, stream); size += count; if (count != requested) { save_errno = errno; if (ferror (stream)) break; buf[size] = '\0'; *length = size; return buf; } } free (buf); errno = save_errno; return NULL; } static char * internal_read_file (const char *filename, size_t * length, const char *mode) { FILE *stream = fopen (filename, mode); char *out; int save_errno; if (!stream) return NULL; out = fread_file (stream, length); save_errno = errno; if (fclose (stream) != 0) { if (out) { save_errno = errno; free (out); } errno = save_errno; return NULL; } return out; } /* Open and read the contents of FILENAME, and return a newly allocated string with the content, and set *LENGTH to the length of the string. The string is zero-terminated, but the terminating zero byte is not counted in *LENGTH. On errors, *LENGTH is undefined, errno preserves the values set by system functions (if any), and NULL is returned. */ char * read_file (const char *filename, size_t * length) { return internal_read_file (filename, length, "r"); } /* Open (on non-POSIX systems, in binary mode) and read the contents of FILENAME, and return a newly allocated string with the content, and set LENGTH to the length of the string. The string is zero-terminated, but the terminating zero byte is not counted in the LENGTH variable. On errors, *LENGTH is undefined, errno preserves the values set by system functions (if any), and NULL is returned. */ char * read_binary_file (const char *filename, size_t * length) { return internal_read_file (filename, length, "rb"); }