queue.tcl

Go to the documentation of this file.
00001 /*  queue.tcl --*/
00002 /* */
00003 /*  Queue implementation for Tcl.*/
00004 /* */
00005 /*  Copyright (c) 1998-2000 by Ajuba Solutions.*/
00006 /* */
00007 /*  See the file "license.terms" for information on usage and redistribution*/
00008 /*  of this file, and for a DISCLAIMER OF ALL WARRANTIES.*/
00009 /*  */
00010 /*  RCS: @(#) $Id: queue.tcl,v 1.13 2005/09/30 23:48:41 andreas_kupries Exp $*/
00011 
00012 namespace ::struct {}
00013 namespace ::struct::queue {
00014     /*  The queues array holds all of the queues you've made*/
00015     variable queues
00016     
00017     /*  counter is used to give a unique name for unnamed queues*/
00018     variable counter 0
00019 
00020     /*  Only export one command, the one used to instantiate a new queue*/
00021     namespace export queue
00022 }
00023 
00024 /*  ::struct::queue::queue --*/
00025 /* */
00026 /*  Create a new queue with a given name; if no name is given, use*/
00027 /*  queueX, where X is a number.*/
00028 /* */
00029 /*  Arguments:*/
00030 /*  name    name of the queue; if null, generate one.*/
00031 /* */
00032 /*  Results:*/
00033 /*  name    name of the queue created*/
00034 
00035 ret  ::struct::queue::queue (type args) {
00036     variable queues
00037     variable counter
00038 
00039     switch -exact -- [llength [info level 0]] {
00040     1 {
00041         # Missing name, generate one.
00042         incr counter
00043         set name "queue${counter}"
00044     }
00045     2 {
00046         # Standard call. New empty queue.
00047         set name [lindex $args 0]
00048     }
00049     default {
00050         # Error.
00051         return -code error \
00052             "wrong # args: should be \"queue ?name?\""
00053     }
00054     }
00055 
00056     # FIRST, qualify the name.
00057     if {![string match "::*" $name]} {
00058         # Get caller's namespace; append :: if not global namespace.
00059         set ns [uplevel 1 [list namespace current]]
00060         if {"::" != $ns} {
00061             append ns "::"
00062         }
00063 
00064         set name "$ns$name"
00065     }
00066     if {[llength [info commands $name]]} {
00067     return -code error \
00068         "command \"$name\" already exists, unable to create queue"
00069     }
00070 
00071     # Initialize the queue as empty
00072     set queues($name) [list ]
00073 
00074     # Create the command to manipulate the queue
00075     interp alias {} $name {} ::struct::queue::QueueProc $name
00076 
00077     return $name
00078 }
00079 
00080 /* */
00081 /*  Private functions follow*/
00082 
00083 /*  ::struct::queue::QueueProc --*/
00084 /* */
00085 /*  Command that processes all queue object commands.*/
00086 /* */
00087 /*  Arguments:*/
00088 /*  name    name of the queue object to manipulate.*/
00089 /*  args    command name and args for the command*/
00090 /* */
00091 /*  Results:*/
00092 /*  Varies based on command to perform*/
00093 
00094 ret  ::struct::queue::QueueProc (type name , optional cmd ="" , type args) {
00095     # Do minimal args checks here
00096     if { [llength [info level 0]] == 2 } {
00097     error "wrong # args: should be \"$name option ?arg arg ...?\""
00098     }
00099     
00100     # Split the args into command and args components
00101     set sub _$cmd
00102     if { [llength [info commands ::struct::queue::$sub]] == 0 } {
00103     set optlist [lsort [info commands ::struct::queue::_*]]
00104     set xlist {}
00105     foreach p $optlist {
00106         set p [namespace tail $p]
00107         lappend xlist [string range $p 1 end]
00108     }
00109     set optlist [linsert [join $xlist ", "] "end-1" "or"]
00110     return -code error \
00111         "bad option \"$cmd\": must be $optlist"
00112     }
00113 
00114     uplevel 1 [linsert $args 0 ::struct::queue::_$cmd $name]
00115 }
00116 
00117 /*  ::struct::queue::_clear --*/
00118 /* */
00119 /*  Clear a queue.*/
00120 /* */
00121 /*  Arguments:*/
00122 /*  name    name of the queue object.*/
00123 /* */
00124 /*  Results:*/
00125 /*  None.*/
00126 
00127 ret  ::struct::queue::_clear (type name) {
00128     variable queues
00129     set queues($name) [list ]
00130     return
00131 }
00132 
00133 /*  ::struct::queue::_destroy --*/
00134 /* */
00135 /*  Destroy a queue object by removing it's storage space and */
00136 /*  eliminating it's proc.*/
00137 /* */
00138 /*  Arguments:*/
00139 /*  name    name of the queue object.*/
00140 /* */
00141 /*  Results:*/
00142 /*  None.*/
00143 
00144 ret  ::struct::queue::_destroy (type name) {
00145     variable queues
00146     unset queues($name)
00147     interp alias {} $name {}
00148     return
00149 }
00150 
00151 /*  ::struct::queue::_get --*/
00152 /* */
00153 /*  Get an item from a queue.*/
00154 /* */
00155 /*  Arguments:*/
00156 /*  name    name of the queue object.*/
00157 /*  count   number of items to get; defaults to 1*/
00158 /* */
00159 /*  Results:*/
00160 /*  item    first count items from the queue; if there are not enough */
00161 /*      items in the queue, throws an error.*/
00162 
00163 ret  ::struct::queue::_get (type name , optional count =1) {
00164     variable queues
00165     if { $count < 1 } {
00166     error "invalid item count $count"
00167     }
00168 
00169     if { $count > [llength $queues($name)] } {
00170     error "insufficient items in queue to fill request"
00171     }
00172 
00173     if { $count == 1 } {
00174     # Handle this as a special case, so single item gets aren't listified
00175     set item [lindex $queues($name) 0]
00176     set queues($name) [lreplace $queues($name) 0 0]
00177     return $item
00178     }
00179 
00180     # Otherwise, return a list of items
00181     set index [expr {$count - 1}]
00182     set result [lrange $queues($name) 0 $index]
00183     set queues($name) [lreplace $queues($name) 0 $index]
00184 
00185     return $result
00186 }
00187 
00188 /*  ::struct::queue::_peek --*/
00189 /* */
00190 /*  Retrieve the value of an item on the queue without removing it.*/
00191 /* */
00192 /*  Arguments:*/
00193 /*  name    name of the queue object.*/
00194 /*  count   number of items to peek; defaults to 1*/
00195 /* */
00196 /*  Results:*/
00197 /*  items   top count items from the queue; if there are not enough items*/
00198 /*      to fulfill the request, throws an error.*/
00199 
00200 ret  ::struct::queue::_peek (type name , optional count =1) {
00201     variable queues
00202     if { $count < 1 } {
00203     error "invalid item count $count"
00204     }
00205 
00206     if { $count > [llength $queues($name)] } {
00207     error "insufficient items in queue to fill request"
00208     }
00209 
00210     if { $count == 1 } {
00211     # Handle this as a special case, so single item pops aren't listified
00212     return [lindex $queues($name) 0]
00213     }
00214 
00215     # Otherwise, return a list of items
00216     set index [expr {$count - 1}]
00217     return [lrange $queues($name) 0 $index]
00218 }
00219 
00220 /*  ::struct::queue::_put --*/
00221 /* */
00222 /*  Put an item into a queue.*/
00223 /* */
00224 /*  Arguments:*/
00225 /*  name    name of the queue object*/
00226 /*  args    items to put.*/
00227 /* */
00228 /*  Results:*/
00229 /*  None.*/
00230 
00231 ret  ::struct::queue::_put (type name , type args) {
00232     variable queues
00233     if { [llength $args] == 0 } {
00234     error "wrong # args: should be \"$name put item ?item ...?\""
00235     }
00236     foreach item $args {
00237     lappend queues($name) $item
00238     }
00239     return
00240 }
00241 
00242 /*  ::struct::queue::_unget --*/
00243 /* */
00244 /*  Put an item into a queue. At the _front_!*/
00245 /* */
00246 /*  Arguments:*/
00247 /*  name    name of the queue object*/
00248 /*  item    item to put at the front of the queue*/
00249 /* */
00250 /*  Results:*/
00251 /*  None.*/
00252 
00253 ret  ::struct::queue::_unget (type name , type item) {
00254     variable queues
00255     if {![llength $queues($name)]} {
00256     set queues($name) [list $item]
00257     } else {
00258     set queues($name) [linsert $queues($name) 0 $item]
00259     }
00260     return
00261 }
00262 
00263 /*  ::struct::queue::_size --*/
00264 /* */
00265 /*  Return the number of objects on a queue.*/
00266 /* */
00267 /*  Arguments:*/
00268 /*  name    name of the queue object.*/
00269 /* */
00270 /*  Results:*/
00271 /*  count   number of items on the queue.*/
00272 
00273 ret  ::struct::queue::_size (type name) {
00274     variable queues
00275     return [llength $queues($name)]
00276 }
00277 
00278 /*  ### ### ### ######### ######### #########*/
00279 /*  Ready*/
00280 
00281 namespace ::struct {
00282     /*  Get 'queue::queue' into the general structure namespace.*/
00283     namespace import -force queue::queue
00284     namespace export queue
00285 }
00286 package provide struct::queue 1.4
00287 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1