The branch stable/14 has been updated by emaste:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9ef162b2392f34a88fb40b560ef700d0aacadfe1

commit 9ef162b2392f34a88fb40b560ef700d0aacadfe1
Author:     Pierre Pronchery <pie...@freebsdfoundation.org>
AuthorDate: 2023-07-27 16:07:22 +0000
Commit:     Ed Maste <ema...@freebsd.org>
CommitDate: 2023-10-16 12:29:46 +0000

    tzsetup: add support for countries in two continents
    
    This supports countries located across multiple continents, as per the
    zone1970.tab file. This only affects Cyprus and Türkiye at the moment.
    
    PR:             236874
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D41306
    
    (cherry picked from commit 914ab28c598c108bcfa5c040cc3056a8e6fc3811)
---
 usr.sbin/tzsetup/tzsetup.c | 67 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 61 insertions(+), 6 deletions(-)

diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c
index 5dfe840528b5..4279f888a33f 100644
--- a/usr.sbin/tzsetup/tzsetup.c
+++ b/usr.sbin/tzsetup/tzsetup.c
@@ -276,6 +276,7 @@ struct country {
        char            *tlc;
        int             nzones;
        struct continent *override;     /* continent override */
+       struct continent *alternate;    /* extra continent */
        TAILQ_HEAD(, zone) zones;
        dialogMenuItem  *submenu;
 };
@@ -374,6 +375,18 @@ find_country(int lineno, const char *tlc)
        return (cp);
 }
 
+static void
+add_cont_to_country(struct country *cp, struct continent *cont)
+{
+       struct zone     *zp;
+
+       TAILQ_FOREACH(zp, &cp->zones, link) {
+               if (zp->continent == cont)
+                       return;
+       }
+       cp->alternate = cont;
+}
+
 static void
 add_zone_to_country(int lineno, struct country *cp, const char *descr,
     const char *file, struct continent *cont)
@@ -441,13 +454,13 @@ read_zones(void)
        struct country  *cp;
        size_t          len;
        char            *line, *country_list, *tlc, *file, *descr;
+       char            *p, *q;
        int             lineno;
-       bool            pass1;
+       int             pass = 1;
 
        fp = fopen(path_zonetab, "r");
        if (!fp)
                err(1, "%s", path_zonetab);
-       pass1 = true;
 
 again:
        lineno = 0;
@@ -457,7 +470,9 @@ again:
                        errx(1, "%s:%d: invalid format", path_zonetab, lineno);
                line[len - 1] = '\0';
 
-               if (pass1) {
+               switch (pass)
+               {
+               case 1:
                        /*
                         * First pass: collect overrides, only looking for
                         * single continent ones for the moment.
@@ -481,7 +496,8 @@ again:
                                cp = find_country(lineno, tlc);
                                cp->override = cont;
                        }
-               } else {
+                       break;
+               case 2:
                        /* Second pass: parse actual data */
                        if (line[0] == '#')
                                continue;
@@ -498,11 +514,34 @@ again:
                                add_zone_to_country(lineno, cp, descr, file,
                                    cont);
                        }
+                       break;
+               case 3:
+                       /* Third pass: collect multi-continent overrides */
+                       if (strncmp(line, "#@", strlen("#@")) != 0)
+                               continue;
+                       line += 2;
+                       country_list = strsep(&line, "\t");
+                       /* Skip single-continent overrides */
+                       if (strchr(line, ',') == NULL)
+                               continue;
+                       while (line != NULL) {
+                               cont = find_continent(lineno, line);
+                               p = q = strdup(country_list);
+                               if (p == NULL)
+                                       errx(1, "malloc failed");
+                               while (q != NULL) {
+                                       tlc = strsep(&q, ",");
+                                       cp = find_country(lineno, tlc);
+                                       add_cont_to_country(cp, cont);
+                               }
+                               free(p);
+                               strsep(&line, ",");
+                       }
+                       break;
                }
        }
 
-       if (pass1) {
-               pass1 = false;
+       if (pass++ < 3) {
                errno = 0;
                rewind(fp);
                if (errno != 0)
@@ -555,6 +594,12 @@ make_menus(void)
                        if (zp2 == zp)
                                zp->continent->nitems++;
                }
+
+               for (i = 0; i < NCONTINENTS; i++) {
+                       if (cp->alternate == continent_names[i].continent) {
+                               continent_names[i].continent->nitems++;
+                       }
+               }
        }
 
        /*
@@ -611,6 +656,16 @@ make_menus(void)
                        dmi->fire = set_zone_menu;
                        dmi->data = cp;
                }
+
+               if (cp->alternate != NULL) {
+                       cont = cp->alternate;
+                       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;
+               }
        }
 }
 

Reply via email to