Daily bump.
[gcc.git] / gcc / gcov.c
1 /* Gcov.c: prepend line execution counts and branch probabilities to a
2 source file.
3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
4 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
5 2012, 2013
6 Free Software Foundation, Inc.
7 Contributed by James E. Wilson of Cygnus Support.
8 Mangled by Bob Manson of Cygnus Support.
9 Mangled further by Nathan Sidwell <nathan@codesourcery.com>
10
11 Gcov is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3, or (at your option)
14 any later version.
15
16 Gcov is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with Gcov; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
24
25 /* ??? Print a list of the ten blocks with the highest execution counts,
26 and list the line numbers corresponding to those blocks. Also, perhaps
27 list the line numbers with the highest execution counts, only printing
28 the first if there are several which are all listed in the same block. */
29
30 /* ??? Should have an option to print the number of basic blocks, and the
31 percent of them that are covered. */
32
33 /* Need an option to show individual block counts, and show
34 probabilities of fall through arcs. */
35
36 #include "config.h"
37 #include "system.h"
38 #include "coretypes.h"
39 #include "tm.h"
40 #include "intl.h"
41 #include "diagnostic.h"
42 #include "version.h"
43
44 #include <getopt.h>
45
46 #define IN_GCOV 1
47 #include "gcov-io.h"
48 #include "gcov-io.c"
49
50 /* The gcno file is generated by -ftest-coverage option. The gcda file is
51 generated by a program compiled with -fprofile-arcs. Their formats
52 are documented in gcov-io.h. */
53
54 /* The functions in this file for creating and solution program flow graphs
55 are very similar to functions in the gcc source file profile.c. In
56 some places we make use of the knowledge of how profile.c works to
57 select particular algorithms here. */
58
59 /* The code validates that the profile information read in corresponds
60 to the code currently being compiled. Rather than checking for
61 identical files, the code below compares a checksum on the CFG
62 (based on the order of basic blocks and the arcs in the CFG). If
63 the CFG checksum in the gcda file match the CFG checksum in the
64 gcno file, the profile data will be used. */
65
66 /* This is the size of the buffer used to read in source file lines. */
67
68 struct function_info;
69 struct block_info;
70 struct source_info;
71
72 /* Describes an arc between two basic blocks. */
73
74 typedef struct arc_info
75 {
76 /* source and destination blocks. */
77 struct block_info *src;
78 struct block_info *dst;
79
80 /* transition counts. */
81 gcov_type count;
82 /* used in cycle search, so that we do not clobber original counts. */
83 gcov_type cs_count;
84
85 unsigned int count_valid : 1;
86 unsigned int on_tree : 1;
87 unsigned int fake : 1;
88 unsigned int fall_through : 1;
89
90 /* Arc to a catch handler. */
91 unsigned int is_throw : 1;
92
93 /* Arc is for a function that abnormally returns. */
94 unsigned int is_call_non_return : 1;
95
96 /* Arc is for catch/setjmp. */
97 unsigned int is_nonlocal_return : 1;
98
99 /* Is an unconditional branch. */
100 unsigned int is_unconditional : 1;
101
102 /* Loop making arc. */
103 unsigned int cycle : 1;
104
105 /* Next branch on line. */
106 struct arc_info *line_next;
107
108 /* Links to next arc on src and dst lists. */
109 struct arc_info *succ_next;
110 struct arc_info *pred_next;
111 } arc_t;
112
113 /* Describes a basic block. Contains lists of arcs to successor and
114 predecessor blocks. */
115
116 typedef struct block_info
117 {
118 /* Chain of exit and entry arcs. */
119 arc_t *succ;
120 arc_t *pred;
121
122 /* Number of unprocessed exit and entry arcs. */
123 gcov_type num_succ;
124 gcov_type num_pred;
125
126 /* Block execution count. */
127 gcov_type count;
128 unsigned flags : 12;
129 unsigned count_valid : 1;
130 unsigned valid_chain : 1;
131 unsigned invalid_chain : 1;
132 unsigned exceptional : 1;
133
134 /* Block is a call instrumenting site. */
135 unsigned is_call_site : 1; /* Does the call. */
136 unsigned is_call_return : 1; /* Is the return. */
137
138 /* Block is a landing pad for longjmp or throw. */
139 unsigned is_nonlocal_return : 1;
140
141 union
142 {
143 struct
144 {
145 /* Array of line numbers and source files. source files are
146 introduced by a linenumber of zero, the next 'line number' is
147 the number of the source file. Always starts with a source
148 file. */
149 unsigned *encoding;
150 unsigned num;
151 } line; /* Valid until blocks are linked onto lines */
152 struct
153 {
154 /* Single line graph cycle workspace. Used for all-blocks
155 mode. */
156 arc_t *arc;
157 unsigned ident;
158 } cycle; /* Used in all-blocks mode, after blocks are linked onto
159 lines. */
160 } u;
161
162 /* Temporary chain for solving graph, and for chaining blocks on one
163 line. */
164 struct block_info *chain;
165
166 } block_t;
167
168 /* Describes a single function. Contains an array of basic blocks. */
169
170 typedef struct function_info
171 {
172 /* Name of function. */
173 char *name;
174 unsigned ident;
175 unsigned lineno_checksum;
176 unsigned cfg_checksum;
177
178 /* The graph contains at least one fake incoming edge. */
179 unsigned has_catch : 1;
180
181 /* Array of basic blocks. Like in GCC, the entry block is
182 at blocks[0] and the exit block is at blocks[1]. */
183 #define ENTRY_BLOCK (0)
184 #define EXIT_BLOCK (1)
185 block_t *blocks;
186 unsigned num_blocks;
187 unsigned blocks_executed;
188
189 /* Raw arc coverage counts. */
190 gcov_type *counts;
191 unsigned num_counts;
192
193 /* First line number & file. */
194 unsigned line;
195 unsigned src;
196
197 /* Next function in same source file. */
198 struct function_info *line_next;
199
200 /* Next function. */
201 struct function_info *next;
202 } function_t;
203
204 /* Describes coverage of a file or function. */
205
206 typedef struct coverage_info
207 {
208 int lines;
209 int lines_executed;
210
211 int branches;
212 int branches_executed;
213 int branches_taken;
214
215 int calls;
216 int calls_executed;
217
218 char *name;
219 } coverage_t;
220
221 /* Describes a single line of source. Contains a chain of basic blocks
222 with code on it. */
223
224 typedef struct line_info
225 {
226 gcov_type count; /* execution count */
227 union
228 {
229 arc_t *branches; /* branches from blocks that end on this
230 line. Used for branch-counts when not
231 all-blocks mode. */
232 block_t *blocks; /* blocks which start on this line. Used
233 in all-blocks mode. */
234 } u;
235 unsigned exists : 1;
236 unsigned unexceptional : 1;
237 } line_t;
238
239 /* Describes a file mentioned in the block graph. Contains an array
240 of line info. */
241
242 typedef struct source_info
243 {
244 /* Canonical name of source file. */
245 char *name;
246 time_t file_time;
247
248 /* Array of line information. */
249 line_t *lines;
250 unsigned num_lines;
251
252 coverage_t coverage;
253
254 /* Functions in this source file. These are in ascending line
255 number order. */
256 function_t *functions;
257 } source_t;
258
259 typedef struct name_map
260 {
261 char *name; /* Source file name */
262 unsigned src; /* Source file */
263 } name_map_t;
264
265 /* Holds a list of function basic block graphs. */
266
267 static function_t *functions;
268 static function_t **fn_end = &functions;
269
270 static source_t *sources; /* Array of source files */
271 static unsigned n_sources; /* Number of sources */
272 static unsigned a_sources; /* Allocated sources */
273
274 static name_map_t *names; /* Mapping of file names to sources */
275 static unsigned n_names; /* Number of names */
276 static unsigned a_names; /* Allocated names */
277
278 /* This holds data summary information. */
279
280 static unsigned object_runs;
281 static unsigned program_count;
282
283 static unsigned total_lines;
284 static unsigned total_executed;
285
286 /* Modification time of graph file. */
287
288 static time_t bbg_file_time;
289
290 /* Name of the notes (gcno) output file. The "bbg" prefix is for
291 historical reasons, when the notes file contained only the
292 basic block graph notes. */
293
294 static char *bbg_file_name;
295
296 /* Stamp of the bbg file */
297 static unsigned bbg_stamp;
298
299 /* Name and file pointer of the input file for the count data (gcda). */
300
301 static char *da_file_name;
302
303 /* Data file is missing. */
304
305 static int no_data_file;
306
307 /* If there is several input files, compute and display results after
308 reading all data files. This way if two or more gcda file refer to
309 the same source file (eg inline subprograms in a .h file), the
310 counts are added. */
311
312 static int multiple_files = 0;
313
314 /* Output branch probabilities. */
315
316 static int flag_branches = 0;
317
318 /* Show unconditional branches too. */
319 static int flag_unconditional = 0;
320
321 /* Output a gcov file if this is true. This is on by default, and can
322 be turned off by the -n option. */
323
324 static int flag_gcov_file = 1;
325
326 /* Output progress indication if this is true. This is off by default
327 and can be turned on by the -d option. */
328
329 static int flag_display_progress = 0;
330
331 /* For included files, make the gcov output file name include the name
332 of the input source file. For example, if x.h is included in a.c,
333 then the output file name is a.c##x.h.gcov instead of x.h.gcov. */
334
335 static int flag_long_names = 0;
336
337 /* Output count information for every basic block, not merely those
338 that contain line number information. */
339
340 static int flag_all_blocks = 0;
341
342 /* Output summary info for each function. */
343
344 static int flag_function_summary = 0;
345
346 /* Object directory file prefix. This is the directory/file where the
347 graph and data files are looked for, if nonzero. */
348
349 static char *object_directory = 0;
350
351 /* Source directory prefix. This is removed from source pathnames
352 that match, when generating the output file name. */
353
354 static char *source_prefix = 0;
355 static size_t source_length = 0;
356
357 /* Only show data for sources with relative pathnames. Absolute ones
358 usually indicate a system header file, which although it may
359 contain inline functions, is usually uninteresting. */
360 static int flag_relative_only = 0;
361
362 /* Preserve all pathname components. Needed when object files and
363 source files are in subdirectories. '/' is mangled as '#', '.' is
364 elided and '..' mangled to '^'. */
365
366 static int flag_preserve_paths = 0;
367
368 /* Output the number of times a branch was taken as opposed to the percentage
369 of times it was taken. */
370
371 static int flag_counts = 0;
372
373 /* Forward declarations. */
374 static int process_args (int, char **);
375 static void print_usage (int) ATTRIBUTE_NORETURN;
376 static void print_version (void) ATTRIBUTE_NORETURN;
377 static void process_file (const char *);
378 static void generate_results (const char *);
379 static void create_file_names (const char *);
380 static int name_search (const void *, const void *);
381 static int name_sort (const void *, const void *);
382 static char *canonicalize_name (const char *);
383 static unsigned find_source (const char *);
384 static function_t *read_graph_file (void);
385 static int read_count_file (function_t *);
386 static void solve_flow_graph (function_t *);
387 static void find_exception_blocks (function_t *);
388 static void add_branch_counts (coverage_t *, const arc_t *);
389 static void add_line_counts (coverage_t *, function_t *);
390 static void executed_summary (unsigned, unsigned);
391 static void function_summary (const coverage_t *, const char *);
392 static const char *format_gcov (gcov_type, gcov_type, int);
393 static void accumulate_line_counts (source_t *);
394 static int output_branch_count (FILE *, int, const arc_t *);
395 static void output_lines (FILE *, const source_t *);
396 static char *make_gcov_file_name (const char *, const char *);
397 static char *mangle_name (const char *, char *);
398 static void release_structures (void);
399 static void release_function (function_t *);
400 extern int main (int, char **);
401
402 int
403 main (int argc, char **argv)
404 {
405 int argno;
406 int first_arg;
407 const char *p;
408
409 p = argv[0] + strlen (argv[0]);
410 while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
411 --p;
412 progname = p;
413
414 xmalloc_set_program_name (progname);
415
416 /* Unlock the stdio streams. */
417 unlock_std_streams ();
418
419 gcc_init_libintl ();
420
421 diagnostic_initialize (global_dc, 0);
422
423 /* Handle response files. */
424 expandargv (&argc, &argv);
425
426 a_names = 10;
427 names = XNEWVEC (name_map_t, a_names);
428 a_sources = 10;
429 sources = XNEWVEC (source_t, a_sources);
430
431 argno = process_args (argc, argv);
432 if (optind == argc)
433 print_usage (true);
434
435 if (argc - argno > 1)
436 multiple_files = 1;
437
438 first_arg = argno;
439
440 for (; argno != argc; argno++)
441 {
442 if (flag_display_progress)
443 printf("Processing file %d out of %d\n",
444 argno - first_arg + 1, argc - first_arg);
445 process_file (argv[argno]);
446 }
447
448 generate_results (multiple_files ? NULL : argv[argc - 1]);
449
450 release_structures ();
451
452 return 0;
453 }
454 \f
455 /* Print a usage message and exit. If ERROR_P is nonzero, this is an error,
456 otherwise the output of --help. */
457
458 static void
459 print_usage (int error_p)
460 {
461 FILE *file = error_p ? stderr : stdout;
462 int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
463
464 fnotice (file, "Usage: gcov [OPTION]... SOURCE|OBJ...\n\n");
465 fnotice (file, "Print code coverage information.\n\n");
466 fnotice (file, " -h, --help Print this help, then exit\n");
467 fnotice (file, " -v, --version Print version number, then exit\n");
468 fnotice (file, " -a, --all-blocks Show information for every basic block\n");
469 fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n");
470 fnotice (file, " -c, --branch-counts Given counts of branches taken\n\
471 rather than percentages\n");
472 fnotice (file, " -n, --no-output Do not create an output file\n");
473 fnotice (file, " -l, --long-file-names Use long output file names for included\n\
474 source files\n");
475 fnotice (file, " -f, --function-summaries Output summaries for each function\n");
476 fnotice (file, " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
477 fnotice (file, " -s, --source-prefix DIR Source prefix to elide\n");
478 fnotice (file, " -r, --relative-only Only show data for relative sources\n");
479 fnotice (file, " -p, --preserve-paths Preserve all pathname components\n");
480 fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
481 fnotice (file, " -d, --display-progress Display progress information\n");
482 fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
483 bug_report_url);
484 exit (status);
485 }
486
487 /* Print version information and exit. */
488
489 static void
490 print_version (void)
491 {
492 fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
493 fprintf (stdout, "Copyright %s 2013 Free Software Foundation, Inc.\n",
494 _("(C)"));
495 fnotice (stdout,
496 _("This is free software; see the source for copying conditions.\n"
497 "There is NO warranty; not even for MERCHANTABILITY or \n"
498 "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
499 exit (SUCCESS_EXIT_CODE);
500 }
501
502 static const struct option options[] =
503 {
504 { "help", no_argument, NULL, 'h' },
505 { "version", no_argument, NULL, 'v' },
506 { "all-blocks", no_argument, NULL, 'a' },
507 { "branch-probabilities", no_argument, NULL, 'b' },
508 { "branch-counts", no_argument, NULL, 'c' },
509 { "no-output", no_argument, NULL, 'n' },
510 { "long-file-names", no_argument, NULL, 'l' },
511 { "function-summaries", no_argument, NULL, 'f' },
512 { "preserve-paths", no_argument, NULL, 'p' },
513 { "relative-only", no_argument, NULL, 'r' },
514 { "object-directory", required_argument, NULL, 'o' },
515 { "object-file", required_argument, NULL, 'o' },
516 { "source-prefix", required_argument, NULL, 's' },
517 { "unconditional-branches", no_argument, NULL, 'u' },
518 { "display-progress", no_argument, NULL, 'd' },
519 { 0, 0, 0, 0 }
520 };
521
522 /* Process args, return index to first non-arg. */
523
524 static int
525 process_args (int argc, char **argv)
526 {
527 int opt;
528
529 while ((opt = getopt_long (argc, argv, "abcdfhlno:s:pruv", options, NULL)) != -1)
530 {
531 switch (opt)
532 {
533 case 'a':
534 flag_all_blocks = 1;
535 break;
536 case 'b':
537 flag_branches = 1;
538 break;
539 case 'c':
540 flag_counts = 1;
541 break;
542 case 'f':
543 flag_function_summary = 1;
544 break;
545 case 'h':
546 print_usage (false);
547 /* print_usage will exit. */
548 case 'l':
549 flag_long_names = 1;
550 break;
551 case 'n':
552 flag_gcov_file = 0;
553 break;
554 case 'o':
555 object_directory = optarg;
556 break;
557 case 's':
558 source_prefix = optarg;
559 source_length = strlen (source_prefix);
560 break;
561 case 'r':
562 flag_relative_only = 1;
563 break;
564 case 'p':
565 flag_preserve_paths = 1;
566 break;
567 case 'u':
568 flag_unconditional = 1;
569 break;
570 case 'd':
571 flag_display_progress = 1;
572 break;
573 case 'v':
574 print_version ();
575 /* print_version will exit. */
576 default:
577 print_usage (true);
578 /* print_usage will exit. */
579 }
580 }
581
582 return optind;
583 }
584
585 /* Process a single input file. */
586
587 static void
588 process_file (const char *file_name)
589 {
590 function_t *fns;
591
592 create_file_names (file_name);
593 fns = read_graph_file ();
594 if (!fns)
595 return;
596
597 read_count_file (fns);
598 while (fns)
599 {
600 function_t *fn = fns;
601
602 fns = fn->next;
603 fn->next = NULL;
604 if (fn->counts)
605 {
606 unsigned src = fn->src;
607 unsigned line = fn->line;
608 unsigned block_no;
609 function_t *probe, **prev;
610
611 /* Now insert it into the source file's list of
612 functions. Normally functions will be encountered in
613 ascending order, so a simple scan is quick. Note we're
614 building this list in reverse order. */
615 for (prev = &sources[src].functions;
616 (probe = *prev); prev = &probe->line_next)
617 if (probe->line <= line)
618 break;
619 fn->line_next = probe;
620 *prev = fn;
621
622 /* Mark last line in files touched by function. */
623 for (block_no = 0; block_no != fn->num_blocks; block_no++)
624 {
625 unsigned *enc = fn->blocks[block_no].u.line.encoding;
626 unsigned num = fn->blocks[block_no].u.line.num;
627
628 for (; num--; enc++)
629 if (!*enc)
630 {
631 if (enc[1] != src)
632 {
633 if (line >= sources[src].num_lines)
634 sources[src].num_lines = line + 1;
635 line = 0;
636 src = enc[1];
637 }
638 enc++;
639 num--;
640 }
641 else if (*enc > line)
642 line = *enc;
643 }
644 if (line >= sources[src].num_lines)
645 sources[src].num_lines = line + 1;
646
647 solve_flow_graph (fn);
648 if (fn->has_catch)
649 find_exception_blocks (fn);
650 *fn_end = fn;
651 fn_end = &fn->next;
652 }
653 else
654 /* The function was not in the executable -- some other
655 instance must have been selected. */
656 release_function (fn);
657 }
658 }
659
660 static void
661 generate_results (const char *file_name)
662 {
663 unsigned ix;
664 source_t *src;
665 function_t *fn;
666
667 for (ix = n_sources, src = sources; ix--; src++)
668 if (src->num_lines)
669 src->lines = XCNEWVEC (line_t, src->num_lines);
670
671 for (fn = functions; fn; fn = fn->next)
672 {
673 coverage_t coverage;
674
675 memset (&coverage, 0, sizeof (coverage));
676 coverage.name = fn->name;
677 add_line_counts (flag_function_summary ? &coverage : NULL, fn);
678 if (flag_function_summary)
679 {
680 function_summary (&coverage, "Function");
681 fnotice (stdout, "\n");
682 }
683 }
684
685 if (file_name)
686 {
687 name_map_t *name_map = (name_map_t *)bsearch
688 (file_name, names, n_names, sizeof (*names), name_search);
689 if (name_map)
690 file_name = sources[name_map->src].coverage.name;
691 else
692 file_name = canonicalize_name (file_name);
693 }
694
695 for (ix = n_sources, src = sources; ix--; src++)
696 {
697 if (flag_relative_only)
698 {
699 /* Ignore this source, if it is an absolute path (after
700 source prefix removal). */
701 char first = src->coverage.name[0];
702
703 #if HAVE_DOS_BASED_FILE_SYSTEM
704 if (first && src->coverage.name[1] == ':')
705 first = src->coverage.name[2];
706 #endif
707 if (IS_DIR_SEPARATOR (first))
708 continue;
709 }
710
711 accumulate_line_counts (src);
712 function_summary (&src->coverage, "File");
713 total_lines += src->coverage.lines;
714 total_executed += src->coverage.lines_executed;
715 if (flag_gcov_file)
716 {
717 char *gcov_file_name
718 = make_gcov_file_name (file_name, src->coverage.name);
719
720 if (src->coverage.lines)
721 {
722 FILE *gcov_file = fopen (gcov_file_name, "w");
723
724 if (gcov_file)
725 {
726 fnotice (stdout, "Creating '%s'\n", gcov_file_name);
727 output_lines (gcov_file, src);
728 if (ferror (gcov_file))
729 fnotice (stderr, "Error writing output file '%s'\n",
730 gcov_file_name);
731 fclose (gcov_file);
732 }
733 else
734 fnotice (stderr, "Could not open output file '%s'\n",
735 gcov_file_name);
736 }
737 else
738 {
739 unlink (gcov_file_name);
740 fnotice (stdout, "Removing '%s'\n", gcov_file_name);
741 }
742 free (gcov_file_name);
743 }
744 fnotice (stdout, "\n");
745 }
746
747 if (!file_name)
748 executed_summary (total_lines, total_executed);
749 }
750
751 /* Release a function structure */
752
753 static void
754 release_function (function_t *fn)
755 {
756 unsigned ix;
757 block_t *block;
758
759 for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
760 {
761 arc_t *arc, *arc_n;
762
763 for (arc = block->succ; arc; arc = arc_n)
764 {
765 arc_n = arc->succ_next;
766 free (arc);
767 }
768 }
769 free (fn->blocks);
770 free (fn->counts);
771 }
772
773 /* Release all memory used. */
774
775 static void
776 release_structures (void)
777 {
778 unsigned ix;
779 function_t *fn;
780
781 for (ix = n_sources; ix--;)
782 free (sources[ix].lines);
783 free (sources);
784
785 for (ix = n_names; ix--;)
786 free (names[ix].name);
787 free (names);
788
789 while ((fn = functions))
790 {
791 functions = fn->next;
792 release_function (fn);
793 }
794 }
795
796 /* Generate the names of the graph and data files. If OBJECT_DIRECTORY
797 is not specified, these are named from FILE_NAME sans extension. If
798 OBJECT_DIRECTORY is specified and is a directory, the files are in that
799 directory, but named from the basename of the FILE_NAME, sans extension.
800 Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
801 and the data files are named from that. */
802
803 static void
804 create_file_names (const char *file_name)
805 {
806 char *cptr;
807 char *name;
808 int length = strlen (file_name);
809 int base;
810
811 /* Free previous file names. */
812 free (bbg_file_name);
813 free (da_file_name);
814 da_file_name = bbg_file_name = NULL;
815 bbg_file_time = 0;
816 bbg_stamp = 0;
817
818 if (object_directory && object_directory[0])
819 {
820 struct stat status;
821
822 length += strlen (object_directory) + 2;
823 name = XNEWVEC (char, length);
824 name[0] = 0;
825
826 base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
827 strcat (name, object_directory);
828 if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
829 strcat (name, "/");
830 }
831 else
832 {
833 name = XNEWVEC (char, length + 1);
834 strcpy (name, file_name);
835 base = 0;
836 }
837
838 if (base)
839 {
840 /* Append source file name. */
841 const char *cptr = lbasename (file_name);
842 strcat (name, cptr ? cptr : file_name);
843 }
844
845 /* Remove the extension. */
846 cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
847 if (cptr)
848 *cptr = 0;
849
850 length = strlen (name);
851
852 bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
853 strcpy (bbg_file_name, name);
854 strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
855
856 da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
857 strcpy (da_file_name, name);
858 strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
859
860 free (name);
861 return;
862 }
863
864 /* A is a string and B is a pointer to name_map_t. Compare for file
865 name orderability. */
866
867 static int
868 name_search (const void *a_, const void *b_)
869 {
870 const char *a = (const char *)a_;
871 const name_map_t *b = (const name_map_t *)b_;
872
873 #if HAVE_DOS_BASED_FILE_SYSTEM
874 return strcasecmp (a, b->name);
875 #else
876 return strcmp (a, b->name);
877 #endif
878 }
879
880 /* A and B are a pointer to name_map_t. Compare for file name
881 orderability. */
882
883 static int
884 name_sort (const void *a_, const void *b_)
885 {
886 const name_map_t *a = (const name_map_t *)a_;
887 return name_search (a->name, b_);
888 }
889
890 /* Find or create a source file structure for FILE_NAME. Copies
891 FILE_NAME on creation */
892
893 static unsigned
894 find_source (const char *file_name)
895 {
896 name_map_t *name_map;
897 char *canon;
898 unsigned idx;
899 struct stat status;
900
901 if (!file_name)
902 file_name = "<unknown>";
903 name_map = (name_map_t *)bsearch
904 (file_name, names, n_names, sizeof (*names), name_search);
905 if (name_map)
906 {
907 idx = name_map->src;
908 goto check_date;
909 }
910
911 if (n_names + 2 > a_names)
912 {
913 /* Extend the name map array -- we'll be inserting one or two
914 entries. */
915 a_names *= 2;
916 name_map = XNEWVEC (name_map_t, a_names);
917 memcpy (name_map, names, n_names * sizeof (*names));
918 free (names);
919 names = name_map;
920 }
921
922 /* Not found, try the canonical name. */
923 canon = canonicalize_name (file_name);
924 name_map = (name_map_t *)bsearch
925 (canon, names, n_names, sizeof (*names), name_search);
926 if (!name_map)
927 {
928 /* Not found with canonical name, create a new source. */
929 source_t *src;
930
931 if (n_sources == a_sources)
932 {
933 a_sources *= 2;
934 src = XNEWVEC (source_t, a_sources);
935 memcpy (src, sources, n_sources * sizeof (*sources));
936 free (sources);
937 sources = src;
938 }
939
940 idx = n_sources;
941
942 name_map = &names[n_names++];
943 name_map->name = canon;
944 name_map->src = idx;
945
946 src = &sources[n_sources++];
947 memset (src, 0, sizeof (*src));
948 src->name = canon;
949 src->coverage.name = src->name;
950 if (source_length
951 #if HAVE_DOS_BASED_FILE_SYSTEM
952 /* You lose if separators don't match exactly in the
953 prefix. */
954 && !strncasecmp (source_prefix, src->coverage.name, source_length)
955 #else
956 && !strncmp (source_prefix, src->coverage.name, source_length)
957 #endif
958 && IS_DIR_SEPARATOR (src->coverage.name[source_length]))
959 src->coverage.name += source_length + 1;
960 if (!stat (src->name, &status))
961 src->file_time = status.st_mtime;
962 }
963 else
964 idx = name_map->src;
965
966 if (name_search (file_name, name_map))
967 {
968 /* Append the non-canonical name. */
969 name_map = &names[n_names++];
970 name_map->name = xstrdup (file_name);
971 name_map->src = idx;
972 }
973
974 /* Resort the name map. */
975 qsort (names, n_names, sizeof (*names), name_sort);
976
977 check_date:
978 if (sources[idx].file_time > bbg_file_time)
979 {
980 static int info_emitted;
981
982 fnotice (stderr, "%s:source file is newer than notes file '%s'\n",
983 file_name, bbg_file_name);
984 if (!info_emitted)
985 {
986 fnotice (stderr,
987 "(the message is only displayed one per source file)\n");
988 info_emitted = 1;
989 }
990 sources[idx].file_time = 0;
991 }
992
993 return idx;
994 }
995
996 /* Read the notes file. Return list of functions read -- in reverse order. */
997
998 static function_t *
999 read_graph_file (void)
1000 {
1001 unsigned version;
1002 unsigned current_tag = 0;
1003 function_t *fn = NULL;
1004 function_t *fns = NULL;
1005 function_t **fns_end = &fns;
1006 unsigned src_idx = 0;
1007 unsigned ix;
1008 unsigned tag;
1009
1010 if (!gcov_open (bbg_file_name, 1))
1011 {
1012 fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
1013 return fns;
1014 }
1015 bbg_file_time = gcov_time ();
1016 if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
1017 {
1018 fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
1019 gcov_close ();
1020 return fns;
1021 }
1022
1023 version = gcov_read_unsigned ();
1024 if (version != GCOV_VERSION)
1025 {
1026 char v[4], e[4];
1027
1028 GCOV_UNSIGNED2STRING (v, version);
1029 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1030
1031 fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
1032 bbg_file_name, v, e);
1033 }
1034 bbg_stamp = gcov_read_unsigned ();
1035
1036 while ((tag = gcov_read_unsigned ()))
1037 {
1038 unsigned length = gcov_read_unsigned ();
1039 gcov_position_t base = gcov_position ();
1040
1041 if (tag == GCOV_TAG_FUNCTION)
1042 {
1043 char *function_name;
1044 unsigned ident, lineno;
1045 unsigned lineno_checksum, cfg_checksum;
1046
1047 ident = gcov_read_unsigned ();
1048 lineno_checksum = gcov_read_unsigned ();
1049 cfg_checksum = gcov_read_unsigned ();
1050 function_name = xstrdup (gcov_read_string ());
1051 src_idx = find_source (gcov_read_string ());
1052 lineno = gcov_read_unsigned ();
1053
1054 fn = XCNEW (function_t);
1055 fn->name = function_name;
1056 fn->ident = ident;
1057 fn->lineno_checksum = lineno_checksum;
1058 fn->cfg_checksum = cfg_checksum;
1059 fn->src = src_idx;
1060 fn->line = lineno;
1061
1062 fn->line_next = NULL;
1063 fn->next = NULL;
1064 *fns_end = fn;
1065 fns_end = &fn->next;
1066 current_tag = tag;
1067 }
1068 else if (fn && tag == GCOV_TAG_BLOCKS)
1069 {
1070 if (fn->blocks)
1071 fnotice (stderr, "%s:already seen blocks for '%s'\n",
1072 bbg_file_name, fn->name);
1073 else
1074 {
1075 unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
1076 fn->num_blocks = num_blocks;
1077
1078 fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
1079 for (ix = 0; ix != num_blocks; ix++)
1080 fn->blocks[ix].flags = gcov_read_unsigned ();
1081 }
1082 }
1083 else if (fn && tag == GCOV_TAG_ARCS)
1084 {
1085 unsigned src = gcov_read_unsigned ();
1086 unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
1087 block_t *src_blk = &fn->blocks[src];
1088 unsigned mark_catches = 0;
1089 struct arc_info *arc;
1090
1091 if (src >= fn->num_blocks || fn->blocks[src].succ)
1092 goto corrupt;
1093
1094 while (num_dests--)
1095 {
1096 unsigned dest = gcov_read_unsigned ();
1097 unsigned flags = gcov_read_unsigned ();
1098
1099 if (dest >= fn->num_blocks)
1100 goto corrupt;
1101 arc = XCNEW (arc_t);
1102
1103 arc->dst = &fn->blocks[dest];
1104 arc->src = src_blk;
1105
1106 arc->count = 0;
1107 arc->count_valid = 0;
1108 arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
1109 arc->fake = !!(flags & GCOV_ARC_FAKE);
1110 arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
1111
1112 arc->succ_next = src_blk->succ;
1113 src_blk->succ = arc;
1114 src_blk->num_succ++;
1115
1116 arc->pred_next = fn->blocks[dest].pred;
1117 fn->blocks[dest].pred = arc;
1118 fn->blocks[dest].num_pred++;
1119
1120 if (arc->fake)
1121 {
1122 if (src)
1123 {
1124 /* Exceptional exit from this function, the
1125 source block must be a call. */
1126 fn->blocks[src].is_call_site = 1;
1127 arc->is_call_non_return = 1;
1128 mark_catches = 1;
1129 }
1130 else
1131 {
1132 /* Non-local return from a callee of this
1133 function. The destination block is a setjmp. */
1134 arc->is_nonlocal_return = 1;
1135 fn->blocks[dest].is_nonlocal_return = 1;
1136 }
1137 }
1138
1139 if (!arc->on_tree)
1140 fn->num_counts++;
1141 }
1142
1143 if (mark_catches)
1144 {
1145 /* We have a fake exit from this block. The other
1146 non-fall through exits must be to catch handlers.
1147 Mark them as catch arcs. */
1148
1149 for (arc = src_blk->succ; arc; arc = arc->succ_next)
1150 if (!arc->fake && !arc->fall_through)
1151 {
1152 arc->is_throw = 1;
1153 fn->has_catch = 1;
1154 }
1155 }
1156 }
1157 else if (fn && tag == GCOV_TAG_LINES)
1158 {
1159 unsigned blockno = gcov_read_unsigned ();
1160 unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
1161
1162 if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
1163 goto corrupt;
1164
1165 for (ix = 0; ; )
1166 {
1167 unsigned lineno = gcov_read_unsigned ();
1168
1169 if (lineno)
1170 {
1171 if (!ix)
1172 {
1173 line_nos[ix++] = 0;
1174 line_nos[ix++] = src_idx;
1175 }
1176 line_nos[ix++] = lineno;
1177 }
1178 else
1179 {
1180 const char *file_name = gcov_read_string ();
1181
1182 if (!file_name)
1183 break;
1184 src_idx = find_source (file_name);
1185 line_nos[ix++] = 0;
1186 line_nos[ix++] = src_idx;
1187 }
1188 }
1189
1190 fn->blocks[blockno].u.line.encoding = line_nos;
1191 fn->blocks[blockno].u.line.num = ix;
1192 }
1193 else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
1194 {
1195 fn = NULL;
1196 current_tag = 0;
1197 }
1198 gcov_sync (base, length);
1199 if (gcov_is_error ())
1200 {
1201 corrupt:;
1202 fnotice (stderr, "%s:corrupted\n", bbg_file_name);
1203 break;
1204 }
1205 }
1206 gcov_close ();
1207
1208 if (!fns)
1209 fnotice (stderr, "%s:no functions found\n", bbg_file_name);
1210
1211 return fns;
1212 }
1213
1214 /* Reads profiles from the count file and attach to each
1215 function. Return nonzero if fatal error. */
1216
1217 static int
1218 read_count_file (function_t *fns)
1219 {
1220 unsigned ix;
1221 unsigned version;
1222 unsigned tag;
1223 function_t *fn = NULL;
1224 int error = 0;
1225
1226 if (!gcov_open (da_file_name, 1))
1227 {
1228 fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1229 da_file_name);
1230 no_data_file = 1;
1231 return 0;
1232 }
1233 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1234 {
1235 fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1236 cleanup:;
1237 gcov_close ();
1238 return 1;
1239 }
1240 version = gcov_read_unsigned ();
1241 if (version != GCOV_VERSION)
1242 {
1243 char v[4], e[4];
1244
1245 GCOV_UNSIGNED2STRING (v, version);
1246 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1247
1248 fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1249 da_file_name, v, e);
1250 }
1251 tag = gcov_read_unsigned ();
1252 if (tag != bbg_stamp)
1253 {
1254 fnotice (stderr, "%s:stamp mismatch with notes file\n", da_file_name);
1255 goto cleanup;
1256 }
1257
1258 while ((tag = gcov_read_unsigned ()))
1259 {
1260 unsigned length = gcov_read_unsigned ();
1261 unsigned long base = gcov_position ();
1262
1263 if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1264 {
1265 struct gcov_summary summary;
1266 gcov_read_summary (&summary);
1267 object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs;
1268 program_count++;
1269 }
1270 else if (tag == GCOV_TAG_FUNCTION && !length)
1271 ; /* placeholder */
1272 else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
1273 {
1274 unsigned ident;
1275 struct function_info *fn_n;
1276
1277 /* Try to find the function in the list. To speed up the
1278 search, first start from the last function found. */
1279 ident = gcov_read_unsigned ();
1280 fn_n = fns;
1281 for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1282 {
1283 if (fn)
1284 ;
1285 else if ((fn = fn_n))
1286 fn_n = NULL;
1287 else
1288 {
1289 fnotice (stderr, "%s:unknown function '%u'\n",
1290 da_file_name, ident);
1291 break;
1292 }
1293 if (fn->ident == ident)
1294 break;
1295 }
1296
1297 if (!fn)
1298 ;
1299 else if (gcov_read_unsigned () != fn->lineno_checksum
1300 || gcov_read_unsigned () != fn->cfg_checksum)
1301 {
1302 mismatch:;
1303 fnotice (stderr, "%s:profile mismatch for '%s'\n",
1304 da_file_name, fn->name);
1305 goto cleanup;
1306 }
1307 }
1308 else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1309 {
1310 if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1311 goto mismatch;
1312
1313 if (!fn->counts)
1314 fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1315
1316 for (ix = 0; ix != fn->num_counts; ix++)
1317 fn->counts[ix] += gcov_read_counter ();
1318 }
1319 gcov_sync (base, length);
1320 if ((error = gcov_is_error ()))
1321 {
1322 fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1323 da_file_name);
1324 goto cleanup;
1325 }
1326 }
1327
1328 gcov_close ();
1329 return 0;
1330 }
1331
1332 /* Solve the flow graph. Propagate counts from the instrumented arcs
1333 to the blocks and the uninstrumented arcs. */
1334
1335 static void
1336 solve_flow_graph (function_t *fn)
1337 {
1338 unsigned ix;
1339 arc_t *arc;
1340 gcov_type *count_ptr = fn->counts;
1341 block_t *blk;
1342 block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */
1343 block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */
1344
1345 /* The arcs were built in reverse order. Fix that now. */
1346 for (ix = fn->num_blocks; ix--;)
1347 {
1348 arc_t *arc_p, *arc_n;
1349
1350 for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1351 arc_p = arc, arc = arc_n)
1352 {
1353 arc_n = arc->succ_next;
1354 arc->succ_next = arc_p;
1355 }
1356 fn->blocks[ix].succ = arc_p;
1357
1358 for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1359 arc_p = arc, arc = arc_n)
1360 {
1361 arc_n = arc->pred_next;
1362 arc->pred_next = arc_p;
1363 }
1364 fn->blocks[ix].pred = arc_p;
1365 }
1366
1367 if (fn->num_blocks < 2)
1368 fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1369 bbg_file_name, fn->name);
1370 else
1371 {
1372 if (fn->blocks[ENTRY_BLOCK].num_pred)
1373 fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1374 bbg_file_name, fn->name);
1375 else
1376 /* We can't deduce the entry block counts from the lack of
1377 predecessors. */
1378 fn->blocks[ENTRY_BLOCK].num_pred = ~(unsigned)0;
1379
1380 if (fn->blocks[EXIT_BLOCK].num_succ)
1381 fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1382 bbg_file_name, fn->name);
1383 else
1384 /* Likewise, we can't deduce exit block counts from the lack
1385 of its successors. */
1386 fn->blocks[EXIT_BLOCK].num_succ = ~(unsigned)0;
1387 }
1388
1389 /* Propagate the measured counts, this must be done in the same
1390 order as the code in profile.c */
1391 for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1392 {
1393 block_t const *prev_dst = NULL;
1394 int out_of_order = 0;
1395 int non_fake_succ = 0;
1396
1397 for (arc = blk->succ; arc; arc = arc->succ_next)
1398 {
1399 if (!arc->fake)
1400 non_fake_succ++;
1401
1402 if (!arc->on_tree)
1403 {
1404 if (count_ptr)
1405 arc->count = *count_ptr++;
1406 arc->count_valid = 1;
1407 blk->num_succ--;
1408 arc->dst->num_pred--;
1409 }
1410 if (prev_dst && prev_dst > arc->dst)
1411 out_of_order = 1;
1412 prev_dst = arc->dst;
1413 }
1414 if (non_fake_succ == 1)
1415 {
1416 /* If there is only one non-fake exit, it is an
1417 unconditional branch. */
1418 for (arc = blk->succ; arc; arc = arc->succ_next)
1419 if (!arc->fake)
1420 {
1421 arc->is_unconditional = 1;
1422 /* If this block is instrumenting a call, it might be
1423 an artificial block. It is not artificial if it has
1424 a non-fallthrough exit, or the destination of this
1425 arc has more than one entry. Mark the destination
1426 block as a return site, if none of those conditions
1427 hold. */
1428 if (blk->is_call_site && arc->fall_through
1429 && arc->dst->pred == arc && !arc->pred_next)
1430 arc->dst->is_call_return = 1;
1431 }
1432 }
1433
1434 /* Sort the successor arcs into ascending dst order. profile.c
1435 normally produces arcs in the right order, but sometimes with
1436 one or two out of order. We're not using a particularly
1437 smart sort. */
1438 if (out_of_order)
1439 {
1440 arc_t *start = blk->succ;
1441 unsigned changes = 1;
1442
1443 while (changes)
1444 {
1445 arc_t *arc, *arc_p, *arc_n;
1446
1447 changes = 0;
1448 for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1449 {
1450 if (arc->dst > arc_n->dst)
1451 {
1452 changes = 1;
1453 if (arc_p)
1454 arc_p->succ_next = arc_n;
1455 else
1456 start = arc_n;
1457 arc->succ_next = arc_n->succ_next;
1458 arc_n->succ_next = arc;
1459 arc_p = arc_n;
1460 }
1461 else
1462 {
1463 arc_p = arc;
1464 arc = arc_n;
1465 }
1466 }
1467 }
1468 blk->succ = start;
1469 }
1470
1471 /* Place it on the invalid chain, it will be ignored if that's
1472 wrong. */
1473 blk->invalid_chain = 1;
1474 blk->chain = invalid_blocks;
1475 invalid_blocks = blk;
1476 }
1477
1478 while (invalid_blocks || valid_blocks)
1479 {
1480 while ((blk = invalid_blocks))
1481 {
1482 gcov_type total = 0;
1483 const arc_t *arc;
1484
1485 invalid_blocks = blk->chain;
1486 blk->invalid_chain = 0;
1487 if (!blk->num_succ)
1488 for (arc = blk->succ; arc; arc = arc->succ_next)
1489 total += arc->count;
1490 else if (!blk->num_pred)
1491 for (arc = blk->pred; arc; arc = arc->pred_next)
1492 total += arc->count;
1493 else
1494 continue;
1495
1496 blk->count = total;
1497 blk->count_valid = 1;
1498 blk->chain = valid_blocks;
1499 blk->valid_chain = 1;
1500 valid_blocks = blk;
1501 }
1502 while ((blk = valid_blocks))
1503 {
1504 gcov_type total;
1505 arc_t *arc, *inv_arc;
1506
1507 valid_blocks = blk->chain;
1508 blk->valid_chain = 0;
1509 if (blk->num_succ == 1)
1510 {
1511 block_t *dst;
1512
1513 total = blk->count;
1514 inv_arc = NULL;
1515 for (arc = blk->succ; arc; arc = arc->succ_next)
1516 {
1517 total -= arc->count;
1518 if (!arc->count_valid)
1519 inv_arc = arc;
1520 }
1521 dst = inv_arc->dst;
1522 inv_arc->count_valid = 1;
1523 inv_arc->count = total;
1524 blk->num_succ--;
1525 dst->num_pred--;
1526 if (dst->count_valid)
1527 {
1528 if (dst->num_pred == 1 && !dst->valid_chain)
1529 {
1530 dst->chain = valid_blocks;
1531 dst->valid_chain = 1;
1532 valid_blocks = dst;
1533 }
1534 }
1535 else
1536 {
1537 if (!dst->num_pred && !dst->invalid_chain)
1538 {
1539 dst->chain = invalid_blocks;
1540 dst->invalid_chain = 1;
1541 invalid_blocks = dst;
1542 }
1543 }
1544 }
1545 if (blk->num_pred == 1)
1546 {
1547 block_t *src;
1548
1549 total = blk->count;
1550 inv_arc = NULL;
1551 for (arc = blk->pred; arc; arc = arc->pred_next)
1552 {
1553 total -= arc->count;
1554 if (!arc->count_valid)
1555 inv_arc = arc;
1556 }
1557 src = inv_arc->src;
1558 inv_arc->count_valid = 1;
1559 inv_arc->count = total;
1560 blk->num_pred--;
1561 src->num_succ--;
1562 if (src->count_valid)
1563 {
1564 if (src->num_succ == 1 && !src->valid_chain)
1565 {
1566 src->chain = valid_blocks;
1567 src->valid_chain = 1;
1568 valid_blocks = src;
1569 }
1570 }
1571 else
1572 {
1573 if (!src->num_succ && !src->invalid_chain)
1574 {
1575 src->chain = invalid_blocks;
1576 src->invalid_chain = 1;
1577 invalid_blocks = src;
1578 }
1579 }
1580 }
1581 }
1582 }
1583
1584 /* If the graph has been correctly solved, every block will have a
1585 valid count. */
1586 for (ix = 0; ix < fn->num_blocks; ix++)
1587 if (!fn->blocks[ix].count_valid)
1588 {
1589 fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1590 bbg_file_name, fn->name);
1591 break;
1592 }
1593 }
1594
1595 /* Mark all the blocks only reachable via an incoming catch. */
1596
1597 static void
1598 find_exception_blocks (function_t *fn)
1599 {
1600 unsigned ix;
1601 block_t **queue = XALLOCAVEC (block_t *, fn->num_blocks);
1602
1603 /* First mark all blocks as exceptional. */
1604 for (ix = fn->num_blocks; ix--;)
1605 fn->blocks[ix].exceptional = 1;
1606
1607 /* Now mark all the blocks reachable via non-fake edges */
1608 queue[0] = fn->blocks;
1609 queue[0]->exceptional = 0;
1610 for (ix = 1; ix;)
1611 {
1612 block_t *block = queue[--ix];
1613 const arc_t *arc;
1614
1615 for (arc = block->succ; arc; arc = arc->succ_next)
1616 if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
1617 {
1618 arc->dst->exceptional = 0;
1619 queue[ix++] = arc->dst;
1620 }
1621 }
1622 }
1623 \f
1624
1625 /* Increment totals in COVERAGE according to arc ARC. */
1626
1627 static void
1628 add_branch_counts (coverage_t *coverage, const arc_t *arc)
1629 {
1630 if (arc->is_call_non_return)
1631 {
1632 coverage->calls++;
1633 if (arc->src->count)
1634 coverage->calls_executed++;
1635 }
1636 else if (!arc->is_unconditional)
1637 {
1638 coverage->branches++;
1639 if (arc->src->count)
1640 coverage->branches_executed++;
1641 if (arc->count)
1642 coverage->branches_taken++;
1643 }
1644 }
1645
1646 /* Format a GCOV_TYPE integer as either a percent ratio, or absolute
1647 count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1648 If DP is zero, no decimal point is printed. Only print 100% when
1649 TOP==BOTTOM and only print 0% when TOP=0. If dp < 0, then simply
1650 format TOP. Return pointer to a static string. */
1651
1652 static char const *
1653 format_gcov (gcov_type top, gcov_type bottom, int dp)
1654 {
1655 static char buffer[20];
1656
1657 if (dp >= 0)
1658 {
1659 float ratio = bottom ? (float)top / bottom : 0;
1660 int ix;
1661 unsigned limit = 100;
1662 unsigned percent;
1663
1664 for (ix = dp; ix--; )
1665 limit *= 10;
1666
1667 percent = (unsigned) (ratio * limit + (float)0.5);
1668 if (percent <= 0 && top)
1669 percent = 1;
1670 else if (percent >= limit && top != bottom)
1671 percent = limit - 1;
1672 ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1673 if (dp)
1674 {
1675 dp++;
1676 do
1677 {
1678 buffer[ix+1] = buffer[ix];
1679 ix--;
1680 }
1681 while (dp--);
1682 buffer[ix + 1] = '.';
1683 }
1684 }
1685 else
1686 sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
1687
1688 return buffer;
1689 }
1690
1691 /* Summary of execution */
1692
1693 static void
1694 executed_summary (unsigned lines, unsigned executed)
1695 {
1696 if (lines)
1697 fnotice (stdout, "Lines executed:%s of %d\n",
1698 format_gcov (executed, lines, 2), lines);
1699 else
1700 fnotice (stdout, "No executable lines\n");
1701 }
1702
1703 /* Output summary info for a function or file. */
1704
1705 static void
1706 function_summary (const coverage_t *coverage, const char *title)
1707 {
1708 fnotice (stdout, "%s '%s'\n", title, coverage->name);
1709 executed_summary (coverage->lines, coverage->lines_executed);
1710
1711 if (flag_branches)
1712 {
1713 if (coverage->branches)
1714 {
1715 fnotice (stdout, "Branches executed:%s of %d\n",
1716 format_gcov (coverage->branches_executed,
1717 coverage->branches, 2),
1718 coverage->branches);
1719 fnotice (stdout, "Taken at least once:%s of %d\n",
1720 format_gcov (coverage->branches_taken,
1721 coverage->branches, 2),
1722 coverage->branches);
1723 }
1724 else
1725 fnotice (stdout, "No branches\n");
1726 if (coverage->calls)
1727 fnotice (stdout, "Calls executed:%s of %d\n",
1728 format_gcov (coverage->calls_executed, coverage->calls, 2),
1729 coverage->calls);
1730 else
1731 fnotice (stdout, "No calls\n");
1732 }
1733 }
1734
1735 /* Canonicalize the filename NAME by canonicalizing directory
1736 separators, eliding . components and resolving .. components
1737 appropriately. Always returns a unique string. */
1738
1739 static char *
1740 canonicalize_name (const char *name)
1741 {
1742 /* The canonical name cannot be longer than the incoming name. */
1743 char *result = XNEWVEC (char, strlen (name) + 1);
1744 const char *base = name, *probe;
1745 char *ptr = result;
1746 char *dd_base;
1747 int slash = 0;
1748
1749 #if HAVE_DOS_BASED_FILE_SYSTEM
1750 if (base[0] && base[1] == ':')
1751 {
1752 result[0] = base[0];
1753 result[1] = ':';
1754 base += 2;
1755 ptr += 2;
1756 }
1757 #endif
1758 for (dd_base = ptr; *base; base = probe)
1759 {
1760 size_t len;
1761
1762 for (probe = base; *probe; probe++)
1763 if (IS_DIR_SEPARATOR (*probe))
1764 break;
1765
1766 len = probe - base;
1767 if (len == 1 && base[0] == '.')
1768 /* Elide a '.' directory */
1769 ;
1770 else if (len == 2 && base[0] == '.' && base[1] == '.')
1771 {
1772 /* '..', we can only elide it and the previous directory, if
1773 we're not a symlink. */
1774 struct stat ATTRIBUTE_UNUSED buf;
1775
1776 *ptr = 0;
1777 if (dd_base == ptr
1778 #if defined (S_ISLNK)
1779 /* S_ISLNK is not POSIX.1-1996. */
1780 || stat (result, &buf) || S_ISLNK (buf.st_mode)
1781 #endif
1782 )
1783 {
1784 /* Cannot elide, or unreadable or a symlink. */
1785 dd_base = ptr + 2 + slash;
1786 goto regular;
1787 }
1788 while (ptr != dd_base && *ptr != '/')
1789 ptr--;
1790 slash = ptr != result;
1791 }
1792 else
1793 {
1794 regular:
1795 /* Regular pathname component. */
1796 if (slash)
1797 *ptr++ = '/';
1798 memcpy (ptr, base, len);
1799 ptr += len;
1800 slash = 1;
1801 }
1802
1803 for (; IS_DIR_SEPARATOR (*probe); probe++)
1804 continue;
1805 }
1806 *ptr = 0;
1807
1808 return result;
1809 }
1810
1811 /* Generate an output file name. INPUT_NAME is the canonicalized main
1812 input file and SRC_NAME is the canonicalized file name.
1813 LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation. With
1814 long_output_names we prepend the processed name of the input file
1815 to each output name (except when the current source file is the
1816 input file, so you don't get a double concatenation). The two
1817 components are separated by '##'. With preserve_paths we create a
1818 filename from all path components of the source file, replacing '/'
1819 with '#', and .. with '^', without it we simply take the basename
1820 component. (Remember, the canonicalized name will already have
1821 elided '.' components and converted \\ separators.) */
1822
1823 static char *
1824 make_gcov_file_name (const char *input_name, const char *src_name)
1825 {
1826 char *ptr;
1827 char *result;
1828
1829 if (flag_long_names && input_name && strcmp (src_name, input_name))
1830 {
1831 /* Generate the input filename part. */
1832 result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);
1833
1834 ptr = result;
1835 ptr = mangle_name (input_name, ptr);
1836 ptr[0] = ptr[1] = '#';
1837 ptr += 2;
1838 }
1839 else
1840 {
1841 result = XNEWVEC (char, strlen (src_name) + 10);
1842 ptr = result;
1843 }
1844
1845 ptr = mangle_name (src_name, ptr);
1846 strcpy (ptr, ".gcov");
1847
1848 return result;
1849 }
1850
1851 static char *
1852 mangle_name (char const *base, char *ptr)
1853 {
1854 size_t len;
1855
1856 /* Generate the source filename part. */
1857 if (!flag_preserve_paths)
1858 {
1859 base = lbasename (base);
1860 len = strlen (base);
1861 memcpy (ptr, base, len);
1862 ptr += len;
1863 }
1864 else
1865 {
1866 /* Convert '/' to '#', convert '..' to '^',
1867 convert ':' to '~' on DOS based file system. */
1868 const char *probe;
1869
1870 #if HAVE_DOS_BASED_FILE_SYSTEM
1871 if (base[0] && base[1] == ':')
1872 {
1873 ptr[0] = base[0];
1874 ptr[1] = '~';
1875 ptr += 2;
1876 base += 2;
1877 }
1878 #endif
1879 for (; *base; base = probe)
1880 {
1881 size_t len;
1882
1883 for (probe = base; *probe; probe++)
1884 if (*probe == '/')
1885 break;
1886 len = probe - base;
1887 if (len == 2 && base[0] == '.' && base[1] == '.')
1888 *ptr++ = '^';
1889 else
1890 {
1891 memcpy (ptr, base, len);
1892 ptr += len;
1893 }
1894 if (*probe)
1895 {
1896 *ptr++ = '#';
1897 probe++;
1898 }
1899 }
1900 }
1901
1902 return ptr;
1903 }
1904
1905 /* Scan through the bb_data for each line in the block, increment
1906 the line number execution count indicated by the execution count of
1907 the appropriate basic block. */
1908
1909 static void
1910 add_line_counts (coverage_t *coverage, function_t *fn)
1911 {
1912 unsigned ix;
1913 line_t *line = NULL; /* This is propagated from one iteration to the
1914 next. */
1915
1916 /* Scan each basic block. */
1917 for (ix = 0; ix != fn->num_blocks; ix++)
1918 {
1919 block_t *block = &fn->blocks[ix];
1920 unsigned *encoding;
1921 const source_t *src = NULL;
1922 unsigned jx;
1923
1924 if (block->count && ix && ix + 1 != fn->num_blocks)
1925 fn->blocks_executed++;
1926 for (jx = 0, encoding = block->u.line.encoding;
1927 jx != block->u.line.num; jx++, encoding++)
1928 if (!*encoding)
1929 {
1930 src = &sources[*++encoding];
1931 jx++;
1932 }
1933 else
1934 {
1935 line = &src->lines[*encoding];
1936
1937 if (coverage)
1938 {
1939 if (!line->exists)
1940 coverage->lines++;
1941 if (!line->count && block->count)
1942 coverage->lines_executed++;
1943 }
1944 line->exists = 1;
1945 if (!block->exceptional)
1946 line->unexceptional = 1;
1947 line->count += block->count;
1948 }
1949 free (block->u.line.encoding);
1950 block->u.cycle.arc = NULL;
1951 block->u.cycle.ident = ~0U;
1952
1953 if (!ix || ix + 1 == fn->num_blocks)
1954 /* Entry or exit block */;
1955 else if (flag_all_blocks)
1956 {
1957 line_t *block_line = line;
1958
1959 if (!block_line)
1960 block_line = &sources[fn->src].lines[fn->line];
1961
1962 block->chain = block_line->u.blocks;
1963 block_line->u.blocks = block;
1964 }
1965 else if (flag_branches)
1966 {
1967 arc_t *arc;
1968
1969 for (arc = block->succ; arc; arc = arc->succ_next)
1970 {
1971 arc->line_next = line->u.branches;
1972 line->u.branches = arc;
1973 if (coverage && !arc->is_unconditional)
1974 add_branch_counts (coverage, arc);
1975 }
1976 }
1977 }
1978 if (!line)
1979 fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1980 }
1981
1982 /* Accumulate the line counts of a file. */
1983
1984 static void
1985 accumulate_line_counts (source_t *src)
1986 {
1987 line_t *line;
1988 function_t *fn, *fn_p, *fn_n;
1989 unsigned ix;
1990
1991 /* Reverse the function order. */
1992 for (fn = src->functions, fn_p = NULL; fn;
1993 fn_p = fn, fn = fn_n)
1994 {
1995 fn_n = fn->line_next;
1996 fn->line_next = fn_p;
1997 }
1998 src->functions = fn_p;
1999
2000 for (ix = src->num_lines, line = src->lines; ix--; line++)
2001 {
2002 if (!flag_all_blocks)
2003 {
2004 arc_t *arc, *arc_p, *arc_n;
2005
2006 /* Total and reverse the branch information. */
2007 for (arc = line->u.branches, arc_p = NULL; arc;
2008 arc_p = arc, arc = arc_n)
2009 {
2010 arc_n = arc->line_next;
2011 arc->line_next = arc_p;
2012
2013 add_branch_counts (&src->coverage, arc);
2014 }
2015 line->u.branches = arc_p;
2016 }
2017 else if (line->u.blocks)
2018 {
2019 /* The user expects the line count to be the number of times
2020 a line has been executed. Simply summing the block count
2021 will give an artificially high number. The Right Thing
2022 is to sum the entry counts to the graph of blocks on this
2023 line, then find the elementary cycles of the local graph
2024 and add the transition counts of those cycles. */
2025 block_t *block, *block_p, *block_n;
2026 gcov_type count = 0;
2027
2028 /* Reverse the block information. */
2029 for (block = line->u.blocks, block_p = NULL; block;
2030 block_p = block, block = block_n)
2031 {
2032 block_n = block->chain;
2033 block->chain = block_p;
2034 block->u.cycle.ident = ix;
2035 }
2036 line->u.blocks = block_p;
2037
2038 /* Sum the entry arcs. */
2039 for (block = line->u.blocks; block; block = block->chain)
2040 {
2041 arc_t *arc;
2042
2043 for (arc = block->pred; arc; arc = arc->pred_next)
2044 {
2045 if (arc->src->u.cycle.ident != ix)
2046 count += arc->count;
2047 if (flag_branches)
2048 add_branch_counts (&src->coverage, arc);
2049 }
2050
2051 /* Initialize the cs_count. */
2052 for (arc = block->succ; arc; arc = arc->succ_next)
2053 arc->cs_count = arc->count;
2054 }
2055
2056 /* Find the loops. This uses the algorithm described in
2057 Tiernan 'An Efficient Search Algorithm to Find the
2058 Elementary Circuits of a Graph', CACM Dec 1970. We hold
2059 the P array by having each block point to the arc that
2060 connects to the previous block. The H array is implicitly
2061 held because of the arc ordering, and the block's
2062 previous arc pointer.
2063
2064 Although the algorithm is O(N^3) for highly connected
2065 graphs, at worst we'll have O(N^2), as most blocks have
2066 only one or two exits. Most graphs will be small.
2067
2068 For each loop we find, locate the arc with the smallest
2069 transition count, and add that to the cumulative
2070 count. Decrease flow over the cycle and remove the arc
2071 from consideration. */
2072 for (block = line->u.blocks; block; block = block->chain)
2073 {
2074 block_t *head = block;
2075 arc_t *arc;
2076
2077 next_vertex:;
2078 arc = head->succ;
2079 current_vertex:;
2080 while (arc)
2081 {
2082 block_t *dst = arc->dst;
2083 if (/* Already used that arc. */
2084 arc->cycle
2085 /* Not to same graph, or before first vertex. */
2086 || dst->u.cycle.ident != ix
2087 /* Already in path. */
2088 || dst->u.cycle.arc)
2089 {
2090 arc = arc->succ_next;
2091 continue;
2092 }
2093
2094 if (dst == block)
2095 {
2096 /* Found a closing arc. */
2097 gcov_type cycle_count = arc->cs_count;
2098 arc_t *cycle_arc = arc;
2099 arc_t *probe_arc;
2100
2101 /* Locate the smallest arc count of the loop. */
2102 for (dst = head; (probe_arc = dst->u.cycle.arc);
2103 dst = probe_arc->src)
2104 if (cycle_count > probe_arc->cs_count)
2105 {
2106 cycle_count = probe_arc->cs_count;
2107 cycle_arc = probe_arc;
2108 }
2109
2110 count += cycle_count;
2111 cycle_arc->cycle = 1;
2112
2113 /* Remove the flow from the cycle. */
2114 arc->cs_count -= cycle_count;
2115 for (dst = head; (probe_arc = dst->u.cycle.arc);
2116 dst = probe_arc->src)
2117 probe_arc->cs_count -= cycle_count;
2118
2119 /* Unwind to the cyclic arc. */
2120 while (head != cycle_arc->src)
2121 {
2122 arc = head->u.cycle.arc;
2123 head->u.cycle.arc = NULL;
2124 head = arc->src;
2125 }
2126 /* Move on. */
2127 arc = arc->succ_next;
2128 continue;
2129 }
2130
2131 /* Add new block to chain. */
2132 dst->u.cycle.arc = arc;
2133 head = dst;
2134 goto next_vertex;
2135 }
2136 /* We could not add another vertex to the path. Remove
2137 the last vertex from the list. */
2138 arc = head->u.cycle.arc;
2139 if (arc)
2140 {
2141 /* It was not the first vertex. Move onto next arc. */
2142 head->u.cycle.arc = NULL;
2143 head = arc->src;
2144 arc = arc->succ_next;
2145 goto current_vertex;
2146 }
2147 /* Mark this block as unusable. */
2148 block->u.cycle.ident = ~0U;
2149 }
2150
2151 line->count = count;
2152 }
2153
2154 if (line->exists)
2155 {
2156 src->coverage.lines++;
2157 if (line->count)
2158 src->coverage.lines_executed++;
2159 }
2160 }
2161 }
2162
2163 /* Output information about ARC number IX. Returns nonzero if
2164 anything is output. */
2165
2166 static int
2167 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
2168 {
2169 if (arc->is_call_non_return)
2170 {
2171 if (arc->src->count)
2172 {
2173 fnotice (gcov_file, "call %2d returned %s\n", ix,
2174 format_gcov (arc->src->count - arc->count,
2175 arc->src->count, -flag_counts));
2176 }
2177 else
2178 fnotice (gcov_file, "call %2d never executed\n", ix);
2179 }
2180 else if (!arc->is_unconditional)
2181 {
2182 if (arc->src->count)
2183 fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
2184 format_gcov (arc->count, arc->src->count, -flag_counts),
2185 arc->fall_through ? " (fallthrough)"
2186 : arc->is_throw ? " (throw)" : "");
2187 else
2188 fnotice (gcov_file, "branch %2d never executed\n", ix);
2189 }
2190 else if (flag_unconditional && !arc->dst->is_call_return)
2191 {
2192 if (arc->src->count)
2193 fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
2194 format_gcov (arc->count, arc->src->count, -flag_counts));
2195 else
2196 fnotice (gcov_file, "unconditional %2d never executed\n", ix);
2197 }
2198 else
2199 return 0;
2200 return 1;
2201
2202 }
2203
2204 static const char *
2205 read_line (FILE *file)
2206 {
2207 static char *string;
2208 static size_t string_len;
2209 size_t pos = 0;
2210 char *ptr;
2211
2212 if (!string_len)
2213 {
2214 string_len = 200;
2215 string = XNEWVEC (char, string_len);
2216 }
2217
2218 while ((ptr = fgets (string + pos, string_len - pos, file)))
2219 {
2220 size_t len = strlen (string + pos);
2221
2222 if (string[pos + len - 1] == '\n')
2223 {
2224 string[pos + len - 1] = 0;
2225 return string;
2226 }
2227 pos += len;
2228 string = XRESIZEVEC (char, string, string_len * 2);
2229 string_len *= 2;
2230 }
2231
2232 return pos ? string : NULL;
2233 }
2234
2235 /* Read in the source file one line at a time, and output that line to
2236 the gcov file preceded by its execution count and other
2237 information. */
2238
2239 static void
2240 output_lines (FILE *gcov_file, const source_t *src)
2241 {
2242 FILE *source_file;
2243 unsigned line_num; /* current line number. */
2244 const line_t *line; /* current line info ptr. */
2245 const char *retval = ""; /* status of source file reading. */
2246 function_t *fn = NULL;
2247
2248 fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
2249 if (!multiple_files)
2250 {
2251 fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
2252 fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
2253 no_data_file ? "-" : da_file_name);
2254 fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, object_runs);
2255 }
2256 fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
2257
2258 source_file = fopen (src->name, "r");
2259 if (!source_file)
2260 {
2261 fnotice (stderr, "Cannot open source file %s\n", src->name);
2262 retval = NULL;
2263 }
2264 else if (src->file_time == 0)
2265 fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
2266
2267 if (flag_branches)
2268 fn = src->functions;
2269
2270 for (line_num = 1, line = &src->lines[line_num];
2271 line_num < src->num_lines; line_num++, line++)
2272 {
2273 for (; fn && fn->line == line_num; fn = fn->line_next)
2274 {
2275 arc_t *arc = fn->blocks[EXIT_BLOCK].pred;
2276 gcov_type return_count = fn->blocks[EXIT_BLOCK].count;
2277 gcov_type called_count = fn->blocks[ENTRY_BLOCK].count;
2278
2279 for (; arc; arc = arc->pred_next)
2280 if (arc->fake)
2281 return_count -= arc->count;
2282
2283 fprintf (gcov_file, "function %s", fn->name);
2284 fprintf (gcov_file, " called %s",
2285 format_gcov (called_count, 0, -1));
2286 fprintf (gcov_file, " returned %s",
2287 format_gcov (return_count, called_count, 0));
2288 fprintf (gcov_file, " blocks executed %s",
2289 format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
2290 fprintf (gcov_file, "\n");
2291 }
2292
2293 if (retval)
2294 retval = read_line (source_file);
2295
2296 /* For lines which don't exist in the .bb file, print '-' before
2297 the source line. For lines which exist but were never
2298 executed, print '#####' or '=====' before the source line.
2299 Otherwise, print the execution count before the source line.
2300 There are 16 spaces of indentation added before the source
2301 line so that tabs won't be messed up. */
2302 fprintf (gcov_file, "%9s:%5u:%s\n",
2303 !line->exists ? "-" : line->count
2304 ? format_gcov (line->count, 0, -1)
2305 : line->unexceptional ? "#####" : "=====", line_num,
2306 retval ? retval : "/*EOF*/");
2307
2308 if (flag_all_blocks)
2309 {
2310 block_t *block;
2311 arc_t *arc;
2312 int ix, jx;
2313
2314 for (ix = jx = 0, block = line->u.blocks; block;
2315 block = block->chain)
2316 {
2317 if (!block->is_call_return)
2318 fprintf (gcov_file, "%9s:%5u-block %2d\n",
2319 !line->exists ? "-" : block->count
2320 ? format_gcov (block->count, 0, -1)
2321 : block->exceptional ? "%%%%%" : "$$$$$",
2322 line_num, ix++);
2323 if (flag_branches)
2324 for (arc = block->succ; arc; arc = arc->succ_next)
2325 jx += output_branch_count (gcov_file, jx, arc);
2326 }
2327 }
2328 else if (flag_branches)
2329 {
2330 int ix;
2331 arc_t *arc;
2332
2333 for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
2334 ix += output_branch_count (gcov_file, ix, arc);
2335 }
2336 }
2337
2338 /* Handle all remaining source lines. There may be lines after the
2339 last line of code. */
2340 if (retval)
2341 {
2342 for (; (retval = read_line (source_file)); line_num++)
2343 fprintf (gcov_file, "%9s:%5u:%s\n", "-", line_num, retval);
2344 }
2345
2346 if (source_file)
2347 fclose (source_file);
2348 }