* Makefile.in (loop-init.o): Do not depend on gcov-io.h,
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Apr 2003 10:38:57 +0000 (10:38 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Apr 2003 10:38:57 +0000 (10:38 +0000)
gcov-iov.h.

Simplify interface to gcov reading and writing.
* gcov-io.h (gcov_file, gcov_position, gcov_length, gcov_buffer,
gcov_alloc, gcov_modified, gcov_errored): Move into ...
(struct gcov_var gcov_var): ... this static structure.
(gcov_write_unsigned, gcov_write_counter, gcov_write_string):
Return void.
(gcov_read_unsigned, gcov_read_couter, gcov_read_string): Return
read object.
(gcov_read_bytes, gcov_write_bytes): Set error flag on error.
(gcov_reserve_length): Remove.
(gcov_write_tag): New.
(gcov_write_length): Adjust.
(gcov_read_summary, gcov_write_summary): Adjust.
(gcov_eof, gcov_ok): Rename to ...
(gcov_is_eof, gcov_is_error): ... here. Return error code.
(gcov_save_position, gcov_resync): Rename to ...
(gcov_position, gcov_seek): ... here.
(gcov_skip, gcov_skip_string): Remove.
(gcov_error): Remove.
(gcov_open, gcov_close): Adjust.
* gcov.c (find_source): Take const char *, copy it on allocation.
(read_graph_file): Adjust.
(read_count_file): Adjust.
* libgcov.c (gcov_exit): Adjust.
* gcov-dump.c (tag_function, tag_blocks, tag_arcs, tag_lines,
tag_arc_counts, tag_summary): Return void. Adjust.
(struct tag_format): Adjust proc member.
(dump_file): Adjust gcov calls.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@65464 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/gcov-dump.c
gcc/gcov-io.h
gcc/gcov.c
gcc/libgcov.c
gcc/profile.c

index 0277521..ca55295 100644 (file)
@@ -1,3 +1,37 @@
+2003-04-11  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * Makefile.in (loop-init.o): Do not depend on gcov-io.h,
+       gcov-iov.h.
+
+       Simplify interface to gcov reading and writing.
+       * gcov-io.h (gcov_file, gcov_position, gcov_length, gcov_buffer,
+       gcov_alloc, gcov_modified, gcov_errored): Move into ...
+       (struct gcov_var gcov_var): ... this static structure.
+       (gcov_write_unsigned, gcov_write_counter, gcov_write_string):
+       Return void.
+       (gcov_read_unsigned, gcov_read_couter, gcov_read_string): Return
+       read object.
+       (gcov_read_bytes, gcov_write_bytes): Set error flag on error.
+       (gcov_reserve_length): Remove.
+       (gcov_write_tag): New.
+       (gcov_write_length): Adjust.
+       (gcov_read_summary, gcov_write_summary): Adjust.
+       (gcov_eof, gcov_ok): Rename to ...
+       (gcov_is_eof, gcov_is_error): ... here. Return error code.
+       (gcov_save_position, gcov_resync): Rename to ...
+       (gcov_position, gcov_seek): ... here.
+       (gcov_skip, gcov_skip_string): Remove.
+       (gcov_error): Remove.
+       (gcov_open, gcov_close): Adjust.
+       * gcov.c (find_source): Take const char *, copy it on allocation.
+       (read_graph_file): Adjust.
+       (read_count_file): Adjust.
+       * libgcov.c (gcov_exit): Adjust.
+       * gcov-dump.c (tag_function, tag_blocks, tag_arcs, tag_lines,
+       tag_arc_counts, tag_summary): Return void. Adjust.
+       (struct tag_format): Adjust proc member.
+       (dump_file): Adjust gcov calls.
+
 2003-04-11  Alexandre Oliva  <aoliva@redhat.com>
 
        * Makefile.in (fixinc.sh): Pass BUILD_LIBERTY as LIBERTY to
index 6b9e64f..1ab232f 100644 (file)
@@ -1652,8 +1652,8 @@ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
    $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h $(EXPR_H) coretypes.h $(TM_H)
 cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
    $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h output.h coretypes.h $(TM_H)
-loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) gcov-io.h \
-   gcov-iov.h $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \
+loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
+   $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \
    coretypes.h $(TM_H)
 loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
    $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h params.h \
index 5ca64a4..ba56fee 100644 (file)
@@ -30,19 +30,19 @@ static void dump_file PARAMS ((const char *));
 static void print_prefix PARAMS ((const char *, unsigned));
 static void print_usage PARAMS ((void));
 static void print_version PARAMS ((void));
-static int tag_function PARAMS ((const char *, unsigned, unsigned));
-static int tag_blocks PARAMS ((const char *, unsigned, unsigned));
-static int tag_arcs PARAMS ((const char *, unsigned, unsigned));
-static int tag_lines PARAMS ((const char *, unsigned, unsigned));
-static int tag_arc_counts PARAMS ((const char *, unsigned, unsigned));
-static int tag_summary PARAMS ((const char *, unsigned, unsigned));
+static void tag_function PARAMS ((const char *, unsigned, unsigned));
+static void tag_blocks PARAMS ((const char *, unsigned, unsigned));
+static void tag_arcs PARAMS ((const char *, unsigned, unsigned));
+static void tag_lines PARAMS ((const char *, unsigned, unsigned));
+static void tag_arc_counts PARAMS ((const char *, unsigned, unsigned));
+static void tag_summary PARAMS ((const char *, unsigned, unsigned));
 extern int main PARAMS ((int, char **));
 
 typedef struct tag_format
 {
   unsigned tag;
   char const *name;
-  int (*proc) (const char *, unsigned, unsigned);
+  void (*proc) (const char *, unsigned, unsigned);
 } tag_format_t;
 
 static int flag_dump_contents = 0;
@@ -140,8 +140,6 @@ dump_file (filename)
 {
   unsigned tags[4];
   unsigned depth = 0;
-  unsigned magic, version;
-  unsigned tag, length;
   
   if (!gcov_open (filename, 1))
     {
@@ -149,16 +147,10 @@ dump_file (filename)
       return;
     }
   
-  if (gcov_read_unsigned (&magic) || gcov_read_unsigned (&version))
-    {
-    read_error:;
-      printf ("%s:read error at %lu\n", filename, gcov_save_position ());
-      gcov_close ();
-      return;
-    }
-
   /* magic */
   {
+    unsigned magic = gcov_read_unsigned ();
+    unsigned version = gcov_read_unsigned ();
     const char *type = NULL;
     char e[4], v[4], m[4];
     unsigned expected = GCOV_VERSION;
@@ -187,13 +179,14 @@ dump_file (filename)
       printf ("%s:warning:current version is `%.4s'\n", filename, e);
   }
 
-  while (!gcov_read_unsigned (&tag) && !gcov_read_unsigned (&length))
+  while (!gcov_is_eof ())
     {
+      unsigned tag = gcov_read_unsigned ();
+      unsigned length = gcov_read_unsigned ();
+      unsigned long base = gcov_position ();
       tag_format_t const *format;
       unsigned tag_depth;
-      long base, end;
-      
-      base = gcov_save_position ();
+      int error;
       
       if (!tag)
        tag_depth = depth;
@@ -231,57 +224,53 @@ dump_file (filename)
       print_prefix (filename, tag_depth);
       printf ("%08x:%4u:%s", tag, length, format->name);
       if (format->proc)
-       if ((*format->proc) (filename, tag, length))
-         goto read_error;
+       (*format->proc) (filename, tag, length);
+      
       printf ("\n");
-      end = gcov_save_position ();
-      gcov_resync (base, length);
-      if (format->proc && end != base + (long)length)
+      if (flag_dump_contents && format->proc)
        {
-         if (end > base + (long)length)
+         unsigned long actual_length = gcov_position () - base;
+         
+         if (actual_length > length)
            printf ("%s:record size mismatch %lu bytes overread\n",
-                   filename, (end - base) - length);
-         else
+                   filename, actual_length - length);
+         else if (length > actual_length)
            printf ("%s:record size mismatch %lu bytes unread\n",
-                   filename, length - (end - base));
+                   filename, length - actual_length);
+       }
+      gcov_seek (base, length);
+      if ((error = gcov_is_error ()))
+       {
+         printf (error < 0 ? "%s:counter overflow at %lu\n" :
+                 "%s:read error at %lu\n", filename, gcov_position ());
+         break;
        }
     }
-  if (!gcov_eof ())
-    goto read_error;
   gcov_close ();
 }
 
-static int
+static void
 tag_function (filename, tag, length)
      const char *filename ATTRIBUTE_UNUSED;
      unsigned tag ATTRIBUTE_UNUSED;
      unsigned length ATTRIBUTE_UNUSED;
 {
-  char *name = NULL;
-  unsigned checksum;
-  char *src = NULL;
-  unsigned lineno = 0;
-  unsigned long pos = gcov_save_position ();
+  const char *name;
+  unsigned long pos = gcov_position ();
   
-  if (gcov_read_string (&name)
-      || gcov_read_unsigned (&checksum))
-    return 1;
-
-  if (gcov_save_position () - pos != length
-      && (gcov_read_string (&src)
-         || gcov_read_unsigned (&lineno)))
-    return 1;
+  name = gcov_read_string ();
+  printf (" `%s'", name ? name : "NULL");
+  printf (" checksum=0x%08x", gcov_read_unsigned ());
 
-  printf (" `%s' checksum=0x%08x", name, checksum);
-  if (src)
-    printf (" %s:%u", src, lineno);
-  free (name);
-  free (src);
-  
-  return 0;
+  if (gcov_position () - pos < length)
+    {
+      name = gcov_read_string ();
+      printf (" %s", name ? name : "NULL");
+      printf (":%u", gcov_read_unsigned ());
+    }
 }
 
-static int
+static void
 tag_blocks (filename, tag, length)
      const char *filename ATTRIBUTE_UNUSED;
      unsigned tag ATTRIBUTE_UNUSED;
@@ -297,22 +286,14 @@ tag_blocks (filename, tag, length)
 
       for (ix = 0; ix != n_blocks; ix++)
        {
-         unsigned flags;
-         if (gcov_read_unsigned (&flags))
-           return 1;
          if (!(ix & 7))
            printf ("\n%s:\t\t%u", filename, ix);
-         printf (" %04x", flags);
+         printf (" %04x", gcov_read_unsigned ());
        }
-      
     }
-  else
-    gcov_skip (n_blocks * 4);
-  
-  return 0;
 }
 
-static int
+static void
 tag_arcs (filename, tag, length)
      const char *filename ATTRIBUTE_UNUSED;
      unsigned tag ATTRIBUTE_UNUSED;
@@ -324,29 +305,21 @@ tag_arcs (filename, tag, length)
   if (flag_dump_contents)
     {
       unsigned ix;
-      unsigned blockno;
-
-      if (gcov_read_unsigned (&blockno))
-       return 1;
+      unsigned blockno = gcov_read_unsigned ();
 
       for (ix = 0; ix != n_arcs; ix++)
        {
-         unsigned dst, flags;
+         unsigned dst = gcov_read_unsigned ();
+         unsigned flags = gcov_read_unsigned ();
          
-         if (gcov_read_unsigned (&dst) || gcov_read_unsigned (&flags))
-           return 1;
          if (!(ix & 3))
-           printf ("\n%s:\t\t%u:", filename, blockno);
+           printf ("\n%s:\tblock %u:", filename, blockno);
          printf (" %u:%04x", dst, flags);
        }
     }
-  else
-    gcov_skip (4 + n_arcs * 8);
-  
-  return 0;
 }
 
-static int
+static void
 tag_lines (filename, tag, length)
      const char *filename ATTRIBUTE_UNUSED;
      unsigned tag ATTRIBUTE_UNUSED;
@@ -354,26 +327,17 @@ tag_lines (filename, tag, length)
 {
   if (flag_dump_contents)
     {
-      char *source = NULL;
-      unsigned blockno;
+      unsigned blockno = gcov_read_unsigned ();
       char const *sep = NULL;
 
-      if (gcov_read_unsigned (&blockno))
-       return 1;
-      
       while (1)
        {
-         unsigned lineno;
+         const char *source = NULL;
+         unsigned lineno = gcov_read_unsigned ();
          
-         if (gcov_read_unsigned (&lineno))
-           {
-             free (source);
-             return 1;
-           }
          if (!lineno)
            {
-             if (gcov_read_string (&source))
-               return 1;
+             source = gcov_read_string ();
              if (!source)
                break;
              sep = NULL;
@@ -381,7 +345,7 @@ tag_lines (filename, tag, length)
          
          if (!sep)
            {
-             printf ("\n%s:\t\t%u:", filename, blockno);
+             printf ("\n%s:\tblock %u:", filename, blockno);
              sep = "";
            }
          if (lineno)
@@ -396,13 +360,9 @@ tag_lines (filename, tag, length)
            }
        }
     }
-  else
-    gcov_skip (length);
-  
-  return 0;
 }
 
-static int
+static void
 tag_arc_counts (filename, tag, length)
      const char *filename ATTRIBUTE_UNUSED;
      unsigned tag ATTRIBUTE_UNUSED;
@@ -417,23 +377,17 @@ tag_arc_counts (filename, tag, length)
 
       for (ix = 0; ix != n_counts; ix++)
        {
-         gcov_type count;
+         gcov_type count = gcov_read_counter ();
          
-         if (gcov_read_counter (&count))
-           return 1;
          if (!(ix & 7))
            printf ("\n%s:\t\t%u", filename, ix);
          printf (" ");
          printf (HOST_WIDEST_INT_PRINT_DEC, count);
        }
     }
-  else
-    gcov_skip (n_counts * 8);
-  
-  return 0;
 }
 
-static int
+static void
 tag_summary (filename, tag, length)
      const char *filename ATTRIBUTE_UNUSED;
      unsigned tag ATTRIBUTE_UNUSED;
@@ -441,8 +395,8 @@ tag_summary (filename, tag, length)
 {
   struct gcov_summary summary;
 
-  if (gcov_read_summary (&summary))
-    return 1;
+  gcov_read_summary (&summary);
+  
   printf (" checksum=0x%08x", summary.checksum);
   
   printf ("\n%s:\t\truns=%u, arcs=%u", filename,
@@ -459,5 +413,4 @@ tag_summary (filename, tag, length)
   printf (", sum_max=");
   printf (HOST_WIDEST_INT_PRINT_DEC, 
          (HOST_WIDEST_INT)summary.arc_sum_max);
-  return 0;
 }
index 04a01ac..3bd2729 100644 (file)
@@ -287,45 +287,44 @@ extern void __gcov_flush (void);
 /* Because small reads and writes, interspersed with seeks cause lots
    of disk activity, we buffer the entire count files.  */
 
-static FILE *gcov_file;
-static size_t gcov_position;
-static size_t gcov_length;
-static unsigned char *gcov_buffer;
-static size_t gcov_alloc;
-static int gcov_modified;
-static int gcov_errored = 1;
+static struct gcov_var
+{
+  FILE *file;
+  size_t position;
+  size_t length;
+  size_t alloc;
+  unsigned modified;
+  int error;
+  unsigned char *buffer;
+} gcov_var;
 
 /* Functions for reading and writing gcov files.  */
 static int gcov_open (const char */*name*/, int /*truncate*/);
 static int gcov_close (void);
 #if !IN_GCOV
 static unsigned char *gcov_write_bytes (unsigned);
-static int gcov_write_unsigned (unsigned);
+static void gcov_write_unsigned (unsigned);
 #if IN_LIBGCOV
-static int gcov_write_counter (gcov_type);
+static void gcov_write_counter (gcov_type);
 #endif
-static int gcov_write_string (const char *);
-static unsigned long gcov_reserve_length (void);
-static int gcov_write_length (unsigned long /*position*/);
+static void gcov_write_string (const char *);
+static unsigned long gcov_write_tag (unsigned);
+static void gcov_write_length (unsigned long /*position*/);
 #if IN_LIBGCOV
-static int gcov_write_summary (unsigned, const struct gcov_summary *);
+static void gcov_write_summary (unsigned, const struct gcov_summary *);
 #endif
 #endif /* !IN_GCOV */
 static const unsigned char *gcov_read_bytes (unsigned);
-static int gcov_read_unsigned (unsigned *);
-static int gcov_read_counter (gcov_type *);
-#if !IN_LIBGCOV
-static int gcov_read_string (char **);
-#endif
-static int gcov_read_summary (struct gcov_summary *);
-static unsigned long gcov_save_position (void);
-static int gcov_resync (unsigned long /*base*/, unsigned /*length */);
+static unsigned gcov_read_unsigned (void);
+static gcov_type gcov_read_counter (void);
+static const char *gcov_read_string (void);
+static void gcov_read_summary (struct gcov_summary *);
+
+static unsigned long gcov_position (void);
+static void gcov_seek (unsigned long /*base*/, unsigned /*length */);
 static unsigned long gcov_seek_end (void);
-static int gcov_skip (unsigned /*length*/);
-static int gcov_skip_string (unsigned /*length*/);
-static int gcov_ok (void);
-static int gcov_error (void);
-static int gcov_eof (void);
+static int gcov_is_eof (void);
+static int gcov_is_error (void);
 #if IN_GCOV > 0
 static time_t gcov_time (void);
 #endif
@@ -353,62 +352,63 @@ gcov_open (const char *name, int mode)
   s_flock.l_pid = getpid ();
 #endif
   
-  if (gcov_file)
+  if (gcov_var.file)
     abort ();
-  gcov_position = gcov_length = 0;
-  gcov_errored = gcov_modified = 0;
+  gcov_var.position = gcov_var.length = 0;
+  gcov_var.error = gcov_var.modified = 0;
   if (mode >= 0)
-    gcov_file = fopen (name, "r+b");
-  if (!gcov_file && mode <= 0)
+    gcov_var.file = fopen (name, "r+b");
+  if (!gcov_var.file && mode <= 0)
     {
       result = -1;
-      gcov_file = fopen (name, "w+b");
+      gcov_var.file = fopen (name, "w+b");
     }
-  if (!gcov_file)
+  if (!gcov_var.file)
     return 0;
 
 #if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
-  while (fcntl (fileno (gcov_file), F_SETLKW, &s_flock)
+  while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
         && errno == EINTR)
     continue;
 #endif
 
   if (result >= 0)
     {
-      if (fseek (gcov_file, 0, SEEK_END))
+      if (fseek (gcov_var.file, 0, SEEK_END))
        {
-         fclose (gcov_file);
-         gcov_file = 0;
+         fclose (gcov_var.file);
+         gcov_var.file = 0;
          return 0;
        }
-      gcov_length = ftell (gcov_file);
-      fseek (gcov_file, 0, SEEK_SET);
-      alloc += gcov_length;
+      gcov_var.length = ftell (gcov_var.file);
+      fseek (gcov_var.file, 0, SEEK_SET);
+      alloc += gcov_var.length;
     }
-  if (alloc > gcov_alloc)
+  if (alloc > gcov_var.alloc)
     {
-      if (gcov_buffer)
-       free (gcov_buffer);
-      gcov_alloc = alloc;
+      if (gcov_var.buffer)
+       free (gcov_var.buffer);
+      gcov_var.alloc = alloc;
 #if IN_LIBGCOV
-      gcov_buffer = malloc (gcov_alloc);
-      if (!gcov_buffer)
+      gcov_var.buffer = malloc (gcov_var.alloc);
+      if (!gcov_var.buffer)
        {
-         fclose (gcov_file);
-         gcov_file = 0;
-         gcov_length = 0;
-         gcov_alloc = 0;
+         fclose (gcov_var.file);
+         gcov_var.file = 0;
+         gcov_var.length = 0;
+         gcov_var.alloc = 0;
          return 0;
        }
 #else
-      gcov_buffer = xmalloc (gcov_alloc);
+      gcov_var.buffer = xmalloc (gcov_var.alloc);
 #endif
     }
-  if (result >= 0 && fread (gcov_buffer, gcov_length, 1, gcov_file) != 1)
+  if (result >= 0
+      && fread (gcov_var.buffer, gcov_var.length, 1, gcov_var.file) != 1)
     {
-      fclose (gcov_file);
-      gcov_file = 0;
-      gcov_length = 0;
+      fclose (gcov_var.file);
+      gcov_var.file = 0;
+      gcov_var.length = 0;
       return 0;
     }
   return result;
@@ -422,17 +422,23 @@ gcov_close ()
 {
   int result = 0;
   
-  if (gcov_file)
+  if (gcov_var.file)
     {
-      if (gcov_modified
-         && (fseek (gcov_file, 0, SEEK_SET)
-             || fwrite (gcov_buffer, gcov_length, 1, gcov_file) != 1))
-       result = -1;
-      fclose (gcov_file);
-      gcov_file = 0;
-      gcov_length = 0;
+      if (gcov_var.modified
+         && (fseek (gcov_var.file, 0, SEEK_SET)
+             || fwrite (gcov_var.buffer, gcov_var.length,
+                        1, gcov_var.file) != 1))
+       result = 1;
+      fclose (gcov_var.file);
+      gcov_var.file = 0;
+      gcov_var.length = 0;
     }
-  return result || gcov_errored;
+#if !IN_LIBGCOV
+  free (gcov_var.buffer);
+  gcov_var.alloc = 0;
+  gcov_var.buffer = 0;
+#endif
+  return result ? 1 : gcov_var.error;
 }
 
 #if !IN_GCOV
@@ -444,167 +450,177 @@ gcov_write_bytes (unsigned bytes)
 {
   char unsigned *result;
 
-  if (gcov_position + bytes > gcov_alloc)
+  if (gcov_var.position + bytes > gcov_var.alloc)
     {
-      size_t new_size = (gcov_alloc + bytes) * 3 / 2;
+      size_t new_size = (gcov_var.alloc + bytes) * 3 / 2;
 
-      if (!gcov_buffer)
+      if (!gcov_var.buffer)
        return 0;
 #if IN_LIBGCOV
-      result = realloc (gcov_buffer, new_size);
+      result = realloc (gcov_var.buffer, new_size);
       if (!result)
        {
-         free (gcov_buffer);
-         gcov_buffer = 0;
-         gcov_alloc = 0;
-         gcov_position = gcov_length = 0;
+         free (gcov_var.buffer);
+         gcov_var.buffer = 0;
+         gcov_var.alloc = 0;
+         gcov_var.position = gcov_var.length = 0;
+         gcov_var.error = 1;
          return 0;
        }
 #else
-      result = xrealloc (gcov_buffer, new_size);
+      result = xrealloc (gcov_var.buffer, new_size);
 #endif
-      gcov_alloc = new_size;
-      gcov_buffer = result;
+      gcov_var.alloc = new_size;
+      gcov_var.buffer = result;
     }
   
-  result = &gcov_buffer[gcov_position];
-  gcov_position += bytes;
-  gcov_modified = 1;
-  if (gcov_position > gcov_length)
-    gcov_length = gcov_position;
+  result = &gcov_var.buffer[gcov_var.position];
+  gcov_var.position += bytes;
+  gcov_var.modified = 1;
+  if (gcov_var.position > gcov_var.length)
+    gcov_var.length = gcov_var.position;
   return result;
 }
 
-/* Write VALUE to coverage file.  Return nonzero if failed due to
-   file i/o error, or value error.  */
+/* Write unsigned VALUE to coverage file.  Sets error flag
+   appropriately.  */
 
-static int
+static void
 gcov_write_unsigned (unsigned value)
 {
   unsigned char *buffer = gcov_write_bytes (4);
   unsigned ix;
 
   if (!buffer)
-    return 1;
-  
+    return;
   for (ix = 4; ix--; )
     {
       buffer[ix] = value;
       value >>= 8;
     }
-  return sizeof (value) > 4 && value;
+  if (sizeof (value) > 4 && value)
+    gcov_var.error = -1;
+
+  return;
 }
 
-/* Write VALUE to coverage file.  Return nonzero if failed due to
-   file i/o error, or value error.  Negative values are not checked
-   here -- they are checked in gcov_read_counter.  */
+/* Write counter VALUE to coverage file.  Sets error flag
+   appropriately.  */
 
 #if IN_LIBGCOV
-static int
+static void
 gcov_write_counter (gcov_type value)
 {
   unsigned char *buffer = gcov_write_bytes (8);
   unsigned ix;
 
   if (!buffer)
-    return 1;
-  
+    return;
   for (ix = 8; ix--; )
     {
       buffer[ix] = value;
       value >>= 8;
     }
-  return sizeof (value) > 8 && value;
+  if ((sizeof (value) > 8 && value) || value < 0)
+    gcov_var.error = -1;
+  return;
 }
 #endif /* IN_LIBGCOV */
 
-/* Write VALUE to coverage file.  Return nonzero if failed due to
-   file i/o error, or value error.  */
+/* Write STRING to coverage file.  Sets error flag on file
+   error, overflow flag on overflow */
 
-static int
+static void
 gcov_write_string (const char *string)
 {
+  unsigned length = 0;
+  unsigned pad = 0;
+  unsigned rem = 0;
+  unsigned char *buffer;
+
   if (string)
     {
-      unsigned length = strlen (string);
-      unsigned pad = 0;
-      unsigned rem = 4 - (length & 3);
-      unsigned char *buffer;
-
-      if (gcov_write_unsigned (length))
-       return 1;
-      buffer = gcov_write_bytes (length + rem);
-      if (!buffer)
-       return 1;
-      memcpy (buffer, string, length);
-      memcpy (buffer + length, &pad, rem);
-      return 0;
+      length = strlen (string);
+      rem = 4 - (length & 3);
+    }
+  
+  buffer = gcov_write_bytes (4 + length + rem);
+  if (buffer)
+    {
+      unsigned ix;
+      unsigned value = length;
+      
+      for (ix = 4; ix--; )
+       {
+         buffer[ix] = value;
+         value >>= 8;
+       }
+      memcpy (buffer + 4, string, length);
+      memcpy (buffer + 4 + length, &pad, rem);
     }
-  else
-    return gcov_write_unsigned (0);
 }
 
-/* Allocate space to write a record tag length.  Return a value to be
-   used for gcov_write_length.  */
+/* Write a tag TAG and reserve space for the record length. Return a
+   value to be used for gcov_write_length.  */
 
 static unsigned long
-gcov_reserve_length (void)
+gcov_write_tag (unsigned tag)
 {
-  unsigned long result = gcov_position;
-  unsigned char *buffer = gcov_write_bytes (4);
+  unsigned long result = gcov_var.position;
+  unsigned char *buffer = gcov_write_bytes (8);
+  unsigned ix;
 
   if (!buffer)
     return 0;
-  memset (buffer, 0, 4);
+  for (ix = 4; ix--; )
+    {
+      buffer[ix] = tag;
+      tag >>= 8;
+    }
+  memset (buffer + 4, 0, 4);
   return result;
 }
 
-/* Write a record length at PLACE.  The current file position is the
-   end of the record, and is restored before returning.  Returns
-   nonzero on failure.  */
+/* Write a record length using POSITION, which was returned by
+   gcov_write_tag.  The current file position is the end of the
+   record, and is restored before returning.  Returns nonzero on
+   overflow.  */
 
-static int
+static void
 gcov_write_length (unsigned long position)
 {
-  unsigned length = gcov_position - position - 4;
-  unsigned char *buffer = &gcov_buffer[position];
-  unsigned ix;
-
-  if (!position)
-    return 1;
-  for (ix = 4; ix--; )
+  if (position)
     {
-      buffer[ix] = length;
-      length >>= 8;
+      unsigned length = gcov_var.position - position - 8;
+      unsigned char *buffer = &gcov_var.buffer[position + 4];
+      unsigned ix;
+      
+      for (ix = 4; ix--; )
+       {
+         buffer[ix] = length;
+         length >>= 8;
+       }
     }
-  return 0;
 }
 
 #if IN_LIBGCOV
-/* Write a summary structure to the gcov file.  */
+/* Write a summary structure to the gcov file.  Return non-zero on
+   overflow.  */
 
-static int
+static void
 gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
 {
-  volatile unsigned long base; /* volatile is necessary to work around
-                                 a compiler bug. */
-
-  if (gcov_write_unsigned (tag))
-    return 1;
-  base = gcov_reserve_length ();
-  if (gcov_write_unsigned (summary->checksum))
-    return 1;
-  if (gcov_write_unsigned (summary->runs)
-      || gcov_write_unsigned (summary->arcs))
-    return 1;
-  if (gcov_write_counter (summary->arc_sum)
-      || gcov_write_counter (summary->arc_max_one)
-      || gcov_write_counter (summary->arc_max_sum)
-      || gcov_write_counter (summary->arc_sum_max))
-    return 1;
-  if (gcov_write_length (base))
-    return 1;
-  return 0;
+  unsigned long base;
+
+  base = gcov_write_tag (tag);
+  gcov_write_unsigned (summary->checksum);
+  gcov_write_unsigned (summary->runs);
+  gcov_write_unsigned (summary->arcs);
+  gcov_write_counter (summary->arc_sum);
+  gcov_write_counter (summary->arc_max_one);
+  gcov_write_counter (summary->arc_max_sum);
+  gcov_write_counter (summary->arc_sum_max);
+  gcov_write_length (base);
 }
 #endif /* IN_LIBGCOV */
 
@@ -618,127 +634,118 @@ gcov_read_bytes (unsigned bytes)
 {
   const unsigned char *result;
   
-  if (gcov_position + bytes > gcov_length)
-    return 0;
-  result = &gcov_buffer[gcov_position];
-  gcov_position += bytes;
+  if (gcov_var.position + bytes > gcov_var.length)
+    {
+      gcov_var.error = 1;
+      return 0;
+    }
+  
+  result = &gcov_var.buffer[gcov_var.position];
+  gcov_var.position += bytes;
   return result;
 }
 
-/* Read *VALUE_P from coverage file.  Return nonzero if failed
-   due to file i/o error, or range error.  */
+/* Read unsigned value from a coverage file. Sets error flag on file
+   error, overflow flag on overflow */
 
-static int
-gcov_read_unsigned (unsigned *value_p)
+static unsigned
+gcov_read_unsigned ()
 {
   unsigned value = 0;
   unsigned ix;
   const unsigned char *buffer = gcov_read_bytes (4);
 
   if (!buffer)
-    return 1;
+    return 0;
   for (ix = sizeof (value); ix < 4; ix++)
     if (buffer[ix])
-      return 1;
+      gcov_var.error = -1;
   for (ix = 0; ix != 4; ix++)
     {
       value <<= 8;
       value |= buffer[ix];
     }
-  *value_p = value;
-  return 0;
+  return value;
 }
 
-/* Read *VALUE_P from coverage file.  Return nonzero if failed
-   due to file i/o error, or range error.  */
+/* Read counter value from a coverage file. Sets error flag on file
+   error, overflow flag on overflow */
 
-static int
-gcov_read_counter (gcov_type *value_p)
+static gcov_type
+gcov_read_counter ()
 {
   gcov_type value = 0;
   unsigned ix;
   const unsigned char *buffer = gcov_read_bytes (8);
 
   if (!buffer)
-    return 1;
+    return 0;
   for (ix = sizeof (value); ix < 8; ix++)
     if (buffer[ix])
-      return 1;
+      gcov_var.error = -1;
   for (ix = 0; ix != 8; ix++)
     {
       value <<= 8;
       value |= buffer[ix];
     }
-
-  *value_p = value;
-  return value < 0;
+  if (value < 0)
+    gcov_var.error = -1;
+  return value;
 }
 
-#if !IN_LIBGCOV
-
-/* Read string from coverage file.  A buffer is allocated and returned
-   in *STRING_P.  Return nonzero if failed due to file i/o error, or
-   range error.  Uses xmalloc to allocate the string buffer.  */
+/* Read string from coverage file. Returns a pointer to a static
+   buffer, or NULL on empty string. You must copy the string before
+   calling another gcov function.  */
 
-static int
-gcov_read_string (char **string_p)
+static const char *
+gcov_read_string ()
 {
-  unsigned length;
-  const unsigned char *buffer;
-
-  if (gcov_read_unsigned (&length))
-    return 1;
-
-  free (*string_p);
-  *string_p = NULL;
+  unsigned length = gcov_read_unsigned ();
+  
   if (!length)
     return 0;
 
   length += 4 - (length & 3);
-  buffer = gcov_read_bytes (length);
-  if (!buffer)
-    return 1;
-  
-  *string_p = xmalloc (length);
-  if (!*string_p)
-    return 1;
-
-  memcpy (*string_p, buffer, length);
-  return 0;
+  return (const char *) gcov_read_bytes (length);
 }
 
-#endif /* !IN_LIBGCOV */
-
 #define GCOV_SUMMARY_LENGTH 44
-static int
+static void
 gcov_read_summary (struct gcov_summary *summary)
 {
-  return (gcov_read_unsigned (&summary->checksum)
-         || gcov_read_unsigned (&summary->runs)
-         || gcov_read_unsigned (&summary->arcs)
-         || gcov_read_counter (&summary->arc_sum)
-         || gcov_read_counter (&summary->arc_max_one)
-         || gcov_read_counter (&summary->arc_max_sum)
-         || gcov_read_counter (&summary->arc_sum_max));
+  summary->checksum = gcov_read_unsigned ();
+  summary->runs = gcov_read_unsigned ();
+  summary->arcs = gcov_read_unsigned ();
+  summary->arc_sum = gcov_read_counter ();
+  summary->arc_max_one = gcov_read_counter ();
+  summary->arc_max_sum =  gcov_read_counter ();
+  summary->arc_sum_max = gcov_read_counter ();
 }
 
 /* Save the current position in the gcov file.  */
 
 static inline unsigned long
-gcov_save_position (void)
+gcov_position (void)
 {
-  return gcov_position;
+  return gcov_var.position;
 }
 
 /* Reset to a known position.  BASE should have been obtained from
    gcov_save_position, LENGTH should be a record length, or zero.  */
 
-static inline int
-gcov_resync (unsigned long base, unsigned length)
+static inline void
+gcov_seek (unsigned long base, unsigned length)
 {
-  if (gcov_buffer)
-    gcov_position = base + length;
-  return 0;
+  if (gcov_var.buffer)
+    {
+      base += length;
+      if (gcov_var.length < base)
+       {
+         gcov_var.error = 1;
+         base = gcov_var.length;
+       }
+      gcov_var.position = base;
+    }
 }
 
 /* Move to the end of the gcov file.  */
@@ -746,53 +753,24 @@ gcov_resync (unsigned long base, unsigned length)
 static inline unsigned long
 gcov_seek_end ()
 {
-  gcov_position = gcov_length;
-  return gcov_position;
-}
-
-/* Skip LENGTH bytes in the file.  */
-
-static inline int
-gcov_skip (unsigned length)
-{
-  if (gcov_length < gcov_position + length)
-    return 1;
-  gcov_position += length;
-  return 0;
-}
-
-/* Skip a string of LENGTH bytes.  */
-
-static inline int
-gcov_skip_string (unsigned length)
-{
-  return gcov_skip (length + 4 - (length & 3));
+  gcov_var.position = gcov_var.length;
+  return gcov_var.position;
 }
 
 /* Tests whether we have reached end of .da file.  */
 
 static inline int
-gcov_eof ()
+gcov_is_eof ()
 {
-  return gcov_position == gcov_length;
+  return gcov_var.position == gcov_var.length;
 }
 
 /* Return non-zero if the error flag is set.  */
 
 static inline int
-gcov_ok ()
+gcov_is_error ()
 {
-  return gcov_file != 0 && !gcov_errored;
-}
-
-/* Set the error flag. */
-static inline int
-gcov_error ()
-{
-  int error = gcov_errored;
-  
-  gcov_errored = 1;
-  return error;
+  return gcov_var.file ? gcov_var.error : 1;
 }
 
 #if IN_GCOV > 0
@@ -803,7 +781,7 @@ gcov_time ()
 {
   struct stat status;
   
-  if (fstat (fileno (gcov_file), &status))
+  if (fstat (fileno (gcov_var.file), &status))
     return 0;
   else
     return status.st_mtime;
index 5a2f429..b6cbbc8 100644 (file)
@@ -321,7 +321,7 @@ static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN;
 static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN;
 static void process_file PARAMS ((const char *));
 static void create_file_names PARAMS ((const char *));
-static source_t *find_source PARAMS ((char *));
+static source_t *find_source PARAMS ((const char *));
 static int read_graph_file PARAMS ((void));
 static int read_count_file PARAMS ((void));
 static void solve_flow_graph PARAMS ((function_t *));
@@ -673,31 +673,29 @@ create_file_names (file_name)
   return;
 }
 
-/* Find or create a source file structure for FILE_NAME. Free
-   FILE_NAME appropriately */
+/* Find or create a source file structure for FILE_NAME. Copies
+   FILE_NAME on creation */
 
 static source_t *
 find_source (file_name)
-     char *file_name;
+     const char *file_name;
 {
-
   source_t *src;
+
+  if (!file_name)
+    file_name = "<unknown>";
   
   for (src = sources; src; src = src->next)
     if (!strcmp (file_name, src->name))
-      {
-       free (file_name);
-       break;
-      }
-  if (!src)
-    {
-      src = (source_t *)xcalloc (1, sizeof (source_t));
-      src->name = file_name;
-      src->coverage.name = file_name;
-      src->index = sources ? sources->index + 1 : 1;
-      src->next = sources;
-      sources = src;
-    }
+      return src;
+  
+  src = (source_t *)xcalloc (1, sizeof (source_t));
+  src->name = xstrdup (file_name);
+  src->coverage.name = src->name;
+  src->index = sources ? sources->index + 1 : 1;
+  src->next = sources;
+  sources = src;
+
   return src;
 }
 
@@ -706,9 +704,8 @@ find_source (file_name)
 static int
 read_graph_file ()
 {
-  unsigned magic, version;
+  unsigned version;
   unsigned current_tag = 0;
-  unsigned tag;
   struct function_info *fn = NULL;
   source_t *src = NULL;
   unsigned ix;
@@ -719,52 +716,46 @@ read_graph_file ()
       return 1;
     }
   bbg_file_time = gcov_time ();
-  if (gcov_read_unsigned (&magic) || magic != GCOV_GRAPH_MAGIC)
+  if (gcov_read_unsigned () != GCOV_GRAPH_MAGIC)
     {
       fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
       gcov_close ();
       return 1;
     }
 
-  if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
+  version = gcov_read_unsigned ();
+  if (version != GCOV_VERSION)
     {
       char v[4], e[4];
-
-      magic = GCOV_VERSION;
+      unsigned required = GCOV_VERSION;
       
-      for (ix = 4; ix--; magic >>= 8, version >>= 8)
+      for (ix = 4; ix--; required >>= 8, version >>= 8)
        {
          v[ix] = version;
-         e[ix] = magic;
+         e[ix] = required;
        }
       fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
               bbg_file_name, v, e);
     }
   
-  while (!gcov_read_unsigned (&tag))
+  while (!gcov_is_eof ())
     {
-      unsigned length;
-      long base;
-
-      if (gcov_read_unsigned (&length))
-       goto corrupt;
-
-      base = gcov_save_position ();
-
+      unsigned tag = gcov_read_unsigned ();
+      unsigned length = gcov_read_unsigned ();
+      unsigned long base = gcov_position ();
+      
       if (tag == GCOV_TAG_FUNCTION)
        {
-         char *function_name = NULL;
-         char *function_file = NULL;
+         char *function_name;
          unsigned checksum, lineno;
          source_t *src;
          function_t *probe, *prev;
 
-         if (gcov_read_string (&function_name)
-             || gcov_read_unsigned (&checksum)
-             || gcov_read_string (&function_file)
-             || gcov_read_unsigned (&lineno))
-           goto corrupt;
-         src = find_source (function_file);
+         function_name = xstrdup (gcov_read_string ());
+         checksum = gcov_read_unsigned ();
+         src = find_source (gcov_read_string ());
+         lineno = gcov_read_unsigned ();
+         
          fn = (function_t *)xcalloc (1, sizeof (function_t));
          fn->name = function_name;
          fn->checksum = checksum;
@@ -803,33 +794,24 @@ read_graph_file ()
              fn->blocks
                = (block_t *)xcalloc (fn->num_blocks, sizeof (block_t));
              for (ix = 0; ix != num_blocks; ix++)
-               {
-                 unsigned flags;
-                 
-                 if (gcov_read_unsigned (&flags))
-                   goto corrupt;
-                 fn->blocks[ix].flags = flags;
-               }
+               fn->blocks[ix].flags = gcov_read_unsigned ();
            }
        }
       else if (fn && tag == GCOV_TAG_ARCS)
        {
-         unsigned src;
+         unsigned src = gcov_read_unsigned ();
          unsigned num_dests = (length - 4) / 8;
-         unsigned dest, flags;
 
-         if (gcov_read_unsigned (&src)
-             || src >= fn->num_blocks
-             || fn->blocks[src].succ)
+         if (src >= fn->num_blocks || fn->blocks[src].succ)
            goto corrupt;
          
          while (num_dests--)
            {
              struct arc_info *arc;
+             unsigned dest = gcov_read_unsigned ();
+             unsigned flags = gcov_read_unsigned ();
              
-             if (gcov_read_unsigned (&dest)
-                 || gcov_read_unsigned (&flags)
-                 || dest >= fn->num_blocks)
+             if (dest >= fn->num_blocks)
                goto corrupt;
              arc = (arc_t *) xcalloc (1, sizeof (arc_t));
              
@@ -875,21 +857,17 @@ read_graph_file ()
        }
       else if (fn && tag == GCOV_TAG_LINES)
        {
-         unsigned blockno;
+         unsigned blockno = gcov_read_unsigned ();
          unsigned *line_nos
            = (unsigned *)xcalloc ((length - 4) / 4, sizeof (unsigned));
 
-         if (gcov_read_unsigned (&blockno)
-             || blockno >= fn->num_blocks
-             || fn->blocks[blockno].u.line.encoding)
+         if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
            goto corrupt;
          
          for (ix = 0; ;  )
            {
-             unsigned lineno;
+             unsigned lineno = gcov_read_unsigned ();
              
-             if (gcov_read_unsigned (&lineno))
-               goto corrupt;
              if (lineno)
                {
                  if (!ix)
@@ -903,10 +881,8 @@ read_graph_file ()
                }
              else
                {
-                 char *file_name = NULL;
+                 const char *file_name = gcov_read_string ();
                  
-                 if (gcov_read_string (&file_name))
-                   goto corrupt;
                  if (!file_name)
                    break;
                  src = find_source (file_name);
@@ -924,7 +900,8 @@ read_graph_file ()
          fn = NULL;
          current_tag = 0;
        }
-      if (gcov_resync (base, length))
+      gcov_seek (base, length);
+      if (gcov_is_error ())
        {
        corrupt:;
          fnotice (stderr, "%s:corrupted\n", bbg_file_name);
@@ -994,8 +971,7 @@ static int
 read_count_file ()
 {
   unsigned ix;
-  char *function_name_buffer = NULL;
-  unsigned magic, version;
+  unsigned version;
   function_t *fn = NULL;
 
   if (!gcov_open (da_file_name, 1))
@@ -1003,63 +979,44 @@ read_count_file ()
       fnotice (stderr, "%s:cannot open data file\n", da_file_name);
       return 1;
     }
-  if (gcov_read_unsigned (&magic) || magic != GCOV_DATA_MAGIC)
+  if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
     {
       fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
     cleanup:;
-      free (function_name_buffer);
       gcov_close ();
       return 1;
     }
-  if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
+  version = gcov_read_unsigned ();
+  if (version != GCOV_VERSION)
     {
       char v[4], e[4];
+      unsigned desired = GCOV_VERSION;
       
-      magic = GCOV_VERSION;
-      for (ix = 4; ix--; magic >>= 8, version >>= 8)
+      for (ix = 4; ix--; desired >>= 8, version >>= 8)
        {
          v[ix] = version;
-         e[ix] = magic;
+         e[ix] = desired;
        }
       fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
               da_file_name, v, e);
     }
   
-  while (1)
+  while (!gcov_is_eof ())
     {
-      unsigned tag, length;
-      long base;
-      
-      if (gcov_read_unsigned (&tag)
-         || gcov_read_unsigned (&length))
-       {
-         if (gcov_eof ())
-           break;
-         
-       corrupt:;
-         fnotice (stderr, "%s:corrupted\n", da_file_name);
-         goto cleanup;
-       }
-      base = gcov_save_position ();
+      unsigned tag = gcov_read_unsigned ();
+      unsigned length = gcov_read_unsigned ();
+      unsigned long base = gcov_position ();
+      int error;
+
       if (tag == GCOV_TAG_OBJECT_SUMMARY)
-       {
-         if (gcov_read_summary (&object_summary))
-           goto corrupt;
-       }
+       gcov_read_summary (&object_summary);
       else if (tag == GCOV_TAG_PROGRAM_SUMMARY
               || tag == GCOV_TAG_INCORRECT_SUMMARY)
-       {
-         program_count++;
-         gcov_resync (base, length);
-       }
+       program_count++;
       else if (tag == GCOV_TAG_FUNCTION)
        {
-         unsigned checksum;
+         const char *function_name = gcov_read_string ();
          struct function_info *fn_n = functions;
-         
-         if (gcov_read_string (&function_name_buffer)
-             || gcov_read_unsigned (&checksum))
-           goto corrupt;
 
          for (fn = fn ? fn->next : NULL; ; fn = fn->next)
            {
@@ -1070,20 +1027,20 @@ read_count_file ()
              else
                {
                  fnotice (stderr, "%s:unknown function `%s'\n",
-                          da_file_name, function_name_buffer);
+                          da_file_name, function_name);
                  break;
                }
-             if (!strcmp (fn->name, function_name_buffer))
+             if (!strcmp (fn->name, function_name))
                break;
            }
 
          if (!fn)
            ;
-         else if (checksum != fn->checksum)
+         else if (gcov_read_unsigned () != fn->checksum)
            {
            mismatch:;
              fnotice (stderr, "%s:profile mismatch for `%s'\n",
-                      da_file_name, function_name_buffer);
+                      da_file_name, fn->name);
              goto cleanup;
            }
        }
@@ -1097,20 +1054,18 @@ read_count_file ()
              = (gcov_type *)xcalloc (fn->num_counts, sizeof (gcov_type));
          
          for (ix = 0; ix != fn->num_counts; ix++)
-           {
-             gcov_type count;
-             
-             if (gcov_read_counter (&count))
-               goto corrupt;
-             fn->counts[ix] += count;
-           }
+           fn->counts[ix] += gcov_read_counter ();
+       }
+      gcov_seek (base, length);
+      if ((error = gcov_is_error ()))
+       {
+         fnotice (stderr, error < 0
+                  ? "%s:overflowed\n" : "%s:corrupted\n", da_file_name);
+         goto cleanup;
        }
-      else
-       gcov_resync (base, length);
     }
 
   gcov_close ();
-  free (function_name_buffer);
   return 0;
 }
 
index 37d3e80..ea197f8 100644 (file)
@@ -110,14 +110,14 @@ gcov_exit (void)
     {
       struct gcov_summary object;
       struct gcov_summary local_prg;
+      int error;
       int merging;
-      long base;
+      unsigned long base;
       const struct function_info *fn_info;
       gcov_type **counters;
       gcov_type *count_ptr;
       gcov_type object_max_one = 0;
-      gcov_type count;
-      unsigned tag, length, flength, checksum;
+      unsigned tag, length;
       unsigned arc_data_index, f_sect_index, sect_index;
 
       ptr->wkspc = 0;
@@ -167,7 +167,7 @@ gcov_exit (void)
       if (merging > 0)
        {
          /* Merge data from file.  */
-         if (gcov_read_unsigned (&tag) || tag != GCOV_DATA_MAGIC)
+         if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
            {
              fprintf (stderr, "profiling:%s:Not a gcov data file\n",
                       ptr->filename);
@@ -176,7 +176,8 @@ gcov_exit (void)
              ptr->filename = 0;
              continue;
            }
-         if (gcov_read_unsigned (&length) || length != GCOV_VERSION)
+         length = gcov_read_unsigned ();
+         if (length != GCOV_VERSION)
            {
              gcov_version_mismatch (ptr, length);
              goto read_fatal;
@@ -186,13 +187,8 @@ gcov_exit (void)
          for (ix = ptr->n_functions, fn_info = ptr->functions;
               ix--; fn_info++)
            {
-             if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length))
-               {
-               read_error:;
-                 fprintf (stderr, "profiling:%s:Error merging\n",
-                          ptr->filename);
-                 goto read_fatal;
-               }
+             tag = gcov_read_unsigned ();
+             length = gcov_read_unsigned ();
 
              /* Check function */
              if (tag != GCOV_TAG_FUNCTION)
@@ -203,12 +199,8 @@ gcov_exit (void)
                  goto read_fatal;
                }
 
-             if (gcov_read_unsigned (&flength)
-                 || gcov_skip_string (flength)
-                 || gcov_read_unsigned (&checksum))
-               goto read_error;
-             if (flength != strlen (fn_info->name)
-                 || checksum != fn_info->checksum)
+             if (strcmp (gcov_read_string (), fn_info->name)
+                 || gcov_read_unsigned () != fn_info->checksum)
                goto read_mismatch;
 
              /* Counters.  */
@@ -218,9 +210,9 @@ gcov_exit (void)
                {
                  unsigned n_counters;
 
-                 if (gcov_read_unsigned (&tag)
-                     || gcov_read_unsigned (&length))
-                   goto read_error;
+                 tag = gcov_read_unsigned ();
+                 length = gcov_read_unsigned ();
+                 
                  for (sect_index = 0;
                       sect_index < ptr->n_counter_sections;
                       sect_index++)
@@ -235,40 +227,42 @@ gcov_exit (void)
                    goto read_mismatch;
                 
                  for (jx = 0; jx < n_counters; jx++)
-                   if (gcov_read_counter (&count))
-                     goto read_error;
-                   else
-                     counters[sect_index][jx] += count;
+                   counters[sect_index][jx] += gcov_read_counter ();
+                 
                  counters[sect_index] += n_counters;
                }
+             if ((error = gcov_is_error ()))
+               goto read_error;
            }
 
          /* Check object summary */
-         if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length))
-           goto read_error;
-         if (tag != GCOV_TAG_OBJECT_SUMMARY)
+         if (gcov_read_unsigned () != GCOV_TAG_OBJECT_SUMMARY)
            goto read_mismatch;
-         if (gcov_read_summary (&object))
-           goto read_error;
+         gcov_read_unsigned ();
+         gcov_read_summary (&object);
 
          /* Check program summary */
-         while (1)
+         while (!gcov_is_eof ())
            {
-             long base = gcov_save_position ();
+             unsigned long base = gcov_position ();
              
-             if (gcov_read_unsigned (&tag)
-                 || gcov_read_unsigned (&length))
-               {
-                 if (gcov_eof ())
-                   break;
-                 goto read_error;
-               }
+             tag = gcov_read_unsigned ();
+             gcov_read_unsigned ();
              if (tag != GCOV_TAG_PROGRAM_SUMMARY
                  && tag != GCOV_TAG_PLACEHOLDER_SUMMARY
                  && tag != GCOV_TAG_INCORRECT_SUMMARY)
                goto read_mismatch;
-             if (gcov_read_summary (&local_prg))
-               goto read_error;
+             gcov_read_summary (&local_prg);
+             if ((error = gcov_is_error ()))
+               {
+               read_error:;
+                 fprintf (stderr, error < 0 ?
+                          "profiling:%s:Overflow merging\n" :
+                          "profiling:%s:Error merging\n",
+                          ptr->filename);
+                 goto read_fatal;
+               }
+             
              if (local_prg.checksum != program.checksum)
                continue;
              if (tag == GCOV_TAG_PLACEHOLDER_SUMMARY)
@@ -294,7 +288,7 @@ gcov_exit (void)
              ptr->wkspc = base;
              break;
            }
-         gcov_resync (0, 0);
+         gcov_seek (0, 0);
        }
 
       object.runs++;
@@ -305,17 +299,8 @@ gcov_exit (void)
       object.arc_sum_max += object_max_one;
       
       /* Write out the data.  */
-      if (/* magic */
-         gcov_write_unsigned (GCOV_DATA_MAGIC)
-         /* version number */
-         || gcov_write_unsigned (GCOV_VERSION))
-       {
-       write_error:;
-         gcov_close ();
-         fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
-         ptr->filename = 0;
-         continue;
-       }
+      gcov_write_unsigned (GCOV_DATA_MAGIC);
+      gcov_write_unsigned (GCOV_VERSION);
       
       /* Write execution counts for each function.  */
       for (ix = 0; ix < ptr->n_counter_sections; ix++)
@@ -323,14 +308,10 @@ gcov_exit (void)
       for (ix = ptr->n_functions, fn_info = ptr->functions; ix--; fn_info++)
        {
          /* Announce function.  */
-         if (gcov_write_unsigned (GCOV_TAG_FUNCTION)
-             || !(base = gcov_reserve_length ())
-             /* function name */
-             || gcov_write_string (fn_info->name)
-             /* function checksum */
-             || gcov_write_unsigned (fn_info->checksum)
-             || gcov_write_length (base))
-           goto write_error;
+         base = gcov_write_tag (GCOV_TAG_FUNCTION);
+         gcov_write_string (fn_info->name);
+         gcov_write_unsigned (fn_info->checksum);
+         gcov_write_length (base);
 
          /* counters.  */
          for (f_sect_index = 0;
@@ -346,10 +327,7 @@ gcov_exit (void)
              if (sect_index == ptr->n_counter_sections)
                abort ();
 
-             if (gcov_write_unsigned (tag)
-                 || !(base = gcov_reserve_length ()))
-               goto write_error;
-         
+             base = gcov_write_tag (tag);
              for (jx = fn_info->counter_sections[f_sect_index].n_counters; jx--;)
                {
                  gcov_type count = *counters[sect_index]++;
@@ -360,41 +338,33 @@ gcov_exit (void)
                      if (object.arc_max_sum < count)
                        object.arc_max_sum = count;
                    }
-                 if (gcov_write_counter (count))
-                   goto write_error; /* RIP Edsger Dijkstra */
+                 gcov_write_counter (count);
                }
-             if (gcov_write_length (base))
-               goto write_error;
+             gcov_write_length (base);
            }
        }
 
       /* Object file summary.  */
-      if (gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object))
-       goto write_error;
+      gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
 
       if (merging)
        {
          ptr->wkspc = gcov_seek_end ();
-         if (gcov_write_summary (GCOV_TAG_PLACEHOLDER_SUMMARY,
-                                 &program))
-           goto write_error;
+         gcov_write_summary (GCOV_TAG_PLACEHOLDER_SUMMARY, &program);
        }
       else if (ptr->wkspc)
        {
          /* Zap trailing program summary */
-         if (gcov_resync (ptr->wkspc, 0))
-           goto write_error;
+         gcov_seek (ptr->wkspc, 0);
          if (!local_prg.runs)
            ptr->wkspc = 0;
-         if (gcov_write_unsigned (local_prg.runs
-                                  ? GCOV_TAG_PLACEHOLDER_SUMMARY
-                                  : GCOV_TAG_INCORRECT_SUMMARY))
-           goto write_error;
+         gcov_write_unsigned (local_prg.runs
+                              ? GCOV_TAG_PLACEHOLDER_SUMMARY
+                              : GCOV_TAG_INCORRECT_SUMMARY);
        }
-
       if (gcov_close ())
        {
-         fprintf (stderr, "profiling:%s:Error closing\n", ptr->filename);
+         fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
          ptr->filename = 0;
        }
       else
@@ -427,11 +397,10 @@ gcov_exit (void)
            continue;
          }
        
-       if (gcov_resync (ptr->wkspc, 0)
-           || gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program))
-         fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
+       gcov_seek (ptr->wkspc, 0);
+       gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
        if (gcov_close ())
-         fprintf (stderr, "profiling:%s:Error closing\n", ptr->filename);
+         fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
       }
 }
 
index ec53065..7593144 100644 (file)
@@ -274,7 +274,7 @@ static void
 read_counts_file (const char *name)
 {
   char *function_name_buffer = NULL;
-  unsigned magic, version, ix, checksum;
+  unsigned version, ix, checksum;
   counts_entry_t *summaried = NULL;
   unsigned seen_summary = 0;
   
@@ -284,21 +284,21 @@ read_counts_file (const char *name)
       return;
     }
   
-  if (gcov_read_unsigned (&magic) || magic != GCOV_DATA_MAGIC)
+  if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
     {
       warning ("`%s' is not a gcov data file", name);
       gcov_close ();
       return;
     }
-  else if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
+  else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
     {
       char v[4], e[4];
-      magic = GCOV_VERSION;
+      unsigned required = GCOV_VERSION;
       
-      for (ix = 4; ix--; magic >>= 8, version >>= 8)
+      for (ix = 4; ix--; required >>= 8, version >>= 8)
        {
          v[ix] = version;
-         e[ix] = magic;
+         e[ix] = required;
        }
       warning ("`%s' is version `%.4s', expected version `%.4s'", name, v, e);
       gcov_close ();
@@ -308,27 +308,21 @@ read_counts_file (const char *name)
   counts_hash = htab_create (10,
                             htab_counts_entry_hash, htab_counts_entry_eq,
                             htab_counts_entry_del);
-  while (1)
+  while (!gcov_is_eof ())
     {
       unsigned tag, length;
-      long offset;
+      unsigned long offset;
+      int error;
       
-      offset = gcov_save_position ();
-      if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length))
-       {
-         if (gcov_eof ())
-           break;
-       corrupt:;
-         warning ("`%s' is corrupted", name);
-       cleanup:
-         htab_delete (counts_hash);
-         break;
-       }
+      tag = gcov_read_unsigned ();
+      length = gcov_read_unsigned ();
+      offset = gcov_position ();
       if (tag == GCOV_TAG_FUNCTION)
        {
-         if (gcov_read_string (&function_name_buffer)
-             || gcov_read_unsigned (&checksum))
-           goto corrupt;
+         const char *string = gcov_read_string ();
+         free (function_name_buffer);
+         function_name_buffer = string ? xstrdup (string) : NULL;
+         checksum = gcov_read_unsigned ();
          if (seen_summary)
            {
              /* We have already seen a summary, this means that this
@@ -352,10 +346,7 @@ read_counts_file (const char *name)
          counts_entry_t *entry;
          struct gcov_summary summary;
          
-         if (length != GCOV_SUMMARY_LENGTH
-             || gcov_read_summary (&summary))
-           goto corrupt;
-
+         gcov_read_summary (&summary);
          seen_summary = 1;
          for (entry = summaried; entry; entry = entry->chain)
            {
@@ -370,7 +361,6 @@ read_counts_file (const char *name)
          counts_entry_t **slot, *entry, elt;
          unsigned n_counts = length / 8;
          unsigned ix;
-         gcov_type count;
 
          elt.function_name = function_name_buffer;
          elt.section = tag;
@@ -390,7 +380,8 @@ read_counts_file (const char *name)
          else if (entry->checksum != checksum || entry->n_counts != n_counts)
            {
              warning ("profile mismatch for `%s'", function_name_buffer);
-             goto cleanup;
+             htab_delete (counts_hash);
+             break;
            }
          
          /* This should always be true for a just allocated entry,
@@ -402,15 +393,16 @@ read_counts_file (const char *name)
              summaried = entry;
            }
          for (ix = 0; ix != n_counts; ix++)
-           {
-             if (gcov_read_counter (&count))
-               goto corrupt;
-             entry->counts[ix] += count;
-           }
+           entry->counts[ix] += gcov_read_counter ();
+       }
+      gcov_seek (offset, length);
+      if ((error = gcov_is_error ()))
+       {
+         warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
+                  name);
+         htab_delete (counts_hash);
+         break;
        }
-      else
-       if (gcov_skip (length))
-         goto corrupt;
     }
 
   free (function_name_buffer);
@@ -1007,42 +999,34 @@ branch_prob ()
      edge output the source and target basic block numbers.
      NOTE: The format of this file must be compatible with gcov.  */
 
-  if (gcov_ok ())
+  if (!gcov_is_error ())
     {
       long offset;
       const char *file = DECL_SOURCE_FILE (current_function_decl);
       unsigned line = DECL_SOURCE_LINE (current_function_decl);
       
       /* Announce function */
-      if (gcov_write_unsigned (GCOV_TAG_FUNCTION)
-         || !(offset = gcov_reserve_length ())
-         || gcov_write_string (name)
-         || gcov_write_unsigned (profile_info.current_function_cfg_checksum)
-         || gcov_write_string (file)
-         || gcov_write_unsigned (line)
-         || gcov_write_length (offset))
-       goto bbg_error;
+      offset = gcov_write_tag (GCOV_TAG_FUNCTION);
+      gcov_write_string (name);
+      gcov_write_unsigned (profile_info.current_function_cfg_checksum);
+      gcov_write_string (file);
+      gcov_write_unsigned (line);
+      gcov_write_length (offset);
 
       /* Basic block flags */
-      if (gcov_write_unsigned (GCOV_TAG_BLOCKS)
-         || !(offset = gcov_reserve_length ()))
-       goto bbg_error;
+      offset = gcov_write_tag (GCOV_TAG_BLOCKS);
       for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
-       if (gcov_write_unsigned (0))
-         goto bbg_error;
-      if (gcov_write_length (offset))
-       goto bbg_error;
+       gcov_write_unsigned (0);
+      gcov_write_length (offset);
       
       /* Arcs */
       FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
        {
          edge e;
 
-         if (gcov_write_unsigned (GCOV_TAG_ARCS)
-             || !(offset = gcov_reserve_length ())
-             || gcov_write_unsigned (BB_TO_GCOV_INDEX (bb)))
-           goto bbg_error;
-
+         offset = gcov_write_tag (GCOV_TAG_ARCS);
+         gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
+         
          for (e = bb->succ; e; e = e->succ_next)
            {
              struct edge_info *i = EDGE_INFO (e);
@@ -1057,14 +1041,12 @@ branch_prob ()
                  if (e->flags & EDGE_FALLTHRU)
                    flag_bits |= GCOV_ARC_FALLTHROUGH;
 
-                 if (gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest))
-                     || gcov_write_unsigned (flag_bits))
-                   goto bbg_error;
+                 gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
+                 gcov_write_unsigned (flag_bits);
                }
            }
 
-         if (gcov_write_length (offset))
-           goto bbg_error;
+         gcov_write_length (offset);
        }
 
       /* Output line number information about each basic block for
@@ -1104,13 +1086,12 @@ branch_prob ()
                      ignore_next_note = 0;
                    else
                      {
-                       if (offset)
-                         /*NOP*/;
-                       else if (gcov_write_unsigned (GCOV_TAG_LINES)
-                                || !(offset = gcov_reserve_length ())
-                                || (gcov_write_unsigned
-                                    (BB_TO_GCOV_INDEX (bb))))
-                         goto bbg_error;
+                       if (!offset)
+                         {
+                           offset = gcov_write_tag (GCOV_TAG_LINES);
+                           gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
+                         }
+
                        /* If this is a new source file, then output
                           the file's name to the .bb file.  */
                        if (!prev_file_name
@@ -1118,12 +1099,10 @@ branch_prob ()
                                       prev_file_name))
                          {
                            prev_file_name = NOTE_SOURCE_FILE (insn);
-                           if (gcov_write_unsigned (0)
-                               || gcov_write_string (prev_file_name))
-                             goto bbg_error;
+                           gcov_write_unsigned (0);
+                           gcov_write_string (prev_file_name);
                          }
-                       if (gcov_write_unsigned (NOTE_LINE_NUMBER (insn)))
-                         goto bbg_error;
+                       gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
                      }
                  }
                insn = NEXT_INSN (insn);
@@ -1131,15 +1110,13 @@ branch_prob ()
 
            if (offset)
              {
-               if (gcov_write_unsigned (0)
-                   || gcov_write_string (NULL)
-                   || gcov_write_length (offset))
-                 {
-                 bbg_error:;
-                   warning ("error writing `%s'", bbg_file_name);
-                   gcov_error ();
-                 }
+               /* A file of NULL indicates the end of run.  */
+               gcov_write_unsigned (0);
+               gcov_write_string (NULL);
+               gcov_write_length (offset);
              }
+           if (gcov_is_error ())
+             warning ("error writing `%s'", bbg_file_name);
          }
       }
     }
@@ -1328,13 +1305,9 @@ init_branch_prob (filename)
       strcpy (bbg_file_name, filename);
       strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
       if (!gcov_open (bbg_file_name, -1))
-       {
-         error ("cannot open %s", bbg_file_name);
-         gcov_error ();
-       }
-      else if (gcov_write_unsigned (GCOV_GRAPH_MAGIC)
-              || gcov_write_unsigned (GCOV_VERSION))
-       gcov_error ();
+       error ("cannot open %s", bbg_file_name);
+      gcov_write_unsigned (GCOV_GRAPH_MAGIC);
+      gcov_write_unsigned (GCOV_VERSION);
     }
 
   if (profile_arc_flag)