summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2005-02-26 21:47:54 +0000
committerru <ru@FreeBSD.org>2005-02-26 21:47:54 +0000
commitdff27cebe275d2de1de24d62623529f164c72a94 (patch)
treed3e227cd7ec0d15f6cf44deceb0a9da81b1c521c /lib
parentb34b4a5a6425877bb5b584eec83471a89ebe46d1 (diff)
downloadFreeBSD-src-dff27cebe275d2de1de24d62623529f164c72a94.zip
FreeBSD-src-dff27cebe275d2de1de24d62623529f164c72a94.tar.gz
Make the format of LC_CTYPE files architecture independent by
introducing the disk formats for _RuneLocale and friends. The disk formats do not have (useless) pointers and have 32-bit quantities instead of rune_t and long. (htonl(3) only works with 32-bit quantities, so there's no loss). Bootstrap mklocale(1) when necessary. (Bootstrapping from 4.x would be trivial (verified), but we no longer provide pre-5.3 source upgrades and this is the first commit to actually break it.)
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/locale/rune.c222
1 files changed, 156 insertions, 66 deletions
diff --git a/lib/libc/locale/rune.c b/lib/libc/locale/rune.c
index d179da1..4d37f36 100644
--- a/lib/libc/locale/rune.c
+++ b/lib/libc/locale/rune.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include <arpa/inet.h>
#include <errno.h>
#include <runetype.h>
+#include <runefile.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -51,149 +52,238 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include "un-namespace.h"
+_RuneLocale *_Read_RuneMagi(FILE *);
+
_RuneLocale *
-_Read_RuneMagi(fp)
- FILE *fp;
+_Read_RuneMagi(FILE *fp)
{
- char *data;
+ char *fdata, *data;
void *lastp;
+ _FileRuneLocale *frl;
_RuneLocale *rl;
+ _FileRuneEntry *frr;
_RuneEntry *rr;
struct stat sb;
int x, saverr;
+ void *variable;
+ _FileRuneEntry *runetype_ext_ranges;
+ _FileRuneEntry *maplower_ext_ranges;
+ _FileRuneEntry *mapupper_ext_ranges;
+ int runetype_ext_len = 0;
if (_fstat(fileno(fp), &sb) < 0)
return (NULL);
- if (sb.st_size < sizeof(_RuneLocale)) {
+ if ((size_t)sb.st_size < sizeof(_FileRuneLocale)) {
errno = EFTYPE;
return (NULL);
}
- if ((data = malloc(sb.st_size)) == NULL)
+ if ((fdata = malloc(sb.st_size)) == NULL)
return (NULL);
errno = 0;
rewind(fp); /* Someone might have read the magic number once already */
if (errno) {
saverr = errno;
- free(data);
+ free(fdata);
errno = saverr;
return (NULL);
}
- if (fread(data, sb.st_size, 1, fp) != 1) {
+ if (fread(fdata, sb.st_size, 1, fp) != 1) {
saverr = errno;
- free(data);
+ free(fdata);
errno = saverr;
return (NULL);
}
- rl = (_RuneLocale *)data;
- lastp = data + sb.st_size;
+ frl = (_FileRuneLocale *)fdata;
+ lastp = fdata + sb.st_size;
- rl->__variable = rl + 1;
+ variable = frl + 1;
- if (memcmp(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic))) {
- free(data);
+ if (memcmp(frl->magic, _FILE_RUNE_MAGIC_1, sizeof(frl->magic))) {
+ free(fdata);
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);
+ frl->variable_len = ntohl(frl->variable_len);
+ frl->runetype_ext_nranges = ntohl(frl->runetype_ext_nranges);
+ frl->maplower_ext_nranges = ntohl(frl->maplower_ext_nranges);
+ frl->mapupper_ext_nranges = ntohl(frl->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]);
+ frl->runetype[x] = ntohl(frl->runetype[x]);
+ frl->maplower[x] = ntohl(frl->maplower[x]);
+ frl->mapupper[x] = ntohl(frl->mapupper[x]);
}
- rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
- rl->__variable = rl->__runetype_ext.__ranges +
- rl->__runetype_ext.__nranges;
- if (rl->__variable > lastp) {
- free(data);
+ runetype_ext_ranges = (_FileRuneEntry *)variable;
+ variable = runetype_ext_ranges + frl->runetype_ext_nranges;
+ if (variable > lastp) {
+ free(fdata);
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) {
- free(data);
+ maplower_ext_ranges = (_FileRuneEntry *)variable;
+ variable = maplower_ext_ranges + frl->maplower_ext_nranges;
+ if (variable > lastp) {
+ free(fdata);
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) {
- free(data);
+ mapupper_ext_ranges = (_FileRuneEntry *)variable;
+ variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
+ if (variable > lastp) {
+ free(fdata);
errno = EFTYPE;
return (NULL);
}
+ frr = runetype_ext_ranges;
+ for (x = 0; x < frl->runetype_ext_nranges; ++x) {
+ uint32_t *types;
+
+ frr[x].min = ntohl(frr[x].min);
+ frr[x].max = ntohl(frr[x].max);
+ frr[x].map = ntohl(frr[x].map);
+ if (frr[x].map == 0) {
+ int len = frr[x].max - frr[x].min + 1;
+ types = variable;
+ variable = types + len;
+ runetype_ext_len += len;
+ if (variable > lastp) {
+ free(fdata);
+ errno = EFTYPE;
+ return (NULL);
+ }
+ while (len-- > 0)
+ types[len] = ntohl(types[len]);
+ }
+ }
+
+ frr = maplower_ext_ranges;
+ for (x = 0; x < frl->maplower_ext_nranges; ++x) {
+ frr[x].min = ntohl(frr[x].min);
+ frr[x].max = ntohl(frr[x].max);
+ frr[x].map = ntohl(frr[x].map);
+ }
+
+ frr = mapupper_ext_ranges;
+ for (x = 0; x < frl->mapupper_ext_nranges; ++x) {
+ frr[x].min = ntohl(frr[x].min);
+ frr[x].max = ntohl(frr[x].max);
+ frr[x].map = ntohl(frr[x].map);
+ }
+ if ((char *)variable + frl->variable_len > (char *)lastp) {
+ free(fdata);
+ errno = EFTYPE;
+ return (NULL);
+ }
+
+ /*
+ * Convert from disk format to host format.
+ */
+ data = malloc(sizeof(_RuneLocale) +
+ (frl->runetype_ext_nranges + frl->maplower_ext_nranges +
+ frl->mapupper_ext_nranges) * sizeof(_RuneEntry) +
+ runetype_ext_len * sizeof(*rr->__types) +
+ frl->variable_len);
+ if (data == NULL) {
+ saverr = errno;
+ free(fdata);
+ errno = saverr;
+ return (NULL);
+ }
+
+ rl = (_RuneLocale *)data;
+ rl->__variable = rl + 1;
+
+ memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
+ memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
+ rl->__invalid_rune = 0;
+
+ rl->__variable_len = frl->variable_len;
+ rl->__runetype_ext.__nranges = frl->runetype_ext_nranges;
+ rl->__maplower_ext.__nranges = frl->maplower_ext_nranges;
+ rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges;
+
+ for (x = 0; x < _CACHED_RUNES; ++x) {
+ rl->__runetype[x] = frl->runetype[x];
+ rl->__maplower[x] = frl->maplower[x];
+ rl->__mapupper[x] = frl->mapupper[x];
+ }
+
+ rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
+ rl->__variable = rl->__runetype_ext.__ranges +
+ rl->__runetype_ext.__nranges;
+
+ rl->__maplower_ext.__ranges = (_RuneEntry *)rl->__variable;
+ rl->__variable = rl->__maplower_ext.__ranges +
+ rl->__maplower_ext.__nranges;
+
+ rl->__mapupper_ext.__ranges = (_RuneEntry *)rl->__variable;
+ rl->__variable = rl->__mapupper_ext.__ranges +
+ rl->__mapupper_ext.__nranges;
+
+ variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
+ frr = runetype_ext_ranges;
+ rr = rl->__runetype_ext.__ranges;
for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
- rr = rl->__runetype_ext.__ranges;
+ uint32_t *types;
- rr[x].__min = ntohl(rr[x].__min);
- rr[x].__max = ntohl(rr[x].__max);
- if ((rr[x].__map = ntohl(rr[x].__map)) == 0) {
+ rr[x].__min = frr[x].min;
+ rr[x].__max = frr[x].max;
+ rr[x].__map = frr[x].map;
+ if (rr[x].__map == 0) {
int len = rr[x].__max - rr[x].__min + 1;
+ types = variable;
+ variable = types + len;
rr[x].__types = rl->__variable;
rl->__variable = rr[x].__types + len;
- if (rl->__variable > lastp) {
- free(data);
- errno = EFTYPE;
- return (NULL);
- }
while (len-- > 0)
- rr[x].__types[len] = ntohl(rr[x].__types[len]);
+ rr[x].__types[len] = types[len];
} else
- rr[x].__types = 0;
+ rr[x].__types = NULL;
}
+ frr = maplower_ext_ranges;
+ rr = rl->__maplower_ext.__ranges;
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 = frr[x].min;
+ rr[x].__max = frr[x].max;
+ rr[x].__map = frr[x].map;
}
+ frr = mapupper_ext_ranges;
+ 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);
- }
- if (((char *)rl->__variable) + rl->__variable_len > (char *)lastp) {
- free(data);
- errno = EFTYPE;
- return (NULL);
+ rr[x].__min = frr[x].min;
+ rr[x].__max = frr[x].max;
+ rr[x].__map = frr[x].map;
}
+ memcpy(rl->__variable, variable, rl->__variable_len);
+ free(fdata);
+
/*
* Go out and zero pointers that should be zero.
*/
if (!rl->__variable_len)
- rl->__variable = 0;
+ rl->__variable = NULL;
if (!rl->__runetype_ext.__nranges)
- rl->__runetype_ext.__ranges = 0;
+ rl->__runetype_ext.__ranges = NULL;
if (!rl->__maplower_ext.__nranges)
- rl->__maplower_ext.__ranges = 0;
+ rl->__maplower_ext.__ranges = NULL;
if (!rl->__mapupper_ext.__nranges)
- rl->__mapupper_ext.__ranges = 0;
+ rl->__mapupper_ext.__ranges = NULL;
return (rl);
}
OpenPOWER on IntegriCloud