diff options
author | Thomas Munro <tmunro@FreeBSD.org> | 2020-11-08 02:50:34 +0000 |
---|---|---|
committer | Thomas Munro <tmunro@FreeBSD.org> | 2020-11-08 02:50:34 +0000 |
commit | cc7edd258c2564fe9e3c4a0dc839acc4a71caff9 (patch) | |
tree | 713e7f140bcc509d153f6843f0c0c4e93cf43991 /usr.bin | |
parent | d2799054f0d29c33a1f2ab87ee4d88970ec36d91 (diff) | |
download | src-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.h | 3 | ||||
-rw-r--r-- | usr.bin/localedef/collate.c | 13 | ||||
-rw-r--r-- | usr.bin/localedef/localedef.1 | 11 | ||||
-rw-r--r-- | usr.bin/localedef/localedef.c | 13 | ||||
-rw-r--r-- | usr.bin/localedef/localedef.h | 2 |
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); |