/* 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, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
Contributed by James E. Wilson of Cygnus Support.
Mangled by Bob Manson of Cygnus Support.
Mangled further by Nathan Sidwell <nathan@codesourcery.com>
Gcov is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
Gcov is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with Gcov; see the file COPYING. If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA. */
+along with Gcov; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
/* ??? Print a list of the ten blocks with the highest execution counts,
and list the line numbers corresponding to those blocks. Also, perhaps
/* Arc is for a function that abnormally returns. */
unsigned int is_call_non_return : 1;
- /* Arc is for catch/setjump. */
+ /* Arc is for catch/setjmp. */
unsigned int is_nonlocal_return : 1;
/* Is an unconditional branch. */
gcc_init_libintl ();
+ /* Handle response files. */
+ expandargv (&argc, &argv);
+
argno = process_args (argc, argv);
if (optind == argc)
print_usage (true);
static void
print_version (void)
{
- fnotice (stdout, "gcov (GCC) %s\n", version_string);
- fprintf (stdout, "Copyright %s 2006 Free Software Foundation, Inc.\n",
+ fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
+ fprintf (stdout, "Copyright %s 2009 Free Software Foundation, Inc.\n",
_("(C)"));
fnotice (stdout,
_("This is free software; see the source for copying conditions.\n"
base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
strcat (name, object_directory);
- if (base && name[strlen (name) - 1] != '/')
+ if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
strcat (name, "/");
}
else
if (base)
{
/* Append source file name. */
- cptr = strrchr (file_name, '/');
- strcat (name, cptr ? cptr + 1 : file_name);
+ const char *cptr = lbasename (file_name);
+ strcat (name, cptr ? cptr : file_name);
}
/* Remove the extension. */
static char *
make_gcov_file_name (const char *input_name, const char *src_name)
{
- char *cptr;
+ const char *cptr;
char *name;
if (flag_long_names && input_name && strcmp (src_name, input_name))
name = XNEWVEC (char, strlen (src_name) + strlen (input_name) + 10);
name[0] = 0;
/* Generate the input filename part. */
- cptr = flag_preserve_paths ? NULL : strrchr (input_name, '/');
- strcat (name, cptr ? cptr + 1 : input_name);
+ cptr = flag_preserve_paths ? NULL : lbasename (input_name);
+ strcat (name, cptr ? cptr : input_name);
strcat (name, "##");
}
else
}
/* Generate the source filename part. */
- cptr = flag_preserve_paths ? NULL : strrchr (src_name, '/');
- strcat (name, cptr ? cptr + 1 : src_name);
+
+ cptr = flag_preserve_paths ? NULL : lbasename (src_name);
+ strcat (name, cptr ? cptr : src_name);
if (flag_preserve_paths)
{
- /* Convert '/' to '#', remove '/./', convert '/../' to '/^/' */
- char *prev;
+ /* Convert '/' and '\' to '#', remove '/./', convert '/../' to '/^/',
+ convert ':' to '~' on DOS based file system. */
+ char *pnew = name, *pold = name;
- for (cptr = name; (cptr = strchr ((prev = cptr), '/'));)
- {
- unsigned shift = 0;
+ /* First check for leading drive separator. */
- if (prev + 1 == cptr && prev[0] == '.')
+ while (*pold != '\0')
+ {
+ if (*pold == '/' || *pold == '\\')
{
- /* Remove '.' */
- shift = 2;
+ *pnew++ = '#';
+ pold++;
}
- else if (prev + 2 == cptr && prev[0] == '.' && prev[1] == '.')
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ else if (*pold == ':')
{
- /* Convert '..' */
- shift = 1;
- prev[1] = '^';
+ *pnew++ = '~';
+ pold++;
}
- else
- *cptr++ = '#';
- if (shift)
+#endif
+ else if ((*pold == '/' && strstr (pold, "/./") == pold)
+ || (*pold == '\\' && strstr (pold, "\\.\\") == pold))
+ pold += 3;
+ else if (*pold == '/' && strstr (pold, "/../") == pold)
+ {
+ strcpy (pnew, "/^/");
+ pnew += 3;
+ pold += 4;
+ }
+ else if (*pold == '\\' && strstr (pold, "\\..\\") == pold)
{
- cptr = prev;
- do
- prev[0] = prev[shift];
- while (*prev++);
+ strcpy (pnew, "\\^\\");
+ pnew += 3;
+ pold += 4;
}
+ else
+ *pnew++ = *pold++;
}
+
+ *pnew = '\0';
}
strcat (name, ".gcov");