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