diff --git a/usr.bin/localedef/charmap.c b/usr.bin/localedef/charmap.c --- a/usr.bin/localedef/charmap.c +++ b/usr.bin/localedef/charmap.c @@ -236,7 +236,7 @@ const charmap_t *c1 = n1; const charmap_t *c2 = n2; - return ((c1->wc < c2->wc) ? -1 : (c1->wc > c2->wc) ? 1 : 0); + return (wchar_cmp(c1->wc, c2->wc)); } void diff --git a/usr.bin/localedef/collate.c b/usr.bin/localedef/collate.c --- a/usr.bin/localedef/collate.c +++ b/usr.bin/localedef/collate.c @@ -422,7 +422,7 @@ wchar_t k1 = ((const collchar_t *)n1)->wc; wchar_t k2 = ((const collchar_t *)n2)->wc; - return (k1 < k2 ? -1 : k1 > k2 ? 1 : 0); + return (wchar_cmp(k1, k2)); } RB_GENERATE_STATIC(collchars, collchar, entry, collchar_compare); diff --git a/usr.bin/localedef/ctype.c b/usr.bin/localedef/ctype.c --- a/usr.bin/localedef/ctype.c +++ b/usr.bin/localedef/ctype.c @@ -93,7 +93,7 @@ const ctype_node_t *c1 = n1; const ctype_node_t *c2 = n2; - return (c1->wc < c2->wc ? -1 : c1->wc > c2->wc ? 1 : 0); + return (wchar_cmp(c1->wc, c2->wc)); } void diff --git a/usr.bin/localedef/localedef.h b/usr.bin/localedef/localedef.h --- a/usr.bin/localedef/localedef.h +++ b/usr.bin/localedef/localedef.h @@ -38,6 +38,7 @@ #include #include #include +#include extern int com_char; extern int esc_char; @@ -173,5 +174,19 @@ const char *get_wide_encoding(void); int max_wide(void); +/* + * A helper function to compare wide characters when sorting. Forcibly cast to + * an unsigned type to help ensure that output is consistent no matter the + * signedness of wchar_t. + */ +static inline int +wchar_cmp(const wchar_t a, const wchar_t b) +{ + return ((uint32_t)a < (uint32_t)b ? -1 : + ((uint32_t)a > (uint32_t)b ? 1 : 0)); +} +_Static_assert(sizeof(wchar_t) == sizeof(uint32_t), + "wchar_t must be 32 bits wide"); + //#define _(x) gettext(x) #define INTERR fprintf(stderr,"internal fault (%s:%d)\n", __FILE__, __LINE__)