* SUCH DAMAGE.
*/
+#ifndef RUNEOFF32
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)rune.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.10 2002/08/09 08:22:29 ache Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/locale/rune.c,v 1.12 2004/07/29 06:16:19 tjr Exp $");
+
+#include "xlocale_private.h"
#include "namespace.h"
#include <arpa/inet.h>
#include <errno.h>
-#include <rune.h>
+#include <runetype.h>
+#else
+#include "runetype.h"
+#endif /* !RUNEOFF32 */
#include <stdio.h>
+#ifndef RUNEOFF32
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "un-namespace.h"
+#endif /* !RUNEOFF32 */
+
+#if defined(__LP64__) || defined(RUNEOFF32)
+/*
+ * Because the LC_CTYPE files were created with a 32-bit program, we need
+ * to adjust for the larger pointers in LP64 (the longs have already been
+ * replaced by 32-bit equivalents). Also, natural alignment will pad
+ * 64-bit types to 8-byte boundaries, and make structures containing
+ * 64-bit types sized to 8-byte boundaries.
+ */
+#include <stddef.h>
+#ifndef RUNEOFF32
+#include "rune32.h"
+#define BYTES32BITS 4
+#define BYTES64BITS 8
+/* whether to skip over a pointer or not (one-to-one with off64) */
+int skip[] = {
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0
+};
+#endif /* !RUNEOFF32 */
+int off64[] = {
+ offsetof(_RuneLocale, __sgetrune),
+ offsetof(_RuneLocale, __sputrune),
+ offsetof(_RuneLocale, __runetype_ext),
+ offsetof(_RuneLocale, __runetype_ext) + offsetof(_RuneRange, __ranges),
+ offsetof(_RuneLocale, __maplower_ext),
+ offsetof(_RuneLocale, __maplower_ext) + offsetof(_RuneRange, __ranges),
+ offsetof(_RuneLocale, __mapupper_ext),
+ offsetof(_RuneLocale, __mapupper_ext) + offsetof(_RuneRange, __ranges),
+ offsetof(_RuneLocale, __variable),
+ offsetof(_RuneLocale, __charclasses),
+ sizeof(_RuneLocale)
+};
+#define NOFF (sizeof(off64) / sizeof(int))
+#ifdef RUNEOFF32
+/*
+ * This program generates a header file (on stdout) that containes the 32-bit
+ * offsets, plus some 32-bit sizes
+ */
+main()
+{
+ int i;
+ printf("#define SIZEOF32_RUNEENTRY %d\n", sizeof(_RuneEntry));
+ printf("#define SIZEOF32_RUNELOCALE %d\n", sizeof(_RuneLocale));
+ printf("int off32[] = {\n");
+ for(i = 0; i < NOFF; i++)
+ printf("\t%d,\n", off64[i]);
+ printf("};\n");
+ return 0;
+}
+#endif /* RUNEOFF32 */
+#else /* !__LP64__ && !RUNEOFF32 */
+#define SIZEOF32_RUNELOCALE sizeof(_RuneLocale)
+#endif /* __LP64__ || RUNEOFF32 */
-_RuneLocale *
+#ifndef RUNEOFF32
+struct __xlocale_st_runelocale *
_Read_RuneMagi(fp)
FILE *fp;
{
- char *data;
+ struct __xlocale_st_runelocale *data;
void *lastp;
_RuneLocale *rl;
_RuneEntry *rr;
if (_fstat(fileno(fp), &sb) < 0)
return (NULL);
- if (sb.st_size < sizeof(_RuneLocale)) {
+ if (sb.st_size < SIZEOF32_RUNELOCALE) {
errno = EFTYPE;
return (NULL);
}
- if ((data = malloc(sb.st_size)) == NULL)
+#ifdef __LP64__
+ /* will adjust later */
+ if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale))) == NULL)
+#else /* !__LP64__ */
+ if ((data = (struct __xlocale_st_runelocale *)malloc(sizeof(struct __xlocale_st_runelocale) - sizeof(_RuneLocale) + sb.st_size)) == NULL)
+#endif /* __LP64__ */
return (NULL);
+ data->__refcount = 1;
+ data->__free_extra = NULL;
errno = 0;
rewind(fp); /* Someone might have read the magic number once already */
return (NULL);
}
- if (fread(data, sb.st_size, 1, fp) != 1) {
+ rl = &data->_CurrentRuneLocale;
+
+#ifdef __LP64__
+ if (fread(rl, SIZEOF32_RUNELOCALE, 1, fp) != 1)
+#else /* !__LP64__ */
+ if (fread(rl, sb.st_size, 1, fp) != 1)
+#endif /* __LP64__ */
+ {
saverr = errno;
free(data);
errno = saverr;
return (NULL);
}
- rl = (_RuneLocale *)data;
- lastp = data + sb.st_size;
+#ifndef __LP64__
+ lastp = (char *)rl + sb.st_size;
- rl->variable = rl + 1;
+ rl->__variable = rl + 1;
+#endif /* __LP64__ */
- if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) {
+ if (memcmp(rl->__magic, _RUNE_MAGIC_A, sizeof(rl->__magic))) {
free(data);
errno = EFTYPE;
return (NULL);
}
- rl->invalid_rune = ntohl(rl->invalid_rune);
- rl->variable_len = ntohl(rl->variable_len);
- rl->runetype_ext.nranges = ntohl(rl->runetype_ext.nranges);
- rl->maplower_ext.nranges = ntohl(rl->maplower_ext.nranges);
- rl->mapupper_ext.nranges = ntohl(rl->mapupper_ext.nranges);
+#ifdef __LP64__
+ /* shift things into the right position */
+ for (x = NOFF - 2; x >= 0; x--)
+ memmove((char *)rl + off64[x] + (skip[x] ? BYTES64BITS : 0),
+ (char *)rl + off32[x] + (skip[x] ? BYTES32BITS : 0),
+ off32[x + 1] - off32[x] - (skip[x] ? BYTES32BITS : 0));
+#endif /* __LP64__ */
+#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
+ rl->__invalid_rune = ntohl(rl->__invalid_rune);
+ rl->__variable_len = ntohl(rl->__variable_len);
+ rl->__ncharclasses = ntohl(rl->__ncharclasses);
+ rl->__runetype_ext.__nranges = ntohl(rl->__runetype_ext.__nranges);
+ rl->__maplower_ext.__nranges = ntohl(rl->__maplower_ext.__nranges);
+ rl->__mapupper_ext.__nranges = ntohl(rl->__mapupper_ext.__nranges);
for (x = 0; x < _CACHED_RUNES; ++x) {
- rl->runetype[x] = ntohl(rl->runetype[x]);
- rl->maplower[x] = ntohl(rl->maplower[x]);
- rl->mapupper[x] = ntohl(rl->mapupper[x]);
+ rl->__runetype[x] = ntohl(rl->__runetype[x]);
+ rl->__maplower[x] = ntohl(rl->__maplower[x]);
+ rl->__mapupper[x] = ntohl(rl->__mapupper[x]);
}
+#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
+
+#ifdef __LP64__
+ {
+ int count = rl->__runetype_ext.__nranges + rl->__maplower_ext.__nranges
+ + rl->__mapupper_ext.__nranges;
+ int extra = sb.st_size - SIZEOF32_RUNELOCALE - count * SIZEOF32_RUNEENTRY - rl->__ncharclasses * sizeof(_RuneCharClass);
+ _RuneEntry *rp;
- rl->runetype_ext.ranges = (_RuneEntry *)rl->variable;
- rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges;
- if (rl->variable > lastp) {
+ if (extra < 0) {
+ saverr = errno;
+ free(data);
+ errno = saverr;
+ return (NULL);
+ }
+ if ((data = (struct __xlocale_st_runelocale *)reallocf(data, sizeof(struct __xlocale_st_runelocale)
+ + count * sizeof(_RuneEntry)
+ + rl->__ncharclasses * sizeof(_RuneCharClass)
+ + extra)) == NULL)
+ return (NULL);
+ rl = &data->_CurrentRuneLocale;
+ rl->__variable = rl + 1;
+ rp = (_RuneEntry *)rl->__variable;
+ for (x = 0; x < count; x++, rp++)
+ if (fread(rp, SIZEOF32_RUNEENTRY, 1, fp) != 1) {
+ saverr = errno;
+ free(data);
+ errno = saverr;
+ return (NULL);
+ }
+ if (rl->__ncharclasses > 0) {
+ if (fread(rp, sizeof(_RuneCharClass), rl->__ncharclasses, fp) != rl->__ncharclasses) {
+ saverr = errno;
+ free(data);
+ errno = saverr;
+ return (NULL);
+ }
+ rp = (_RuneEntry *)((char *)rp + rl->__ncharclasses * sizeof(_RuneCharClass));
+ }
+ if (extra > 0 && fread(rp, extra, 1, fp) != 1) {
+ saverr = errno;
+ free(data);
+ errno = saverr;
+ return (NULL);
+ }
+ lastp = (char *)rp + extra;
+ }
+#endif /* __LP64__ */
+ rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
+ rl->__variable = rl->__runetype_ext.__ranges +
+ rl->__runetype_ext.__nranges;
+ if (rl->__variable > lastp) {
free(data);
errno = EFTYPE;
return (NULL);
}
- rl->maplower_ext.ranges = (_RuneEntry *)rl->variable;
- rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges;
- if (rl->variable > lastp) {
+ rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
+ rl->__variable = rl->__maplower_ext.__ranges +
+ rl->__maplower_ext.__nranges;
+ if (rl->__variable > lastp) {
free(data);
errno = EFTYPE;
return (NULL);
}
- rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable;
- rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges;
- if (rl->variable > lastp) {
+ rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
+ rl->__variable = rl->__mapupper_ext.__ranges +
+ rl->__mapupper_ext.__nranges;
+ if (rl->__variable > lastp) {
free(data);
errno = EFTYPE;
return (NULL);
}
- for (x = 0; x < rl->runetype_ext.nranges; ++x) {
- rr = rl->runetype_ext.ranges;
+ for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
+ rr = rl->__runetype_ext.__ranges;
- rr[x].min = ntohl(rr[x].min);
- rr[x].max = ntohl(rr[x].max);
- if ((rr[x].map = ntohl(rr[x].map)) == 0) {
- int len = rr[x].max - rr[x].min + 1;
- rr[x].types = rl->variable;
- rl->variable = rr[x].types + len;
- if (rl->variable > lastp) {
+#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
+ rr[x].__min = ntohl(rr[x].__min);
+ rr[x].__max = ntohl(rr[x].__max);
+#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
+ if ((rr[x].__map = ntohl(rr[x].__map)) == 0) {
+ int len = rr[x].__max - rr[x].__min + 1;
+ rr[x].__types = rl->__variable;
+ rl->__variable = rr[x].__types + len;
+ if (rl->__variable > lastp) {
free(data);
errno = EFTYPE;
return (NULL);
}
+#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
while (len-- > 0)
- rr[x].types[len] = ntohl(rr[x].types[len]);
+ rr[x].__types[len] = ntohl(rr[x].__types[len]);
+#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
} else
- rr[x].types = 0;
+ rr[x].__types = 0;
}
- for (x = 0; x < rl->maplower_ext.nranges; ++x) {
- rr = rl->maplower_ext.ranges;
+#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
+ for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
+ rr = rl->__maplower_ext.__ranges;
- rr[x].min = ntohl(rr[x].min);
- rr[x].max = ntohl(rr[x].max);
- rr[x].map = ntohl(rr[x].map);
+ rr[x].__min = ntohl(rr[x].__min);
+ rr[x].__max = ntohl(rr[x].__max);
+ rr[x].__map = ntohl(rr[x].__map);
}
- for (x = 0; x < rl->mapupper_ext.nranges; ++x) {
- rr = rl->mapupper_ext.ranges;
+ for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
+ rr = rl->__mapupper_ext.__ranges;
- rr[x].min = ntohl(rr[x].min);
- rr[x].max = ntohl(rr[x].max);
- rr[x].map = ntohl(rr[x].map);
+ rr[x].__min = ntohl(rr[x].__min);
+ rr[x].__max = ntohl(rr[x].__max);
+ rr[x].__map = ntohl(rr[x].__map);
}
- if (((char *)rl->variable) + rl->variable_len > (char *)lastp) {
+#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
+
+ if (rl->__ncharclasses > 0) {
+ rl->__charclasses = (_RuneCharClass *)rl->__variable;
+ rl->__variable = (void *)(rl->__charclasses + rl->__ncharclasses);
+ if (rl->__variable > lastp) {
+ free(data);
+ errno = EFTYPE;
+ return (NULL);
+ }
+#if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
+ for (x = 0; x < rl->__ncharclasses; ++x)
+ rl->__charclasses[x].__mask = ntohl(rl->__charclasses[x].__mask);
+#endif /* __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN */
+ }
+
+ if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) {
free(data);
errno = EFTYPE;
return (NULL);
/*
* Go out and zero pointers that should be zero.
*/
- if (!rl->variable_len)
- rl->variable = 0;
+ if (!rl->__variable_len)
+ rl->__variable = 0;
- if (!rl->runetype_ext.nranges)
- rl->runetype_ext.ranges = 0;
+ if (!rl->__runetype_ext.__nranges)
+ rl->__runetype_ext.__ranges = 0;
- if (!rl->maplower_ext.nranges)
- rl->maplower_ext.ranges = 0;
+ if (!rl->__maplower_ext.__nranges)
+ rl->__maplower_ext.__ranges = 0;
- if (!rl->mapupper_ext.nranges)
- rl->mapupper_ext.ranges = 0;
+ if (!rl->__mapupper_ext.__nranges)
+ rl->__mapupper_ext.__ranges = 0;
- return (rl);
+ data->__datasize = lastp - (void *)data;
+ return (data);
}
+#endif /* !RUNEOFF32 */