8339803: Acknowledge case insensitive unambiguous keywords in tzdata files

Reviewed-by: jlu, coffeys
This commit is contained in:
Naoto Sato 2024-09-11 19:27:00 +00:00
parent 51b85a1f69
commit 35a94b7697
4 changed files with 37 additions and 34 deletions

View File

@ -1372,6 +1372,7 @@ public class CLDRConverter {
private static void generateTZDBShortNamesMap() throws IOException { private static void generateTZDBShortNamesMap() throws IOException {
Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS) Files.walk(Path.of(tzDataDir), 1, FileVisitOption.FOLLOW_LINKS)
.filter(p -> p.toFile().isFile()) .filter(p -> p.toFile().isFile())
.filter(p -> p.getFileName().toString().matches("africa|antarctica|asia|australasia|backward|etcetera|europe|northamerica|southamerica"))
.forEach(p -> { .forEach(p -> {
try { try {
String zone = null; String zone = null;
@ -1394,43 +1395,41 @@ public class CLDRConverter {
} }
// remove comments in-line // remove comments in-line
line = line.replaceAll("[ \t]*#.*", ""); line = line.replaceAll("[ \t]*#.*", "");
var tokens = line.split("[ \t]+", -1);
var token0len = tokens.length > 0 ? tokens[0].length() : 0;
// Zone line // Zone line
if (line.startsWith("Zone")) { if (token0len > 0 && tokens[0].regionMatches(true, 0, "Zone", 0, token0len)) {
if (zone != null) { if (zone != null) {
tzdbShortNamesMap.put(zone, format + NBSP + rule); tzdbShortNamesMap.put(zone, format + NBSP + rule);
} }
var zl = line.split("[ \t]+", -1); zone = tokens[1];
zone = zl[1]; rule = tokens[3];
rule = zl[3]; format = flipIfNeeded(inVanguard, tokens[4]);
format = flipIfNeeded(inVanguard, zl[4]);
} else { } else {
if (zone != null) { if (zone != null) {
if (line.startsWith("Rule") || if (token0len > 0 &&
line.startsWith("Link")) { (tokens[0].regionMatches(true, 0, "Rule", 0, token0len) ||
tokens[0].regionMatches(true, 0, "Link", 0, token0len))) {
tzdbShortNamesMap.put(zone, format + NBSP + rule); tzdbShortNamesMap.put(zone, format + NBSP + rule);
zone = null; zone = null;
rule = null; rule = null;
format = null; format = null;
} else { } else {
var s = line.split("[ \t]+", -1); rule = tokens[2];
rule = s[2]; format = flipIfNeeded(inVanguard, tokens[3]);
format = flipIfNeeded(inVanguard, s[3]);
} }
} }
} }
// Rule line // Rule line
if (line.startsWith("Rule")) { if (token0len > 0 && tokens[0].regionMatches(true, 0, "Rule", 0, token0len)) {
var rl = line.split("[ \t]+", -1); tzdbSubstLetters.put(tokens[1] + NBSP + (tokens[8].equals("0") ? STD : DST),
tzdbSubstLetters.put(rl[1] + NBSP + (rl[8].equals("0") ? STD : DST), tokens[9].replace(NO_SUBST, ""));
rl[9].replace(NO_SUBST, ""));
} }
// Link line // Link line
if (line.startsWith("Link")) { if (token0len > 0 && tokens[0].regionMatches(true, 0, "Link", 0, token0len)) {
var ll = line.split("[ \t]+", -1); tzdbLinks.put(tokens[2], tokens[1]);
tzdbLinks.put(ll[2], ll[1]);
} }
} }

View File

@ -164,7 +164,8 @@ class TzdbZoneRulesProvider {
} }
continue; continue;
} }
if (line.startsWith("Zone")) { // parse Zone line int token0len = tokens.length > 0 ? tokens[0].length() : line.length();
if (line.regionMatches(true, 0, "Zone", 0, token0len)) { // parse Zone line
String name = tokens[1]; String name = tokens[1];
if (excludedZones.contains(name)){ if (excludedZones.contains(name)){
continue; continue;
@ -182,13 +183,13 @@ class TzdbZoneRulesProvider {
if (zLine.parse(tokens, 2)) { if (zLine.parse(tokens, 2)) {
openZone = null; openZone = null;
} }
} else if (line.startsWith("Rule")) { // parse Rule line } else if (line.regionMatches(true, 0, "Rule", 0, token0len)) { // parse Rule line
String name = tokens[1]; String name = tokens[1];
if (!rules.containsKey(name)) { if (!rules.containsKey(name)) {
rules.put(name, new ArrayList<RuleLine>(10)); rules.put(name, new ArrayList<RuleLine>(10));
} }
rules.get(name).add(new RuleLine().parse(tokens)); rules.get(name).add(new RuleLine().parse(tokens));
} else if (line.startsWith("Link")) { // parse link line } else if (line.regionMatches(true, 0, "Link", 0, token0len)) { // parse link line
if (tokens.length >= 3) { if (tokens.length >= 3) {
String realId = tokens[1]; String realId = tokens[1];
String aliasId = tokens[2]; String aliasId = tokens[2];
@ -304,7 +305,7 @@ class TzdbZoneRulesProvider {
month = parseMonth(tokens[off++]); month = parseMonth(tokens[off++]);
if (off < tokens.length) { if (off < tokens.length) {
String dayRule = tokens[off++]; String dayRule = tokens[off++];
if (dayRule.startsWith("last")) { if (dayRule.regionMatches(true, 0, "last", 0, 4)) {
dayOfMonth = -1; dayOfMonth = -1;
dayOfWeek = parseDayOfWeek(dayRule.substring(4)); dayOfWeek = parseDayOfWeek(dayRule.substring(4));
adjustForwards = false; adjustForwards = false;
@ -355,11 +356,12 @@ class TzdbZoneRulesProvider {
} }
int parseYear(String year, int defaultYear) { int parseYear(String year, int defaultYear) {
switch (year.toLowerCase()) { int len = year.length();
case "min": return 1900;
case "max": return Year.MAX_VALUE; if (year.regionMatches(true, 0, "minimum", 0, len)) return 1900;
case "only": return defaultYear; if (year.regionMatches(true, 0, "maximum", 0, len)) return Year.MAX_VALUE;
} if (year.regionMatches(true, 0, "only", 0, len)) return defaultYear;
return Integer.parseInt(year); return Integer.parseInt(year);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -168,12 +168,13 @@ class RuleRec {
rec.toYear = Integer.parseInt(token); rec.toYear = Integer.parseInt(token);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// it's not integer // it's not integer
if ("min".equals(token) || "minimum".equals(token)) { int len = token.length();
if (token.regionMatches(true, 0, "minimum", 0, len)) {
rec.fromYear = Zoneinfo.getMinYear(); rec.fromYear = Zoneinfo.getMinYear();
} else if ("max".equals(token) || "maximum".equals(token)) { } else if (token.regionMatches(true, 0, "maximum", 0, len)) {
rec.toYear = Integer.MAX_VALUE; rec.toYear = Integer.MAX_VALUE;
rec.isLastRule = true; rec.isLastRule = true;
} else if ("only".equals(token)) { } else if (token.regionMatches(true, 0, "only", 0, len)) {
rec.toYear = rec.fromYear; rec.toYear = rec.fromYear;
} else { } else {
Main.panic("invalid year value: "+token); Main.panic("invalid year value: "+token);

View File

@ -240,8 +240,9 @@ class Zoneinfo {
continue; continue;
} }
String token = tokens.nextToken(); String token = tokens.nextToken();
int len = token.length();
if (continued || "Zone".equals(token)) { if (continued || token.regionMatches(true, 0, "Zone", 0, len)){
if (zone == null) { if (zone == null) {
if (!tokens.hasMoreTokens()) { if (!tokens.hasMoreTokens()) {
panic("syntax error: zone no more token"); panic("syntax error: zone no more token");
@ -268,7 +269,7 @@ class Zoneinfo {
} }
zone = null; zone = null;
} }
} else if ("Rule".equals(token)) { } else if (token.regionMatches(true, 0, "Rule", 0, len)) {
if (!tokens.hasMoreTokens()) { if (!tokens.hasMoreTokens()) {
panic("syntax error: rule no more token"); panic("syntax error: rule no more token");
} }
@ -281,7 +282,7 @@ class Zoneinfo {
RuleRec rrec = RuleRec.parse(tokens); RuleRec rrec = RuleRec.parse(tokens);
rrec.setLine(line); rrec.setLine(line);
rule.add(rrec); rule.add(rrec);
} else if ("Link".equals(token)) { } else if (token.regionMatches(true, 0, "Link", 0, len)) {
// Link <newname> <oldname> // Link <newname> <oldname>
try { try {
String name1 = tokens.nextToken(); String name1 = tokens.nextToken();