summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorThomas Munro <tmunro@FreeBSD.org>2020-11-08 02:50:34 +0000
committerThomas Munro <tmunro@FreeBSD.org>2020-11-08 02:50:34 +0000
commitcc7edd258c2564fe9e3c4a0dc839acc4a71caff9 (patch)
tree713e7f140bcc509d153f6843f0c0c4e93cf43991 /usr.bin
parentd2799054f0d29c33a1f2ab87ee4d88970ec36d91 (diff)
downloadsrc-test2-cc7edd258c2564fe9e3c4a0dc839acc4a71caff9.tar.gz
src-test2-cc7edd258c2564fe9e3c4a0dc839acc4a71caff9.zip
Add collation version support to querylocale(3).
Provide a way to ask for an opaque version string for a locale_t, so that potential changes in sort order can be detected. Similar to ICU's ucol_getVersion() and Windows' GetNLSVersionEx(), this API is intended to allow databases to detect when text order-based indexes might need to be rebuilt. The CLDR version is extracted from CLDR source data by the Makefile under tools/tools/locale, written into the machine-generated Makefile under shared/colldef, passed to localedef -V, and then written into LC_COLLATE file headers. The initial version is 34.0. tools/tools/locale was recently updated to pull down 35.0, but the output hasn't been committed under share/colldef yet, so that will provide the first observable change when it happens. Other versioning schemes are possible in future, because the format is unspecified. Reviewed by: bapt, 0mp, kib, yuripv (albeit a long time ago) Differential Revision: https://reviews.freebsd.org/D17166
Notes
Notes: svn path=/head/; revision=367476
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/localedef/bootstrap/bootstrap_xlocale_private.h3
-rw-r--r--usr.bin/localedef/collate.c13
-rw-r--r--usr.bin/localedef/localedef.111
-rw-r--r--usr.bin/localedef/localedef.c13
-rw-r--r--usr.bin/localedef/localedef.h2
5 files changed, 36 insertions, 6 deletions
diff --git a/usr.bin/localedef/bootstrap/bootstrap_xlocale_private.h b/usr.bin/localedef/bootstrap/bootstrap_xlocale_private.h
index 243139ff09b8..48203aaa0f61 100644
--- a/usr.bin/localedef/bootstrap/bootstrap_xlocale_private.h
+++ b/usr.bin/localedef/bootstrap/bootstrap_xlocale_private.h
@@ -51,4 +51,7 @@ struct localedef_bootstrap_xlocale_component {
char unused;
};
+/* This must agree with the definition in xlocale_private.h. */
+#define XLOCALE_DEF_VERSION_LEN 12
+
#endif /* _LOCALDEF_BOOTSTRAP_XLOCALE_PRIVATE_H */
diff --git a/usr.bin/localedef/collate.c b/usr.bin/localedef/collate.c
index 3e3c7539dd8d..0bed283b6aab 100644
--- a/usr.bin/localedef/collate.c
+++ b/usr.bin/localedef/collate.c
@@ -1119,7 +1119,8 @@ dump_collate(void)
collelem_t *ce;
collchar_t *cc;
subst_t *sb;
- char vers[COLLATE_STR_LEN];
+ char fmt_version[COLLATE_FMT_VERSION_LEN];
+ char def_version[XLOCALE_DEF_VERSION_LEN];
collate_char_t chars[UCHAR_MAX + 1];
collate_large_t *large;
collate_subst_t *subst[COLL_WEIGHTS_MAX];
@@ -1160,8 +1161,11 @@ dump_collate(void)
}
(void) memset(&chars, 0, sizeof (chars));
- (void) memset(vers, 0, COLLATE_STR_LEN);
- (void) strlcpy(vers, COLLATE_VERSION, sizeof (vers));
+ (void) memset(fmt_version, 0, COLLATE_FMT_VERSION_LEN);
+ (void) strlcpy(fmt_version, COLLATE_FMT_VERSION, sizeof (fmt_version));
+ (void) memset(def_version, 0, XLOCALE_DEF_VERSION_LEN);
+ if (version)
+ (void) strlcpy(def_version, version, sizeof (def_version));
/*
* We need to make sure we arrange for the UNDEFINED field
@@ -1301,7 +1305,8 @@ dump_collate(void)
collinfo.chain_count = htote(chain_count);
collinfo.large_count = htote(large_count);
- if ((wr_category(vers, COLLATE_STR_LEN, f) < 0) ||
+ if ((wr_category(fmt_version, COLLATE_FMT_VERSION_LEN, f) < 0) ||
+ (wr_category(def_version, XLOCALE_DEF_VERSION_LEN, f) < 0) ||
(wr_category(&collinfo, sizeof (collinfo), f) < 0) ||
(wr_category(&chars, sizeof (chars), f) < 0)) {
return;
diff --git a/usr.bin/localedef/localedef.1 b/usr.bin/localedef/localedef.1
index 126193caebb3..f67672f9a0c6 100644
--- a/usr.bin/localedef/localedef.1
+++ b/usr.bin/localedef/localedef.1
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 18, 2018
+.Dd November 8, 2020
.Dt LOCALEDEF 1
.Os
.Sh NAME
@@ -135,6 +135,14 @@ If not supplied, then default screen widths will be assumed, which will
generally not account for East Asian encodings requiring more than a single
character cell to display, nor for combining or accent marks that occupy
no additional screen width.
+.It Fl V Ar version
+Specifies a version string describing the version of the locale definition.
+This string can be retrieved with
+.Xr querylocale 3 ,
+and is intended to allow applications to detect locale definition changes.
+Currently it is stored only for the
+.Sy LC_COLLATE
+category.
.El
.Pp
The following operands are required:
@@ -198,6 +206,7 @@ If an error is detected, no permanent output will be created.
.Xr locale 1 ,
.Xr iconv_open 3 ,
.Xr nl_langinfo 3 ,
+.Xr querylocale 3 ,
.Xr strftime 3 ,
.Xr environ 7
.Sh WARNINGS
diff --git a/usr.bin/localedef/localedef.c b/usr.bin/localedef/localedef.c
index 40b4ee58367f..390ebf8784ef 100644
--- a/usr.bin/localedef/localedef.c
+++ b/usr.bin/localedef/localedef.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <limits.h>
#include <locale.h>
#include <dirent.h>
+#include "collate.h"
#include "localedef.h"
#include "parser.h"
@@ -62,6 +63,7 @@ int undefok = 0;
int warnok = 0;
static char *locname = NULL;
static char locpath[PATH_MAX];
+char *version = NULL;
const char *
category_name(void)
@@ -253,6 +255,7 @@ usage(void)
(void) fprintf(stderr, " -u encoding : assume encoding\n");
(void) fprintf(stderr, " -w widths : use screen widths file\n");
(void) fprintf(stderr, " -i locsrc : source file for locale\n");
+ (void) fprintf(stderr, " -V version : version string for locale\n");
exit(4);
}
@@ -279,7 +282,7 @@ main(int argc, char **argv)
(void) setlocale(LC_ALL, "");
- while ((c = getopt(argc, argv, "blw:i:cf:u:vUD")) != -1) {
+ while ((c = getopt(argc, argv, "blw:i:cf:u:vUDV:")) != -1) {
switch (c) {
case 'D':
bsd = 1;
@@ -314,6 +317,9 @@ main(int argc, char **argv)
case '?':
usage();
break;
+ case 'V':
+ version = optarg;
+ break;
}
}
@@ -325,6 +331,11 @@ main(int argc, char **argv)
(void) printf("Processing locale %s.\n", locname);
}
+ if (version && strlen(version) >= XLOCALE_DEF_VERSION_LEN) {
+ (void) fprintf(stderr, "Version string too long.\n");
+ exit(1);
+ }
+
if (cfname) {
if (verbose)
(void) printf("Loading charmap %s.\n", cfname);
diff --git a/usr.bin/localedef/localedef.h b/usr.bin/localedef/localedef.h
index b8c831f1d38d..ba95e27701d8 100644
--- a/usr.bin/localedef/localedef.h
+++ b/usr.bin/localedef/localedef.h
@@ -55,6 +55,8 @@ extern int undefok; /* mostly ignore undefined symbols */
extern int warnok;
extern int warnings;
+extern char *version;
+
int yylex(void);
void yyerror(const char *);
_Noreturn void errf(const char *, ...) __printflike(1, 2);