mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 17:18:32 +00:00
tzsetup: adopt zone1970.tab changes
- assumption that single-zone countries do not have description is no longer correct; do not try to optimize this case as it's only going to make the code more confusing and we now have menus with a single zone selection because of this - remove the single-country continent short cut, it also only serves to confuse users as we now have such a continent - instead add a single-zone contry short cut (see above), now all single-zone countries fall here - use the #@ continent overrides that zone1970.tab introduces (this is visible at least fixing Iceland being currently listed under Africa) - add Arctic Ocean "continent" coming only from the overrides at the moment - update baseline with the changes Reviewed by: bapt, philip Differential Revision: https://reviews.freebsd.org/D39606
This commit is contained in:
parent
ec45f952a2
commit
cfd0217aa9
|
@ -19,10 +19,10 @@ AQ:Antarctica
|
|||
Antarctica:Antarctica/Palmer
|
||||
Antarctica:Antarctica/Rothera
|
||||
Antarctica:Antarctica/Troll
|
||||
Asia:Asia/Urumqi
|
||||
Pacific:Pacific/Auckland
|
||||
Pacific:Pacific/Port_Moresby
|
||||
Asia:Asia/Riyadh
|
||||
Antarctica:Asia/Urumqi
|
||||
Antarctica:Pacific/Auckland
|
||||
Antarctica:Pacific/Port_Moresby
|
||||
Antarctica:Asia/Riyadh
|
||||
AG:Antigua and Barbuda
|
||||
America:America/Puerto_Rico
|
||||
AR:Argentina
|
||||
|
@ -159,13 +159,13 @@ CN:China
|
|||
Asia:Asia/Shanghai
|
||||
Asia:Asia/Urumqi
|
||||
CX:Christmas Island
|
||||
Asia:Asia/Bangkok
|
||||
Indian:Asia/Bangkok
|
||||
CC:Cocos (Keeling) Islands
|
||||
Asia:Asia/Yangon
|
||||
Indian:Asia/Yangon
|
||||
CO:Colombia
|
||||
America:America/Bogota
|
||||
KM:Comoros
|
||||
Africa:Africa/Nairobi
|
||||
Indian:Africa/Nairobi
|
||||
CG:Congo
|
||||
Africa:Africa/Lagos
|
||||
CD:Congo, Democratic Republic of the
|
||||
|
@ -280,7 +280,7 @@ HK:Hong Kong
|
|||
HU:Hungary
|
||||
Europe:Europe/Budapest
|
||||
IS:Iceland
|
||||
Africa:Africa/Abidjan
|
||||
Atlantic:Africa/Abidjan
|
||||
IN:India
|
||||
Asia:Asia/Kolkata
|
||||
ID:Indonesia
|
||||
|
@ -353,7 +353,7 @@ MO:Macao
|
|||
MK:Macedonia (the former Yugoslav Republic of)
|
||||
Europe:Europe/Belgrade
|
||||
MG:Madagascar
|
||||
Africa:Africa/Nairobi
|
||||
Indian:Africa/Nairobi
|
||||
MW:Malawi
|
||||
Africa:Africa/Maputo
|
||||
MY:Malaysia
|
||||
|
@ -375,7 +375,7 @@ MR:Mauritania
|
|||
MU:Mauritius
|
||||
Indian:Indian/Mauritius
|
||||
YT:Mayotte
|
||||
Africa:Africa/Nairobi
|
||||
Indian:Africa/Nairobi
|
||||
MX:Mexico
|
||||
America:America/Mexico_City
|
||||
America:America/Cancun
|
||||
|
@ -507,7 +507,7 @@ RE:Réunion
|
|||
BL:Saint Barthélemy
|
||||
America:America/Puerto_Rico
|
||||
SH:Saint Helena Ascension and Tristan da Cunha
|
||||
Africa:Africa/Abidjan
|
||||
Atlantic:Africa/Abidjan
|
||||
KN:Saint Kitts and Nevis
|
||||
America:America/Puerto_Rico
|
||||
LC:Saint Lucia
|
||||
|
@ -563,7 +563,7 @@ SD:Sudan
|
|||
SR:Suriname
|
||||
America:America/Paramaribo
|
||||
SJ:Svalbard and Jan Mayen
|
||||
Europe:Europe/Berlin
|
||||
Arctic:Europe/Berlin
|
||||
SE:Sweden
|
||||
Europe:Europe/Berlin
|
||||
CH:Switzerland
|
||||
|
|
|
@ -157,8 +157,7 @@ static int usedialog = 1;
|
|||
|
||||
static int confirm_zone(const char *filename);
|
||||
static int continent_country_menu(dialogMenuItem *);
|
||||
static int set_zone_multi(dialogMenuItem *);
|
||||
static int set_zone_whole_country(dialogMenuItem *);
|
||||
static int set_zone(dialogMenuItem *);
|
||||
static int set_zone_menu(dialogMenuItem *);
|
||||
static int set_zone_utc(void);
|
||||
|
||||
|
@ -167,7 +166,7 @@ struct continent {
|
|||
int nitems;
|
||||
};
|
||||
|
||||
static struct continent africa, america, antarctica, asia, atlantic;
|
||||
static struct continent africa, america, antarctica, arctic, asia, atlantic;
|
||||
static struct continent australia, europe, indian, pacific, utc;
|
||||
|
||||
static struct continent_names {
|
||||
|
@ -177,6 +176,7 @@ static struct continent_names {
|
|||
{ "Africa", &africa },
|
||||
{ "America", &america },
|
||||
{ "Antarctica", &antarctica },
|
||||
{ "Arctic", &arctic },
|
||||
{ "Asia", &asia },
|
||||
{ "Atlantic", &atlantic },
|
||||
{ "Australia", &australia },
|
||||
|
@ -187,26 +187,27 @@ static struct continent_names {
|
|||
};
|
||||
|
||||
static struct continent_items {
|
||||
char prompt[2];
|
||||
char prompt[3];
|
||||
char title[30];
|
||||
} continent_items[] = {
|
||||
{ "1", "Africa" },
|
||||
{ "2", "America -- North and South" },
|
||||
{ "3", "Antarctica" },
|
||||
{ "4", "Asia" },
|
||||
{ "5", "Atlantic Ocean" },
|
||||
{ "6", "Australia" },
|
||||
{ "7", "Europe" },
|
||||
{ "8", "Indian Ocean" },
|
||||
{ "9", "Pacific Ocean" },
|
||||
{ "0", "UTC" }
|
||||
{ "4", "Arctic Ocean" },
|
||||
{ "5", "Asia" },
|
||||
{ "6", "Atlantic Ocean" },
|
||||
{ "7", "Australia" },
|
||||
{ "8", "Europe" },
|
||||
{ "9", "Indian Ocean" },
|
||||
{ "10", "Pacific Ocean" },
|
||||
{ "11", "UTC" }
|
||||
};
|
||||
|
||||
#define NCONTINENTS \
|
||||
(int)((sizeof(continent_items)) / (sizeof(continent_items[0])))
|
||||
static dialogMenuItem continents[NCONTINENTS];
|
||||
|
||||
#define OCEANP(x) ((x) == 4 || (x) == 7 || (x) == 8)
|
||||
#define OCEANP(x) ((x) == 3 || (x) == 5 || (x) == 8 || (x) == 9)
|
||||
|
||||
static int
|
||||
continent_country_menu(dialogMenuItem *continent)
|
||||
|
@ -219,10 +220,6 @@ continent_country_menu(dialogMenuItem *continent)
|
|||
if (strcmp(continent->title, "UTC") == 0)
|
||||
return (set_zone_utc());
|
||||
|
||||
/* Short cut -- if there's only one country, don't post a menu. */
|
||||
if (contp->nitems == 1)
|
||||
return (contp->menu[0].fire(&contp->menu[0]));
|
||||
|
||||
/* It's amazing how much good grammar really matters... */
|
||||
if (!isocean) {
|
||||
snprintf(title, sizeof(title), "Countries in %s",
|
||||
|
@ -239,14 +236,30 @@ continent_country_menu(dialogMenuItem *continent)
|
|||
}
|
||||
|
||||
static struct continent *
|
||||
find_continent(const char *name)
|
||||
find_continent(int lineno, const char *name)
|
||||
{
|
||||
char *cname, *cp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Both normal (the ones in zone filename, e.g. Europe/Andorra) and
|
||||
* override (e.g. Atlantic/) entries should contain '/'.
|
||||
*/
|
||||
cp = strdup(name);
|
||||
if (cp == NULL)
|
||||
err(1, "strdup");
|
||||
cname = strsep(&cp, "/");
|
||||
if (cp == NULL)
|
||||
errx(1, "%s:%d: invalid entry `%s'", path_zonetab, lineno,
|
||||
cname);
|
||||
|
||||
for (i = 0; i < NCONTINENTS; i++)
|
||||
if (strcmp(name, continent_names[i].name) == 0)
|
||||
if (strcmp(cname, continent_names[i].name) == 0) {
|
||||
free(cname);
|
||||
return (continent_names[i].continent);
|
||||
return (0);
|
||||
}
|
||||
|
||||
errx(1, "%s:%d: continent `%s' unknown", path_zonetab, lineno, cname);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -264,10 +277,9 @@ struct country {
|
|||
char *name;
|
||||
char *tlc;
|
||||
int nzones;
|
||||
char *filename; /* use iff nzones < 0 */
|
||||
struct continent *continent; /* use iff nzones < 0 */
|
||||
TAILQ_HEAD(, zone) zones; /* use iff nzones > 0 */
|
||||
dialogMenuItem *submenu; /* use iff nzones > 0 */
|
||||
struct continent *override; /* continent override */
|
||||
TAILQ_HEAD(, zone) zones;
|
||||
dialogMenuItem *submenu;
|
||||
};
|
||||
|
||||
struct zone {
|
||||
|
@ -346,56 +358,50 @@ read_iso3166_table(void)
|
|||
fclose(fp);
|
||||
}
|
||||
|
||||
static void
|
||||
add_zone_to_country(int lineno, const char *tlc, const char *descr,
|
||||
const char *file, struct continent *cont)
|
||||
static struct country *
|
||||
find_country(int lineno, const char *tlc)
|
||||
{
|
||||
struct zone *zp;
|
||||
struct country *cp;
|
||||
|
||||
if (tlc[0] < 'A' || tlc[0] > 'Z' || tlc[1] < 'A' || tlc[1] > 'Z')
|
||||
if (strlen(tlc) != 2 ||
|
||||
tlc[0] < 'A' || tlc[0] > 'Z' || tlc[1] < 'A' || tlc[1] > 'Z')
|
||||
errx(1, "%s:%d: country code `%s' invalid", path_zonetab,
|
||||
lineno, tlc);
|
||||
|
||||
cp = &countries[CODE2INT(tlc)];
|
||||
if (cp->name == 0)
|
||||
if (cp->name == NULL)
|
||||
errx(1, "%s:%d: country code `%s' unknown", path_zonetab,
|
||||
lineno, tlc);
|
||||
|
||||
if (descr) {
|
||||
if (cp->nzones < 0)
|
||||
errx(1, "%s:%d: conflicting zone definition",
|
||||
path_zonetab, lineno);
|
||||
return (cp);
|
||||
}
|
||||
|
||||
zp = malloc(sizeof(*zp));
|
||||
if (zp == NULL)
|
||||
errx(1, "malloc(%zu)", sizeof(*zp));
|
||||
static void
|
||||
add_zone_to_country(int lineno, struct country *cp, const char *descr,
|
||||
const char *file, struct continent *cont)
|
||||
{
|
||||
struct zone *zp;
|
||||
|
||||
if (cp->nzones == 0)
|
||||
TAILQ_INIT(&cp->zones);
|
||||
zp = malloc(sizeof(*zp));
|
||||
if (zp == NULL)
|
||||
errx(1, "malloc(%zu)", sizeof(*zp));
|
||||
|
||||
if (cp->nzones == 0)
|
||||
TAILQ_INIT(&cp->zones);
|
||||
|
||||
if (descr != NULL) {
|
||||
zp->descr = strdup(descr);
|
||||
if (zp->descr == NULL)
|
||||
errx(1, "malloc failed");
|
||||
zp->filename = strdup(file);
|
||||
if (zp->filename == NULL)
|
||||
errx(1, "malloc failed");
|
||||
zp->continent = cont;
|
||||
TAILQ_INSERT_TAIL(&cp->zones, zp, link);
|
||||
cp->nzones++;
|
||||
} else {
|
||||
if (cp->nzones > 0)
|
||||
errx(1, "%s:%d: zone must have description",
|
||||
path_zonetab, lineno);
|
||||
if (cp->nzones < 0)
|
||||
errx(1, "%s:%d: zone multiply defined",
|
||||
path_zonetab, lineno);
|
||||
cp->nzones = -1;
|
||||
cp->filename = strdup(file);
|
||||
if (cp->filename == NULL)
|
||||
errx(1, "malloc failed");
|
||||
cp->continent = cont;
|
||||
zp->descr = NULL;
|
||||
}
|
||||
zp->filename = strdup(file);
|
||||
if (zp->filename == NULL)
|
||||
errx(1, "malloc failed");
|
||||
zp->continent = cp->override != NULL ? cp->override : cont;
|
||||
TAILQ_INSERT_TAIL(&cp->zones, zp, link);
|
||||
cp->nzones++;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -432,54 +438,79 @@ sort_countries(void)
|
|||
static void
|
||||
read_zones(void)
|
||||
{
|
||||
char contbuf[16];
|
||||
FILE *fp;
|
||||
struct continent *cont;
|
||||
size_t len, contlen;
|
||||
char *line, *country_list, *tlc, *file, *descr, *p;
|
||||
struct country *cp;
|
||||
size_t len;
|
||||
char *line, *country_list, *tlc, *file, *descr;
|
||||
int lineno;
|
||||
bool pass1;
|
||||
|
||||
fp = fopen(path_zonetab, "r");
|
||||
if (!fp)
|
||||
err(1, "%s", path_zonetab);
|
||||
lineno = 0;
|
||||
pass1 = true;
|
||||
|
||||
again:
|
||||
lineno = 0;
|
||||
while ((line = fgetln(fp, &len)) != NULL) {
|
||||
lineno++;
|
||||
if (line[len - 1] != '\n')
|
||||
errx(1, "%s:%d: invalid format", path_zonetab, lineno);
|
||||
line[len - 1] = '\0';
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
country_list = strsep(&line, "\t");
|
||||
/* coord = */ strsep(&line, "\t"); /* Unused */
|
||||
file = strsep(&line, "\t");
|
||||
/* get continent portion from continent/country */
|
||||
p = strchr(file, '/');
|
||||
if (p == NULL)
|
||||
errx(1, "%s:%d: invalid zone name `%s'", path_zonetab,
|
||||
lineno, file);
|
||||
contlen = p - file + 1; /* trailing nul */
|
||||
if (contlen > sizeof(contbuf))
|
||||
errx(1, "%s:%d: continent name in zone name `%s' too long",
|
||||
path_zonetab, lineno, file);
|
||||
strlcpy(contbuf, file, contlen);
|
||||
cont = find_continent(contbuf);
|
||||
if (!cont)
|
||||
errx(1, "%s:%d: invalid region `%s'", path_zonetab,
|
||||
lineno, contbuf);
|
||||
if (pass1) {
|
||||
/*
|
||||
* First pass: collect overrides, only looking for
|
||||
* single continent ones for the moment.
|
||||
*
|
||||
* zone1970.tab introduced continent overrides in the
|
||||
* following format:
|
||||
*
|
||||
* #@TLC[,TLC...]<tab>CONTINENT/[,CONTINENT/...]
|
||||
*/
|
||||
if (strncmp(line, "#@", strlen("#@")) != 0)
|
||||
continue;
|
||||
line += 2;
|
||||
country_list = strsep(&line, "\t");
|
||||
/* Skip multi-continent overrides */
|
||||
if (strchr(line, ',') != NULL)
|
||||
continue;
|
||||
cont = find_continent(lineno, line);
|
||||
/* Parse and store overrides */
|
||||
while (country_list != NULL) {
|
||||
tlc = strsep(&country_list, ",");
|
||||
cp = find_country(lineno, tlc);
|
||||
cp->override = cont;
|
||||
}
|
||||
} else {
|
||||
/* Second pass: parse actual data */
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
descr = (line != NULL && *line != '\0') ? line : NULL;
|
||||
country_list = strsep(&line, "\t");
|
||||
/* coord = */ strsep(&line, "\t"); /* Unused */
|
||||
file = strsep(&line, "\t");
|
||||
cont = find_continent(lineno, file);
|
||||
descr = (line != NULL && *line != '\0') ? line : NULL;
|
||||
|
||||
while (country_list != NULL) {
|
||||
tlc = strsep(&country_list, ",");
|
||||
if (strlen(tlc) != 2)
|
||||
errx(1, "%s:%d: invalid country code `%s'",
|
||||
path_zonetab, lineno, tlc);
|
||||
add_zone_to_country(lineno, tlc, descr, file, cont);
|
||||
while (country_list != NULL) {
|
||||
tlc = strsep(&country_list, ",");
|
||||
cp = find_country(lineno, tlc);
|
||||
add_zone_to_country(lineno, cp, descr, file,
|
||||
cont);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pass1) {
|
||||
pass1 = false;
|
||||
errno = 0;
|
||||
rewind(fp);
|
||||
if (errno != 0)
|
||||
err(1, "failed to rewind %s", path_zonetab);
|
||||
goto again;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
@ -492,14 +523,9 @@ dump_zonetab(void)
|
|||
|
||||
for (cp = countries; cp->name != NULL; cp++) {
|
||||
printf("%s:%s\n", cp->tlc, cp->name);
|
||||
if (cp->nzones < 0) {
|
||||
cont = find_continent_name(cp->continent);
|
||||
printf(" %s:%s\n", cont, cp->filename);
|
||||
} else {
|
||||
TAILQ_FOREACH(zp, &cp->zones, link) {
|
||||
cont = find_continent_name(zp->continent);
|
||||
printf(" %s:%s\n", cont, zp->filename);
|
||||
}
|
||||
TAILQ_FOREACH(zp, &cp->zones, link) {
|
||||
cont = find_continent_name(zp->continent);
|
||||
printf(" %s:%s\n", cont, zp->filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -522,18 +548,14 @@ make_menus(void)
|
|||
for (cp = countries; cp->name; cp++) {
|
||||
if (cp->nzones == 0)
|
||||
continue;
|
||||
if (cp->nzones < 0) {
|
||||
cp->continent->nitems++;
|
||||
} else {
|
||||
TAILQ_FOREACH(zp, &cp->zones, link) {
|
||||
cont = zp->continent;
|
||||
for (zp2 = TAILQ_FIRST(&cp->zones);
|
||||
zp2->continent != cont;
|
||||
zp2 = TAILQ_NEXT(zp2, link))
|
||||
;
|
||||
if (zp2 == zp)
|
||||
zp->continent->nitems++;
|
||||
}
|
||||
TAILQ_FOREACH(zp, &cp->zones, link) {
|
||||
cont = zp->continent;
|
||||
for (zp2 = TAILQ_FIRST(&cp->zones);
|
||||
zp2->continent != cont;
|
||||
zp2 = TAILQ_NEXT(zp2, link))
|
||||
;
|
||||
if (zp2 == zp)
|
||||
zp->continent->nitems++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,41 +586,32 @@ make_menus(void)
|
|||
for (cp = countries; cp->name; cp++) {
|
||||
if (cp->nzones == 0)
|
||||
continue;
|
||||
if (cp->nzones < 0) {
|
||||
dmi = &cp->continent->menu[cp->continent->nitems];
|
||||
cp->submenu = malloc(cp->nzones * sizeof(*dmi));
|
||||
if (cp->submenu == 0)
|
||||
errx(1, "malloc for submenu");
|
||||
cp->nzones = 0;
|
||||
TAILQ_FOREACH(zp, &cp->zones, link) {
|
||||
cont = zp->continent;
|
||||
dmi = &cp->submenu[cp->nzones];
|
||||
memset(dmi, 0, sizeof(*dmi));
|
||||
asprintf(&dmi->prompt, "%d", ++cp->continent->nitems);
|
||||
asprintf(&dmi->prompt, "%d", ++cp->nzones);
|
||||
dmi->title = zp->descr;
|
||||
dmi->fire = set_zone;
|
||||
dmi->data = zp;
|
||||
|
||||
for (zp2 = TAILQ_FIRST(&cp->zones);
|
||||
zp2->continent != cont;
|
||||
zp2 = TAILQ_NEXT(zp2, link))
|
||||
;
|
||||
if (zp2 != zp)
|
||||
continue;
|
||||
|
||||
dmi = &cont->menu[cont->nitems];
|
||||
memset(dmi, 0, sizeof(*dmi));
|
||||
asprintf(&dmi->prompt, "%d", ++cont->nitems);
|
||||
dmi->title = cp->name;
|
||||
dmi->fire = set_zone_whole_country;
|
||||
dmi->fire = set_zone_menu;
|
||||
dmi->data = cp;
|
||||
} else {
|
||||
cp->submenu = malloc(cp->nzones * sizeof(*dmi));
|
||||
if (cp->submenu == 0)
|
||||
errx(1, "malloc for submenu");
|
||||
cp->nzones = 0;
|
||||
TAILQ_FOREACH(zp, &cp->zones, link) {
|
||||
cont = zp->continent;
|
||||
dmi = &cp->submenu[cp->nzones];
|
||||
memset(dmi, 0, sizeof(*dmi));
|
||||
asprintf(&dmi->prompt, "%d", ++cp->nzones);
|
||||
dmi->title = zp->descr;
|
||||
dmi->fire = set_zone_multi;
|
||||
dmi->data = zp;
|
||||
|
||||
for (zp2 = TAILQ_FIRST(&cp->zones);
|
||||
zp2->continent != cont;
|
||||
zp2 = TAILQ_NEXT(zp2, link))
|
||||
;
|
||||
if (zp2 != zp)
|
||||
continue;
|
||||
|
||||
dmi = &cont->menu[cont->nitems];
|
||||
memset(dmi, 0, sizeof(*dmi));
|
||||
asprintf(&dmi->prompt, "%d", ++cont->nitems);
|
||||
dmi->title = cp->name;
|
||||
dmi->fire = set_zone_menu;
|
||||
dmi->data = cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -610,6 +623,10 @@ set_zone_menu(dialogMenuItem *dmi)
|
|||
struct country *cp = dmi->data;
|
||||
int rv;
|
||||
|
||||
/* Short cut -- if there's only one zone, don't post a menu. */
|
||||
if (cp->nzones == 1)
|
||||
return (cp->submenu[0].fire(&cp->submenu[0]));
|
||||
|
||||
snprintf(title, sizeof(title), "%s Time Zones", cp->name);
|
||||
snprintf(prompt, sizeof(prompt),
|
||||
"Select a zone which observes the same time as your locality.");
|
||||
|
@ -646,7 +663,7 @@ confirm_zone(const char *filename)
|
|||
}
|
||||
|
||||
static int
|
||||
set_zone_multi(dialogMenuItem *dmi)
|
||||
set_zone(dialogMenuItem *dmi)
|
||||
{
|
||||
struct zone *zp = dmi->data;
|
||||
int rv;
|
||||
|
@ -658,19 +675,6 @@ set_zone_multi(dialogMenuItem *dmi)
|
|||
return (rv);
|
||||
}
|
||||
|
||||
static int
|
||||
set_zone_whole_country(dialogMenuItem *dmi)
|
||||
{
|
||||
struct country *cp = dmi->data;
|
||||
int rv;
|
||||
|
||||
if (!confirm_zone(cp->filename))
|
||||
return (DITEM_FAILURE | DITEM_RECREATE);
|
||||
|
||||
rv = install_zoneinfo(cp->filename);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void message_zoneinfo_file(const char *title, char *prompt)
|
||||
|
|
Loading…
Reference in a new issue