1 /* Machine-independent I/O routines for gcov.
2 Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
3 Contributed by Bob Manson <manson@cygnus.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 #include <sys/types.h>
27 static int __fetch_long
PARAMS ((long *, char *, size_t))
29 static int __read_long
PARAMS ((long *, FILE *, size_t))
31 static int __write_long
PARAMS ((long, FILE *, size_t))
33 static int __fetch_gcov_type
PARAMS ((gcov_type
*, char *, size_t))
35 static int __store_gcov_type
PARAMS ((gcov_type
, char *, size_t))
37 static int __read_gcov_type
PARAMS ((gcov_type
*, FILE *, size_t))
39 static int __write_gcov_type
PARAMS ((gcov_type
, FILE *, size_t))
41 static int __write_gcov_string
PARAMS ((const char *, size_t, FILE*, long))
43 static int __read_gcov_string
PARAMS ((char *, size_t, FILE*, long))
46 /* These routines only work for signed values. */
48 /* Store a portable representation of VALUE in DEST using BYTES*8-1 bits.
49 Return a non-zero value if VALUE requires more than BYTES*8-1 bits
53 __store_gcov_type (value
, dest
, bytes
)
58 int upper_bit
= (value
< 0 ? 128 : 0);
63 gcov_type oldvalue
= value
;
65 if (oldvalue
!= -value
)
69 for(i
= 0 ; i
< (sizeof (value
) < bytes
? sizeof (value
) : bytes
) ; i
++) {
70 dest
[i
] = value
& (i
== (bytes
- 1) ? 127 : 255);
74 if (value
&& value
!= -1)
77 for(; i
< bytes
; i
++)
79 dest
[bytes
- 1] |= upper_bit
;
83 /* Retrieve a quantity containing BYTES*8-1 bits from SOURCE and store
84 the result in DEST. Returns a non-zero value if the value in SOURCE
85 will not fit in DEST. */
88 __fetch_gcov_type (dest
, source
, bytes
)
96 for (i
= bytes
- 1; (size_t) i
> (sizeof (*dest
) - 1); i
--)
97 if (source
[i
] & ((size_t) i
== (bytes
- 1) ? 127 : 255 ))
101 value
= value
* 256 + (source
[i
] & ((size_t)i
== (bytes
- 1) ? 127 : 255));
103 if ((source
[bytes
- 1] & 128) && (value
> 0))
111 __fetch_long (dest
, source
, bytes
)
119 for (i
= bytes
- 1; (size_t) i
> (sizeof (*dest
) - 1); i
--)
120 if (source
[i
] & ((size_t) i
== (bytes
- 1) ? 127 : 255 ))
124 value
= value
* 256 + (source
[i
] & ((size_t)i
== (bytes
- 1) ? 127 : 255));
126 if ((source
[bytes
- 1] & 128) && (value
> 0))
133 /* Write a BYTES*8-bit quantity to FILE, portably. Returns a non-zero
134 value if the write fails, or if VALUE can't be stored in BYTES*8
137 Note that VALUE may not actually be large enough to hold BYTES*8
138 bits, but BYTES characters will be written anyway.
140 BYTES may be a maximum of 10. */
143 __write_gcov_type (value
, file
, bytes
)
150 if (bytes
> 10 || __store_gcov_type (value
, c
, bytes
))
153 return fwrite(c
, 1, bytes
, file
) != bytes
;
157 __write_long (value
, file
, bytes
)
164 if (bytes
> 10 || __store_gcov_type ((gcov_type
)value
, c
, bytes
))
167 return fwrite(c
, 1, bytes
, file
) != bytes
;
170 /* Read a quantity containing BYTES bytes from FILE, portably. Return
171 a non-zero value if the read fails or if the value will not fit
174 Note that DEST may not be large enough to hold all of the requested
175 data, but the function will read BYTES characters anyway.
177 BYTES may be a maximum of 10. */
180 __read_gcov_type (dest
, file
, bytes
)
187 if (bytes
> 10 || fread(c
, 1, bytes
, file
) != bytes
)
190 return __fetch_gcov_type (dest
, c
, bytes
);
194 __read_long (dest
, file
, bytes
)
201 if (bytes
> 10 || fread(c
, 1, bytes
, file
) != bytes
)
204 return __fetch_long (dest
, c
, bytes
);
208 /* Writes string in gcov format. */
211 __write_gcov_string (string
, length
, file
, delim
)
217 size_t temp
= length
+ 1;
220 if (__write_long (delim
, file
, 4) != 0)
223 if (__write_long (length
, file
, 4) != 0)
226 if (fwrite (string
, temp
, 1, file
) != 1)
235 c
[0] = c
[1] = c
[2] = c
[3] = 0;
237 if (fwrite (c
, sizeof (char), 4 - temp
, file
) != 4 - temp
)
241 if (__write_long (delim
, file
, 4) != 0)
247 /* Reads string in gcov format. */
251 __read_gcov_string (string
, max_length
, file
, delim
)
257 long delim_from_file
;
262 if (__read_long (&delim_from_file
, file
, 4) != 0)
265 if (delim_from_file
!= delim
)
268 if (__read_long (&length
, file
, 4) != 0)
271 if (length
> (long) max_length
)
272 read_length
= max_length
;
274 read_length
= length
;
276 tmp
= (((length
+ 1) - 1) / 4 + 1) * 4;
277 /* This is the size occupied by the string in the file */
279 if (fread (string
, read_length
, 1, file
) != 1)
282 string
[read_length
] = 0;
284 if (fseek (file
, tmp
- read_length
, SEEK_CUR
) < 0)
287 if (__read_long (&delim_from_file
, file
, 4) != 0)
290 if (delim_from_file
!= delim
)
297 #endif /* ! GCC_GCOV_IO_H */