Add -b/-l options to localedef(1) to specify output endianness and use

it appropriately when building share/ctypedef and share/colldef.

This makes the resulting locale data in EL->EB (amd64->powerpc64) cross
build and in the native EB build match.  Revert the changes done to libc
in r308170 as they are no longer needed.

PR:		231965
Reviewed by:	bapt, emaste, sbruno, 0mp
Approved by:	kib (mentor)
Differential Revision:	https://reviews.freebsd.org/D17603
This commit is contained in:
Yuri Pankov 2018-10-20 20:51:05 +00:00
parent f4f33ea0c7
commit 4644f9bef6
13 changed files with 177 additions and 171 deletions

View File

@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <fcntl.h> #include <fcntl.h>
#include "un-namespace.h" #include "un-namespace.h"
#include "endian.h"
#include "collate.h" #include "collate.h"
#include "setlocale.h" #include "setlocale.h"
#include "ldpart.h" #include "ldpart.h"
@ -162,7 +161,7 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
if ((info->directive_count < 1) || if ((info->directive_count < 1) ||
(info->directive_count >= COLL_WEIGHTS_MAX) || (info->directive_count >= COLL_WEIGHTS_MAX) ||
((chains = BSWAP(info->chain_count)) < 0)) { ((chains = info->chain_count) < 0)) {
(void) munmap(map, sbuf.st_size); (void) munmap(map, sbuf.st_size);
errno = EINVAL; errno = EINVAL;
return (_LDP_ERROR); return (_LDP_ERROR);
@ -170,9 +169,9 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
i = (sizeof (collate_char_t) * (UCHAR_MAX + 1)) + i = (sizeof (collate_char_t) * (UCHAR_MAX + 1)) +
(sizeof (collate_chain_t) * chains) + (sizeof (collate_chain_t) * chains) +
(sizeof (collate_large_t) * BSWAP(info->large_count)); (sizeof (collate_large_t) * info->large_count);
for (z = 0; z < info->directive_count; z++) { for (z = 0; z < info->directive_count; z++) {
i += sizeof (collate_subst_t) * BSWAP(info->subst_count[z]); i += sizeof (collate_subst_t) * info->subst_count[z];
} }
if (i != (sbuf.st_size - (TMP - map))) { if (i != (sbuf.st_size - (TMP - map))) {
(void) munmap(map, sbuf.st_size); (void) munmap(map, sbuf.st_size);
@ -185,9 +184,9 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
TMP += sizeof (collate_char_t) * (UCHAR_MAX + 1); TMP += sizeof (collate_char_t) * (UCHAR_MAX + 1);
for (z = 0; z < info->directive_count; z++) { for (z = 0; z < info->directive_count; z++) {
if (BSWAP(info->subst_count[z]) > 0) { if (info->subst_count[z] > 0) {
table->subst_table[z] = (void *)TMP; table->subst_table[z] = (void *)TMP;
TMP += BSWAP(info->subst_count[z]) * sizeof (collate_subst_t); TMP += info->subst_count[z] * sizeof (collate_subst_t);
} else { } else {
table->subst_table[z] = NULL; table->subst_table[z] = NULL;
} }
@ -198,7 +197,7 @@ __collate_load_tables_l(const char *encoding, struct xlocale_collate *table)
TMP += chains * sizeof (collate_chain_t); TMP += chains * sizeof (collate_chain_t);
} else } else
table->chain_pri_table = NULL; table->chain_pri_table = NULL;
if (BSWAP(info->large_count) > 0) if (info->large_count > 0)
table->large_pri_table = (void *)TMP; table->large_pri_table = (void *)TMP;
else else
table->large_pri_table = NULL; table->large_pri_table = NULL;
@ -211,7 +210,7 @@ static const int32_t *
substsearch(struct xlocale_collate *table, const wchar_t key, int pass) substsearch(struct xlocale_collate *table, const wchar_t key, int pass)
{ {
const collate_subst_t *p; const collate_subst_t *p;
int n = BSWAP(table->info->subst_count[pass]); int n = table->info->subst_count[pass];
if (n == 0) if (n == 0)
return (NULL); return (NULL);
@ -223,7 +222,7 @@ substsearch(struct xlocale_collate *table, const wchar_t key, int pass)
return (NULL); return (NULL);
p = table->subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY); p = table->subst_table[pass] + (key & ~COLLATE_SUBST_PRIORITY);
assert(BSWAP(p->key) == key); assert(p->key == key);
return (p->pri); return (p->pri);
} }
@ -232,7 +231,7 @@ static collate_chain_t *
chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len) chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len)
{ {
int low = 0; int low = 0;
int high = BSWAP(table->info->chain_count) - 1; int high = table->info->chain_count - 1;
int next, compar, l; int next, compar, l;
collate_chain_t *p; collate_chain_t *p;
collate_chain_t *tab = table->chain_pri_table; collate_chain_t *tab = table->chain_pri_table;
@ -243,7 +242,7 @@ chainsearch(struct xlocale_collate *table, const wchar_t *key, int *len)
while (low <= high) { while (low <= high) {
next = (low + high) / 2; next = (low + high) / 2;
p = tab + next; p = tab + next;
compar = *key - le16toh(*p->str); compar = *key - *p->str;
if (compar == 0) { if (compar == 0) {
l = wcsnlen(p->str, COLLATE_STR_LEN); l = wcsnlen(p->str, COLLATE_STR_LEN);
compar = wcsncmp(key, p->str, l); compar = wcsncmp(key, p->str, l);
@ -264,7 +263,7 @@ static collate_large_t *
largesearch(struct xlocale_collate *table, const wchar_t key) largesearch(struct xlocale_collate *table, const wchar_t key)
{ {
int low = 0; int low = 0;
int high = BSWAP(table->info->large_count) - 1; int high = table->info->large_count - 1;
int next, compar; int next, compar;
collate_large_t *p; collate_large_t *p;
collate_large_t *tab = table->large_pri_table; collate_large_t *tab = table->large_pri_table;
@ -275,7 +274,7 @@ largesearch(struct xlocale_collate *table, const wchar_t key)
while (low <= high) { while (low <= high) {
next = (low + high) / 2; next = (low + high) / 2;
p = tab + next; p = tab + next;
compar = key - BSWAP(p->val); compar = key - p->val;
if (compar == 0) if (compar == 0)
return (p); return (p);
if (compar > 0) if (compar > 0)
@ -340,15 +339,15 @@ _collate_lookup(struct xlocale_collate *table, const wchar_t *t, int *len,
* Character is a small (8-bit) character. * Character is a small (8-bit) character.
* We just look these up directly for speed. * We just look these up directly for speed.
*/ */
*pri = BSWAP(table->char_pri_table[*t].pri[which]); *pri = table->char_pri_table[*t].pri[which];
} else if ((BSWAP(table->info->large_count) > 0) && } else if ((table->info->large_count > 0) &&
((match = largesearch(table, *t)) != NULL)) { ((match = largesearch(table, *t)) != NULL)) {
/* /*
* Character was found in the extended table. * Character was found in the extended table.
*/ */
*pri = BSWAP(match->pri.pri[which]); *pri = match->pri.pri[which];
} else { } else {
/* /*
@ -358,7 +357,7 @@ _collate_lookup(struct xlocale_collate *table, const wchar_t *t, int *len,
/* Mask off sign bit to prevent ordering confusion. */ /* Mask off sign bit to prevent ordering confusion. */
*pri = (*t & COLLATE_MAX_PRIORITY); *pri = (*t & COLLATE_MAX_PRIORITY);
} else { } else {
*pri = BSWAP(table->info->undef_pri[which]); *pri = table->info->undef_pri[which];
} }
/* No substitutions for undefined characters! */ /* No substitutions for undefined characters! */
return; return;
@ -377,9 +376,9 @@ _collate_lookup(struct xlocale_collate *table, const wchar_t *t, int *len,
* code ensures this for us. * code ensures this for us.
*/ */
if ((sptr = substsearch(table, *pri, which)) != NULL) { if ((sptr = substsearch(table, *pri, which)) != NULL) {
if ((*pri = BSWAP(*sptr)) > 0) { if ((*pri = *sptr) > 0) {
sptr++; sptr++;
*state = BSWAP(*sptr) ? sptr : NULL; *state = *sptr ? sptr : NULL;
} }
} }
@ -521,7 +520,7 @@ static int
xfrm(struct xlocale_collate *table, unsigned char *p, int pri, int pass) xfrm(struct xlocale_collate *table, unsigned char *p, int pri, int pass)
{ {
/* we use unsigned to ensure zero fill on right shift */ /* we use unsigned to ensure zero fill on right shift */
uint32_t val = BSWAP((uint32_t)table->info->pri_count[pass]); uint32_t val = (uint32_t)table->info->pri_count[pass];
int nc = 0; int nc = 0;
while (val) { while (val) {
@ -681,7 +680,7 @@ __collate_equiv_value(locale_t locale, const wchar_t *str, size_t len)
e = -1; e = -1;
if (*str <= UCHAR_MAX) if (*str <= UCHAR_MAX)
e = table->char_pri_table[*str].pri[0]; e = table->char_pri_table[*str].pri[0];
else if (BSWAP(table->info->large_count) > 0) { else if (table->info->large_count > 0) {
collate_large_t *match_large; collate_large_t *match_large;
match_large = largesearch(table, *str); match_large = largesearch(table, *str);
if (match_large) if (match_large)
@ -691,7 +690,7 @@ __collate_equiv_value(locale_t locale, const wchar_t *str, size_t len)
return (1); return (1);
return (e > 0 ? e : 0); return (e > 0 ? e : 0);
} }
if (BSWAP(table->info->chain_count) > 0) { if (table->info->chain_count > 0) {
wchar_t name[COLLATE_STR_LEN]; wchar_t name[COLLATE_STR_LEN];
collate_chain_t *match_chain; collate_chain_t *match_chain;
int clen; int clen;

View File

@ -1,52 +0,0 @@
/*-
* Copyright (c) 2016 Ruslan Bukin <br@bsdpad.com>
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
*
* Portions of this software were developed by the University of Cambridge
* Computer Laboratory as part of the CTSRD Project, with support from the
* UK Higher Education Innovation Fund (HEIF).
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/endian.h>
/*
* We assume locale files were generated on EL machine
* (e.g. during cross build on amd64 host), but used on EB
* machine (e.g. MIPS64EB), so convert it to host endianness.
*
* TODO: detect host endianness on the build machine and use
* correct macros here.
*/
#if BYTE_ORDER == BIG_ENDIAN && defined(__mips__)
#define BSWAP(x) le32toh(x)
#else
#define BSWAP(x) x
#endif

View File

@ -54,7 +54,6 @@ __FBSDID("$FreeBSD$");
#include <unistd.h> #include <unistd.h>
#include "un-namespace.h" #include "un-namespace.h"
#include "endian.h"
#include "runefile.h" #include "runefile.h"
_RuneLocale * _RuneLocale *
@ -110,29 +109,29 @@ _Read_RuneMagi(const char *fname)
} }
runetype_ext_ranges = (_FileRuneEntry *)variable; runetype_ext_ranges = (_FileRuneEntry *)variable;
variable = runetype_ext_ranges + BSWAP(frl->runetype_ext_nranges); variable = runetype_ext_ranges + frl->runetype_ext_nranges;
if (variable > lastp) { if (variable > lastp) {
goto invalid; goto invalid;
} }
maplower_ext_ranges = (_FileRuneEntry *)variable; maplower_ext_ranges = (_FileRuneEntry *)variable;
variable = maplower_ext_ranges + BSWAP(frl->maplower_ext_nranges); variable = maplower_ext_ranges + frl->maplower_ext_nranges;
if (variable > lastp) { if (variable > lastp) {
goto invalid; goto invalid;
} }
mapupper_ext_ranges = (_FileRuneEntry *)variable; mapupper_ext_ranges = (_FileRuneEntry *)variable;
variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges); variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
if (variable > lastp) { if (variable > lastp) {
goto invalid; goto invalid;
} }
frr = runetype_ext_ranges; frr = runetype_ext_ranges;
for (x = 0; x < BSWAP(frl->runetype_ext_nranges); ++x) { for (x = 0; x < frl->runetype_ext_nranges; ++x) {
uint32_t *types; uint32_t *types;
if (BSWAP(frr[x].map) == 0) { if (frr[x].map == 0) {
int len = BSWAP(frr[x].max) - BSWAP(frr[x].min) + 1; int len = frr[x].max - frr[x].min + 1;
types = variable; types = variable;
variable = types + len; variable = types + len;
runetype_ext_len += len; runetype_ext_len += len;
@ -142,7 +141,7 @@ _Read_RuneMagi(const char *fname)
} }
} }
if ((char *)variable + BSWAP(frl->variable_len) > (char *)lastp) { if ((char *)variable + frl->variable_len > (char *)lastp) {
goto invalid; goto invalid;
} }
@ -150,10 +149,9 @@ _Read_RuneMagi(const char *fname)
* Convert from disk format to host format. * Convert from disk format to host format.
*/ */
data = malloc(sizeof(_RuneLocale) + data = malloc(sizeof(_RuneLocale) +
(BSWAP(frl->runetype_ext_nranges) + BSWAP(frl->maplower_ext_nranges) + (frl->runetype_ext_nranges + frl->maplower_ext_nranges +
BSWAP(frl->mapupper_ext_nranges)) * sizeof(_RuneEntry) + frl->mapupper_ext_nranges) * sizeof(_RuneEntry) +
runetype_ext_len * sizeof(*rr->__types) + runetype_ext_len * sizeof(*rr->__types) + frl->variable_len);
BSWAP(frl->variable_len));
if (data == NULL) { if (data == NULL) {
saverr = errno; saverr = errno;
munmap(fdata, sb.st_size); munmap(fdata, sb.st_size);
@ -167,15 +165,15 @@ _Read_RuneMagi(const char *fname)
memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic)); memcpy(rl->__magic, _RUNE_MAGIC_1, sizeof(rl->__magic));
memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding)); memcpy(rl->__encoding, frl->encoding, sizeof(rl->__encoding));
rl->__variable_len = BSWAP(frl->variable_len); rl->__variable_len = frl->variable_len;
rl->__runetype_ext.__nranges = BSWAP(frl->runetype_ext_nranges); rl->__runetype_ext.__nranges = frl->runetype_ext_nranges;
rl->__maplower_ext.__nranges = BSWAP(frl->maplower_ext_nranges); rl->__maplower_ext.__nranges = frl->maplower_ext_nranges;
rl->__mapupper_ext.__nranges = BSWAP(frl->mapupper_ext_nranges); rl->__mapupper_ext.__nranges = frl->mapupper_ext_nranges;
for (x = 0; x < _CACHED_RUNES; ++x) { for (x = 0; x < _CACHED_RUNES; ++x) {
rl->__runetype[x] = BSWAP(frl->runetype[x]); rl->__runetype[x] = frl->runetype[x];
rl->__maplower[x] = BSWAP(frl->maplower[x]); rl->__maplower[x] = frl->maplower[x];
rl->__mapupper[x] = BSWAP(frl->mapupper[x]); rl->__mapupper[x] = frl->mapupper[x];
} }
rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable; rl->__runetype_ext.__ranges = (_RuneEntry *)rl->__variable;
@ -190,15 +188,15 @@ _Read_RuneMagi(const char *fname)
rl->__variable = rl->__mapupper_ext.__ranges + rl->__variable = rl->__mapupper_ext.__ranges +
rl->__mapupper_ext.__nranges; rl->__mapupper_ext.__nranges;
variable = mapupper_ext_ranges + BSWAP(frl->mapupper_ext_nranges); variable = mapupper_ext_ranges + frl->mapupper_ext_nranges;
frr = runetype_ext_ranges; frr = runetype_ext_ranges;
rr = rl->__runetype_ext.__ranges; rr = rl->__runetype_ext.__ranges;
for (x = 0; x < rl->__runetype_ext.__nranges; ++x) { for (x = 0; x < rl->__runetype_ext.__nranges; ++x) {
uint32_t *types; uint32_t *types;
rr[x].__min = BSWAP(frr[x].min); rr[x].__min = frr[x].min;
rr[x].__max = BSWAP(frr[x].max); rr[x].__max = frr[x].max;
rr[x].__map = BSWAP(frr[x].map); rr[x].__map = frr[x].map;
if (rr[x].__map == 0) { if (rr[x].__map == 0) {
int len = rr[x].__max - rr[x].__min + 1; int len = rr[x].__max - rr[x].__min + 1;
types = variable; types = variable;
@ -214,17 +212,17 @@ _Read_RuneMagi(const char *fname)
frr = maplower_ext_ranges; frr = maplower_ext_ranges;
rr = rl->__maplower_ext.__ranges; rr = rl->__maplower_ext.__ranges;
for (x = 0; x < rl->__maplower_ext.__nranges; ++x) { for (x = 0; x < rl->__maplower_ext.__nranges; ++x) {
rr[x].__min = BSWAP(frr[x].min); rr[x].__min = frr[x].min;
rr[x].__max = BSWAP(frr[x].max); rr[x].__max = frr[x].max;
rr[x].__map = BSWAP(frr[x].map); rr[x].__map = frr[x].map;
} }
frr = mapupper_ext_ranges; frr = mapupper_ext_ranges;
rr = rl->__mapupper_ext.__ranges; rr = rl->__mapupper_ext.__ranges;
for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) { for (x = 0; x < rl->__mapupper_ext.__nranges; ++x) {
rr[x].__min = BSWAP(frr[x].min); rr[x].__min = frr[x].min;
rr[x].__max = BSWAP(frr[x].max); rr[x].__max = frr[x].max;
rr[x].__map = BSWAP(frr[x].map); rr[x].__map = frr[x].map;
} }
memcpy(rl->__variable, variable, rl->__variable_len); memcpy(rl->__variable, variable, rl->__variable_len);

View File

@ -7,8 +7,10 @@ FILESNAME= LC_COLLATE
.SUFFIXES: .src .LC_COLLATE .SUFFIXES: .src .LC_COLLATE
MAPLOC= ${.CURDIR}/../../tools/tools/locale/etc/final-maps MAPLOC= ${.CURDIR}/../../tools/tools/locale/etc/final-maps
.include <bsd.endian.mk>
.src.LC_COLLATE: .src.LC_COLLATE:
localedef -D -U -i ${.IMPSRC} \ localedef ${LOCALEDEF_ENDIAN} -D -U -i ${.IMPSRC} \
-f ${MAPLOC}/map.${.TARGET:T:R:E:C/@.*//} ${.OBJDIR}/${.IMPSRC:T:R} -f ${MAPLOC}/map.${.TARGET:T:R:E:C/@.*//} ${.OBJDIR}/${.IMPSRC:T:R}
LOCALES+= af_ZA.UTF-8 LOCALES+= af_ZA.UTF-8
@ -223,7 +225,7 @@ FILESDIR_${f}.LC_COLLATE= ${LOCALEDIR}/${f}
FILES+= $t.LC_COLLATE FILES+= $t.LC_COLLATE
FILESDIR_$t.LC_COLLATE= ${LOCALEDIR}/$t FILESDIR_$t.LC_COLLATE= ${LOCALEDIR}/$t
$t.LC_COLLATE: ${.CURDIR}/$f.src $t.LC_COLLATE: ${.CURDIR}/$f.src
localedef -D -U -i ${.ALLSRC} \ localedef ${LOCALEDEF_ENDIAN} -D -U -i ${.ALLSRC} \
-f ${MAPLOC}/map.${.TARGET:T:R:E:C/@.*//} \ -f ${MAPLOC}/map.${.TARGET:T:R:E:C/@.*//} \
${.OBJDIR}/${.TARGET:T:R} ${.OBJDIR}/${.TARGET:T:R}
.endfor .endfor

View File

@ -7,8 +7,10 @@ FILESNAME= LC_CTYPE
.SUFFIXES: .src .LC_CTYPE .SUFFIXES: .src .LC_CTYPE
MAPLOC= ${.CURDIR}/../../tools/tools/locale/etc/final-maps MAPLOC= ${.CURDIR}/../../tools/tools/locale/etc/final-maps
.include <bsd.endian.mk>
.src.LC_CTYPE: .src.LC_CTYPE:
localedef -D -U -c -w ${MAPLOC}/widths.txt \ localedef ${LOCALEDEF_ENDIAN} -D -U -c -w ${MAPLOC}/widths.txt \
-f ${MAPLOC}/map.${.IMPSRC:T:R:E} \ -f ${MAPLOC}/map.${.IMPSRC:T:R:E} \
-i ${.IMPSRC} ${.OBJDIR}/${.IMPSRC:T:R} || true -i ${.IMPSRC} ${.OBJDIR}/${.IMPSRC:T:R} || true
@ -238,7 +240,7 @@ SYMPAIRS+= be_BY.CP1131.src ru_RU.KOI8-R.src
.for s t in ${SYMPAIRS} .for s t in ${SYMPAIRS}
${t:S/src$/LC_CTYPE/}: $s ${t:S/src$/LC_CTYPE/}: $s
localedef -D -U -c -w ${MAPLOC}/widths.txt \ localedef ${LOCALEDEF_ENDIAN} -D -U -c -w ${MAPLOC}/widths.txt \
-f ${MAPLOC}/map.${.TARGET:T:R:C/^.*\.//} \ -f ${MAPLOC}/map.${.TARGET:T:R:C/^.*\.//} \
-i ${.ALLSRC} ${.OBJDIR}/${.TARGET:T:R} || true -i ${.ALLSRC} ${.OBJDIR}/${.TARGET:T:R} || true
.endfor .endfor

View File

@ -8,6 +8,7 @@
${MACHINE_ARCH:Mmips*el*} != "" ${MACHINE_ARCH:Mmips*el*} != ""
TARGET_ENDIANNESS= 1234 TARGET_ENDIANNESS= 1234
CAP_MKDB_ENDIAN= -l CAP_MKDB_ENDIAN= -l
LOCALEDEF_ENDIAN= -l
.elif ${MACHINE_ARCH} == "powerpc" || \ .elif ${MACHINE_ARCH} == "powerpc" || \
${MACHINE_ARCH} == "powerpc64" || \ ${MACHINE_ARCH} == "powerpc64" || \
${MACHINE_ARCH} == "powerpcspe" || \ ${MACHINE_ARCH} == "powerpcspe" || \
@ -16,4 +17,5 @@ CAP_MKDB_ENDIAN= -l
${MACHINE_ARCH:Mmips*} != "" ${MACHINE_ARCH:Mmips*} != ""
TARGET_ENDIANNESS= 4321 TARGET_ENDIANNESS= 4321
CAP_MKDB_ENDIAN= -b CAP_MKDB_ENDIAN= -b
LOCALEDEF_ENDIAN= -b
.endif .endif

View File

@ -246,6 +246,7 @@ DIRDEPS+= \
usr.bin/lex/lib \ usr.bin/lex/lib \
usr.bin/limits \ usr.bin/limits \
usr.bin/locale \ usr.bin/locale \
usr.bin/localedef \
usr.bin/locate/bigram \ usr.bin/locate/bigram \
usr.bin/locate/code \ usr.bin/locate/code \
usr.bin/locate/locate \ usr.bin/locate/locate \

View File

@ -857,7 +857,8 @@ sub make_makefile {
my $SRCOUT4 = ""; my $SRCOUT4 = "";
my $MAPLOC; my $MAPLOC;
if ($TYPE eq "colldef") { if ($TYPE eq "colldef") {
$SRCOUT = "localedef -D -U -i \${.IMPSRC} \\\n" . $SRCOUT = "localedef \${LOCALEDEF_ENDIAN} -D -U " .
"-i \${.IMPSRC} \\\n" .
"\t-f \${MAPLOC}/map.\${.TARGET:T:R:E:C/@.*//} " . "\t-f \${MAPLOC}/map.\${.TARGET:T:R:E:C/@.*//} " .
"\${.OBJDIR}/\${.IMPSRC:T:R}"; "\${.OBJDIR}/\${.IMPSRC:T:R}";
$MAPLOC = "MAPLOC=\t\t\${.CURDIR}/../../tools/tools/" . $MAPLOC = "MAPLOC=\t\t\${.CURDIR}/../../tools/tools/" .
@ -868,14 +869,16 @@ sub make_makefile {
"FILES+=\t\$t.LC_COLLATE\n" . "FILES+=\t\$t.LC_COLLATE\n" .
"FILESDIR_\$t.LC_COLLATE=\t\${LOCALEDIR}/\$t\n" . "FILESDIR_\$t.LC_COLLATE=\t\${LOCALEDIR}/\$t\n" .
"\$t.LC_COLLATE: \${.CURDIR}/\$f.src\n" . "\$t.LC_COLLATE: \${.CURDIR}/\$f.src\n" .
"\tlocaledef -D -U -i \${.ALLSRC} \\\n" . "\tlocaledef \${LOCALEDEF_ENDIAN} -D -U " .
"-i \${.ALLSRC} \\\n" .
"\t\t-f \${MAPLOC}/map.\${.TARGET:T:R:E:C/@.*//} \\\n" . "\t\t-f \${MAPLOC}/map.\${.TARGET:T:R:E:C/@.*//} \\\n" .
"\t\t\${.OBJDIR}/\${.TARGET:T:R}\n" . "\t\t\${.OBJDIR}/\${.TARGET:T:R}\n" .
".endfor\n\n"; ".endfor\n\n";
$SRCOUT4 = "## LOCALES_MAPPED\n"; $SRCOUT4 = "## LOCALES_MAPPED\n";
} }
elsif ($TYPE eq "ctypedef") { elsif ($TYPE eq "ctypedef") {
$SRCOUT = "localedef -D -U -c -w \${MAPLOC}/widths.txt \\\n" . $SRCOUT = "localedef \${LOCALEDEF_ENDIAN} -D -U -c " .
"-w \${MAPLOC}/widths.txt \\\n" .
"\t-f \${MAPLOC}/map.\${.IMPSRC:T:R:E} " . "\t-f \${MAPLOC}/map.\${.IMPSRC:T:R:E} " .
"\\\n\t-i \${.IMPSRC} \${.OBJDIR}/\${.IMPSRC:T:R} " . "\\\n\t-i \${.IMPSRC} \${.OBJDIR}/\${.IMPSRC:T:R} " .
" || true"; " || true";
@ -886,7 +889,8 @@ sub make_makefile {
".for s t in \${SYMPAIRS}\n" . ".for s t in \${SYMPAIRS}\n" .
"\${t:S/src\$/LC_CTYPE/}: " . "\${t:S/src\$/LC_CTYPE/}: " .
"\$s\n" . "\$s\n" .
"\tlocaledef -D -U -c -w \${MAPLOC}/widths.txt \\\n" . "\tlocaledef \${LOCALEDEF_ENDIAN} -D -U -c " .
"-w \${MAPLOC}/widths.txt \\\n" .
"\t-f \${MAPLOC}/map.\${.TARGET:T:R:C/^.*\\.//} " . "\t-f \${MAPLOC}/map.\${.TARGET:T:R:C/^.*\\.//} " .
"\\\n\t-i \${.ALLSRC} \${.OBJDIR}/\${.TARGET:T:R} " . "\\\n\t-i \${.ALLSRC} \${.OBJDIR}/\${.TARGET:T:R} " .
" || true\n" . " || true\n" .
@ -907,6 +911,8 @@ LOCALEDIR= \${SHAREDIR}/locale
FILESNAME= $FILESNAMES{$TYPE} FILESNAME= $FILESNAMES{$TYPE}
.SUFFIXES: .src .${SRCOUT2} .SUFFIXES: .src .${SRCOUT2}
${MAPLOC} ${MAPLOC}
.include <bsd.endian.mk>
.src.${SRCOUT2}: .src.${SRCOUT2}:
$SRCOUT $SRCOUT

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright 2018 Nexenta Systems, Inc.
* Copyright 2015 John Marino <draco@marino.st> * Copyright 2015 John Marino <draco@marino.st>
* *
* This source code is derived from the illumos localedef command, and * This source code is derived from the illumos localedef command, and
@ -253,6 +253,9 @@ static int32_t pri_undefined[COLL_WEIGHTS_MAX];
static int32_t pri_ignore; static int32_t pri_ignore;
static collate_info_t collinfo; static collate_info_t collinfo;
static int32_t subst_count[COLL_WEIGHTS_MAX];
static int32_t chain_count;
static int32_t large_count;
static collpri_t *prilist = NULL; static collpri_t *prilist = NULL;
static int numpri = 0; static int numpri = 0;
@ -1080,7 +1083,7 @@ wsncpy(wchar_t *s1, const wchar_t *s2, size_t n)
wchar_t *os1 = s1; wchar_t *os1 = s1;
n++; n++;
while (--n > 0 && (*s1++ = *s2++) != 0) while (--n > 0 && (*s1++ = htote(*s2++)) != 0)
continue; continue;
if (n > 0) if (n > 0)
while (--n > 0) while (--n > 0)
@ -1165,13 +1168,13 @@ dump_collate(void)
if (resolve_pri(pri_undefined[i]) == -1) { if (resolve_pri(pri_undefined[i]) == -1) {
set_pri(pri_undefined[i], -1, RESOLVED); set_pri(pri_undefined[i], -1, RESOLVED);
/* they collate at the end of everything else */ /* they collate at the end of everything else */
collinfo.undef_pri[i] = COLLATE_MAX_PRIORITY; collinfo.undef_pri[i] = htote(COLLATE_MAX_PRIORITY);
} }
collinfo.pri_count[i] = nweight[i]; collinfo.pri_count[i] = htote(nweight[i]);
} }
collinfo.pri_count[NUM_WT] = max_wide(); collinfo.pri_count[NUM_WT] = htote(max_wide());
collinfo.undef_pri[NUM_WT] = COLLATE_MAX_PRIORITY; collinfo.undef_pri[NUM_WT] = htote(COLLATE_MAX_PRIORITY);
collinfo.directive[NUM_WT] = DIRECTIVE_UNDEFINED; collinfo.directive[NUM_WT] = DIRECTIVE_UNDEFINED;
/* /*
@ -1180,19 +1183,20 @@ dump_collate(void)
for (i = 0; i <= UCHAR_MAX; i++) { for (i = 0; i <= UCHAR_MAX; i++) {
if ((cc = get_collchar(i, 0)) != NULL) { if ((cc = get_collchar(i, 0)) != NULL) {
for (j = 0; j < NUM_WT; j++) { for (j = 0; j < NUM_WT; j++) {
chars[i].pri[j] = get_weight(cc->ref[j], j); chars[i].pri[j] =
htote(get_weight(cc->ref[j], j));
} }
} else { } else {
for (j = 0; j < NUM_WT; j++) { for (j = 0; j < NUM_WT; j++) {
chars[i].pri[j] = chars[i].pri[j] =
get_weight(pri_undefined[j], j); htote(get_weight(pri_undefined[j], j));
} }
/* /*
* Per POSIX, for undefined characters, we * Per POSIX, for undefined characters, we
* also have to add a last item, which is the * also have to add a last item, which is the
* character code. * character code.
*/ */
chars[i].pri[NUM_WT] = i; chars[i].pri[NUM_WT] = htote(i);
} }
} }
@ -1203,7 +1207,7 @@ dump_collate(void)
collate_subst_t *st = NULL; collate_subst_t *st = NULL;
subst_t *temp; subst_t *temp;
RB_COUNT(temp, substs, &substs[i], n); RB_COUNT(temp, substs, &substs[i], n);
collinfo.subst_count[i] = n; subst_count[i] = n;
if ((st = calloc(n, sizeof(collate_subst_t))) == NULL) { if ((st = calloc(n, sizeof(collate_subst_t))) == NULL) {
fprintf(stderr, "out of memory"); fprintf(stderr, "out of memory");
return; return;
@ -1217,12 +1221,14 @@ dump_collate(void)
if (st[n].key != (n | COLLATE_SUBST_PRIORITY)) { if (st[n].key != (n | COLLATE_SUBST_PRIORITY)) {
INTERR; INTERR;
} }
st[n].key = htote(st[n].key);
for (j = 0; sb->ref[j]; j++) { for (j = 0; sb->ref[j]; j++) {
st[n].pri[j] = get_weight(sb->ref[j], i); st[n].pri[j] = htote(get_weight(sb->ref[j],
i));
} }
n++; n++;
} }
if (n != collinfo.subst_count[i]) if (n != subst_count[i])
INTERR; INTERR;
subst[i] = st; subst[i] = st;
} }
@ -1231,9 +1237,8 @@ dump_collate(void)
/* /*
* Chains, i.e. collating elements * Chains, i.e. collating elements
*/ */
RB_NUMNODES(collelem_t, elem_by_expand, &elem_by_expand, RB_NUMNODES(collelem_t, elem_by_expand, &elem_by_expand, chain_count);
collinfo.chain_count); chain = calloc(chain_count, sizeof(collate_chain_t));
chain = calloc(collinfo.chain_count, sizeof(collate_chain_t));
if (chain == NULL) { if (chain == NULL) {
fprintf(stderr, "out of memory"); fprintf(stderr, "out of memory");
return; return;
@ -1242,11 +1247,11 @@ dump_collate(void)
RB_FOREACH(ce, elem_by_expand, &elem_by_expand) { RB_FOREACH(ce, elem_by_expand, &elem_by_expand) {
(void) wsncpy(chain[n].str, ce->expand, COLLATE_STR_LEN); (void) wsncpy(chain[n].str, ce->expand, COLLATE_STR_LEN);
for (i = 0; i < NUM_WT; i++) { for (i = 0; i < NUM_WT; i++) {
chain[n].pri[i] = get_weight(ce->ref[i], i); chain[n].pri[i] = htote(get_weight(ce->ref[i], i));
} }
n++; n++;
} }
if (n != collinfo.chain_count) if (n != chain_count)
INTERR; INTERR;
/* /*
@ -1273,12 +1278,12 @@ dump_collate(void)
/* if undefined, then all priorities are */ /* if undefined, then all priorities are */
INTERR; INTERR;
} else { } else {
large[i].pri.pri[j] = pri; large[i].pri.pri[j] = htote(pri);
} }
} }
if (!undef) { if (!undef) {
large[i].val = cc->wc; large[i].val = htote(cc->wc);
collinfo.large_count = i++; large_count = i++;
} }
} }
@ -1288,6 +1293,11 @@ dump_collate(void)
/* Time to write the entire data set out */ /* Time to write the entire data set out */
for (i = 0; i < NUM_WT; i++)
collinfo.subst_count[i] = htote(subst_count[i]);
collinfo.chain_count = htote(chain_count);
collinfo.large_count = htote(large_count);
if ((wr_category(vers, COLLATE_STR_LEN, f) < 0) || if ((wr_category(vers, COLLATE_STR_LEN, f) < 0) ||
(wr_category(&collinfo, sizeof (collinfo), f) < 0) || (wr_category(&collinfo, sizeof (collinfo), f) < 0) ||
(wr_category(&chars, sizeof (chars), f) < 0)) { (wr_category(&chars, sizeof (chars), f) < 0)) {
@ -1295,16 +1305,16 @@ dump_collate(void)
} }
for (i = 0; i < NUM_WT; i++) { for (i = 0; i < NUM_WT; i++) {
sz = sizeof (collate_subst_t) * collinfo.subst_count[i]; sz = sizeof (collate_subst_t) * subst_count[i];
if (wr_category(subst[i], sz, f) < 0) { if (wr_category(subst[i], sz, f) < 0) {
return; return;
} }
} }
sz = sizeof (collate_chain_t) * collinfo.chain_count; sz = sizeof (collate_chain_t) * chain_count;
if (wr_category(chain, sz, f) < 0) { if (wr_category(chain, sz, f) < 0) {
return; return;
} }
sz = sizeof (collate_large_t) * collinfo.large_count; sz = sizeof (collate_large_t) * large_count;
if (wr_category(large, sz, f) < 0) { if (wr_category(large, sz, f) < 0) {
return; return;
} }

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright 2018 Nexenta Systems, Inc.
* Copyright 2012 Garrett D'Amore <garrett@damore.org> All rights reserved. * Copyright 2012 Garrett D'Amore <garrett@damore.org> All rights reserved.
* Copyright 2015 John Marino <draco@marino.st> * Copyright 2015 John Marino <draco@marino.st>
* *
@ -296,10 +296,16 @@ dump_ctype(void)
_FileRuneEntry *lo = NULL; _FileRuneEntry *lo = NULL;
_FileRuneEntry *up = NULL; _FileRuneEntry *up = NULL;
wchar_t wc; wchar_t wc;
uint32_t runetype_ext_nranges;
uint32_t maplower_ext_nranges;
uint32_t mapupper_ext_nranges;
(void) memset(&rl, 0, sizeof (rl)); (void) memset(&rl, 0, sizeof (rl));
runetype_ext_nranges = 0;
last_ct = NULL; last_ct = NULL;
maplower_ext_nranges = 0;
last_lo = NULL; last_lo = NULL;
mapupper_ext_nranges = 0;
last_up = NULL; last_up = NULL;
if ((f = open_category()) == NULL) if ((f = open_category()) == NULL)
@ -312,8 +318,8 @@ dump_ctype(void)
* Initialize the identity map. * Initialize the identity map.
*/ */
for (wc = 0; (unsigned)wc < _CACHED_RUNES; wc++) { for (wc = 0; (unsigned)wc < _CACHED_RUNES; wc++) {
rl.maplower[wc] = wc; rl.maplower[wc] = htote(wc);
rl.mapupper[wc] = wc; rl.mapupper[wc] = htote(wc);
} }
RB_FOREACH(ctn, ctypes, &ctypes) { RB_FOREACH(ctn, ctypes, &ctypes) {
@ -399,39 +405,39 @@ dump_ctype(void)
* upper/lower case, then we identity map it. * upper/lower case, then we identity map it.
*/ */
if ((unsigned)wc < _CACHED_RUNES) { if ((unsigned)wc < _CACHED_RUNES) {
rl.runetype[wc] = ctn->ctype; rl.runetype[wc] = htote(ctn->ctype);
if (ctn->tolower) if (ctn->tolower)
rl.maplower[wc] = ctn->tolower; rl.maplower[wc] = htote(ctn->tolower);
if (ctn->toupper) if (ctn->toupper)
rl.mapupper[wc] = ctn->toupper; rl.mapupper[wc] = htote(ctn->toupper);
continue; continue;
} }
if ((last_ct != NULL) && (last_ct->ctype == ctn->ctype) && if ((last_ct != NULL) && (last_ct->ctype == ctn->ctype) &&
(last_ct->wc + 1 == wc)) { (last_ct->wc + 1 == wc)) {
ct[rl.runetype_ext_nranges-1].max = wc; ct[runetype_ext_nranges - 1].max = htote(wc);
} else { } else {
rl.runetype_ext_nranges++; runetype_ext_nranges++;
ct = realloc(ct, ct = realloc(ct, sizeof (*ct) * runetype_ext_nranges);
sizeof (*ct) * rl.runetype_ext_nranges); ct[runetype_ext_nranges - 1].min = htote(wc);
ct[rl.runetype_ext_nranges - 1].min = wc; ct[runetype_ext_nranges - 1].max = htote(wc);
ct[rl.runetype_ext_nranges - 1].max = wc; ct[runetype_ext_nranges - 1].map =
ct[rl.runetype_ext_nranges - 1].map = ctn->ctype; htote(ctn->ctype);
} }
last_ct = ctn; last_ct = ctn;
if (ctn->tolower == 0) { if (ctn->tolower == 0) {
last_lo = NULL; last_lo = NULL;
} else if ((last_lo != NULL) && } else if ((last_lo != NULL) &&
(last_lo->tolower + 1 == ctn->tolower)) { (last_lo->tolower + 1 == ctn->tolower)) {
lo[rl.maplower_ext_nranges-1].max = wc; lo[maplower_ext_nranges - 1].max = htote(wc);
last_lo = ctn; last_lo = ctn;
} else { } else {
rl.maplower_ext_nranges++; maplower_ext_nranges++;
lo = realloc(lo, lo = realloc(lo, sizeof (*lo) * maplower_ext_nranges);
sizeof (*lo) * rl.maplower_ext_nranges); lo[maplower_ext_nranges - 1].min = htote(wc);
lo[rl.maplower_ext_nranges - 1].min = wc; lo[maplower_ext_nranges - 1].max = htote(wc);
lo[rl.maplower_ext_nranges - 1].max = wc; lo[maplower_ext_nranges - 1].map =
lo[rl.maplower_ext_nranges - 1].map = ctn->tolower; htote(ctn->tolower);
last_lo = ctn; last_lo = ctn;
} }
@ -439,23 +445,26 @@ dump_ctype(void)
last_up = NULL; last_up = NULL;
} else if ((last_up != NULL) && } else if ((last_up != NULL) &&
(last_up->toupper + 1 == ctn->toupper)) { (last_up->toupper + 1 == ctn->toupper)) {
up[rl.mapupper_ext_nranges-1].max = wc; up[mapupper_ext_nranges-1].max = htote(wc);
last_up = ctn; last_up = ctn;
} else { } else {
rl.mapupper_ext_nranges++; mapupper_ext_nranges++;
up = realloc(up, up = realloc(up, sizeof (*up) * mapupper_ext_nranges);
sizeof (*up) * rl.mapupper_ext_nranges); up[mapupper_ext_nranges - 1].min = htote(wc);
up[rl.mapupper_ext_nranges - 1].min = wc; up[mapupper_ext_nranges - 1].max = htote(wc);
up[rl.mapupper_ext_nranges - 1].max = wc; up[mapupper_ext_nranges - 1].map =
up[rl.mapupper_ext_nranges - 1].map = ctn->toupper; htote(ctn->toupper);
last_up = ctn; last_up = ctn;
} }
} }
rl.runetype_ext_nranges = htote(runetype_ext_nranges);
rl.maplower_ext_nranges = htote(maplower_ext_nranges);
rl.mapupper_ext_nranges = htote(mapupper_ext_nranges);
if ((wr_category(&rl, sizeof (rl), f) < 0) || if ((wr_category(&rl, sizeof (rl), f) < 0) ||
(wr_category(ct, sizeof (*ct) * rl.runetype_ext_nranges, f) < 0) || (wr_category(ct, sizeof (*ct) * runetype_ext_nranges, f) < 0) ||
(wr_category(lo, sizeof (*lo) * rl.maplower_ext_nranges, f) < 0) || (wr_category(lo, sizeof (*lo) * maplower_ext_nranges, f) < 0) ||
(wr_category(up, sizeof (*up) * rl.mapupper_ext_nranges, f) < 0)) { (wr_category(up, sizeof (*up) * mapupper_ext_nranges, f) < 0)) {
return; return;
} }

View File

@ -33,7 +33,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd July 28, 2015 .Dd October 18, 2018
.Dt LOCALEDEF 1 .Dt LOCALEDEF 1
.Os .Os
.Sh NAME .Sh NAME
@ -41,7 +41,7 @@
.Nd define locale environment .Nd define locale environment
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl cDUv .Op Fl bcDlUv
.Op Fl f Ar charmap .Op Fl f Ar charmap
.Op Fl i Ar sourcefile .Op Fl i Ar sourcefile
.Op Fl u Ar codeset .Op Fl u Ar codeset
@ -84,6 +84,8 @@ Defines the format and values of affirmative and negative responses.
.Pp .Pp
The following options are supported: The following options are supported:
.Bl -tag -width indent .Bl -tag -width indent
.It Fl b
Use big-endian byte order for output.
.It Fl c .It Fl c
Creates permanent output even if warning messages have been issued. Creates permanent output even if warning messages have been issued.
.It Fl D .It Fl D
@ -112,6 +114,8 @@ option is not present, the default character mapping will be used.
The path name of a file containing the source definitions. The path name of a file containing the source definitions.
If this option is not present, source definitions will be read from If this option is not present, source definitions will be read from
standard input. standard input.
.It Fl l
Use little-endian byte order for output.
.It Fl u Ar codeset .It Fl u Ar codeset
Specifies the name of a codeset used as the target mapping of character symbols Specifies the name of a codeset used as the target mapping of character symbols
and collating element symbols whose encoding values are defined in terms of the and collating element symbols whose encoding values are defined in terms of the

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright 2018 Nexenta Systems, Inc.
* Copyright 2015 John Marino <draco@marino.st> * Copyright 2015 John Marino <draco@marino.st>
* *
* This source code is derived from the illumos localedef command, and * This source code is derived from the illumos localedef command, and
@ -34,11 +34,13 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h> #include <string.h>
#include <libgen.h> #include <libgen.h>
#include <stddef.h> #include <stddef.h>
@ -54,6 +56,7 @@ __FBSDID("$FreeBSD$");
#endif #endif
static int bsd = 0; static int bsd = 0;
static int byteorder = 0;
int verbose = 0; int verbose = 0;
int undefok = 0; int undefok = 0;
int warnok = 0; int warnok = 0;
@ -221,6 +224,18 @@ wr_category(void *buf, size_t sz, FILE *f)
return (0); return (0);
} }
uint32_t
htote(uint32_t arg)
{
if (byteorder == 4321)
return (htobe32(arg));
else if (byteorder == 1234)
return (htole32(arg));
else
return (arg);
}
int yyparse(void); int yyparse(void);
static void static void
@ -229,7 +244,9 @@ usage(void)
(void) fprintf(stderr, "Usage: localedef [options] localename\n"); (void) fprintf(stderr, "Usage: localedef [options] localename\n");
(void) fprintf(stderr, "[options] are:\n"); (void) fprintf(stderr, "[options] are:\n");
(void) fprintf(stderr, " -D : BSD-style output\n"); (void) fprintf(stderr, " -D : BSD-style output\n");
(void) fprintf(stderr, " -b : big-endian output\n");
(void) fprintf(stderr, " -c : ignore warnings\n"); (void) fprintf(stderr, " -c : ignore warnings\n");
(void) fprintf(stderr, " -l : little-endian output\n");
(void) fprintf(stderr, " -v : verbose output\n"); (void) fprintf(stderr, " -v : verbose output\n");
(void) fprintf(stderr, " -U : ignore undefined symbols\n"); (void) fprintf(stderr, " -U : ignore undefined symbols\n");
(void) fprintf(stderr, " -f charmap : use given charmap file\n"); (void) fprintf(stderr, " -f charmap : use given charmap file\n");
@ -260,11 +277,17 @@ main(int argc, char **argv)
(void) setlocale(LC_ALL, ""); (void) setlocale(LC_ALL, "");
while ((c = getopt(argc, argv, "w:i:cf:u:vUD")) != -1) { while ((c = getopt(argc, argv, "blw:i:cf:u:vUD")) != -1) {
switch (c) { switch (c) {
case 'D': case 'D':
bsd = 1; bsd = 1;
break; break;
case 'b':
case 'l':
if (byteorder != 0)
usage();
byteorder = c == 'b' ? 4321 : 1234;
break;
case 'v': case 'v':
verbose++; verbose++;
break; break;

View File

@ -1,5 +1,5 @@
/*- /*-
* Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright 2018 Nexenta Systems, Inc.
* Copyright 2015 John Marino <draco@marino.st> * Copyright 2015 John Marino <draco@marino.st>
* *
* This source code is derived from the illumos localedef command, and * This source code is derived from the illumos localedef command, and
@ -75,6 +75,8 @@ void add_wcs(wchar_t);
void add_tok(int); void add_tok(int);
wchar_t *get_wcs(void); wchar_t *get_wcs(void);
uint32_t htote(uint32_t);
/* charmap.c - CHARMAP handling */ /* charmap.c - CHARMAP handling */
void init_charmap(void); void init_charmap(void);
void add_charmap(const char *, int); void add_charmap(const char *, int);