[tz] [PROPOSED 5/5] Fix bug in zic’s abbreviation algorithm
Paul Eggert
eggert at cs.ucla.edu
Wed May 24 05:19:24 UTC 2017
For example, when the context is weekdays, the old, buggy code
rejected both "Sa" and "Su" as ambiguous abbreviations.
* NEWS: Document this.
* zic.c (ciprefix): New function.
(byword): Use it to fix bug in abbreviation determination.
Warn if an unambiguous abbreviation is not portable to
pre-2017c zic.
---
NEWS | 7 +++++++
zic.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/NEWS b/NEWS
index 1af7b69..d22d561 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,13 @@ Unreleased, experimental changes
in civil timekeeping. (Thanks to Robert Elz and Bradley White for
noticing glitches in the code that uncovered this problem.)
+ zic now allows unambiguous abbreviations like "Sa" and "Su" for
+ weekdays; formerly it rejected them due to a bug. Conversely, zic
+ no longer considers non-prefixes to be abbreviations; for example,
+ it no longer accepts "lF" as an abbreviation for "lastFriday".
+ Also, zic warns about the undocumented usage with a "last-"
+ prefix, e.g., "last-Fri".
+
'make BACKWARD=' now suppresses backward-compatibility names
like 'US/Pacific' that are defined in the 'backward' and
'pacificnew' files.
diff --git a/zic.c b/zic.c
index f57d346..c2737e1 100644
--- a/zic.c
+++ b/zic.c
@@ -2901,6 +2901,19 @@ itsabbr(register const char *abbr, register const char *word)
return true;
}
+/* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */
+
+static bool
+ciprefix(char const *abbr, char const *word)
+{
+ do
+ if (!*abbr)
+ return true;
+ while (lowerit(*abbr++) == lowerit(*word++));
+
+ return false;
+}
+
static const struct lookup *
byword(const char *word, const struct lookup *table)
{
@@ -2909,6 +2922,20 @@ byword(const char *word, const struct lookup *table)
if (word == NULL || table == NULL)
return NULL;
+
+ /* If TABLE is LASTS and the word starts with "last" followed
+ by a non-'-', skip the "last" and look in WDAY_NAMES instead.
+ Warn about any usage of the undocumented prefix "last-". */
+ if (table == lasts && ciprefix("last", word) && word[4]) {
+ if (word[4] == '-')
+ warning(_("\"%s\" is undocumented; use \"last%s\" instead"),
+ word, word + 5);
+ else {
+ word += 4;
+ table = wday_names;
+ }
+ }
+
/*
** Look for exact match.
*/
@@ -2920,11 +2947,25 @@ byword(const char *word, const struct lookup *table)
*/
foundlp = NULL;
for (lp = table; lp->l_word != NULL; ++lp)
- if (itsabbr(word, lp->l_word)) {
+ if (ciprefix(word, lp->l_word)) {
if (foundlp == NULL)
foundlp = lp;
else return NULL; /* multiple inexact matches */
}
+
+ /* Warn about any backward-compatibility issue with pre-2017c zic. */
+ if (foundlp) {
+ bool pre_2017c_match = false;
+ for (lp = table; lp->l_word; lp++)
+ if (itsabbr(word, lp->l_word)) {
+ if (pre_2017c_match) {
+ warning(_("\"%s\" is ambiguous in pre-2017c zic"), word);
+ break;
+ }
+ pre_2017c_match = true;
+ }
+ }
+
return foundlp;
}
--
2.9.4
More information about the tz
mailing list