gcov-io.h revision 90075
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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-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
27static int __fetch_long	PARAMS ((long *, char *, size_t)) ATTRIBUTE_UNUSED;
28static int __read_long  PARAMS ((long *, FILE *, size_t)) ATTRIBUTE_UNUSED;
29static int __write_long PARAMS ((long, FILE *, size_t)) ATTRIBUTE_UNUSED;
30static int __fetch_gcov_type PARAMS ((gcov_type *, char *, size_t)) ATTRIBUTE_UNUSED;
31static int __store_gcov_type PARAMS ((gcov_type, char *, size_t)) ATTRIBUTE_UNUSED;
32static int __read_gcov_type  PARAMS ((gcov_type *, FILE *, size_t)) ATTRIBUTE_UNUSED;
33static int __write_gcov_type PARAMS ((gcov_type, FILE *, size_t)) ATTRIBUTE_UNUSED;
34
35/* These routines only work for signed values.  */
36
37/* Store a portable representation of VALUE in DEST using BYTES*8-1 bits.
38   Return a non-zero value if VALUE requires more than BYTES*8-1 bits
39   to store.  */
40
41static int
42__store_gcov_type (value, dest, bytes)
43     gcov_type value;
44     char *dest;
45     size_t bytes;
46{
47  int upper_bit = (value < 0 ? 128 : 0);
48  size_t i;
49
50  if (value < 0)
51    {
52      gcov_type oldvalue = value;
53      value = -value;
54      if (oldvalue != -value)
55	return 1;
56    }
57
58  for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
59    dest[i] = value & (i == (bytes - 1) ? 127 : 255);
60    value = value / 256;
61  }
62
63  if (value && value != -1)
64    return 1;
65
66  for(; i < bytes ; i++)
67    dest[i] = 0;
68  dest[bytes - 1] |= upper_bit;
69  return 0;
70}
71
72/* Retrieve a quantity containing BYTES*8-1 bits from SOURCE and store
73   the result in DEST. Returns a non-zero value if the value in SOURCE
74   will not fit in DEST.  */
75
76static int
77__fetch_gcov_type (dest, source, bytes)
78     gcov_type *dest;
79     char *source;
80     size_t bytes;
81{
82  gcov_type value = 0;
83  int i;
84
85  for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
86    if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
87      return 1;
88
89  for (; i >= 0; i--)
90    value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
91
92  if ((source[bytes - 1] & 128) && (value > 0))
93    value = - value;
94
95  *dest = value;
96  return 0;
97}
98
99static int
100__fetch_long (dest, source, bytes)
101     long *dest;
102     char *source;
103     size_t bytes;
104{
105  long value = 0;
106  int i;
107
108  for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
109    if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
110      return 1;
111
112  for (; i >= 0; i--)
113    value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
114
115  if ((source[bytes - 1] & 128) && (value > 0))
116    value = - value;
117
118  *dest = value;
119  return 0;
120}
121
122/* Write a BYTES*8-bit quantity to FILE, portably. Returns a non-zero
123   value if the write fails, or if VALUE can't be stored in BYTES*8
124   bits.
125
126   Note that VALUE may not actually be large enough to hold BYTES*8
127   bits, but BYTES characters will be written anyway.
128
129   BYTES may be a maximum of 10.  */
130
131static int
132__write_gcov_type (value, file, bytes)
133     gcov_type value;
134     FILE *file;
135     size_t bytes;
136{
137  char c[10];
138
139  if (bytes > 10 || __store_gcov_type (value, c, bytes))
140    return 1;
141  else
142    return fwrite(c, 1, bytes, file) != bytes;
143}
144
145static int
146__write_long (value, file, bytes)
147     long value;
148     FILE *file;
149     size_t bytes;
150{
151  char c[10];
152
153  if (bytes > 10 || __store_gcov_type ((gcov_type)value, c, bytes))
154    return 1;
155  else
156    return fwrite(c, 1, bytes, file) != bytes;
157}
158
159/* Read a quantity containing BYTES bytes from FILE, portably. Return
160   a non-zero value if the read fails or if the value will not fit
161   in DEST.
162
163   Note that DEST may not be large enough to hold all of the requested
164   data, but the function will read BYTES characters anyway.
165
166   BYTES may be a maximum of 10.  */
167
168static int
169__read_gcov_type (dest, file, bytes)
170     gcov_type *dest;
171     FILE *file;
172     size_t bytes;
173{
174  char c[10];
175
176  if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
177    return 1;
178  else
179    return __fetch_gcov_type (dest, c, bytes);
180}
181
182static int
183__read_long (dest, file, bytes)
184     long *dest;
185     FILE *file;
186     size_t bytes;
187{
188  char c[10];
189
190  if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
191    return 1;
192  else
193    return __fetch_long (dest, c, bytes);
194}
195
196#endif /* ! GCC_GCOV_IO_H */
197