Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F138069341
D17166.id48068.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D17166.id48068.diff
View Options
Index: include/xlocale/_locale.h
===================================================================
--- include/xlocale/_locale.h
+++ include/xlocale/_locale.h
@@ -43,6 +43,7 @@
#define LC_MESSAGES_MASK (1<<5)
#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | \
LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
+#define LC_VERSION_MASK (1<<6)
#define LC_GLOBAL_LOCALE ((locale_t)-1)
#ifndef _LOCALE_T_DEFINED
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,12 +27,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 3, 2013
+.Dd September 15, 2018
.Dt QUERYLOCALE 3
.Os
.Sh NAME
.Nm querylocale
-.Nd Look up the locale name for a specified category
+.Nd Look up the locale name or version for a specified category
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
@@ -40,11 +40,22 @@
.Ft const char *
.Fn querylocale "int mask" "locale_t locale"
.Sh DESCRIPTION
-Returns the name of the locale for the category specified by
+Returns the name or version of the locale for the category specified by
.Fa mask .
This possible values for the mask are the same as those in
-.Xr newlocale 3 .
-If more than one bit in the mask is set, the returned value is undefined.
+.Xr newlocale 3 ,
+when requesting the locale name.
+Specify the bitwise OR of
+.Fa LC_VERSION_MASK
+and another mask value to request a version string.
+Version strings can be compared to detect changes to the locale's
+definition.
+Currently, version information is only available for
+.Fa LC_COLLATE_MASK ,
+and an empty string is returned for other categories.
+If more than one bit in the mask is set, not counting
+.Fa LC_VERSION_MASK ,
+the returned value is undefined.
.Sh SEE ALSO
.Xr duplocale 3 ,
.Xr freelocale 3 ,
@@ -52,3 +63,13 @@
.Xr newlocale 3 ,
.Xr uselocale 3 ,
.Xr xlocale 3
+.Sh HISTORY
+The
+.Fn querylocale
+function first appeared in
+.Fx 9.1 ,
+and is based on the function of the same name in Darwin.
+The ability to ask for a version with
+.Fa LC_VERSION_MASK
+first appeared in
+.Fx 13.0 .
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]);
@@ -342,17 +344,24 @@
}
/*
- * Returns the name of the locale for a particular component of a locale_t.
+ * Returns the name or version of the locale for a particular component of a
+ * locale_t.
*/
const char *querylocale(int mask, locale_t loc)
{
- int type = ffs(mask) - 1;
+ int type = ffs(mask & ~LC_VERSION_MASK) - 1;
FIX_LOCALE(loc);
if (type >= XLC_LAST)
return (NULL);
- if (loc->components[type])
- return (loc->components[type]->locale);
- return ("C");
+ if (mask & LC_VERSION_MASK) {
+ if (loc->components[type])
+ return (loc->components[type]->version);
+ return ("");
+ } else {
+ if (loc->components[type])
+ return (loc->components[type]->locale);
+ return ("C");
+ }
}
/*
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 15, 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 querylocale 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 querylocale 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
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 29, 3:34 PM (12 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26343396
Default Alt Text
D17166.id48068.diff (9 KB)
Attached To
Mode
D17166: Add a way to get version information from querylocale(3).
Attached
Detach File
Event Timeline
Log In to Comment