Index: ChangeLog
[gcc.git] / gcc / gcov-io.h
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>.
4
5 This file is part of GCC.
6
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
10 version.
11
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
15 for more details.
16
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
20 02111-1307, USA. */
21
22 #ifndef GCC_GCOV_IO_H
23 #define GCC_GCOV_IO_H
24 #include <stdio.h>
25 #include <sys/types.h>
26
27 static int __fetch_long PARAMS ((long *, char *, size_t))
28 ATTRIBUTE_UNUSED;
29 static int __read_long PARAMS ((long *, FILE *, size_t))
30 ATTRIBUTE_UNUSED;
31 static int __write_long PARAMS ((long, FILE *, size_t))
32 ATTRIBUTE_UNUSED;
33 static int __fetch_gcov_type PARAMS ((gcov_type *, char *, size_t))
34 ATTRIBUTE_UNUSED;
35 static int __store_gcov_type PARAMS ((gcov_type, char *, size_t))
36 ATTRIBUTE_UNUSED;
37 static int __read_gcov_type PARAMS ((gcov_type *, FILE *, size_t))
38 ATTRIBUTE_UNUSED;
39 static int __write_gcov_type PARAMS ((gcov_type, FILE *, size_t))
40 ATTRIBUTE_UNUSED;
41 static int __write_gcov_string PARAMS ((const char *, size_t, FILE*, long))
42 ATTRIBUTE_UNUSED;
43 static int __read_gcov_string PARAMS ((char *, size_t, FILE*, long))
44 ATTRIBUTE_UNUSED;
45
46 /* These routines only work for signed values. */
47
48 /* Store a portable representation of VALUE in DEST using BYTES*8-1 bits.
49 Return a nonzero value if VALUE requires more than BYTES*8-1 bits
50 to store. */
51
52 static int
53 __store_gcov_type (value, dest, bytes)
54 gcov_type value;
55 char *dest;
56 size_t bytes;
57 {
58 int upper_bit = (value < 0 ? 128 : 0);
59 size_t i;
60
61 if (value < 0)
62 {
63 gcov_type oldvalue = value;
64 value = -value;
65 if (oldvalue != -value)
66 return 1;
67 }
68
69 for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
70 dest[i] = value & (i == (bytes - 1) ? 127 : 255);
71 value = value / 256;
72 }
73
74 if (value && value != -1)
75 return 1;
76
77 for(; i < bytes ; i++)
78 dest[i] = 0;
79 dest[bytes - 1] |= upper_bit;
80 return 0;
81 }
82
83 /* Retrieve a quantity containing BYTES*8-1 bits from SOURCE and store
84 the result in DEST. Returns a nonzero value if the value in SOURCE
85 will not fit in DEST. */
86
87 static int
88 __fetch_gcov_type (dest, source, bytes)
89 gcov_type *dest;
90 char *source;
91 size_t bytes;
92 {
93 gcov_type value = 0;
94 int i;
95
96 for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
97 if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
98 return 1;
99
100 for (; i >= 0; i--)
101 value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
102
103 if ((source[bytes - 1] & 128) && (value > 0))
104 value = - value;
105
106 *dest = value;
107 return 0;
108 }
109
110 static int
111 __fetch_long (dest, source, bytes)
112 long *dest;
113 char *source;
114 size_t bytes;
115 {
116 long value = 0;
117 int i;
118
119 for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
120 if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
121 return 1;
122
123 for (; i >= 0; i--)
124 value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
125
126 if ((source[bytes - 1] & 128) && (value > 0))
127 value = - value;
128
129 *dest = value;
130 return 0;
131 }
132
133 /* Write a BYTES*8-bit quantity to FILE, portably. Returns a nonzero
134 value if the write fails, or if VALUE can't be stored in BYTES*8
135 bits.
136
137 Note that VALUE may not actually be large enough to hold BYTES*8
138 bits, but BYTES characters will be written anyway.
139
140 BYTES may be a maximum of 10. */
141
142 static int
143 __write_gcov_type (value, file, bytes)
144 gcov_type value;
145 FILE *file;
146 size_t bytes;
147 {
148 char c[10];
149
150 if (bytes > 10 || __store_gcov_type (value, c, bytes))
151 return 1;
152 else
153 return fwrite(c, 1, bytes, file) != bytes;
154 }
155
156 static int
157 __write_long (value, file, bytes)
158 long value;
159 FILE *file;
160 size_t bytes;
161 {
162 char c[10];
163
164 if (bytes > 10 || __store_gcov_type ((gcov_type)value, c, bytes))
165 return 1;
166 else
167 return fwrite(c, 1, bytes, file) != bytes;
168 }
169
170 /* Read a quantity containing BYTES bytes from FILE, portably. Return
171 a nonzero value if the read fails or if the value will not fit
172 in DEST.
173
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.
176
177 BYTES may be a maximum of 10. */
178
179 static int
180 __read_gcov_type (dest, file, bytes)
181 gcov_type *dest;
182 FILE *file;
183 size_t bytes;
184 {
185 char c[10];
186
187 if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
188 return 1;
189 else
190 return __fetch_gcov_type (dest, c, bytes);
191 }
192
193 static int
194 __read_long (dest, file, bytes)
195 long *dest;
196 FILE *file;
197 size_t bytes;
198 {
199 char c[10];
200
201 if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
202 return 1;
203 else
204 return __fetch_long (dest, c, bytes);
205 }
206
207
208 /* Writes string in gcov format. */
209
210 static int
211 __write_gcov_string (string, length, file, delim)
212 const char *string;
213 size_t length;
214 FILE *file;
215 long delim;
216 {
217 size_t temp = length + 1;
218
219 /* delimiter */
220 if (__write_long (delim, file, 4) != 0)
221 return 1;
222
223 if (__write_long (length, file, 4) != 0)
224 return 1;
225
226 if (fwrite (string, temp, 1, file) != 1)
227 return 1;
228
229 temp &= 3;
230
231 if (temp)
232 {
233 char c[4];
234
235 c[0] = c[1] = c[2] = c[3] = 0;
236
237 if (fwrite (c, sizeof (char), 4 - temp, file) != 4 - temp)
238 return 1;
239 }
240
241 if (__write_long (delim, file, 4) != 0)
242 return 1;
243
244 return 0;
245 }
246
247 /* Reads string in gcov format. */
248
249
250 static int
251 __read_gcov_string (string, max_length, file, delim)
252 char *string;
253 size_t max_length;
254 FILE *file;
255 long delim;
256 {
257 long delim_from_file;
258 long length;
259 long read_length;
260 long tmp;
261
262 if (__read_long (&delim_from_file, file, 4) != 0)
263 return 1;
264
265 if (delim_from_file != delim)
266 return 1;
267
268 if (__read_long (&length, file, 4) != 0)
269 return 1;
270
271 if (length > (long) max_length)
272 read_length = max_length;
273 else
274 read_length = length;
275
276 tmp = (((length + 1) - 1) / 4 + 1) * 4;
277 /* This is the size occupied by the string in the file */
278
279 if (fread (string, read_length, 1, file) != 1)
280 return 1;
281
282 string[read_length] = 0;
283
284 if (fseek (file, tmp - read_length, SEEK_CUR) < 0)
285 return 1;
286
287 if (__read_long (&delim_from_file, file, 4) != 0)
288 return 1;
289
290 if (delim_from_file != delim)
291 return 1;
292
293 return 0;
294 }
295
296
297 #endif /* ! GCC_GCOV_IO_H */