1 /* word_io.c -- word oriented I/O
2 Copyright (C) 2007, 2010 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <stdbool.h> /* for bool */
33 # define _(Text) gettext (Text)
36 #define textdomain(Domain)
37 #define bindtextdomain(Package, Directory)
40 # define N_(String) gettext_noop (String)
42 /* We used to use (String) instead of just String, but apparently ISO C
43 * doesn't allow this (at least, that's what HP said when someone reported
44 * this as a compiler bug). This is HP case number 1205608192. See
45 * also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11250 (which references
46 * ANSI 3.5.7p14-15). The Intel icc compiler also rejects constructs
47 * like: static const char buf[] = ("string");
49 # define N_(String) String
53 /* Swap bytes in 32 bit value. This code is taken from glibc-2.3.3. */
55 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
56 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
61 decode_value (const unsigned char data
[],
63 GetwordEndianState
*endian_state_flag
,
69 int ival
; /* native representation */
70 unsigned char data
[WORDBYTES
];
73 memcpy (&u
.data
, data
, WORDBYTES
);
74 swapped
= bswap_32(u
.ival
); /* byteswapped */
76 if (*endian_state_flag
== GetwordEndianStateInitial
)
82 /* the native value is inside the limit and the
83 * swapped value is not. We take this as proof
84 * that we should be using the ative byte order.
86 *endian_state_flag
= GetwordEndianStateNative
;
94 /* Aha, now we know we have to byte-swap. */
96 _("WARNING: locate database %s was "
97 "built with a different byte order"),
98 quotearg_n_style (0, locale_quoting_style
, filename
));
99 *endian_state_flag
= GetwordEndianStateSwab
;
104 /* u.ival > limit and swapped > limit. For the moment, assume
113 /* We already know the byte order. */
114 if (*endian_state_flag
== GetwordEndianStateSwab
)
125 const char *filename
,
128 GetwordEndianState
*endian_state_flag
)
130 unsigned char data
[4];
134 bytes_read
= fread (data
, WORDBYTES
, 1, fp
);
137 const char * quoted_name
= quotearg_n_style (0, locale_quoting_style
,
139 /* Distinguish between a truncated database and an I/O error.
140 * Either condition is fatal.
143 error (EXIT_FAILURE
, 0, _("unexpected EOF in %s"), quoted_name
);
145 error (EXIT_FAILURE
, errno
,
146 _("error reading a word from %s"), quoted_name
);
151 return decode_value (data
, maxvalue
, endian_state_flag
, filename
);
157 putword (FILE *fp
, int word
,
158 GetwordEndianState endian_state_flag
)
160 size_t items_written
;
162 /* You must decide before calling this function which
163 * endianness you want to use.
165 assert (endian_state_flag
!= GetwordEndianStateInitial
);
166 if (GetwordEndianStateSwab
== endian_state_flag
)
168 word
= bswap_32(word
);
171 items_written
= fwrite (&word
, sizeof (word
), 1, fp
);
172 if (1 == items_written
)