Hello,

It appeared that gcov.c and input.c both have a static function named
read_line.  I guess we ought to keep just one.

So I changed the one in input.c as it handles lines with bytes of zero
value (as of the work on PR preprocessor/58580) to make it suitable for
what the uses of read_line in gcov.c expect.  Note that the gcov.c usage
doesn't need the handling of bytes with zero value in a line, AIUI.

First, the byte count returned by get_line now contains the '\n' at
the end of the line; of course that '\n' is still replaced by the a
terminal zero.

Second, read_line ensures that the current position indicator
correctly moves to the end of the line read, as opposed to moving to
the end of the buffer that get_line fills while reading bytes in
chunk.

Third, I have added a declaration for read_line in input.h.  I
couldn't find a better place where to put this.

Patch tested and bootstrapped on x86_64-unknown-linux-gnu against
trunk.

OK to commit to trunk?

gcc/ChangeLog

        * input.h (read_line): Declare this here.
        * input.c (get_line): Make the returned length of the line contain
        the ending '\n' character.  Replace that '\n' character by a zero
        byte.
        (read_line): Make this *not* be static anymore.  Preserve the
        current file position across invocations.
---
 gcc/gcov.c  | 35 ++---------------------------------
 gcc/input.c | 31 +++++++++++++++++++++----------
 gcc/input.h |  2 ++
 3 files changed, 25 insertions(+), 43 deletions(-)

diff --git a/gcc/gcov.c b/gcc/gcov.c
index 9458812..da53ebe 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -2364,37 +2364,6 @@ output_branch_count (FILE *gcov_file, int ix, const 
arc_t *arc)
 
 }
 
-static const char *
-read_line (FILE *file)
-{
-  static char *string;
-  static size_t string_len;
-  size_t pos = 0;
-  char *ptr;
-
-  if (!string_len)
-    {
-      string_len = 200;
-      string = XNEWVEC (char, string_len);
-    }
-
-  while ((ptr = fgets (string + pos, string_len - pos, file)))
-    {
-      size_t len = strlen (string + pos);
-
-      if (string[pos + len - 1] == '\n')
-       {
-         string[pos + len - 1] = 0;
-         return string;
-       }
-      pos += len;
-      string = XRESIZEVEC (char, string, string_len * 2);
-      string_len *= 2;
-    }
-      
-  return pos ? string : NULL;
-}
-
 /* Read in the source file one line at a time, and output that line to
    the gcov file preceded by its execution count and other
    information.  */
@@ -2455,7 +2424,7 @@ output_lines (FILE *gcov_file, const source_t *src)
        }
 
       if (retval)
-       retval = read_line (source_file);
+       retval = read_line (source_file, NULL);
 
       /* For lines which don't exist in the .bb file, print '-' before
         the source line.  For lines which exist but were never
@@ -2503,7 +2472,7 @@ output_lines (FILE *gcov_file, const source_t *src)
      last line of code.  */
   if (retval)
     {
-      for (; (retval = read_line (source_file)); line_num++)
+      for (; (retval = read_line (source_file, NULL)); line_num++)
        fprintf (gcov_file, "%9s:%5u:%s\n", "-", line_num, retval);
     }
 
diff --git a/gcc/input.c b/gcc/input.c
index cb3a0a0..e42103c 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -88,12 +88,12 @@ expand_location_1 (source_location loc,
 }
 
 /* This function reads a line that might contain bytes whose value is
-   zero.  It returns the number of bytes read.  The 'end-of-line'
-   character found at the end of the line is not contained in the
-   returned buffer.  Note that this function has been adapted from
-   getline() and _IO_getdelim() GNU C library functions.  It's been
-   duplicated here because the getline() function is not necessarily
-   present on all platforms.
+   zero.  It returns the number of bytes read, including the
+   end-of-line character.  That end-of-line character is replaced by a
+   zero byte in the returned buffer.  Note that this function has been
+   adapted from getline() and _IO_getdelim() GNU C library functions.
+   It's been duplicated here because the getline() function is not
+   necessarily present on all platforms.
 
    LINEPTR points to a buffer that is to contain the line read.
 
@@ -124,7 +124,7 @@ get_line (char **lineptr, size_t *n, FILE *fp)
     {
       size_t needed;
       char *t = (char*) memchr (buf, '\n', len);
-      if (t != NULL) len = (t - buf);
+      if (t != NULL) len = (t - buf) + 1;
       if (__builtin_expect (len >= SSIZE_MAX - cur_len, 0))
        return -1;
       needed = cur_len + len + 1;
@@ -149,7 +149,7 @@ get_line (char **lineptr, size_t *n, FILE *fp)
     }
 
   if (cur_len)
-    (*lineptr)[cur_len] = '\0';
+    (*lineptr)[cur_len - 1] = '\0';
   return cur_len;
 }
 
@@ -159,14 +159,21 @@ get_line (char **lineptr, size_t *n, FILE *fp)
  *zero bytes.  Also note that the returned string is allocated in
  *static storage that is going to be re-used by subsequent invocations
  *of read_line.  */
-static const char *
+const char *
 read_line (FILE *file, int *line_length)
 {
   static char *string;
   static size_t string_len;
   int len;
+  long prev_pos;
 
+  prev_pos = ftell (file);
   len = get_line (&string, &string_len, file);
+  /* get_line tried to read STRING_LEN bytes, which is possibly
+    different from LEN bytes of the returned line.  So set the
+    position indicator of FILE to the byte following the LEN'th byte,
+    so that the new call to get_line starts reading from there.  */
+  fseek (file, prev_pos + len, SEEK_SET);
   if (line_length)
     *line_length = len;
   return len ? string : NULL;
@@ -188,7 +195,11 @@ location_get_source_line (expanded_location xloc,
   if (!stream)
     return NULL;
 
-  while ((ptr = read_line (stream, &len)) && lines < xloc.line)
+  /* We make sure not to call read_line unnecessarily because the
+     non-null result of a given call to read_line overrides the result
+     of the previous call to read_line; hence the line test that comes
+     before the call to read_line.  */
+  while (lines < xloc.line && (ptr = read_line (stream, &len)))
     {
       buffer = ptr;
       lines++;
diff --git a/gcc/input.h b/gcc/input.h
index 128e28c..d7c8a0e 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -66,4 +66,6 @@ extern location_t input_location;
 
 void dump_line_table_statistics (void);
 
+const char * read_line (FILE *, int *);
+
 #endif
-- 
                Dodji

Reply via email to