TCL Routines to manipulate handles
Dervish doesn't allow a user to make use of raw C pointers, rather you must
use handles which are in essence typed pointers. At the C level, a handle is
simply a struct:
typedef struct {
void *ptr;
TYPE type;
} HANDLE;
whereas in TCL they are referred to by name, for example "h12". It is usually
helpful to think of a handle as being the object itself rather than a pointer
to it when working from TCL (this may make more sense when you remember that
when you manipulate a variable i in C or any other language you are really
manipulating the place where i's value is stored, in other words an address).
handleNew
handleNewFromType
handleDelFromType
handleBind
handleDel
handleGet
handleList
handleNameGet
handlePrint
handleDeref
handleDerefAndSet
handleExprEval
handleSet
handleSetFromHandle
handleBindFromHandle
expr
There are also a few utility verbs, written in TCL:
handleBindNew
handleDup
handlePtr
handleType
And a few verbs which deal with expressions:
exprGet
exprPrint
handleSet
Make a new thing of the specified type-name, using the constructor specified
in the schema definition.
TCL SYNTAX:
handleNewFromType <type-name>
<type-name> The type of the object to create.
RETURNS:
TCL_OK Successful completion. Returns the name of the new handle.
TCL_ERROR Error occurred.
Delete the object pointed to by a handle using the destructor specified in the
schema definition. The handle type is changed to UNKNOWN and the handle
pointer set to 0x0.
TCL SYNTAX:
handleDelFromType <handle>
<handle> The handle name of the object to delete.
RETURNS:
TCL_OK Successful completion.
TCL_ERROR Error occurred.
Associate a pointer and a type with a handle.
TCL SYNTAX:
handleBind <handle> <address> <type>
<handle> The name of a pre-existing handle, e.g. h11
<address> The address to bind to the handle, e.g. 0x1234af
<type> The type of the object at <address>, e.g. REGION. You can
use a numerical type if you wish (e.g. 1008).
RETURNS:
TCL_OK Successful completion. No result string.
TCL_ERROR Error occurred.
Delete a handle (but not the pointer bound to it).
TCL SYNTAX:
handleDel <handle>
<handle> The name of a handle, e.g. h11
RETURNS:
TCL_OK Successful completion. No result string.
TCL_ERROR Error occurred.
Return all existing handle's pointers and types as a Tcl list.
TCL SYNTAX:
handleList
RETURNS:
TCL_OK Successful completion. Returns "address type", e.g.
0x1234af REGION for each existing handle
TCL_ERROR Error occurred.
Given an address return a handle.
TCL SYNTAX:
handleNameGet <address>
<address> An address bound to handle, e.g. 0x1234af
RETURNS:
TCL_OK Successful completion. Returns a handle, e.g. h11
TCL_ERROR Error occurred.
Return a handle's pointer and type.
TCL SYNTAX:
handleGet <handle>
<handle> The name of a handle, e.g. h11
RETURNS:
TCL_OK Successful completion. Returns "address type", e.g.
0x1234af REGION
TCL_ERROR Error occurred.
Print a handle's pointer and type.
TCL SYNTAX:
handlePrint <handle>
<handle> The name of a handle, e.g. h11
RETURNS:
TCL_OK Successful completion. Prints "address type", e.g.
0x1234af REGION
TCL_ERROR Error occurred.
Return whatever is pointed to by a <handle>; in C, `*(void **)handle'.
TCL SYNTAX:
handleDeref <handle>
<handle> The desired handle, e.g. h12
RETURNS:
TCL_OK Successful completion. Returns the value (e.g. 123.45)
TCL_ERROR Error occurred.
Set what a <handle> points to to a <value>;
in C, *(int *)handle = value. Of course, the value can be a pointer. Note
that the object being set is assumed to have the length of an int; you
cannot use this verb to set char or short values.
TCL SYNTAX:
handleDerefAndSet <handle> <value>
<handle> The handle in question, e.g. h12
<value> The value to set the handle to, e.g. 1234.
RETURNS:
TCL_OK Successful completion. Returns the value (e.g. 1234)
TCL_ERROR Error occurred.
NOTE: This command is obsolete; use handleSet, which allows more types for
<value> and which allows <handle> to be a handle expression
Evaluate an expression involving an expression <expr>. The result is
returned as a string of the form `addr type' ready to be bound to a handle.
For example,
handleExprEval h12.mask->rows<1><2>
might return
0x1234 CHAR
so the command
exprPrint [eval handleBindNew [handleExprEval h12.mask->rows<1><2>]]
might print `\041'. (you need the eval as handleExprEval returns a list
consisting of two strings which handleBindNew treats as a single argument).
NOTE: You might consider using exprGet if
you only intend to get the value of of the handle expression.
TCL SYNTAX:
handleExprEval <expr>
<expr> The expression you want evaluated, e.g. h12.mask->rows<1><2>
RETURNS:
TCL_OK Successful completion. Returns the value and type
(e.g. 0xabcd CHAR)
TCL_ERROR Error occurred.
The grammar for expressions acceptable to handleExprEval is a subset of the
full C grammar, in particular the relevant part of operator table from
K&R (table 2-1) is:
Operators Associativity
() [] <> -> . left to right
* & (type) right to left
You can use either [] or <> to subscript expressions, but note that the
former are special to TCL so you'll have to quote the whole expression
with {}.
Note that two or higher dimensional arrays are treated as if they
are really pointers to pointers (to pointers...) rather than C's
rather useless n-dimensional arrays (e.g. float cc[4][5]).
There are a number of utility functions to make handleExprEval easier
to use, in particular exprGet.
Set what a <handle> points to to a <value>;
in C, *(int *)handle = value. See the overview
for some examples.
TCL SYNTAX:
handleSet <handle> <value>
<handle> The handle expression in question, e.g. h12
<value> The value to set the handle to, e.g. 1234. It can be any
type described be a Schema. It can be simple type like int, float,
double, char, ptr, string, unsigned int, etc ...
It even can be a complexe type like REGION or arrays; to describe
those simply list in order all the values of the different elements
of the struct or the array in a tcl list.
RETURNS:
TCL_OK Successful completion.
TCL_ERROR Error occurred.
Copies what a <handle> from another handle.
Arbitrary types are allowed.
TCL SYNTAX:
handleSetFromHandle <handle1> <handle2>
<handle1> A handle expression to the thing being copied to.
<handle2> A handle expression to the thing being copied from.
The handles are checked to make sure that they reference things of the same
type. A straight binary copy is made of the thing referenced by handle2 to
handle1. Thing can be a primitive type (e.g., an INT) or a more complicated
type (e.g., a region). NOTE: for complicated types like regions, only
the elements in the region structure are copied, not the rows and columns
of pixels themselves. In such cases, this command should be used with
caution to avoid orphaning bits of memory.
RETURNS:
TCL_OK Successful completion.
TCL_ERROR Error occurred.
Sets one handle to point to the same thing that another one does.
TCL SYNTAX:
handleBindFromHandle <handle1> <handle2>
<handle1> A null handle that will be bound to a new thing.
<handle2> A handle expression that points to the thing.
This command provides a safer way to bind a handle to a thing; it should
be used instead of handleBind, which requires one to use explicit addresses
at the TCL level.
RETURNS:
TCL_OK Successful completion.
TCL_ERROR Error occurred.
Calls the expression processor to evaluate arg, and returns the result as a
string. See the section EXPRESSIONS in TCL Man Pages for a detailed
description.
TCL SYNTAX:
expr <arg>
<arg> Argument to evaluate.
RETURNS:
TCL_OK Successful completion.
TCL_ERROR Error occurred.