Removes 100 lines of tricky code.

cheers,
Pádraig.
>From 85798e94a87b4c877da1b23a1c29ff15e642bfc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Tue, 11 Jan 2011 19:30:28 +0000
Subject: [PATCH] maint: refactor to use read-file from gnulib

* bootstrap.conf: Add the read-file module
* ptx.c: Replace the original code which would
needlessly read SIZE_MAX bytes of files larger than this.
* shuf.c: Replace the original code.
---
 bootstrap.conf |    1 +
 src/ptx.c      |   80 +++----------------------------------------------------
 src/shuf.c     |   48 +++------------------------------
 3 files changed, 11 insertions(+), 118 deletions(-)

diff --git a/bootstrap.conf b/bootstrap.conf
index 5f8171f..87de38f 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -170,6 +170,7 @@ gnulib_modules="
   quotearg
   randint
   randperm
+  read-file
   readlink
   readtokens
   readtokens0
diff --git a/src/ptx.c b/src/ptx.c
index 940f6e8..a45c4d8 100644
--- a/src/ptx.c
+++ b/src/ptx.c
@@ -28,6 +28,7 @@
 #include "fadvise.h"
 #include "quote.h"
 #include "quotearg.h"
+#include "read-file.h"
 #include "regex.h"
 #include "stdio--.h"
 #include "xstrtol.h"
@@ -62,10 +63,6 @@
    options.  Many of the "int" values below should be "size_t" or
    something else like that.  */
 
-/* Reallocation step when swallowing non regular files.  The value is not
-   the actual reallocation step, but its base two logarithm.  */
-#define SWALLOW_REALLOC_LOG 12
-
 /* Program options.  */
 
 enum Format
@@ -511,88 +508,21 @@ initialize_regex (void)
 static void
 swallow_file_in_memory (const char *file_name, BLOCK *block)
 {
-  int file_handle;		/* file descriptor number */
-  struct stat stat_block;	/* stat block for file */
-  size_t allocated_length;	/* allocated length of memory buffer */
   size_t used_length;		/* used length in memory buffer */
-  int read_length;		/* number of character gotten on last read */
 
   /* As special cases, a file name which is NULL or "-" indicates standard
      input, which is already opened.  In all other cases, open the file from
      its name.  */
   bool using_stdin = !file_name || !*file_name || STREQ (file_name, "-");
   if (using_stdin)
-    file_handle = STDIN_FILENO;
+    block->start = fread_file (stdin, &used_length);
   else
-    if ((file_handle = open (file_name, O_RDONLY)) < 0)
-      error (EXIT_FAILURE, errno, "%s", file_name);
-
-  /* If the file is a plain, regular file, allocate the memory buffer all at
-     once and swallow the file in one blow.  In other cases, read the file
-     repeatedly in smaller chunks until we have it all, reallocating memory
-     once in a while, as we go.  */
+    block->start = read_file (file_name, &used_length);
 
-  if (fstat (file_handle, &stat_block) < 0)
+  if (!block->start)
     error (EXIT_FAILURE, errno, "%s", file_name);
 
-  if (S_ISREG (stat_block.st_mode))
-    {
-      size_t in_memory_size;
-
-      fdadvise (file_handle, 0, 0, FADVISE_SEQUENTIAL);
-
-      block->start = xmalloc ((size_t) stat_block.st_size);
-
-      if ((in_memory_size = read (file_handle,
-                                  block->start, (size_t) stat_block.st_size))
-          != stat_block.st_size)
-        {
-#if MSDOS
-          /* On MSDOS, in memory size may be smaller than the file
-             size, because of end of line conversions.  But it can
-             never be smaller than half the file size, because the
-             minimum is when all lines are empty and terminated by
-             CR+LF.  */
-          if (in_memory_size != (size_t)-1
-              && in_memory_size >= stat_block.st_size / 2)
-            block->start = xrealloc (block->start, in_memory_size);
-          else
-#endif /* not MSDOS */
-
-            error (EXIT_FAILURE, errno, "%s", file_name);
-        }
-      block->end = block->start + in_memory_size;
-    }
-  else
-    {
-      block->start = xmalloc ((size_t) 1 << SWALLOW_REALLOC_LOG);
-      used_length = 0;
-      allocated_length = (1 << SWALLOW_REALLOC_LOG);
-
-      while (read_length = read (file_handle,
-                                 block->start + used_length,
-                                 allocated_length - used_length),
-             read_length > 0)
-        {
-          used_length += read_length;
-          if (used_length == allocated_length)
-            {
-              allocated_length += (1 << SWALLOW_REALLOC_LOG);
-              block->start
-                = xrealloc (block->start, allocated_length);
-            }
-        }
-
-      if (read_length < 0)
-        error (EXIT_FAILURE, errno, "%s", file_name);
-
-      block->end = block->start + used_length;
-    }
-
-  /* Close the file, but only if it was not the standard input.  */
-
-  if (! using_stdin && close (file_handle) != 0)
-    error (EXIT_FAILURE, errno, "%s", file_name);
+  block->end = block->start + used_length;
 }
 
 /* Sort and search routines.  */
diff --git a/src/shuf.c b/src/shuf.c
index 1d2261e..218ad6d 100644
--- a/src/shuf.c
+++ b/src/shuf.c
@@ -29,6 +29,7 @@
 #include "quotearg.h"
 #include "randint.h"
 #include "randperm.h"
+#include "read-file.h"
 #include "stdio--.h"
 #include "xstrtol.h"
 
@@ -147,52 +148,14 @@ read_input (FILE *in, char eolbyte, char ***pline)
 {
   char *p;
   char *buf = NULL;
+  size_t used;
   char *lim;
-  size_t alloc = 0;
-  size_t used = 0;
-  size_t next_alloc = (1 << 13) + 1;
-  size_t bytes_to_read;
-  size_t nread;
   char **line;
   size_t i;
   size_t n_lines;
-  int fread_errno;
-  struct stat instat;
 
-  if (fstat (fileno (in), &instat) == 0 && S_ISREG (instat.st_mode))
-    {
-      off_t file_size = instat.st_size;
-      off_t current_offset = ftello (in);
-      if (0 <= current_offset)
-        {
-          off_t remaining_size =
-            (current_offset < file_size ? file_size - current_offset : 0);
-          if (SIZE_MAX - 2 < remaining_size)
-            xalloc_die ();
-          next_alloc = remaining_size + 2;
-        }
-    }
-
-  do
-    {
-      if (alloc <= used + 1)
-        {
-          if (alloc == SIZE_MAX)
-            xalloc_die ();
-          alloc = next_alloc;
-          next_alloc = alloc * 2;
-          if (next_alloc < alloc)
-            next_alloc = SIZE_MAX;
-          buf = xrealloc (buf, alloc);
-        }
-
-      bytes_to_read = alloc - used - 1;
-      nread = fread (buf + used, sizeof (char), bytes_to_read, in);
-      used += nread;
-    }
-  while (nread == bytes_to_read);
-
-  fread_errno = errno;
+  if (!(buf = fread_file (in, &used)))
+    error (EXIT_FAILURE, errno, _("error reading input"));
 
   if (used && buf[used - 1] != eolbyte)
     buf[used++] = eolbyte;
@@ -209,7 +172,6 @@ read_input (FILE *in, char eolbyte, char ***pline)
   for (i = 1; i <= n_lines; i++)
     line[i] = p = next_line (p, eolbyte, lim - p);
 
-  errno = fread_errno;
   return n_lines;
 }
 
@@ -396,7 +358,7 @@ main (int argc, char **argv)
      doesn't have to worry about opening something other than
      stdin.  */
   if (! (echo || input_numbers_option_used (lo_input, hi_input))
-      && (ferror (stdin) || fclose (stdin) != 0))
+      && (fclose (stdin) != 0))
     error (EXIT_FAILURE, errno, _("read error"));
 
   permutation = randperm_new (randint_source, head_lines, n_lines);
-- 
1.7.3.4

Reply via email to