cvsimport
[findutils.git] / locate / word_io.c
blobabcc23449264bc0784e70b9df1727f088d84f397
1 /* word_io.c -- word oriented I/O
2 Copyright (C) 2007 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/>.
18 #include <config.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <errno.h>
23 #include <stdbool.h> /* for bool */
24 #include <assert.h>
25 #include <stdlib.h>
27 #include "error.h"
28 #include "quote.h"
29 #include "quotearg.h"
30 #include "locatedb.h"
32 #if ENABLE_NLS
33 # include <libintl.h>
34 # define _(Text) gettext (Text)
35 #else
36 # define _(Text) Text
37 #define textdomain(Domain)
38 #define bindtextdomain(Package, Directory)
39 #endif
40 #ifdef gettext_noop
41 # define N_(String) gettext_noop (String)
42 #else
43 /* We used to use (String) instead of just String, but apparently ISO C
44 * doesn't allow this (at least, that's what HP said when someone reported
45 * this as a compiler bug). This is HP case number 1205608192. See
46 * also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11250 (which references
47 * ANSI 3.5.7p14-15). The Intel icc compiler also rejects constructs
48 * like: static const char buf[] = ("string");
50 # define N_(String) String
51 #endif
54 /* Swap bytes in 32 bit value. This code is taken from glibc-2.3.3. */
55 #define bswap_32(x) \
56 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
57 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
59 enum { WORDBYTES=4 };
61 static int
62 decode_value(const unsigned char data[],
63 int limit,
64 GetwordEndianState *endian_state_flag,
65 const char *filename)
67 int swapped;
68 union
70 int ival; /* native representation */
71 unsigned char data[WORDBYTES];
72 } u;
73 u.ival = 0;
74 memcpy(&u.data, data, WORDBYTES);
75 swapped = bswap_32(u.ival); /* byteswapped */
77 if (*endian_state_flag == GetwordEndianStateInitial)
79 if (u.ival <= limit)
81 if (swapped > limit)
83 /* the native value is inside the limit and the
84 * swapped value is not. We take this as proof
85 * that we should be using the ative byte order.
87 *endian_state_flag = GetwordEndianStateNative;
89 return u.ival;
91 else
93 if (swapped <= limit)
95 /* Aha, now we know we have to byte-swap. */
96 error(0, 0,
97 _("Warning: locate database %s was "
98 "built with a different byte order"),
99 quotearg_n_style(0, locale_quoting_style, filename));
100 *endian_state_flag = GetwordEndianStateSwab;
101 return swapped;
103 else
105 /* u.ival > limit and swapped > limit. For the moment, assume
106 * native ordering.
108 return u.ival;
112 else
114 /* We already know the byte order. */
115 if (*endian_state_flag == GetwordEndianStateSwab)
116 return swapped;
117 else
118 return u.ival;
125 getword (FILE *fp,
126 const char *filename,
127 size_t minvalue,
128 size_t maxvalue,
129 GetwordEndianState *endian_state_flag)
131 unsigned char data[4];
132 size_t bytes_read;
134 clearerr(fp);
135 bytes_read = fread(data, WORDBYTES, 1, fp);
136 if (bytes_read != 1)
138 const char * quoted_name = quotearg_n_style(0, locale_quoting_style,
139 filename);
140 /* Distinguish between a truncated database and an I/O error.
141 * Either condition is fatal.
143 if (feof(fp))
144 error(1, 0, _("unexpected EOF in %s"), quoted_name);
145 else
146 error(1, errno, _("error reading a word from %s"), quoted_name);
147 abort ();
149 else
151 return decode_value(data, maxvalue, endian_state_flag, filename);
156 bool
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)
173 return true;
174 else
175 return false;