TCL Expressions for Dervish Chains
Dervish provides an extensive array of primitive TCL expressions to support
chains. The following discussion details each TCL expression and whenever
appropriate, parts of a TCL procedure are included for illustrative purposes.
For an overview of DERVISH chains, including the definition of cursors and
indexes, press here.
All chain TCL extensions operate on the notion of a handle. Handles are
treated as a valuable resource and are reused wherever possible. Any TCL
extension that returns a handle to an object first checks to see if a handle
is already bound to that object. If so, the bound handle is returned. If a
handle is not bound to an object, a new handle will be created, bound to the
object and returned.
In the discussions for each TCL extension, the following conventions apply:
All required parameters are denoted by delimiting them with < and >,
example <CHAIN>
All optional parameters are denoted by delimiting them with [ and ];
example [pos]
All optional command line switches are denoted by preceeding the switch
with a - (negative sign); example -increasing
The Dervish chain package contains
contributed code as well which
complements, at the TCL level, the chain manipulation extensions provided below.
Description of TCL extensions
Creation and Deletion
chainNew
chainDel
chainDestroy
Miscellaneous Operations
chainTypeSet
chainTypeGet
chainTypeDefine
chainSize
chainJoin
chainCopy
chainSort
chainCursorNew
chainCursorSet
chainCursorDel
chainCursorCount
chainCursorCopy
Chain Maintenance (addition/removal/retreival/traversal)
chainElementAddByPos
chainElementRemByPos
chainElementGetByPos
chainElementTypeGetByPos
chainElementAddByCursor
chainElementRemByCursor
chainElementTypeGetByCursor
chainWalk
_______________________________________________________________________________
Creates a new chain and returns a handle bound to it. The type of the
chain must be specified as well. If a heterogeneous chain is to be
created, a type of GENERIC must be specified.
TCL SYNTAX:
chainNew <TYPE>
<TYPE> - type of the chain to create
RETURNS:
TCL_OK Successful completion. Interp result contains the handle of
the newly created chain
TCL_ERROR On an error. Interp result will contain reason for the error
_______________________________________________________________________________
Deletes an existing chain and all chain elements. Note that the data on each
chain element is not deleted. However, the chain and all it's elements
will be deleted.
TCL SYNTAX:
chainDel <CHAIN>
<CHAIN> handle of the chain to be deleted
RETURNS:
TCL_OK Successful completion. No result string
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
Deletes the specified chain, all chain elements, and all the data on associated
with each chain element.
Note that you can get into trouble applying this proc to a chain
if there are other places where the addresses of the objects on the
chain are stored (e.g. if the object appears on two chains).
This will, in fact, only bite for types that call shMalloc more than
once in their constructor (e.g. REGION). The problem is no worse than
any other way of getting the same pointer into multiple handles, so
don't worry too much about this warning.
SYNOPSIS:
chainDestroy <chain> <delProc>
<chain> handle to the chain to be destroyed
<delProc> name of a proc which deletes each element on the chain
which is passed a handle to the element. If omitted,
genericDel
is assumed
Returns:
0 : On success
1 : Otherwise
_______________________________________________________________________________
This extension changes the existing type of the chain to the new type
specified. It's the callers responsibility to ensure that all elements on the
chain are of the new type. This extension does not check for that; it simply
changes the type of the chain as indicated.
TCL_SYNTAX:
chainTypeSet <CHAIN> <TYPE>
<CHAIN> handle of the chain
<TYPE> new chain type
RETURNS:
TCL_OK Successful completion. No result string
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension returns the existing type of a chain as a TCL list.
TCL_SYNTAX:
chainTypeGet <CHAIN>
<CHAIN> handle of the chain
RETURNS:
TCL_OK Successful completion. Interp result contains the existing
type as a TCL list
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension defines the chain type according to the following conventions:
- if the chain is empty, return the original type as a TCL list
- if the chain TYPE is GENERIC, but the chain contains homogeneous elements,
return the type of the elements as a TCL list
- if the chain TYPE is GENERIC and the chain contains heterogeneous
elements, the chain type is left unchanged
TCL SYNTAX:
chainTypeDefine <CHAIN>
<CHAIN> handle of the chain
RETURNS:
TCL_OK Successful completion. Interp result contains the defined
type as a TCL list
TCL_ERROR Erroc occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension returns the chain size (number of elements on the chain).
TCL SYNTAX:
chainSize <CHAIN>
<CHAIN> handle of the chain
RETURNS
TCL_OK Successful completion. Interp result will contain the size
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension appends a target chain to a source chain. Both the chains
must be of the same type, unless the source chain is of type
GENERIC, in which case the target chain can be of any type. The
target chain will be destroyed on the success of this extension.
TCL SYNTAX:
chainJoin <SOURCE-CHAIN> <TARGET-CHAIN>
<SOUCRE-CHAIN> handle of the source chain
<TARGET-CHAIN> handle of the target chain. Will be destroyed on a
successful completion
RETURNS:
TCL_OK Successful completion. Interp result will contain <SOURCE-CHAIN>
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension copies a given chain. The copied chain does not inherit
any cursor information from the parent. Interp result will contain a handle
bound to the newly copied chain.
TCL SYNTAX:
chainCopy <CHAIN>
<CHAIN> handle of the chain to copy
RETURNS:
TCL_OK Successful completion. Interp result will contain a handle bound
to the newly created chain
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension sorts a chain according to a specified criterion. The chain to
be sorted must be homogeneous. Note that since sorting involves moving the
chain element pointers around, cursor information set on the chain prior to a
call to this extension will be lost.
TCL SYNTAX:
chainSort <CHAIN> <FIELD> -increasing
<CHAIN> handle of the chain to sort
<FIELD> field name to sort on
-increasing Direction of the sort; if specified on the TCL command line,
the sort is performed in an ascending fashion
RETURNS:
TCL_OK Successful completion. No result string
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension creates a new cursor on a chain. A chain can have upto 10
simultaneous active cursors. A cursor can be viewed as a context sensitive
device on a chain; i.e. it holds the context of the chain. Cursors are helpful
while traversing chains using chainWalk
and modifying the state of the chain using
chainElementAddByCursor and
chainElementRemByCursor.
This extension creates a chain cursor and initializes it to point to the first
element on the chain. If the chain is empty, this extension is smart enough to
wait till the first element is added, upon which time the cursor is initialized
to the first element.
TCL SYNTAX:
chainCursorNew <CHAIN>
<CHAIN> Handle of the chain
RETURNS:
TCL_OK Successful completion. Interp result will contain a handle
to the newly created cursor
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
dervish> chainNew GENERIC
h1
dervish> chainCursorNew h1
h2
. . .
_______________________________________________________________________________
This extension initializes a cursor to an element on the chain. The cursor
must have been previously created using
chainCursorNew. This extension will
return an error if the chain is empty.
TCL SYNTAX
chainCursorSet <CHAIN> <CURSOR> [n]
<CHAIN> Handle of the chain
<CURSOR> Handle of the cursor previously created
[n] Optional parameter that specifies the chain element to set
the cursor to. Default value: HEAD
RETURNS:
TCL_OK Successful completion. Interp result will contain a handle
of the nth element on the chain
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
# The following example:
# 1) declares a chain
# 2) inserts two elements on it
# 3) declares a cursor and sets it to the TAIL of the chain
dervish> chainNew GENERIC
h1
dervish> chainElementAddByPos h1 [regNew]
dervish> chainElementAddByPos h1 [ptNew]
dervish> chainCursorNew h1
h4
dervish> chainCursorSet h1 h4 TAIL
h3
. . .
_______________________________________________________________________________
This extension copies an existing cursor. A new cursor is created that holds
the same information as the existing one.
TCL SYNTAX
chainCursorCopy <CHAIN> <CURSOR>
<CHAIN> Handle of the chain
<CURSOR> Handle of the existing cursor
RETURNS:
TCL_OK Successful completion. Interp result will contain a handle
of the newly created cursor
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension deletes a chain cursor. The cursor to be deleted should have
been created with a call to the extension
chainCursorNew
TCL SYNTAX
chainCursorDel <CHAIN> <CURSOR>
<CHAIN> Handle of the chain
<CURSOR> Handle of the cursor to be deleted
RETURNS:
TCL_OK Successful completion. No result string
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension returns a count of all active cursors associated with a chain.
TCL SYNTAX
chainCursorCount <CHAIN>
<CHAIN> Handle of the chain
RETURNS:
TCL_OK Successful completion. Interp result contains the count
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension inserts a new element onto the chain. The new element is added
relative to a fixed position which is specified on the Tcl command line. The
new element can be added either before or after the specified
position. The specified position and relativity are ignored when the very
first element is added to a chain.
Unless the chain is of type GENERIC, the element to be added should be
of the same type as the chain's type.
TCL SYNTAX
chainElementAddByPos <CHAIN> <ELEMENT> [n] [how]
<CHAIN> Handle of the chain
<ELEMENT> Handle of the element to be inserted
[n] New element is added in relation to element at this position
Default value: "TAIL"
[how] How to add the new element in relation to the nth element
Default value: "AFTER"
RETURNS:
TCL_OK Successful completion. No result string
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
# The following example demonstrates how to:
# 1) Create a chain
# 2) Add the first element to it
# 3) Append the next element to the chain
# 4) Add the third element in between the two existing elements
dervish> chainNew GENERIC
h1
dervish> chainElementAddByPos h1 [regNew]
dervish> chainElementAddByPos h1 [maskNew]
dervish> chainElementAddByPos h1 [ptNew] 2 BEFORE
dervish> . . .
_______________________________________________________________________________
This extension removes an element from the chain. The index of the element to
be removed is specified on the TCL command line. Since chains are 0-indexed,
this index must be in the interval [0, size of chain]
TCL SYNTAX
chainElementRemByPos <CHAIN> <position>
<CHAIN> Handle of the chain
<position> Position in chain of the desired element. One can specify
either HEAD or TAIL or an integer
RETURNS:
TCL_OK Successful completion. Interp result contains a handle bound
to the element that was removed from the chain
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
# Assume we have a chain of 10 elements. To delete the 4th element
# one would say:
dervish> chainElementRemByPos h1 3
h3
# So, now we have 9 elements. To delete the first element, one would say:
dervish> chainElementRemByPos h1 HEAD
h5
# So, now we have 8 elements. To delete the 3rd element from head of the
# chain, one would say:
dervish> chainElementRemByPos h1 2
h2
dervish> . . .
_______________________________________________________________________________
This extension retrieves an element from the chain. The index of the element to
be retrieved is specified on the TCL command line. Since chains are 0-indexed,
this index must be in the interval [0, size of chain]
TCL SYNTAX
chainElementGetByPos <CHAIN> <position>
<CHAIN> Handle of the chain
<position> Position in chain of the desired element. One can specify
either HEAD or TAIL or an integer
RETURNS:
TCL_OK Successful completion. Interp result contains a handle bound
to the retrieved element
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
# Assume we have a chain of 10 elements. To get a handle to the 4th
# element of the chain, one would say:
dervish> chainElementGetByPos h1 3
h3
# To get a handle to the first element, one would say:
dervish> chainElementGetByPos h1 HEAD
h5
# To get a handle to the last element, one would say:
dervish> chainElementGetByPos h1 TAIL
h10
_______________________________________________________________________________
This extension gets the type of a requested element from the chain. The type
is returned as a TCL list.
TCL SYNTAX
chainElementTypeGetByPos <CHAIN> <position>
<CHAIN> Handle of the chain
<position> Position in chain of the desired element. One can specify
either HEAD or TAIL or an integer
RETURNS:
TCL_OK Successful completion. Interp result contains a TCL list of
the requested information
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
dervish> chainNew MASK
h1
dervish> chainElementAddByPos h1 [maskNew]
dervish> chainElementTypeGetByPos h1 HEAD
{type "MASK"}
dervish> . . .
_______________________________________________________________________________
This extension adds a new element in relation to the cursor. The new element
can be added either before or after the cursor. The cursor is
supposed to have been correctly created and initialized. As the result of
this extension, the cursor is set to the newly added element.
TCL SYNTAX
chainElementAddByCursor <CHAIN> <ELEMENT> <CURSOR> [how]
<CHAIN> Handle of the chain
<ELEMENT> Handle of the element to be added on the chain
<CURSOR> Handle of the cursor
[how] How to add the new element in relation to the cursor; can be
one of "BEFORE" or "AFTER." Default value: "AFTER"
RETURNS:
TCL_OK Successful completion. No result string
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
dervish> chainNew MASK
h1
dervish> chainCursorNew h1
h2
dervish> chainElementAddByPos h1 [maskNew -name MASK1]
dervish> chainCursorSet h1 h2
h3
dervish> chainElementAddByCursor h1 [maskNew -name MASK2] h2
dervish> chainElementAddByCursor h1 [maskNew -name MASK3] h2 BEFORE
dervish> chainSize h1
3
. . .
_______________________________________________________________________________
This extension removes an element from a chain. The element to be removed is
referenced by the cursor. On a successful removal, the cursor is set to NULL.
Any attempts to retrieve the deleted element will result in failure. Since
an element can be deleted while traversing a chain using
chainWalk, chainElementRemByCursor
saves the locations of the neighbors of the deleted element so that the
chain can still be traversed.
TCL SYNTAX
chainElementRemByCursor <CHAIN> <CURSOR>
<CHAIN> Handle of the chain
<CURSOR> Handle of the cursor
RETURNS:
TCL_OK Successful completion. Interp result will contain a handle
bound to the deleted element
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
# Assume we have a chain (h1) with 3 elements on it. Let's
# 1) create e new cursor
# 2) set it to the 2nd element
# 3) delete that element
dervish> chainCursorNew h1
h7
dervish> chainCursorSet h1 h7 2
h3
dervish> chainElementRemByCursor h1 h7
h3
. . .
_______________________________________________________________________________
This extension gets the type of the element under the cursor.
TCL SYNTAX
chainElementTypeGetByCursor <CHAIN> <CURSOR>
<CHAIN> Handle of the chain
<CURSOR> Handle of the cursor
RETURNS:
TCL_OK Successful completion. Interp result will contain the type of
the element under the cursor as a TCL list
TCL_ERROR Error occurred. Interp result will contain the reason
_______________________________________________________________________________
This extension traverses a chain using a cursor. The state of a chain can be
changed during traversal; i.e. new elements can be added, or existing elements
deleted. Addition and deletion are done relative to the cursor, so the
appropriate cursor APIs (
chainElementAddByCursor,
chainElementRemByCursor)
should be used.
Direction of traversal relative to the cursor can be one of THIS (the current
element is fetched), NEXT (the next element is fetched) or PREVIOUS (the
previous element is fetched).
Two TCL extensions may be used as a preamble to traversing a chain:
chainCursorNew and chainCursorSet. chainCursorNew
actually sets the cursor to one element before the start of
the chain, so that the first chainWalk moves the cursor to the first
element. chainCursorSet provides the ability to set a cursor to the
start, or end of a chain. If this extension is used as a preamble to chain
traversal, the cursor is actually set to one element before (after) the start
(end) of the chain.
chainWalk normally returns a handle bound to the appropriate element
on the chain. On reaching the end of the chain, an empty string is returned in
the interpreter.
TCL SYNTAX
chainWalk <CHAIN> <CURSOR> [whither]
<CHAIN> Handle of the chain
<CURSOR> Handle of the cursor
[whither] Traversal direction; one of PREVIOUS, THIS, or NEXT. Defaults
to NEXT
RETURNS:
TCL_OK Successful completion. Interp result will contain a handle
bound to the chain element being traversed. On reaching the
end of the chain, the interpreter will contain an empty string.
TCL_ERROR Error occurred. Interp result will contain the reason
EXAMPLE:
# In all the examples below, assume we have a chain (h1) that has already
# been populated with 3 elements.
#
# Example 1 demonstrates how to walk the chain using a newly created
# cursor. Note that on reaching the end of the chain, if user wants
# to keep on walking, the first element is returned
#
# Example 2 initializes the cursor to the TAIL of the chain, and loops
# through the chain, applying a TCL extension to each element
# on the chain
# Example 1
dervish> chainCursorNew h1
h5
dervish> chainWalk h1 h5 NEXT
h3
dervish> chainWalk h1 h5 NEXT
h2
dervish> chainWalk h1 h5 NEXT
h4
dervish> chainWalk h1 h5 NEXT
dervish>
dervish> chainWalk h1 h5 NEXT
h3
dervish>
. . .
# Example 2
dervish> chainCursorSet h1 h5 TAIL
dervish> while {[set elem [chainWalk h1 h5 PREVIOUS]] != ""} {
>> exprPrint -header $elem
>> }
. . .
_______________________________________________________________________________