Page MenuHomeFreeBSD

D17166.id48047.diff
No OneTemporary

D17166.id48047.diff

Index: include/xlocale/_locale.h
===================================================================
--- include/xlocale/_locale.h
+++ include/xlocale/_locale.h
@@ -54,6 +54,7 @@
void freelocale(locale_t loc);
locale_t newlocale(int mask, const char *locale, locale_t base);
const char *querylocale(int mask, locale_t loc);
+const char *querylocaleversion(int mask, locale_t loc);
locale_t uselocale(locale_t loc);
#endif /* _XLOCALE_LOCALE_H */
Index: lib/libc/locale/Symbol.map
===================================================================
--- lib/libc/locale/Symbol.map
+++ lib/libc/locale/Symbol.map
@@ -209,6 +209,11 @@
mbrtoc32_l;
};
+/* TODO: Change to FBSD_1.6 once it has been defined, for FreeBSD 13. */
+FBSD_1.5 {
+ querylocaleversion;
+};
+
FBSDprivate_1.0 {
_PathLocale;
__detect_path_locale;
Index: lib/libc/locale/collate.h
===================================================================
--- lib/libc/locale/collate.h
+++ lib/libc/locale/collate.h
@@ -53,6 +53,8 @@
#endif
#define COLLATE_STR_LEN 24 /* should be 64-bit multiple */
+
+#define COLLATE_FORMAT_VERSION_LEN 12
#define COLLATE_VERSION "BSD 1.0\n"
#define COLLATE_MAX_PRIORITY (0x7fffffff) /* max signed value */
@@ -69,7 +71,8 @@
/*
* The collate file format is as follows:
*
- * char version[COLLATE_STR_LEN]; // must be COLLATE_VERSION
+ * char format_version[COLLATE_FORMAT_VERSION_LEN]; // must be COLLATE_VERSION
+ * char data_version[XLOCALE_VERSION_LEN]; // NUL-terminated, may be empty
* collate_info_t info; // see below, includes padding
* collate_char_pri_t char_data[256]; // 8 bit char values
* collate_subst_t subst[*]; // 0 or more substitutions
Index: lib/libc/locale/collate.c
===================================================================
--- lib/libc/locale/collate.c
+++ lib/libc/locale/collate.c
@@ -150,12 +150,14 @@
return (_LDP_ERROR);
}
- if (strncmp(TMP, COLLATE_VERSION, COLLATE_STR_LEN) != 0) {
+ if (strncmp(TMP, COLLATE_VERSION, COLLATE_FORMAT_VERSION_LEN) != 0) {
(void) munmap(map, sbuf.st_size);
errno = EINVAL;
return (_LDP_ERROR);
}
- TMP += COLLATE_STR_LEN;
+ TMP += COLLATE_FORMAT_VERSION_LEN;
+ strlcpy(table->header.version, TMP, sizeof(table->header.version));
+ TMP += XLOCALE_VERSION_LEN;
info = (void *)TMP;
TMP += sizeof (*info);
Index: lib/libc/locale/querylocale.3
===================================================================
--- lib/libc/locale/querylocale.3
+++ lib/libc/locale/querylocale.3
@@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 3, 2013
+.Dd September 3, 2018
.Dt QUERYLOCALE 3
.Os
.Sh NAME
@@ -50,5 +50,6 @@
.Xr freelocale 3 ,
.Xr localeconv 3 ,
.Xr newlocale 3 ,
+.Xr querylocaleversion 3 ,
.Xr uselocale 3 ,
.Xr xlocale 3
Index: lib/libc/locale/querylocaleversion.3
===================================================================
--- /dev/null
+++ lib/libc/locale/querylocaleversion.3
@@ -0,0 +1,52 @@
+.\" Copyright (c) 2018 Thomas Munro
+.\"
+.\" 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 REGENTS 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 REGENTS 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$
+.\"
+.Dd September 3, 2018
+.Dt QUERYLOCALEVERSION 3
+.Os
+.Sh NAME
+.Nm querylocaleversion
+.Nd Look up the locale version for a specified category
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In locale.h
+.Ft const char *
+.Fn querylocaleversion "int mask" "locale_t locale"
+.Sh DESCRIPTION
+Returns the version of the locale definition for the category specified by
+.Fa mask .
+The possible values for the mask are the same as those in
+.Xr newlocale 3 .
+Currently the only component that can provide version information is
+.Dv LC_COLLATE_MASK .
+The version string can be used to check if the collating order of the
+given locale might have changed due to an operating system update.
+If no version information is available, a pointer to an empty string is
+returned. If more than one bit in the mask is set, the returned value is
+undefined.
+.Sh SEE ALSO
+.Xr localedef 1 ,
+.Xr querylocale 3
Index: lib/libc/locale/xlocale.c
===================================================================
--- lib/libc/locale/xlocale.c
+++ lib/libc/locale/xlocale.c
@@ -231,6 +231,8 @@
if (new->components[type]) {
strncpy(new->components[type]->locale, src->locale,
ENCODING_LEN);
+ strncpy(new->components[type]->version, src->version,
+ XLOCALE_VERSION_LEN);
}
} else if (base->components[type]) {
new->components[type] = xlocale_retain(base->components[type]);
@@ -355,6 +357,20 @@
return ("C");
}
+/*
+ * Returns the version of the locale for a particular component of a locale_t.
+ */
+const char *querylocaleversion(int mask, locale_t loc)
+{
+ int type = ffs(mask) - 1;
+ FIX_LOCALE(loc);
+ if (type >= XLC_LAST)
+ return (NULL);
+ if (loc->components[type])
+ return (loc->components[type]->version);
+ return ("");
+}
+
/*
* Installs the specified locale_t as this thread's locale.
*/
Index: lib/libc/locale/xlocale_private.h
===================================================================
--- lib/libc/locale/xlocale_private.h
+++ lib/libc/locale/xlocale_private.h
@@ -91,6 +91,9 @@
/** Function used to destroy this component, if one is required*/
void(*destructor)(void*);
};
+
+#define XLOCALE_VERSION_LEN 12
+
/**
* Header for a locale component. All locale components must begin with this
* header.
@@ -99,6 +102,8 @@
struct xlocale_refcounted header;
/** Name of the locale used for this component. */
char locale[ENCODING_LEN+1];
+ /** Version of the data for this component. */
+ char version[XLOCALE_VERSION_LEN];
};
/**
Index: usr.bin/localedef/collate.c
===================================================================
--- usr.bin/localedef/collate.c
+++ usr.bin/localedef/collate.c
@@ -1113,7 +1113,8 @@
collelem_t *ce;
collchar_t *cc;
subst_t *sb;
- char vers[COLLATE_STR_LEN];
+ char format_version[COLLATE_FORMAT_VERSION_LEN];
+ char data_version[XLOCALE_VERSION_LEN];
collate_char_t chars[UCHAR_MAX + 1];
collate_large_t *large;
collate_subst_t *subst[COLL_WEIGHTS_MAX];
@@ -1154,8 +1155,12 @@
}
(void) memset(&chars, 0, sizeof (chars));
- (void) memset(vers, 0, COLLATE_STR_LEN);
- (void) strlcpy(vers, COLLATE_VERSION, sizeof (vers));
+ (void) memset(format_version, 0, COLLATE_FORMAT_VERSION_LEN);
+ (void) strlcpy(format_version, COLLATE_VERSION,
+ sizeof (format_version));
+ (void) memset(data_version, 0, XLOCALE_VERSION_LEN);
+ if (version)
+ (void) strlcpy(data_version, version, sizeof (data_version));
/*
* We need to make sure we arrange for the UNDEFINED field
@@ -1288,7 +1293,8 @@
/* Time to write the entire data set out */
- if ((wr_category(vers, COLLATE_STR_LEN, f) < 0) ||
+ if ((wr_category(format_version, COLLATE_FORMAT_VERSION_LEN, f) < 0) ||
+ (wr_category(data_version, XLOCALE_VERSION_LEN, f) < 0) ||
(wr_category(&collinfo, sizeof (collinfo), f) < 0) ||
(wr_category(&chars, sizeof (chars), f) < 0)) {
return;
Index: usr.bin/localedef/localedef.h
===================================================================
--- usr.bin/localedef/localedef.h
+++ usr.bin/localedef/localedef.h
@@ -53,6 +53,8 @@
extern int warnok;
extern int warnings;
+extern char *version;
+
int yylex(void);
void yyerror(const char *);
_Noreturn void errf(const char *, ...) __printflike(1, 2);
Index: usr.bin/localedef/localedef.1
===================================================================
--- usr.bin/localedef/localedef.1
+++ usr.bin/localedef/localedef.1
@@ -33,7 +33,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 28, 2015
+.Dd September 3, 2018
.Dt LOCALEDEF 1
.Os
.Sh NAME
@@ -131,6 +131,12 @@
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 source collation data.
+This string can be retrieved using
+.Xr querylocaleversion 3 ,
+and is intended to allow applications to detect when the definition of a
+collation changes.
.El
.Pp
The following operands are required:
@@ -194,6 +200,7 @@
.Xr locale 1 ,
.Xr iconv_open 3 ,
.Xr nl_langinfo 3 ,
+.Xr querylocaleversion 3 ,
.Xr strftime 3 ,
.Xr environ 7
.Sh WARNINGS
Index: usr.bin/localedef/localedef.c
===================================================================
--- usr.bin/localedef/localedef.c
+++ usr.bin/localedef/localedef.c
@@ -46,6 +46,7 @@
#include <limits.h>
#include <locale.h>
#include <dirent.h>
+#include "collate.h"
#include "localedef.h"
#include "parser.h"
@@ -59,6 +60,7 @@
int warnok = 0;
static char *locname = NULL;
static char locpath[PATH_MAX];
+char *version = NULL;
const char *
category_name(void)
@@ -236,6 +238,7 @@
(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);
}
@@ -260,7 +263,7 @@
(void) setlocale(LC_ALL, "");
- while ((c = getopt(argc, argv, "w:i:cf:u:vUD")) != -1) {
+ while ((c = getopt(argc, argv, "w:i:cf:u:vUDV:")) != -1) {
switch (c) {
case 'D':
bsd = 1;
@@ -289,6 +292,9 @@
case '?':
usage();
break;
+ case 'V':
+ version = optarg;
+ break;
}
}
@@ -300,6 +306,11 @@
(void) printf("Processing locale %s.\n", locname);
}
+ if (version && strlen(version) >= XLOCALE_VERSION_LEN) {
+ (void) fprintf(stderr, "Version string too long.\n");
+ exit(1);
+ }
+
if (cfname) {
if (verbose)
(void) printf("Loading charmap %s.\n", cfname);

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 19, 3:46 AM (9 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29943450
Default Alt Text
D17166.id48047.diff (10 KB)

Event Timeline