WJG (06/01/18) Just before the Yultide holidays for some reason I got it into my mind to put together a simple queue command. Don't know why, I didn't need the functionality for any project I'm involved with. Anyway, here's what I came up with. The procedure queue will initialize a namespace ::Q:: within which a number of queues can be created, modified and accessed. Items can be processed directly using the command 'foreach' by supplying the name of a procedure utilized to handle each item in a queue, gradually nibblingly away at the front of that queue untill it's all eaten (erm, processed).
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh "$0" "$@"
#---------------
# Manage a queued list of items.
#---------------
#/param qid queue id, a unique string
#/param action action to be performes on the queue
#/param value relevant value
#/returns
#
proc queue { action {qid ""} {value ""} } {
set cmds [list add clear delete destroy fetch foreach front get item lower names new prioritize raise rear reverse remove search ]
if { [lsearch $cmds $action] == -1 } {
set msg "No such cmd \"$action\". Must be one of: $cmds."
error $msg
}
if { ![namespace exists ::Q] } { namespace eval ::Q {} }
if { $action eq "names" } { return [string map "::Q:: {}" [info vars ::Q::*]] }
if { $action ne "new" && ![info exists ::Q::$qid] } {
set msg "No such queue \"$qid\". Must be one of: $cmds."
error $msg
}
set res ""
switch $action {
new {
# create new queue and initialize as an empty string
set ::Q::$qid ""
}
clear {
# clear the contents of an existing queue
set ::Q::$qid ""
}
add {
# append item to the end of the queue
foreach item [split $value] { lappend ::Q::$qid $item }
}
fetch {
# return complete list of items in the specified queue
return [set ::Q::$qid]
}
foreach {
# process each item in the queue usings named proceedure
set tmp [queue get $qid]
while {$tmp ne ""} { $value $tmp ; set tmp [queue get $qid] }
}
get {
# retrieve next item in the queue, for processing and then remove
set res [lindex [set ::Q::$qid] 0]
set ::Q::$qid [lrange [set ::Q::$qid] 1 end]
}
front {
# retrieve the first item in the specified queue
set res [lindex [set ::Q::$qid] 0]
}
item {
# retrieve the item in the specified queue
set res [lindex [set ::Q::$qid] $value]
}
last {
# retrieve final item in the specified queue
set res [lindex [set ::Q::$qid] end]
}
reverse {
# reverse the items in the specified queue
set ::Q::$qid [lreverse [set ::Q::$qid]]
}
raise -
lower {
# raise or lower position of indexed item in queue
if { $action eq "raise" } {
set pos(from) [expr $value-1]
set pos(to) $value
} else {
set pos(from) $value
set pos(to) [expr $value+1]
}
set tmp [lreverse [lrange [set ::Q::$qid] $pos(from) $pos(to)] ]
lassign $tmp a b
set ::Q::$qid [lreplace [set ::Q::$qid] $pos(from) $pos(to) $a $b ]
}
remove {
# remove item from queue based upon contents
set ::Q::$qid [lsearch -all -inline -not -exact [set ::Q::$qid] $value]
}
delete {
# delete item from queue based upon index
set ::Q::$qid [lreplace [set ::Q::$qid] $value $value]
}
search {
# search for item in queue based upon contents, return index if found, else -1
set res [lsearch [set ::Q::$qid] $value]
}
prioritize {
# move item to the heade of the queue
set item [lindex [set ::Q::$qid] $value]
set ::Q::$qid [lreplace [lreplace [set ::Q::$qid] $value $value] -1 -1 $item]
}
destroy {
# destroy queue and its contents
unset ::Q::$qid
}
}
return $res
}
#---------------
# Script Main Function
#---------------
# Arguments:
# args
# Returns:
# none
#
proc main { args } {
puts "READY..."
# create sample queues
queue new 001
queue new 002
queue new 003
# add items
foreach item { 0 1 2 3 4 5 6 7 8 9 } {
queue add 001 $item
}
foreach item { A B C D E F G H I J } {
queue add 002 $item
}
queue add 003 [list "/home/apple.txt" "/home/blackberry.txt" "/home/cherry.txt"]
# display contents
foreach item [queue names] {
puts "$item : [queue fetch $item]"
}
# other operations
puts "'5' is item [queue search 002 H] in queue 002."
puts "Item 4 in queue 002 is '[queue item 002 4]'."
puts [queue remove 001 5]
# shuffle the contents
queue prioritize 001 5
queue raise 002 3
queue lower 001 3
queue reverse 001
# process the available queues
foreach q [queue names] {
puts \n
while 1 {
set item [queue get $q]
if { $item eq "" } { break }
puts ${q}:$item
puts [queue fetch $q]
after 50
}
}
queue new 004
# add items
foreach item { how now brown cow she sells sea shells by the sea shore } {
queue add 004 $item
}
proc myPuts {args} {
puts ~~~>$args
}
queue foreach 004 myPuts
puts "DONE!"
}
main