Replace "GNU CC" with "GCC"
[official-gcc.git] / gcc / gcov-io.h
blob3bd2729d9d2e9618fe4a6c39e402cd2dbc58928c
1 /* File format for coverage information
2 Copyright (C) 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc.
3 Contributed by Bob Manson <manson@cygnus.com>.
4 Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 /* Coverage information is held in two files. A basic block graph
24 file, which is generated by the compiler, and a counter file, which
25 is generated by the program under test. Both files use a similar
26 structure. We do not attempt to make these files backwards
27 compatible with previous versions, as you only need coverage
28 information when developing a program. We do hold version
29 information, so that mismatches can be detected, and we use a
30 format that allows tools to skip information they do not understand
31 or are not interested in.
33 Numbers are recorded in big endian unsigned binary form. Either in
34 32 or 64 bits. Strings are stored with a length count and NUL
35 terminator, and 0 to 3 bytes of zero padding up to the next 4 byte
36 boundary. Zero length and NULL strings are simply stored as a
37 length of zero (they have no trailing NUL or padding).
39 int32: byte3 byte2 byte1 byte0
40 int64: byte7 byte6 byte5 byte4 byte3 byte2 byte1 byte0
41 string: int32:0 | int32:length char* char:0 padding
42 padding: | char:0 | char:0 char:0 | char:0 char:0 char:0
43 item: int32 | int64 | string
45 The basic format of the files is
47 file : int32:magic int32:version record*
49 The magic ident is different for the bbg and the counter files.
50 The version is the same for both files and is derived from gcc's
51 version number. Although the ident and version are formally 32 bit
52 numbers, they are derived from 4 character ASCII strings. The
53 version number consists of the single character major version
54 number, a two character minor version number (leading zero for
55 versions less than 10), and a single character indicating the
56 status of the release. That will be 'e' experimental, 'p'
57 prerelease and 'r' for release. Because, by good fortune, these are
58 in alphabetical order, string collating can be used to compare
59 version strings, and because numbers are stored big endian, numeric
60 comparison can be used when it is read as a 32 bit value. Be aware
61 that the 'e' designation will (naturally) be unstable and might be
62 incompatible with itself. For gcc 3.4 experimental, it would be
63 '304e' (0x33303465). When the major version reaches 10, the letters
64 A-Z will be used. Assuming minor increments releases every 6
65 months, we have to make a major increment every 50 years. Assuming
66 major increments releases every 5 years, we're ok for the next 155
67 years -- good enough for me.
69 A record has a tag, length and variable amount of data.
71 record: header data
72 header: int32:tag int32:length
73 data: item*
75 Records are not nested, but there is a record hierarchy. Tag
76 numbers reflect this hierarchy. Tags are unique across bbg and da
77 files. Some record types have a varying amount of data. The LENGTH
78 is usually used to determine how much data. The tag value is split
79 into 4 8-bit fields, one for each of four possible levels. The
80 most significant is allocated first. Unused levels are zero.
81 Active levels are odd-valued, so that the LSB of the level is one.
82 A sub-level incorporates the values of its superlevels. This
83 formatting allows you to determine the tag heirarchy, without
84 understanding the tags themselves, and is similar to the standard
85 section numbering used in technical documents. Level values
86 [1..3f] are used for common tags, values [41..9f] for the graph
87 file and [a1..ff] for the counter file.
89 The basic block graph file contains the following records
90 bbg: function-graph*
91 function-graph: announce_function basic_blocks {arcs | lines}*
92 announce_function: header string:name int32:checksum
93 string:source int32:lineno
94 basic_block: header int32:flags*
95 arcs: header int32:block_no arc*
96 arc: int32:dest_block int32:flags
97 lines: header int32:block_no line*
98 int32:0 string:NULL
99 line: int32:line_no | int32:0 string:filename
101 The BASIC_BLOCK record holds per-bb flags. The number of blocks
102 can be inferred from its data length. There is one ARCS record per
103 basic block. The number of arcs from a bb is implicit from the
104 data length. It enumerates the destination bb and per-arc flags.
105 There is one LINES record per basic block, it enumerates the source
106 lines which belong to that basic block. Source file names are
107 introduced by a line number of 0, following lines are from the new
108 source file. The initial source file for the function is NULL, but
109 the current source file should be remembered from one LINES record
110 to the next. The end of a block is indicated by an empty filename
111 - this does not reset the current source file. Note there is no
112 ordering of the ARCS and LINES records: they may be in any order,
113 interleaved in any manner. The current filename follows the order
114 the LINES records are stored in the file, *not* the ordering of the
115 blocks they are for.
117 The data file contains the following records.
118 da: {function-data* summary:object summary:program*}*
119 function-data: announce_function arc_counts
120 announce_function: header string:name int32:checksum
121 arc_counts: header int64:count*
122 summary: in32:checksum int32:runs int32:arcs int64:sum int64:max \
123 int64:max_sum int64:sum_max
125 The ANNOUNCE_FUNCTION record is the same as that in the BBG file,
126 but without the source location.
127 The ARC_COUNTS gives the counter values for those arcs that are
128 instrumented. The SUMMARY records give information about the whole
129 object file and about the whole program. The checksum is used for
130 whole program summaries, and disambiguates different programs which
131 include the same instrumented object file. There may be several
132 program summaries, each with a unique checksum. The object
133 summary's checkum is zero. Note that the da file might contain
134 information from several runs concatenated, or the data might be
135 merged.
137 This file is included by both the compiler, gcov tools and the
138 runtime support library libgcov. IN_LIBGCOV and IN_GCOV are used to
139 distinguish which case is which. If IN_LIBGCOV is non-zero,
140 libgcov is being built. If IN_GCOV is non-zero, the gcov tools are
141 being built. Otherwise the compiler is being built. IN_GCOV may be
142 positive or negative. If positive, we are compiling a tool that
143 requires additional functions (see the code for knowledge of what
144 those functions are). */
146 #ifndef GCC_GCOV_IO_H
147 #define GCC_GCOV_IO_H
149 #if IN_LIBGCOV
150 #if LONG_TYPE_SIZE == GCOV_TYPE_SIZE
151 typedef long gcov_type;
152 #else
153 typedef long long gcov_type;
154 #endif
155 #endif /* IN_LIBGCOV */
156 #if IN_GCOV
157 typedef HOST_WIDEST_INT gcov_type;
158 #if IN_GCOV > 0
159 #include <sys/types.h>
160 #endif
161 #endif
163 /* File suffixes. */
164 #define GCOV_DATA_SUFFIX ".da"
165 #define GCOV_GRAPH_SUFFIX ".bbg"
167 /* File magic. */
168 #define GCOV_DATA_MAGIC 0x67636f76 /* "gcov" */
169 #define GCOV_GRAPH_MAGIC 0x67626267 /* "gbbg" */
171 /* gcov-iov.h is automatically generated by the makefile from
172 version.c, it looks like
173 #define GCOV_VERSION ((unsigned)0x89abcdef)
175 #include "gcov-iov.h"
177 /* The record tags. Values [1..3f] are for tags which may be in either
178 file. Values [41..9f] for those in the bbg file and [a1..ff] for
179 the data file. */
181 #define GCOV_TAG_FUNCTION ((unsigned)0x01000000)
182 #define GCOV_TAG_BLOCKS ((unsigned)0x01410000)
183 #define GCOV_TAG_ARCS ((unsigned)0x01430000)
184 #define GCOV_TAG_LINES ((unsigned)0x01450000)
185 #define GCOV_TAG_ARC_COUNTS ((unsigned)0x01a10000)
186 #define GCOV_TAG_OBJECT_SUMMARY ((unsigned)0xa1000000)
187 #define GCOV_TAG_PROGRAM_SUMMARY ((unsigned)0xa3000000)
188 #define GCOV_TAG_PLACEHOLDER_SUMMARY ((unsigned)0xa5000000)
189 #define GCOV_TAG_INCORRECT_SUMMARY ((unsigned)0xa7000000)
191 /* The tag level mask has 1's in the position of the inner levels, &
192 the lsb of the current level, and zero on the current and outer
193 levels. */
194 #define GCOV_TAG_MASK(TAG) (((TAG) - 1) ^ (TAG))
196 /* Return nonzero if SUB is an immediate subtag of TAG. */
197 #define GCOV_TAG_IS_SUBTAG(TAG,SUB) \
198 (GCOV_TAG_MASK (TAG) >> 8 == GCOV_TAG_MASK (SUB) \
199 && !(((SUB) ^ (TAG)) & ~GCOV_TAG_MASK(TAG)))
201 /* Return nonzero if SUB is at a sublevel to TAG. */
202 #define GCOV_TAG_IS_SUBLEVEL(TAG,SUB) \
203 (GCOV_TAG_MASK (TAG) > GCOV_TAG_MASK (SUB))
205 /* Basic block flags. */
206 #define GCOV_BLOCK_UNEXPECTED (1 << 1)
208 /* Arc flags. */
209 #define GCOV_ARC_ON_TREE (1 << 0)
210 #define GCOV_ARC_FAKE (1 << 1)
211 #define GCOV_ARC_FALLTHROUGH (1 << 2)
213 /* Structured records. */
215 /* Object & program summary record. */
216 struct gcov_summary
218 unsigned checksum; /* checksum of program */
219 unsigned runs; /* number of program runs */
220 unsigned arcs; /* number of instrumented arcs */
221 gcov_type arc_sum; /* sum of all arc counters */
222 gcov_type arc_max_one; /* max counter on any one run */
223 gcov_type arc_max_sum; /* maximum arc_sum */
224 gcov_type arc_sum_max; /* sum of max_one */
227 /* Structures embedded in coveraged program. The structures generated
228 by write_profile must match these. */
230 /* Information about section of counters for a function. */
231 struct counter_section
233 unsigned tag; /* Tag of the section. */
234 unsigned n_counters; /* Number of counters in the section. */
237 #if IN_LIBGCOV
238 /* Information about section of counters for an object file. */
239 struct counter_section_data
241 unsigned tag; /* Tag of the section. */
242 unsigned n_counters; /* Number of counters in the section. */
243 gcov_type *counters; /* The data. */
246 /* Information about a single function. */
247 struct function_info
249 const char *name; /* (mangled) name of function */
250 unsigned checksum; /* function checksum */
251 unsigned n_counter_sections; /* Number of types of counters */
252 const struct counter_section *counter_sections;
253 /* The section descriptions */
256 /* Information about a single object file. */
257 struct gcov_info
259 unsigned long version; /* expected version number */
260 struct gcov_info *next; /* link to next, used by libgcc */
262 const char *filename; /* output file name */
263 long wkspc; /* libgcc workspace */
265 unsigned n_functions; /* number of functions */
266 const struct function_info *functions; /* table of functions */
268 unsigned n_counter_sections; /* Number of types of counters */
269 const struct counter_section_data *counter_sections;
270 /* The data to be put into the sections. */
273 /* Register a new object file module. */
274 extern void __gcov_init (struct gcov_info *);
276 /* Called before fork, to avoid double counting. */
277 extern void __gcov_flush (void);
279 /* Since this file is used in both host and target files, and we don't
280 include ansidecl.h in target files, provide some necessary macros. */
281 #ifndef ATTRIBUTE_UNUSED
282 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
283 #endif
285 #endif /* IN_LIBGCOV */
287 /* Because small reads and writes, interspersed with seeks cause lots
288 of disk activity, we buffer the entire count files. */
290 static struct gcov_var
292 FILE *file;
293 size_t position;
294 size_t length;
295 size_t alloc;
296 unsigned modified;
297 int error;
298 unsigned char *buffer;
299 } gcov_var;
301 /* Functions for reading and writing gcov files. */
302 static int gcov_open (const char */*name*/, int /*truncate*/);
303 static int gcov_close (void);
304 #if !IN_GCOV
305 static unsigned char *gcov_write_bytes (unsigned);
306 static void gcov_write_unsigned (unsigned);
307 #if IN_LIBGCOV
308 static void gcov_write_counter (gcov_type);
309 #endif
310 static void gcov_write_string (const char *);
311 static unsigned long gcov_write_tag (unsigned);
312 static void gcov_write_length (unsigned long /*position*/);
313 #if IN_LIBGCOV
314 static void gcov_write_summary (unsigned, const struct gcov_summary *);
315 #endif
316 #endif /* !IN_GCOV */
317 static const unsigned char *gcov_read_bytes (unsigned);
318 static unsigned gcov_read_unsigned (void);
319 static gcov_type gcov_read_counter (void);
320 static const char *gcov_read_string (void);
321 static void gcov_read_summary (struct gcov_summary *);
323 static unsigned long gcov_position (void);
324 static void gcov_seek (unsigned long /*base*/, unsigned /*length */);
325 static unsigned long gcov_seek_end (void);
326 static int gcov_is_eof (void);
327 static int gcov_is_error (void);
328 #if IN_GCOV > 0
329 static time_t gcov_time (void);
330 #endif
332 /* Open a gcov file. NAME is the name of the file to open and MODE
333 indicates whether a new file should be created, or an existing file
334 opened for modification. If MODE is >= 0 an existing file will be
335 opened, if possible, and if MODE is <= 0, a new file will be
336 created. Use MODE=0 to attempt to reopen an existing file and then
337 fall back on creating a new one. Return zero on failure, >0 on
338 opening an existing file and <0 on creating a new one. */
340 static int
341 gcov_open (const char *name, int mode)
343 int result = 1;
344 size_t alloc = 1024;
345 #if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
346 struct flock s_flock;
348 s_flock.l_type = F_WRLCK;
349 s_flock.l_whence = SEEK_SET;
350 s_flock.l_start = 0;
351 s_flock.l_len = 0; /* Until EOF. */
352 s_flock.l_pid = getpid ();
353 #endif
355 if (gcov_var.file)
356 abort ();
357 gcov_var.position = gcov_var.length = 0;
358 gcov_var.error = gcov_var.modified = 0;
359 if (mode >= 0)
360 gcov_var.file = fopen (name, "r+b");
361 if (!gcov_var.file && mode <= 0)
363 result = -1;
364 gcov_var.file = fopen (name, "w+b");
366 if (!gcov_var.file)
367 return 0;
369 #if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
370 while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
371 && errno == EINTR)
372 continue;
373 #endif
375 if (result >= 0)
377 if (fseek (gcov_var.file, 0, SEEK_END))
379 fclose (gcov_var.file);
380 gcov_var.file = 0;
381 return 0;
383 gcov_var.length = ftell (gcov_var.file);
384 fseek (gcov_var.file, 0, SEEK_SET);
385 alloc += gcov_var.length;
387 if (alloc > gcov_var.alloc)
389 if (gcov_var.buffer)
390 free (gcov_var.buffer);
391 gcov_var.alloc = alloc;
392 #if IN_LIBGCOV
393 gcov_var.buffer = malloc (gcov_var.alloc);
394 if (!gcov_var.buffer)
396 fclose (gcov_var.file);
397 gcov_var.file = 0;
398 gcov_var.length = 0;
399 gcov_var.alloc = 0;
400 return 0;
402 #else
403 gcov_var.buffer = xmalloc (gcov_var.alloc);
404 #endif
406 if (result >= 0
407 && fread (gcov_var.buffer, gcov_var.length, 1, gcov_var.file) != 1)
409 fclose (gcov_var.file);
410 gcov_var.file = 0;
411 gcov_var.length = 0;
412 return 0;
414 return result;
417 /* Close the current gcov file. Flushes data to disk. Returns nonzero
418 on failure or error flag set. */
420 static int
421 gcov_close ()
423 int result = 0;
425 if (gcov_var.file)
427 if (gcov_var.modified
428 && (fseek (gcov_var.file, 0, SEEK_SET)
429 || fwrite (gcov_var.buffer, gcov_var.length,
430 1, gcov_var.file) != 1))
431 result = 1;
432 fclose (gcov_var.file);
433 gcov_var.file = 0;
434 gcov_var.length = 0;
436 #if !IN_LIBGCOV
437 free (gcov_var.buffer);
438 gcov_var.alloc = 0;
439 gcov_var.buffer = 0;
440 #endif
441 return result ? 1 : gcov_var.error;
444 #if !IN_GCOV
445 /* Allocate space to write BYTES bytes to the gcov file. Return a
446 pointer to those bytes, or NULL on failure. */
448 static unsigned char *
449 gcov_write_bytes (unsigned bytes)
451 char unsigned *result;
453 if (gcov_var.position + bytes > gcov_var.alloc)
455 size_t new_size = (gcov_var.alloc + bytes) * 3 / 2;
457 if (!gcov_var.buffer)
458 return 0;
459 #if IN_LIBGCOV
460 result = realloc (gcov_var.buffer, new_size);
461 if (!result)
463 free (gcov_var.buffer);
464 gcov_var.buffer = 0;
465 gcov_var.alloc = 0;
466 gcov_var.position = gcov_var.length = 0;
467 gcov_var.error = 1;
468 return 0;
470 #else
471 result = xrealloc (gcov_var.buffer, new_size);
472 #endif
473 gcov_var.alloc = new_size;
474 gcov_var.buffer = result;
477 result = &gcov_var.buffer[gcov_var.position];
478 gcov_var.position += bytes;
479 gcov_var.modified = 1;
480 if (gcov_var.position > gcov_var.length)
481 gcov_var.length = gcov_var.position;
482 return result;
485 /* Write unsigned VALUE to coverage file. Sets error flag
486 appropriately. */
488 static void
489 gcov_write_unsigned (unsigned value)
491 unsigned char *buffer = gcov_write_bytes (4);
492 unsigned ix;
494 if (!buffer)
495 return;
496 for (ix = 4; ix--; )
498 buffer[ix] = value;
499 value >>= 8;
501 if (sizeof (value) > 4 && value)
502 gcov_var.error = -1;
504 return;
507 /* Write counter VALUE to coverage file. Sets error flag
508 appropriately. */
510 #if IN_LIBGCOV
511 static void
512 gcov_write_counter (gcov_type value)
514 unsigned char *buffer = gcov_write_bytes (8);
515 unsigned ix;
517 if (!buffer)
518 return;
519 for (ix = 8; ix--; )
521 buffer[ix] = value;
522 value >>= 8;
524 if ((sizeof (value) > 8 && value) || value < 0)
525 gcov_var.error = -1;
526 return;
528 #endif /* IN_LIBGCOV */
530 /* Write STRING to coverage file. Sets error flag on file
531 error, overflow flag on overflow */
533 static void
534 gcov_write_string (const char *string)
536 unsigned length = 0;
537 unsigned pad = 0;
538 unsigned rem = 0;
539 unsigned char *buffer;
541 if (string)
543 length = strlen (string);
544 rem = 4 - (length & 3);
547 buffer = gcov_write_bytes (4 + length + rem);
548 if (buffer)
550 unsigned ix;
551 unsigned value = length;
553 for (ix = 4; ix--; )
555 buffer[ix] = value;
556 value >>= 8;
558 memcpy (buffer + 4, string, length);
559 memcpy (buffer + 4 + length, &pad, rem);
563 /* Write a tag TAG and reserve space for the record length. Return a
564 value to be used for gcov_write_length. */
566 static unsigned long
567 gcov_write_tag (unsigned tag)
569 unsigned long result = gcov_var.position;
570 unsigned char *buffer = gcov_write_bytes (8);
571 unsigned ix;
573 if (!buffer)
574 return 0;
575 for (ix = 4; ix--; )
577 buffer[ix] = tag;
578 tag >>= 8;
580 memset (buffer + 4, 0, 4);
581 return result;
584 /* Write a record length using POSITION, which was returned by
585 gcov_write_tag. The current file position is the end of the
586 record, and is restored before returning. Returns nonzero on
587 overflow. */
589 static void
590 gcov_write_length (unsigned long position)
592 if (position)
594 unsigned length = gcov_var.position - position - 8;
595 unsigned char *buffer = &gcov_var.buffer[position + 4];
596 unsigned ix;
598 for (ix = 4; ix--; )
600 buffer[ix] = length;
601 length >>= 8;
606 #if IN_LIBGCOV
607 /* Write a summary structure to the gcov file. Return non-zero on
608 overflow. */
610 static void
611 gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
613 unsigned long base;
615 base = gcov_write_tag (tag);
616 gcov_write_unsigned (summary->checksum);
617 gcov_write_unsigned (summary->runs);
618 gcov_write_unsigned (summary->arcs);
619 gcov_write_counter (summary->arc_sum);
620 gcov_write_counter (summary->arc_max_one);
621 gcov_write_counter (summary->arc_max_sum);
622 gcov_write_counter (summary->arc_sum_max);
623 gcov_write_length (base);
625 #endif /* IN_LIBGCOV */
627 #endif /*!IN_GCOV */
629 /* Return a pointer to read BYTES bytes from the gcov file. Returns
630 NULL on failure (read past EOF). */
632 static const unsigned char *
633 gcov_read_bytes (unsigned bytes)
635 const unsigned char *result;
637 if (gcov_var.position + bytes > gcov_var.length)
639 gcov_var.error = 1;
640 return 0;
643 result = &gcov_var.buffer[gcov_var.position];
644 gcov_var.position += bytes;
645 return result;
648 /* Read unsigned value from a coverage file. Sets error flag on file
649 error, overflow flag on overflow */
651 static unsigned
652 gcov_read_unsigned ()
654 unsigned value = 0;
655 unsigned ix;
656 const unsigned char *buffer = gcov_read_bytes (4);
658 if (!buffer)
659 return 0;
660 for (ix = sizeof (value); ix < 4; ix++)
661 if (buffer[ix])
662 gcov_var.error = -1;
663 for (ix = 0; ix != 4; ix++)
665 value <<= 8;
666 value |= buffer[ix];
668 return value;
671 /* Read counter value from a coverage file. Sets error flag on file
672 error, overflow flag on overflow */
674 static gcov_type
675 gcov_read_counter ()
677 gcov_type value = 0;
678 unsigned ix;
679 const unsigned char *buffer = gcov_read_bytes (8);
681 if (!buffer)
682 return 0;
683 for (ix = sizeof (value); ix < 8; ix++)
684 if (buffer[ix])
685 gcov_var.error = -1;
686 for (ix = 0; ix != 8; ix++)
688 value <<= 8;
689 value |= buffer[ix];
691 if (value < 0)
692 gcov_var.error = -1;
693 return value;
696 /* Read string from coverage file. Returns a pointer to a static
697 buffer, or NULL on empty string. You must copy the string before
698 calling another gcov function. */
700 static const char *
701 gcov_read_string ()
703 unsigned length = gcov_read_unsigned ();
705 if (!length)
706 return 0;
708 length += 4 - (length & 3);
709 return (const char *) gcov_read_bytes (length);
712 #define GCOV_SUMMARY_LENGTH 44
713 static void
714 gcov_read_summary (struct gcov_summary *summary)
716 summary->checksum = gcov_read_unsigned ();
717 summary->runs = gcov_read_unsigned ();
718 summary->arcs = gcov_read_unsigned ();
719 summary->arc_sum = gcov_read_counter ();
720 summary->arc_max_one = gcov_read_counter ();
721 summary->arc_max_sum = gcov_read_counter ();
722 summary->arc_sum_max = gcov_read_counter ();
725 /* Save the current position in the gcov file. */
727 static inline unsigned long
728 gcov_position (void)
730 return gcov_var.position;
733 /* Reset to a known position. BASE should have been obtained from
734 gcov_save_position, LENGTH should be a record length, or zero. */
736 static inline void
737 gcov_seek (unsigned long base, unsigned length)
739 if (gcov_var.buffer)
741 base += length;
742 if (gcov_var.length < base)
744 gcov_var.error = 1;
745 base = gcov_var.length;
747 gcov_var.position = base;
751 /* Move to the end of the gcov file. */
753 static inline unsigned long
754 gcov_seek_end ()
756 gcov_var.position = gcov_var.length;
757 return gcov_var.position;
760 /* Tests whether we have reached end of .da file. */
762 static inline int
763 gcov_is_eof ()
765 return gcov_var.position == gcov_var.length;
768 /* Return non-zero if the error flag is set. */
770 static inline int
771 gcov_is_error ()
773 return gcov_var.file ? gcov_var.error : 1;
776 #if IN_GCOV > 0
777 /* Return the modification time of the current gcov file. */
779 static time_t
780 gcov_time ()
782 struct stat status;
784 if (fstat (fileno (gcov_var.file), &status))
785 return 0;
786 else
787 return status.st_mtime;
789 #endif /* IN_GCOV */
790 #endif /* GCC_GCOV_IO_H */