<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/93634bc97cfd07b4d242d984ee9c0a57cea751ab">https://github.com/macports/macports-base/commit/93634bc97cfd07b4d242d984ee9c0a57cea751ab</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 93634bc97cfd07b4d242d984ee9c0a57cea751ab
</span>Author: Joshua Root <jmr@macports.org>
AuthorDate: Sun Feb 11 07:45:25 2024 +1100

<span style='display:block; white-space:pre;color:#404040;'>    portindex: use dict
</span>---
 src/port/portindex.tcl | 133 ++++++++++++++++++++++---------------------------
 1 file changed, 59 insertions(+), 74 deletions(-)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/port/portindex.tcl b/src/port/portindex.tcl
</span><span style='display:block; white-space:pre;color:#808080;'>index f7a155392..aa56bc9db 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/port/portindex.tcl
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/port/portindex.tcl
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -9,9 +9,10 @@ package require Thread
</span> # Globals
 set full_reindex 0
 set permit_error 0
<span style='display:block; white-space:pre;background:#ffe0e0;'>-set stats(total) 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-set stats(failed) 0
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-set stats(skipped) 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+set stats [dict create \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           total 0 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           failed 0 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           skipped 0]
</span> set extended_mode 0
 array set ui_options        [list ports_no_old_index_warning 1]
 array set global_options    [list ports_no_load_quick_index 1]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -44,13 +45,13 @@ package require macports
</span> package require Thread
 
 proc _read_index {idx} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set offset $::qindex($idx)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set offset [dict get $::qindex $idx]
</span>     thread::mutex lock [tsv::get mutexes PortIndex]
     try {
         seek $::oldfd $offset
         gets $::oldfd in_line
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set len  [lindex $in_line 1]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        set len [lindex $in_line 1]
</span>         set out_line [read $::oldfd [expr {$len - 1}]]
     } finally {
         thread::mutex unlock [tsv::get mutexes PortIndex]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -60,54 +61,42 @@ proc _read_index {idx} {
</span>     return [list $name $len $out_line]
 }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-proc _index_from_portinfo {portinfoname {is_subport no}} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    upvar $portinfoname portinfo
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc _index_from_portinfo {portinfo {is_subport no}} {
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    array set keep_portinfo {}
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    foreach key [array names ::keepkeys] {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        # filter keys
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {![info exists portinfo($key)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            continue
</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:#ffe0e0;'>-        # copy values we want to keep
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set keep_portinfo($key) $portinfo($key)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set keep_portinfo [dict filter $portinfo script {key val} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        dict exists $::keepkeys $key
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }]
</span> 
     # if this is not a subport, add the "subports" key
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    if {!$is_subport && [info exists portinfo(subports)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        set keep_portinfo(subports) $portinfo(subports)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if {!$is_subport && [dict exists $portinfo subports]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        dict set keep_portinfo subports [dict get $portinfo subports]
</span>     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set output [array get keep_portinfo]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    set len [expr {[string length $output] + 1}]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    return [list $portinfo(name) $len $output]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set len [expr {[string length $keep_portinfo] + 1}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return [list [dict get $portinfo name] $len $keep_portinfo]
</span> }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-proc _open_port {portinfo_name portdir absportdir port_options_name {subport {}}} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    upvar $portinfo_name portinfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    upvar $port_options_name port_options
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+proc _open_port {portdir absportdir port_options {subport {}}} {
</span> 
     # Make sure $prefix expands to '${prefix}' so that the PortIndex is
     # portable across prefixes, see https://trac.macports.org/ticket/53169 and
     # https://trac.macports.org/ticket/17182.
     macports_try -pass_signal {
         set macports::prefix {${prefix}}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {$subport eq {}} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set interp [mportopen file://$absportdir $port_options]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        } else {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set interp [mportopen file://$absportdir [concat $port_options subport $subport]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {$subport ne {}} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            dict set port_options subport $subport
</span>         }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+        set mport [mportopen file://$absportdir $port_options]
</span>     } finally {
         # Restore prefix to the previous value
         set macports::prefix $::save_prefix
     }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    array unset portinfo
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    array set portinfo [mportinfo $interp]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-    mportclose $interp
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set portinfo [mportinfo $mport]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    mportclose $mport
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set portinfo(portdir) $portdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    dict set portinfo portdir $portdir
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return $portinfo
</span> }
 
 proc pindex {portdir jobnum {subport {}}} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -123,16 +112,15 @@ proc pindex {portdir jobnum {subport {}}} {
</span>             set is_subport 0
         }
         # try to reuse the existing entry if it's still valid
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        if {$::full_reindex != 1 && [info exists ::qindex($qname)]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        if {$::full_reindex != 1 && [dict exists $::qindex $qname]} {
</span>             macports_try -pass_signal {
                 set mtime [file mtime $portfile]
                 if {$::oldmtime >= $mtime} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    lassign [_read_index $qname] name len line
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                    array set portinfo $line
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    lassign [_read_index $qname] name len portinfo
</span> 
                     # reuse entry if it was made from the same portdir
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    if {[info exists portinfo(portdir)] && $portinfo(portdir) eq $portdir} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                        tsv::set output $jobnum [list $name $len $line]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    if {[dict exists $portinfo portdir] && [dict get $portinfo portdir] eq $portdir} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                        tsv::set output $jobnum [list $name $len $portinfo]
</span> 
                         if {!$is_subport} {
                             if {[info exists ::ui_options(ports_debug)]} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -140,8 +128,8 @@ proc pindex {portdir jobnum {subport {}}} {
</span>                             }
 
                             # report any subports
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                            if {[info exists portinfo(subports)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                                tsv::set subports $jobnum $portinfo(subports)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                            if {[dict exists $portinfo subports]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                                tsv::set subports $jobnum [dict get $portinfo subports]
</span>                             }
                         }
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -158,19 +146,19 @@ proc pindex {portdir jobnum {subport {}}} {
</span>         }
 
         macports_try -pass_signal {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            _open_port portinfo $portdir $absportdir ::port_options $subport
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set portinfo [_open_port $portdir $absportdir $::port_options $subport]
</span>             if {$is_subport} {
                 puts "Adding subport $subport"
             } else {
                 puts "Adding port $portdir"
             }
 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            tsv::set output $jobnum [_index_from_portinfo portinfo $is_subport]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            tsv::set output $jobnum [_index_from_portinfo $portinfo $is_subport]
</span>             tsv::set mtime $jobnum [file mtime $portfile]
 
             # report this portfile's subports (if any)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            if {!$is_subport && [info exists portinfo(subports)]} {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-                tsv::set subports $jobnum $portinfo(subports)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            if {!$is_subport && [dict exists $portinfo subports]} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                tsv::set subports $jobnum [dict get $portinfo subports]
</span>             }
         } on error {eMessage} {
             if {$is_subport} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -197,8 +185,8 @@ proc pindex {portdir jobnum {subport {}}} {
</span> 
 proc init_threads {} {
     append ::worker_init_script \
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        [list array set qindex [array get ::qindex]] \n \
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        [list array set keepkeys [array get ::keepkeys]] \n \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        [list set qindex $::qindex] \n \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        [list set keepkeys $::keepkeys] \n \
</span>         [list array set ui_options [array get ::ui_options]] \n \
         [list array set global_options [array get ::global_options]] \n \
         [list set port_options $::port_options] \n \
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -218,25 +206,25 @@ proc init_threads {} {
</span>     }
     set ::maxjobs [macports:get_parallel_jobs no]
     set ::poolid [tpool::create -minworkers $::maxjobs -maxworkers $::maxjobs -initcmd $::worker_init_script]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    array set ::pending_jobs {}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set ::pending_jobs [dict create]
</span>     set ::nextjobnum 0
     tsv::set mutexes PortIndex [thread::mutex create]
 }
 
 proc handle_completed_jobs {} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set completed_jobs [tpool::wait $::poolid [array names ::pending_jobs]]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    set completed_jobs [tpool::wait $::poolid [dict keys $::pending_jobs]]
</span>     foreach completed_job $completed_jobs {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        lassign $::pending_jobs($completed_job) jobnum portdir subport
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        unset ::pending_jobs($completed_job)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        lassign [dict get $::pending_jobs $completed_job] jobnum portdir subport
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        dict unset ::pending_jobs $completed_job
</span>         tsv::get status $jobnum status
         # -1 = skipped, 0 = success, 1 = fail, 99 = exit
         if {$status == 99} {
             set ::exit_fail 1
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            array unset ::pending_jobs
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            set ::pending_jobs ""
</span>             return -code break "Interrupt"
         } elseif {$status == 1} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            incr ::stats(failed)
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            incr ::stats(total)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            dict incr ::stats failed
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            dict incr ::stats total
</span>             if {[tsv::exists output $jobnum]} {
                 tsv::unset output $jobnum
             }
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -246,15 +234,15 @@ proc handle_completed_jobs {} {
</span>                 foreach nextsubport [tsv::get subports $jobnum] {
                     tsv::set status $::nextjobnum 99
                     set jobid [tpool::post -nowait $::poolid [list pindex $portdir $::nextjobnum $nextsubport]]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                    set ::pending_jobs($jobid) [list $::nextjobnum $portdir $nextsubport]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                    dict set ::pending_jobs $jobid [list $::nextjobnum $portdir $nextsubport]
</span>                     incr ::nextjobnum
                 }
                 tsv::unset subports $jobnum
             }
             if {$status == -1} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                incr ::stats(skipped)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                dict incr ::stats skipped
</span>             } else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-                incr ::stats(total)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                dict incr ::stats total
</span>                 tsv::get mtime $jobnum mtime
                 if {$mtime > $::newest} {
                     set ::newest $mtime
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -273,7 +261,7 @@ proc handle_completed_jobs {} {
</span> # post new job to the pool
 proc pindex_queue {portdir} {
     # Wait for a free thread
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    while {[array size ::pending_jobs] >= $::maxjobs} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while {[dict size $::pending_jobs] >= $::maxjobs} {
</span>         handle_completed_jobs
     }
     if {$::exit_fail} {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -285,13 +273,13 @@ proc pindex_queue {portdir} {
</span>     # returns due to ctrl-c etc.
     tsv::set status $::nextjobnum 99
     set jobid [tpool::post -nowait $::poolid [list pindex $portdir $::nextjobnum {}]]
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set ::pending_jobs($jobid) [list $::nextjobnum $portdir {}]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    dict set ::pending_jobs $jobid [list $::nextjobnum $portdir {}]
</span>     incr ::nextjobnum
 }
 
 proc process_remaining {} {
     # let remaining jobs finish
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    while {[array size ::pending_jobs] > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while {[dict size $::pending_jobs] > 0} {
</span>         handle_completed_jobs
     }
     tpool::release $::poolid
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -397,6 +385,7 @@ if {[info exists outdir]} {
</span> puts "Creating port index in $outdir"
 set outpath [file join $outdir PortIndex]
 # open old index for comparison
<span style='display:block; white-space:pre;background:#e0ffe0;'>+set qindex ""
</span> if {[file isfile $outpath]} {
     set oldmtime [file mtime $outpath]
     set attrlist [list -permissions]
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -408,17 +397,12 @@ if {[file isfile $outpath]} {
</span>     }
     set newest $oldmtime
     if {![catch {open $outpath r} oldfd]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set quicklist [list]
</span>         if {![file isfile ${outpath}.quick]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            catch {set quicklist [mports_generate_quickindex ${outpath}]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            catch {set qindex [dict create {*}[mports_generate_quickindex ${outpath}]]}
</span>         } elseif {![catch {open ${outpath}.quick r} quickfd]} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-            catch {set quicklist [read $quickfd]}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            catch {set qindex [dict create {*}[read $quickfd]]}
</span>             close $quickfd
         }
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        foreach entry [split $quicklist "\n"] {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-            set qindex([lindex $entry 0]) [lindex $entry 1]
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        }
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-        unset quicklist
</span>     }
 } else {
     set newest 0
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -429,18 +413,19 @@ set fd [file tempfile tempportindex mports.portindex.XXXXXXXX]
</span> set save_prefix ${macports::prefix}
 
 # keys for a normal portindex
<span style='display:block; white-space:pre;background:#e0ffe0;'>+set keepkeys [dict create]
</span> foreach key {categories depends_fetch depends_extract depends_patch \
              depends_build depends_lib depends_run depends_test \
              description epoch homepage long_description maintainers \
              name platforms revision variants version portdir \
              replaced_by license installs_libs conflicts known_fail} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-    set keepkeys($key) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    dict set keepkeys $key 1
</span> }
 
 # additional keys for extended portindex (with extra information)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {$extended_mode eq 1 } {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {$extended_mode} {
</span>     foreach key {vinfo notes} {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-        set keepkeys($key) 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        dict set keepkeys $key 1
</span>     }
 }
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -471,11 +456,11 @@ file rename -force $tempportindex $outpath
</span> file mtime $outpath $newest
 file attributes $outpath {*}$oldattrs
 mports_generate_quickindex $outpath
<span style='display:block; white-space:pre;background:#ffe0e0;'>-puts "\nTotal number of ports parsed:\t$stats(total)\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      \nPorts successfully parsed:\t[expr {$stats(total) - $stats(failed)}]\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      \nPorts failed:\t\t\t$stats(failed)\
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      \nUp-to-date ports skipped:\t$stats(skipped)\n"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+puts "\nTotal number of ports parsed:\t[dict get $stats total]\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      \nPorts successfully parsed:\t[expr {[dict get $stats total] - [dict get $stats failed]}]\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      \nPorts failed:\t\t\t[dict get $stats failed]\
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      \nUp-to-date ports skipped:\t[dict get $stats skipped]\n"
</span> 
<span style='display:block; white-space:pre;background:#ffe0e0;'>-if {${permit_error} && $stats(failed) > 0} {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+if {${permit_error} && [dict get $stats failed] > 0} {
</span>     exit 2
 }
</pre><pre style='margin:0'>

</pre>