gcov-io.h revision 52284
1/* Machine-independent I/O routines for gcov.
2   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
3   Contributed by Bob Manson <manson@cygnus.com>.
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING.  If not, write to
19the Free Software Foundation, 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA.  */
21
22#ifndef GCOV_IO_H
23#define GCOV_IO_H
24#include <stdio.h>
25#include <sys/types.h>
26
27static int __fetch_long		PROTO ((long *, char *, size_t));
28static int __store_long		PROTO ((long, char *, size_t));
29static int __read_long		PROTO ((long *, FILE *, size_t));
30static int __write_long		PROTO ((long, FILE *, size_t));
31
32/* These routines only work for signed values. */
33
34/* Store a portable representation of VALUE in DEST using BYTES*8-1 bits.
35   Return a non-zero value if VALUE requires more than BYTES*8-1 bits
36   to store. */
37
38static int
39__store_long (value, dest, bytes)
40     long value;
41     char *dest;
42     size_t bytes;
43{
44  int upper_bit = (value < 0 ? 128 : 0);
45  size_t i;
46
47  if (value < 0)
48    {
49      long oldvalue = value;
50      value = -value;
51      if (oldvalue != -value)
52	return 1;
53    }
54
55  for(i = 0 ; i < (sizeof (value) < bytes ? sizeof (value) : bytes) ; i++) {
56    dest[i] = value & (i == (bytes - 1) ? 127 : 255);
57    value = value / 256;
58  }
59
60  if (value && value != -1)
61    return 1;
62
63  for(; i < bytes ; i++)
64    dest[i] = 0;
65  dest[bytes - 1] |= upper_bit;
66  return 0;
67}
68
69/* Retrieve a quantity containing BYTES*8-1 bits from SOURCE and store
70   the result in DEST. Returns a non-zero value if the value in SOURCE
71   will not fit in DEST. */
72
73static int
74__fetch_long (dest, source, bytes)
75     long *dest;
76     char *source;
77     size_t bytes;
78{
79  long value = 0;
80  int i;
81
82  for (i = bytes - 1; (size_t) i > (sizeof (*dest) - 1); i--)
83    if (source[i] & ((size_t) i == (bytes - 1) ? 127 : 255 ))
84      return 1;
85
86  for (; i >= 0; i--)
87    value = value * 256 + (source[i] & ((size_t)i == (bytes - 1) ? 127 : 255));
88
89  if ((source[bytes - 1] & 128) && (value > 0))
90    value = - value;
91
92  *dest = value;
93  return 0;
94}
95
96/* Write a BYTES*8-bit quantity to FILE, portably. Returns a non-zero
97   value if the write fails, or if VALUE can't be stored in BYTES*8
98   bits.
99
100   Note that VALUE may not actually be large enough to hold BYTES*8
101   bits, but BYTES characters will be written anyway.
102
103   BYTES may be a maximum of 10. */
104
105static int
106__write_long (value, file, bytes)
107     long value;
108     FILE *file;
109     size_t bytes;
110{
111  char c[10];
112
113  if (bytes > 10 || __store_long (value, c, bytes))
114    return 1;
115  else
116    return fwrite(c, 1, bytes, file) != bytes;
117}
118
119/* Read a quantity containing BYTES bytes from FILE, portably. Return
120   a non-zero value if the read fails or if the value will not fit
121   in DEST.
122
123   Note that DEST may not be large enough to hold all of the requested
124   data, but the function will read BYTES characters anyway.
125
126   BYTES may be a maximum of 10. */
127
128static int
129__read_long (dest, file, bytes)
130     long *dest;
131     FILE *file;
132     size_t bytes;
133{
134  char c[10];
135
136  if (bytes > 10 || fread(c, 1, bytes, file) != bytes)
137    return 1;
138  else
139    return __fetch_long (dest, c, bytes);
140}
141
142#endif
143