OSDN Git Service

* config/xtensa/xtensa.md: Remove unused type attributes.
[pf3gnuchains/gcc-fork.git] / gcc / gcov.c
index fa1e9d9..3bb2ce1 100644 (file)
@@ -1,7 +1,7 @@
 /* Gcov.c: prepend line execution counts and branch probabilities to a
    source file.
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by James E. Wilson of Cygnus Support.
    Mangled by Bob Manson of Cygnus Support.
 
@@ -46,8 +46,11 @@ Boston, MA 02111-1307, USA.  */
 #include "config.h"
 #include "system.h"
 #include "intl.h"
+#include "version.h"
 #undef abort
 
+#include <getopt.h>
+
 typedef HOST_WIDEST_INT gcov_type;
 #include "gcov-io.h"
 
@@ -79,8 +82,6 @@ typedef HOST_WIDEST_INT gcov_type;
 /* The functions in this file for creating and solution program flow graphs
    are very similar to functions in the gcc source file profile.c.  */
 
-char gcov_version_string[] = "GNU gcov version 1.5\n";
-
 /* This is the size of the buffer used to read in source file lines.  */
 
 #define STRING_SIZE 200
@@ -218,7 +219,7 @@ static char *object_directory = 0;
 
 /* Output the number of times a branch was taken as opposed to the percentage
    of times it was taken.  Turned on by the -c option */
-   
+
 static int output_branch_counts = 0;
 
 /* Forward declarations.  */
@@ -227,7 +228,8 @@ static void open_files PARAMS ((void));
 static void read_files PARAMS ((void));
 static void scan_for_source_files PARAMS ((void));
 static void output_data PARAMS ((void));
-static void print_usage PARAMS ((void)) ATTRIBUTE_NORETURN;
+static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN;
+static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN;
 static void init_arc PARAMS ((struct adj_list *, int, int, struct bb_info *));
 static struct adj_list *reverse_arcs PARAMS ((struct adj_list *));
 static void create_program_flow_graph PARAMS ((struct bb_info_list *));
@@ -243,18 +245,7 @@ main (argc, argv)
      int argc;
      char **argv;
 {
-/* LC_CTYPE determines the character set used by the terminal so it has be set
-   to output messages correctly.  */
-
-#ifdef HAVE_LC_MESSAGES
-  setlocale (LC_CTYPE, "");
-  setlocale (LC_MESSAGES, "");
-#else
-  setlocale (LC_ALL, "");
-#endif
-
-  (void) bindtextdomain (PACKAGE, localedir);
-  (void) textdomain (PACKAGE);
+  gcc_init_libintl ();
 
   process_args (argc, argv);
 
@@ -273,21 +264,12 @@ static void fnotice PARAMS ((FILE *, const char *, ...)) ATTRIBUTE_PRINTF_2;
 static void
 fnotice VPARAMS ((FILE *file, const char *msgid, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  FILE *file;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  file = va_arg (ap, FILE *);
-  msgid = va_arg (ap, const char *);
-#endif
+  VA_OPEN (ap, msgid);
+  VA_FIXEDARG (ap, FILE *, file);
+  VA_FIXEDARG (ap, const char *, msgid);
 
   vfprintf (file, _(msgid), ap);
-  va_end (ap);
+  VA_CLOSE (ap);
 }
 
 /* More 'friendly' abort that prints the line and file.
@@ -301,15 +283,57 @@ fancy_abort ()
   exit (FATAL_EXIT_CODE);
 }
 \f
-/* Print a usage message and exit.  */
+/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
+   otherwise the output of --help.  */
 
 static void
-print_usage ()
+print_usage (error_p)
+     int error_p;
 {
-  fnotice (stderr, "gcov [-b] [-v] [-n] [-l] [-f] [-o OBJDIR] file\n");
-  exit (FATAL_EXIT_CODE);
+  FILE *file = error_p ? stderr : stdout;
+  int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
+  fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE\n\n");
+  fnotice (file, "Print code coverage information.\n\n");
+  fnotice (file, "  -h, --help                      Print this help, then exit\n");
+  fnotice (file, "  -v, --version                   Print version number, then exit\n");
+  fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
+  fnotice (file, "  -c, --branch-counts             Given counts of branches taken\n\
+                                    rather than percentages\n");
+  fnotice (file, "  -n, --no-output                 Do not create an output file\n");
+  fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
+                                    source files\n");
+  fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
+  fnotice (file, "  -o, --object-directory OBJDIR   Search for object files in OBJDIR\n");
+  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
+          GCCBUGURL);
+  exit (status);
 }
 
+/* Print version information and exit.  */
+
+static void
+print_version ()
+{
+  fnotice (stdout, "gcov (GCC) %s\n", version_string);
+  fnotice (stdout, "Copyright (C) 2001 Free Software Foundation, Inc.\n");
+  fnotice (stdout,
+          "This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
+  exit (SUCCESS_EXIT_CODE);
+}
+
+static const struct option options[] =
+{
+  { "help",                 no_argument,       NULL, 'h' },
+  { "version",              no_argument,       NULL, 'v' },
+  { "branch-probabilities", no_argument,       NULL, 'b' },
+  { "branch-counts",        no_argument,       NULL, 'c' },
+  { "no-output",            no_argument,       NULL, 'n' },
+  { "long-file-names",      no_argument,       NULL, 'l' },
+  { "function-summaries",   no_argument,       NULL, 'f' },
+  { "object-directory",     required_argument, NULL, 'o' }
+};
+
 /* Parse the command line.  */
 
 static void
@@ -317,37 +341,46 @@ process_args (argc, argv)
      int argc;
      char **argv;
 {
-  int i;
+  int opt;
 
-  for (i = 1; i < argc; i++)
+  while ((opt = getopt_long (argc, argv, "hvbclnfo:", options, NULL)) != -1)
     {
-      if (argv[i][0] == '-')
+      switch (opt)
        {
-         if (argv[i][1] == 'b')
-           output_branch_probs = 1;
-         else if (argv[i][1] == 'c')
-           output_branch_counts = 1;
-         else if (argv[i][1] == 'v')
-           fputs (gcov_version_string, stderr);
-         else if (argv[i][1] == 'n')
-           output_gcov_file = 0;
-         else if (argv[i][1] == 'l')
-           output_long_names = 1;
-         else if (argv[i][1] == 'f')
-           output_function_summary = 1;
-         else if (argv[i][1] == 'o' && argv[i][2] == '\0')
-           object_directory = argv[++i];
-         else
-           print_usage ();
+       case 'h':
+         print_usage (false);
+         /* print_usage will exit.  */
+       case 'v':
+         print_version ();
+         /* print_version will exit.  */
+       case 'b':
+         output_branch_probs = 1;
+         break;
+       case 'c':
+         output_branch_counts = 1;
+         break;
+       case 'n':
+         output_gcov_file = 0;
+         break;
+       case 'l':
+         output_long_names = 1;
+         break;
+       case 'f':
+         output_function_summary = 1;
+         break;
+       case 'o':
+         object_directory = optarg;
+         break;
+       default:
+         print_usage (true);
+         /* print_usage will exit.  */
        }
-      else if (! input_file_name)
-       input_file_name = argv[i];
-      else
-       print_usage ();
     }
 
-  if (! input_file_name)
-    print_usage ();
+  if (optind != argc - 1)
+    print_usage (true);
+
+  input_file_name = argv[optind];
 }
 
 
@@ -438,7 +471,7 @@ open_files ()
       fnotice (stderr, "Could not open data file %s.\n", da_file_name);
       fnotice (stderr, "Assuming that all execution counts are zero.\n");
     }
-    
+
   bbg_file = fopen (bbg_file_name, "rb");
   if (bbg_file == NULL)
     {
@@ -486,7 +519,7 @@ init_arc (arcptr, source, target, bb_graph)
 }
 
 
-/* Reverse the arcs on a arc list.  */
+/* Reverse the arcs on an arc list.  */
 
 static struct adj_list *
 reverse_arcs (arcptr)
@@ -582,7 +615,7 @@ create_program_flow_graph (bptr)
        {
          gcov_type tmp_count = 0;
          if (da_file && __read_gcov_type (&tmp_count, da_file, 8))
-           abort();
+           abort ();
 
          arcptr->arc_count = tmp_count;
          arcptr->count_valid = 1;
@@ -590,7 +623,7 @@ create_program_flow_graph (bptr)
          bb_graph[arcptr->target].pred_count--;
        }
 }
-  
+
 static void
 solve_program_flow_graph (bptr)
      struct bb_info_list *bptr;
@@ -707,7 +740,7 @@ solve_program_flow_graph (bptr)
            }
        }
     }
-             
+
   /* If the graph has been correctly solved, every block will have a
      succ and pred count of zero.  */
   for (i = 0; i < num_blocks; i++)
@@ -727,7 +760,7 @@ read_files ()
   /* Read and ignore the first word of the .da file, which is the count of
      how many numbers follow.  */
   if (da_file && __read_long (&total, da_file, 8))
-    abort();
+    abort ();
 
   while (! feof (bbg_file))
     {
@@ -772,7 +805,7 @@ read_files ()
 
   bb_data = (char *) xmalloc ((unsigned) buf.st_size);
   fread (bb_data, sizeof (char), buf.st_size, bb_file);
-  
+
   fclose (bb_file);
   if (da_file)
     fclose (da_file);
@@ -788,7 +821,7 @@ scan_for_source_files ()
 {
   struct sourcefile *s_ptr = NULL;
   char *ptr;
-  int count;
+  long count;
   long line_num;
 
   /* Search the bb_data to find:
@@ -851,8 +884,8 @@ scan_for_source_files ()
        }
       else if (line_num < 0)
        {
-         /* Don't know what this is, but it's garbage. */
-         abort();
+         /* Don't know what this is, but it's garbage.  */
+         abort ();
        }
     }
 }
@@ -878,7 +911,7 @@ calculate_branch_probs (current_graph, block_num, branch_probs, last_line_num)
      struct arcdata **branch_probs;
      int last_line_num;
 {
-  int total;
+  gcov_type total;
   struct adj_list *arcptr;
   struct arcdata *end_ptr, *a_ptr;
 
@@ -890,7 +923,7 @@ calculate_branch_probs (current_graph, block_num, branch_probs, last_line_num)
 
       if (arcptr->fall_through)
        continue;
-                     
+
       a_ptr = (struct arcdata *) xmalloc (sizeof (struct arcdata));
       a_ptr->total = total;
       if (total == 0)
@@ -990,7 +1023,7 @@ output_data ()
   char *source_file_name;
   FILE *source_file;
   struct bb_info_list *current_graph;
-  int count;
+  long count;
   char *cptr;
   long block_num;
   long line_num;
@@ -1018,12 +1051,7 @@ output_data ()
     {
       /* If this is a relative file name, and an object directory has been
         specified, then make it relative to the object directory name.  */
-      if (! (*s_ptr->name == '/' || *s_ptr->name == DIR_SEPARATOR
-            /* Check for disk name on MS-DOS-based systems.  */
-            || (DIR_SEPARATOR == '\\'
-                && s_ptr->name[1] == ':'
-                && (s_ptr->name[2] == DIR_SEPARATOR
-                    || s_ptr->name[2] == '/')))
+      if (! IS_ABSOLUTE_PATHNAME (s_ptr->name)
          && object_directory != 0
          && *object_directory != '\0')
        {
@@ -1042,7 +1070,7 @@ output_data ()
       if (output_branch_probs)
        branch_probs = (struct arcdata **)
          xcalloc (sizeof (struct arcdata *), s_ptr->maxlineno);
-      
+
       /* There will be a zero at the beginning of the bb info, before the
         first list of line numbers, so must initialize block_num to 0.  */
       block_num = 0;
@@ -1066,7 +1094,7 @@ output_data ()
                  this_file = 0;
                else
                  this_file = 1;
-             
+
                /* Scan past the file name.  */
                do {
                  count++;
@@ -1139,7 +1167,7 @@ output_data ()
                             function_name);
                    abort ();
                  }
-                 
+
                if (output_branch_probs && this_file)
                  calculate_branch_probs (current_graph, block_num,
                                          branch_probs, last_line_num);
@@ -1246,7 +1274,7 @@ output_data ()
          /* Now the statistics are ready.  Read in the source file one line
             at a time, and output that line to the gcov file preceded by
             its execution count if non zero.  */
-      
+
          source_file = fopen (source_file_name, "r");
          if (source_file == NULL)
            {
@@ -1266,7 +1294,7 @@ output_data ()
          if (output_long_names && strcmp (cptr, input_file_name))
            {
              gcov_file_name = xmalloc (count + 7 + strlen (input_file_name));
-             
+
              cptr = strrchr (input_file_name, '/');
              if (cptr)
                strcpy (gcov_file_name, cptr + 1);
@@ -1360,14 +1388,23 @@ output_data ()
                            else
                              {
                                if (output_branch_counts)
-                                 fnotice (gcov_file,
-                                          "call %d returns = %d\n",
-                                          i, a_ptr->total - a_ptr->hits);
+                                 {
+                                   char c[20];
+                                   sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                            a_ptr->total - a_ptr->hits);
+                                   fnotice (gcov_file,
+                                            "call %d returns = %s\n", i, c);
+                                 }
                                else
-                                  fnotice (gcov_file,
-                                          "call %d returns = %d%%\n",
-                                           i, 100 - ((a_ptr->hits * 100) +
-                                           (a_ptr->total >> 1))/a_ptr->total);
+                                 {
+                                   char c[20];
+                                   sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                            100 - ((a_ptr->hits * 100)
+                                                   + (a_ptr->total >> 1))
+                                            / a_ptr->total);
+                                   fnotice (gcov_file,
+                                            "call %d returns = %s%%\n", i, c);
+                                 }
                              }
                        }
                      else
@@ -1378,16 +1415,23 @@ output_data ()
                          else
                            {
                              if (output_branch_counts)
-                               fnotice (gcov_file,
-                                        "branch %d taken = %d\n",
-                                         i, a_ptr->hits);
+                               {
+                                 char c[20];
+                                 sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                          a_ptr->hits);
+                                 fnotice (gcov_file,
+                                          "branch %d taken = %s\n", i, c);
+                               }
                              else
+                               {
+                                 char c[20];
+                                 sprintf (c, HOST_WIDEST_INT_PRINT_DEC,
+                                          ((a_ptr->hits * 100)
+                                           + (a_ptr->total >> 1))
+                                          / a_ptr->total);
                                 fnotice (gcov_file,
-                                         "branch %d taken = %d%%\n", i,
-                                         ((a_ptr->hits * 100) +
-                                          (a_ptr->total >> 1))/
-                                          a_ptr->total);
-
+                                         "branch %d taken = %s%%\n", i, c);
+                               }
                            }
                        }
                   }