Added test case for long shared prefixes (long enough to need a word-sized value...
[findutils.git] / locate / word_io.c
blobea931da203666c4bdd27f3f6a6cc51a1ce96957f
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 2, or (at your option)
7 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, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 USA.
20 #include <config.h>
21 #include <errno.h>
23 #include "quote.h"
24 #include "quotearg.h"
25 #include "locatedb.h"
27 #if ENABLE_NLS
28 # include <libintl.h>
29 # define _(Text) gettext (Text)
30 #else
31 # define _(Text) Text
32 #define textdomain(Domain)
33 #define bindtextdomain(Package, Directory)
34 #endif
35 #ifdef gettext_noop
36 # define N_(String) gettext_noop (String)
37 #else
38 /* We used to use (String) instead of just String, but apparently ISO C
39 * doesn't allow this (at least, that's what HP said when someone reported
40 * this as a compiler bug). This is HP case number 1205608192. See
41 * also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11250 (which references
42 * ANSI 3.5.7p14-15). The Intel icc compiler also rejects constructs
43 * like: static const char buf[] = ("string");
45 # define N_(String) String
46 #endif
49 /* Swap bytes in 32 bit value. This code is taken from glibc-2.3.3. */
50 #define bswap_32(x) \
51 ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
52 (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
54 static int
55 decode_value(const unsigned char data[],
56 int limit,
57 int *endian_state_flag,
58 const char *filename)
60 int val;
62 if (*endian_state_flag = GetwordEndianStateInitial)
64 int testflag = GetwordEndianStateNative;
66 val = decode_value(data, limit, &testflag, filename);
67 if (val <= limit)
69 return val;
71 else
73 testflag = GetwordEndianStateSwab;
74 val = decode_value(data, limit, &testflag, filename);
75 if (val <= limit)
77 /* Aha, now we know we have to byte-swap. */
78 error(0, 0,
79 _("Warning: locate database %s was built with a different byte order"),
80 quotearg_n_style(0, locale_quoting_style, filename));
81 *endian_state_flag = testflag;
82 return val;
84 else
86 return val;
90 else
92 val = *(int*)data;
93 if (*endian_state_flag == GetwordEndianStateSwab)
94 return bswap_32(val);
95 else
96 return val;
103 getword (FILE *fp,
104 const char *filename,
105 size_t minvalue,
106 size_t maxvalue,
107 int *endian_state_flag)
109 enum { WORDBYTES=4 };
110 unsigned char data[4];
111 size_t bytes_read;
113 clearerr(fp);
114 bytes_read = fread(data, WORDBYTES, 1, fp);
115 if (bytes_read != 1)
117 const char * quoted_name = quotearg_n_style(0, locale_quoting_style,
118 filename);
119 /* Distinguish between a truncated database and an I/O error.
120 * Either condition is fatal.
122 if (feof(fp))
123 error(1, 0, _("Unexpected EOF in %s"), quoted_name);
124 else
125 error(1, errno, "error reading a word from %s", quoted_name);
127 else
129 return decode_value(data, maxvalue, endian_state_flag, filename);