<pre style='margin:0'>
Joshua Root (jmroot) pushed a commit to branch master
in repository macports-base.

</pre>
<p><a href="https://github.com/macports/macports-base/commit/3f83ad1f315d79eb64f19acce9ad1ebb3d5d354c">https://github.com/macports/macports-base/commit/3f83ad1f315d79eb64f19acce9ad1ebb3d5d354c</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 3f83ad1f315d79eb64f19acce9ad1ebb3d5d354c
</span>Author: Clemens Lang <cal@macports.org>
AuthorDate: Tue Oct 31 11:13:35 2023 +0100

<span style='display:block; white-space:pre;color:#404040;'>    src: Support requested variants in migration code
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Stop the separation into negative and positive variants and add a field
</span><span style='display:block; white-space:pre;color:#404040;'>    for requested variants. This simplifies the code in a few places, since
</span><span style='display:block; white-space:pre;color:#404040;'>    no string concatenation is required at runtime to obtain the full
</span><span style='display:block; white-space:pre;color:#404040;'>    variant string.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    Switch to restoring requested variants only by default, since this is
</span><span style='display:block; white-space:pre;color:#404040;'>    also the default behavior we would do for upgrading.
</span>---
 src/cregistry/snapshot.c      | 36 +++++++++++++-------------------
 src/cregistry/snapshot.h      |  3 +--
 src/cregistry/sql.c           |  4 ++--
 src/macports1.0/restore.tcl   | 48 ++++++++++++-------------------------------
 src/macports1.0/snapshot.tcl  |  2 +-
 src/registry2.0/snapshotobj.c |  5 +++--
 6 files changed, 34 insertions(+), 64 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/snapshot.c b/src/cregistry/snapshot.c
</span><span style='display:block; white-space:pre;color:#808080;'>index e32792ef2..0afcbbf02 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/snapshot.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -227,24 +227,24 @@ int snapshot_store_ports(reg_registry* reg, reg_snapshot* snapshot, reg_error* e
</span>     char* key2 = "requested";
     char* key3 = "state";
     char* key4 = "variants";
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    char* key5 = "negated_variants";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    char* key5 = "requested_variants";
</span>     if (entry_count >= 0) {
         for ( i = 0; i < entry_count; i++) {
             char* port_name;
             char* requested;
             char* state;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            char* positive_variants_str;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            char* negative_variants_str;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            char* variants_str;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            char* requested_variants_str;
</span>             sqlite3_stmt* stmt = NULL;
             reg_entry* entry = NULL;
             if (reg_entry_propget(entries[i], key1, &port_name, &error)
                 && reg_entry_propget(entries[i], key2, &requested, &error)
                 && reg_entry_propget(entries[i], key3, &state, &error)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                && reg_entry_propget(entries[i], key4, &positive_variants_str, &error)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                && reg_entry_propget(entries[i], key5, &negative_variants_str, &error)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                && reg_entry_propget(entries[i], key4, &variants_str, &error)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                && reg_entry_propget(entries[i], key5, &requested_variants_str, &error)) {
</span> 
                 char* query = "INSERT INTO registry.snapshot_ports "
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    "(snapshots_id, port_name, requested, state, variants, negated_variants) "
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    "(snapshots_id, port_name, requested, state, variants, requested_variants) "
</span>                     "VALUES (?, ?, ?, ?, ?, ?)";
 
                 if ((sqlite3_prepare_v2(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -252,8 +252,8 @@ int snapshot_store_ports(reg_registry* reg, reg_snapshot* snapshot, reg_error* e
</span>                         && (sqlite3_bind_text(stmt, 2, port_name, -1, SQLITE_STATIC) == SQLITE_OK)
                         && (sqlite3_bind_int64(stmt, 3, atoi(requested)) == SQLITE_OK)
                         && (sqlite3_bind_text(stmt, 4, state, -1, SQLITE_STATIC) == SQLITE_OK)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                        && (sqlite3_bind_text(stmt, 5, positive_variants_str, -1, SQLITE_STATIC) == SQLITE_OK)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        && (sqlite3_bind_text(stmt, 6, negative_variants_str, -1, SQLITE_STATIC) == SQLITE_OK)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        && (sqlite3_bind_text(stmt, 5, variants_str, -1, SQLITE_STATIC) == SQLITE_OK)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        && (sqlite3_bind_text(stmt, 6, requested_variants_str, -1, SQLITE_STATIC) == SQLITE_OK)) {
</span>                     int r;
                     do {
                         r = sqlite3_step(stmt);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -299,8 +299,8 @@ int reg_snapshot_ports_get(reg_snapshot* snapshot, port*** ports, reg_error* err
</span> 
     const char* port_name;
     const char* state;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    const char* positive_variants;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    const char* negated_variants;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const char* variants;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    const char* requested_variants;;
</span> 
     if ((sqlite3_prepare_v2(reg->db, query, -1, &stmt, NULL) == SQLITE_OK)
         && (sqlite3_bind_int64(stmt, 1, snapshot->id) == SQLITE_OK )) {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -318,7 +318,6 @@ int reg_snapshot_ports_get(reg_snapshot* snapshot, port*** ports, reg_error* err
</span> 
         sqlite_int64 snapshot_port_id;
         int requested;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        char* variantstr = NULL;
</span> 
         do {
             r = sqlite3_step(stmt);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -329,26 +328,19 @@ int reg_snapshot_ports_get(reg_snapshot* snapshot, port*** ports, reg_error* err
</span>                     port_name = (const char*) sqlite3_column_text(stmt, 2);
                     requested = (int) sqlite3_column_int64(stmt, 3);
                     state = (const char*) sqlite3_column_text(stmt, 4);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    positive_variants = (const char*) sqlite3_column_text(stmt, 5);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    negated_variants = (const char*) sqlite3_column_text(stmt, 6);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    variants = (const char*) sqlite3_column_text(stmt, 5);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    requested_variants = (const char*) sqlite3_column_text(stmt, 6);
</span> 
                     port* current_port = (port*) malloc(sizeof(port));
                     if (!current_port) {
                         return -1;
                     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    variantstr = malloc(strlen(positive_variants) + strlen(negated_variants) + 1);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if (!variantstr) {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        return -1;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    variantstr[0] = '\0';
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    strcat(variantstr, positive_variants);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    strcat(variantstr, negated_variants);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span>                     current_port->name = strdup(port_name);
                     current_port->requested = requested;
                     current_port->state = strdup(state);
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    current_port->variants = variantstr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    current_port->variants = strdup(variants);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    current_port->requested_variants = strdup(requested_variants);
</span> 
                     if (!reg_listcat((void***)&result, &result_count, &result_space, current_port)) {
                             r = SQLITE_ERROR;
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/snapshot.h b/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;color:#808080;'>index 9f75eb2dc..af5a690d9 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/snapshot.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -38,14 +38,13 @@
</span> 
 #include <sqlite3.h>
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-// TODO: extend it to support requested variants
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span> typedef struct {
     char* name;     /* port name */
     int requested;  /* 1 if port os requested, else 0 */
     char* state;    /* 'imaged' or 'installed' */
     int variant_count;  /* total number of variants */
     char* variants; /* string of the form: +var1-var2+var3 */
<span style='display:block; white-space:pre;background:#e0ffe0;'>+    char* requested_variants; /* string of the form: +var1-var2 */
</span> } port;
 
 typedef struct {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/cregistry/sql.c b/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 4d8d07783..bb0a510ed 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/cregistry/sql.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -219,7 +219,7 @@ int create_tables(sqlite3* db, reg_error* errPtr) {
</span>             ", requested INTEGER"
             ", state TEXT COLLATE NOCASE"
             ", variants TEXT"
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            ", negated_variants TEXT"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            ", requested_variants TEXT"
</span>             ", FOREIGN KEY(snapshots_id) REFERENCES snapshots(id)"
             " ON DELETE CASCADE"
             ")",
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -899,7 +899,7 @@ int update_db(sqlite3* db, reg_error* errPtr) {
</span>                     ", requested INTEGER"
                     ", state TEXT COLLATE NOCASE"
                     ", variants TEXT"
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ", negated_variants TEXT"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ", requested_variants TEXT"
</span>                     ", FOREIGN KEY(snapshots_id) REFERENCES snapshots(id)"
                     " ON DELETE CASCADE"
                     ")",
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/restore.tcl b/src/macports1.0/restore.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index d9561ef9f..13ebbc91a 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/restore.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/restore.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -194,30 +194,7 @@ namespace eval restore {
</span>             if {[lindex $port 2] eq "installed"} {
                 set active 1
             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            set variantstr [lindex $port 3]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {$variantstr eq "(null)"} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set variantstr ""
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set variants ""
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {[info exists variantstr]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                while 1 {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set nextplus [string last + $variantstr]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set nextminus [string last - $variantstr]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if {$nextplus > $nextminus} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set next $nextplus
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set sign +
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set next $nextminus
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        set sign -
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if {$next == -1} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        break
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set v [string range $variantstr [expr $next + 1] end]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend variants $v $sign
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set variantstr [string range $variantstr 0 [expr $next - 1]]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set requested_variants [lindex $port 4]
</span>             if {![info exists port_in_list($name)]} {
                 set port_in_list($name) 1
                 set port_installed($name) 0
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -225,10 +202,10 @@ namespace eval restore {
</span>                 incr port_in_list($name)
             }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {![info exists port_deps(${name},${variants})]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                set port_deps(${name},${variants}) [portlist_sort_dependencies_first_helper $name $variants]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {![info exists port_deps(${name},${requested_variants})]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                set port_deps(${name},${requested_variants}) [portlist_sort_dependencies_first_helper $name $requested_variants]
</span>             }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            lappend new_list [list $name $variants $active]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            lappend new_list [list $name $requested_variants $active]
</span>         }
 
         set operation_list [list]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -236,22 +213,22 @@ namespace eval restore {
</span> 
             set oldLen [llength $new_list]
             foreach port $new_list {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                foreach {name variants active} $port break
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                lassign $port name requested_variants active
</span> 
                 if {$active && $port_installed($name) < ($port_in_list($name) - 1)} {
                     continue
                 }
                 set installable 1
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                foreach dep $port_deps(${name},${variants}) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                foreach dep $port_deps(${name},${requested_variants}) {
</span>                     if {[info exists port_installed($dep)] && $port_installed($dep) == 0} {
                         set installable 0
                         break
                     }
                 }
                 if {$installable} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend operation_list [list $name $variants $active]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend operation_list [list $name $requested_variants $active]
</span>                     incr port_installed($name)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set index [lsearch $new_list [list $name $variants $active]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    set index [lsearch $new_list [list $name $requested_variants $active]]
</span>                     set new_list [lreplace $new_list $index $index]
                 }
             }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -262,7 +239,7 @@ namespace eval restore {
</span>         return $operation_list
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    proc portlist_sort_dependencies_first_helper {portname variant_info} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    proc portlist_sort_dependencies_first_helper {portname requested_variants} {
</span>         set dependency_list [list]
         set port_search_result [mportlookup $portname]
         if {[llength $port_search_result] < 2} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -270,7 +247,7 @@ namespace eval restore {
</span>             return $dependency_list
         }
         array set portinfo [lindex $port_search_result 1]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {[catch {set mport [mportopen $portinfo(porturl) [list subport $portinfo(name)] $variant_info]} result]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {[catch {set mport [mportopen $portinfo(porturl) [list subport $portinfo(name)] $requested_variants]} result]} {
</span>             global errorInfo
             puts stderr "$errorInfo"
             return -code error "Unable to open port '$portname': $result"
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -298,12 +275,13 @@ namespace eval restore {
</span>             # 1: requested (0/1)
             # 2: state (imaged/installed, i.e. inactive/active)
             # 3: variants
<span style='display:block; white-space:pre;background:#e0ffe0;'>+            # 4: requested_variants
</span>             if {[lindex $port 1] == 1} {
                 # Hide unrequested ports
                 if {[lindex $port 2] eq "installed"} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ui_msg "   [lindex $port 0] [lindex $port 3]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ui_msg "   [lindex $port 0] [lindex $port 3] (requested: [lindex $port 4])"
</span>                 } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    ui_msg "   [lindex $port 0] [lindex $port 3] (inactive)"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    ui_msg "   [lindex $port 0] [lindex $port 3] (requested: [lindex $port 4]) (inactive)"
</span>                 }
             }
         }
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/macports1.0/snapshot.tcl b/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index 04d4707c2..628db3d28 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/macports1.0/snapshot.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -55,7 +55,7 @@ namespace eval snapshot {
</span>             set inactive_ports  [list]
             foreach port [registry::entry imaged] {
                 if {[$port state] eq "imaged"} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lappend inactive_ports "[$port name] @[$port version]_[$port revision] [$port variants][$port negated_variants]"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lappend inactive_ports "[$port name] @[$port version]_[$port revision] [$port variants]"
</span>                 }
             }
             if {[llength $inactive_ports] != 0} {
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/registry2.0/snapshotobj.c b/src/registry2.0/snapshotobj.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 63fb525f3..4c0a66ec3 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/registry2.0/snapshotobj.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/registry2.0/snapshotobj.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -130,11 +130,12 @@ static int snapshot_obj_ports(Tcl_Interp* interp, reg_snapshot* snapshot, int ob
</span>                 for(i = 0; i < port_count; i++){
                     port* current_port = ports[i];
                     portstrs[i] = NULL;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if (asprintf(&portstrs[i], "%s %d %s %s",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if (asprintf(&portstrs[i], "%s %d %s %s %s",
</span>                             current_port->name,
                             current_port->requested,
                             current_port->state,
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                            current_port->variants) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            current_port->variants,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            current_port->requested_variants) < 0) {
</span>                         return TCL_ERROR;
                     }
                 }
</pre><pre style='margin:0'>

</pre>