Dervish Handle Expression Printing Facility

This document describes the Dervish tcl functions that give access to handles, their schema and their values.

Table of Contents

  • Overview
  • Reference Pages
  • Appendixes

  • Overview

    Introduction

    We can distinguish 4 categories of functions:

    Throughout this document we will be using the following BOGUS schema in the examples of the use of the functions:

    struct BOGUS:

    	name 	 "char*"
    	Label 	 "char[80]"
    	nrow 	 "int"
    	type 	 "PIXDATATYPE"
    	mask 	 "MASK*"
    	hdr 	 "HDR"
    	all_mask "MASK[10]"

    We followed these rules in designing these functions:

    Functions Giving Access To Schema.

    schemaGetFullFromType in itself gives enough information to provide for any schema info need. However some additional functions simplify everybody's life. Hence we are providing both getting schema info from a type and from an handle. We will also provide a simpler version which gives information only about types and not about alignment and data size.

    schemaGetFullFromType <type>
    schemaGetFull <handle expr>
    Return the complete definition of a schema in the form used by schemaDefine.

    schemaGet <handle expr>
    schemaGetFromType <type>
    Return a list containing the schema of a data type or handle.

    schemaPrint <handle expr>
    schemaPrintFromType <type>
    Print the schema of a handle or data type.

    schemaKindGetFromType <type>
    schemaKindGet <handle expr>
    return UNKNOWN, PRIM, ENUM or STRUCT for the schema given by the type or handle.

    schemaMemberGet <type> <elem>
    Return a list containing the schema of an elem of schema. This is particularly helpfull to look at schema when you can or don't want to create an instance of it.

    cTypeGet <handle expr>
    return the actual C type of the handle expression.

    Examples:

    <dervish> schemaGetFullFromType BOGUS
    {BOGUS STRUCT 384 7} {name char 1 NULL 0} {Label char 0 80 4}
    {nrow int 0 NULL 84} {type PIXDATATYPE 0 NULL 88}
    {mask MASK 1 NULL 92} {hdr HDR 0 NULL 96} {all_mask MASK 0 10 104}
    
    <dervish> schemaPrintFullFromType BOGUS
    BOGUS	STRUCT 	384 	7
    name 	char	1	NULL 	0
    Label 	char	0 	80 	4
    nrow 	int	0 	NULL	84
    type 	PIXDATATYPE 0	NULL 	88
    mask 	MASK	1	NULL	92
    hdr 	HDR	0 	NULL	96
    all_mask MASK	0 	10 	104
    
    <dervish> schemaGetFromType BOGUS  
    {name char*} {Label {char[80]}} {nrow int}
    {type PIXDATATYPE} {mask MASK*} {hdr HDR} {all_mask {MASK[10]}}
    
    <dervish> schemaPrintFromType BOGUS
    name char*
    Label {char[80]}
    nrow int
    type PIXDATATYPE
    mask MASK*
    hdr HDR
    all_mask {MASK[10]}
    
    <dervish> schemaKindGetFromType BOGUS
    STRUCT
    
    <dervish> schemaKindGet h1.name
    PRIM
    
    <dervish> cTypeGet h1
    BOGUS
    
    <dervish> cTypeGet h1.Label
    char<80>
    
    <dervish> cTypeGet h1.mask
    MASK*
    
    <dervish> cTypeGet h1.hdr
    HDR
    

    Functions Giving Access to Handles.

    The following can probably be reduced to handleGet and handleNameGet since the output of handlePrint and handleGet is the name (except for its direction: stdout vs tcl interp stack).

    Numerous other small functions have been written to facilitate the use of the followings functions (eg. handlePtr, handleType, etc...).

    handlePrint <handle expr>
    Prints the address and type of the 'object' pointed by the handle expression
    handleGet <handle expr>
    Returns the address and type of the 'object' pointed by the handle expression
    handleNameGet <address>
    Return the name of the handle pointing to address if it exits.
    Examples:

    <dervish> handlePrint h1
    0x104fe660 REGION
    
    <dervish> handlePrint h1.hdr
    0x104fe69c HDR
    
    <dervish> handlePrint h1.mask
    0x104fe690 PTR
    
    <dervish> handleNameGet 0x104fe660
    h1
    

    Functions Giving Access to the Content of Handles.

    ExprGet can returns the content of a C stuctures in many differents format.

    As a reminder a handle expression can have a type cast. This allow you to give specify how Dervish is to interpret what the handle is pointing to!

    exprGet [switches] <handle expr>
    Return a list giving the values of <handle expr>

    exprPrint [switches] <handle expr>
    Print the content of <handle expr> This is a pretty presentation of the result of exprGet

    Possible switches:
    Examples:

    <dervish> exprGet h0
    {name h0} {Label {This is a label}} {nrow 10} {type {(enum) TYPE_U16}}
    {mask 0x14095dc28} {hdr ...} {all_mask 0x14094efc0}
    
    <dervish> exprGet -recurse -nostring h0
    {name 0x14095d9a8} {Label 0x14094ef50} {nrow 10} {type {(enum) TYPE_U16}}
    {mask 0x14095dc28} {hdr {{modCnt 100} {hdrVec 0x0}}} {all_mask 0x14094efc0}
    
    <dervish> exprGet -header -unfold -enum h0
    {type BOGUS} {name h0} {Label {This is a label}} {nrow 10} {type TYPE_U16}
    {mask 0x14095dc28} {hdr ...} {all_mask {{<0> ...} {<1> ...} {<2> ...}}}
    
    <dervish> exprGet -header -unfold -enum -recurse h0
    {type BOGUS} {name h0} {Label {This is a label}} {nrow 10} {type TYPE_U16}
    {mask 0x14095dc28} {hdr {{modCnt 100} {hdrVec 0x0}}} {all_mask
    {{<0> {{name all_mask_0} {nrow 10} {ncol 1} {rows 0x0} {row0 0} {col0 0} {prvt 0x0}}}
    {<1> {{name all_mask_1} {nrow 20} {ncol 2} {rows 0x0} {row0 0} {col0 0} {prvt 0x0}}}
    {<2> {{name all_mask_2} {nrow 30} {ncol 3} {rows 0x0} {row0 0} {col0 0} {prvt 0x0}}}}}
    
    <dervish> exprGet -flat -unfold -recurse -enum -nolabel h0
    
    {type BOGUS} {name h0} {Label {This is a label}} {nrow 10} {type TYPE_U16}
    {mask 0x14095dc28} {hdr {{modCnt 100} {hdrVec 0x0}}} {all_mask
    {{<0> {{name all_mask_0} {nrow 10} {ncol 1} {rows 0x0} {row0 0} {col0 0} {prvt 0x0}}}
    {<1> {{name all_mask_1} {nrow 20} {ncol 2} {rows 0x0} {row0 0} {col0 0} {prvt 0x0}}}
    {<2> {{name all_mask_2} {nrow 30} {ncol 3} {rows 0x0} {row0 0} {col0 0} {prvt 0x0}}}}}
    
    <dervish> exprGet h0.Label
    {This is a label}
    
    <dervish> exprGet -nostring h0.Label
    0x14095d9a8
    
    <dervish> exprGet -header h0.Label
    {type STR} {This is a label}
    
    <dervish> exprGet -header -nostring h0.Label
    {type STR} 0x14094ef50
    
    <dervish> exprGet h0.nrow
    10
    
    <dervish> exprGet -header h0.nrow
    {type INT} 10
    
    <dervish> exprPrint h1
    (h0).name            "h0"
    (h0).Label           "This is a label"
    (h0).nrow            10
    (h0).type            (enum) TYPE_U16
    (h0).mask            (handle)h1
    (h0).hdr             ...
    (h0).all_mask        0x14094efc0
    
    <dervish> exprPrint -recurse -nostring h1
    (h0).name            0x14095d9a8
    (h0).Label           0x14094ef50
    (h0).nrow            10
    (h0).type            (enum) TYPE_U16
    (h0).mask            (handle)h1
    (h0).hdr.modCnt      100
    (h0).hdr.hdrVec      0x0
    (h0).all_mask        0x14094efc0
    
    <dervish> exprPrint -header -unfold -enum h1 
    (h0).name            "h0"
    (h0).Label           "This is a label"
    (h0).nrow            10
    (h0).type            TYPE_U16
    (h0).mask            (handle)h1
    (h0).hdr             ...
    (h0).all_mask<0>     ...
    (h0).all_mask<1>     ...
    (h0).all_mask<2>     ...
    
    And with h0.f being an array defined as followed: float f<5><4><3>
    <dervish> exprPrint -header -unfold h0.f
    h0.f                 PTR
    (h0.f).<0><0><0>     0
    (h0.f).<0><0><1>     0
    (h0.f).<0><0><2>     0
    (h0.f).<0><1><0>     0
    (h0.f).<0><1><1>     0
    (h0.f).<0><1><2>     0
    (h0.f).<0><2><0>     0
    etc ...
    
    <dervish> exprPrint -header -unfold -flat h0.f
    h0.f                 PTR
    h0.f                     0  0  0   0  0  0   0  0  0   0  0  0    0  0  0   0  0  0   0  0  0   0  0  0    0  0  0   0  0  0   0  0  0   0  0  0    0  0  0   0  0  0   0  0  0   0  0  0    0  0  0   0  0  0   0  0  0   0  0  0
    
    <dervish> exprPrint -header -unfold -limited 2 h0.f
    h0.f                 PTR
    (h0.f).<0>              0  0  0   0  0  0   0  0  0   0  0  0
    (h0.f).<1>              0  0  0   0  0  0   0  0  0   0  0  0
    (h0.f).<2>              0  0  0   0  0  0   0  0  0   0  0  0
    (h0.f).<3>              0  0  0   0  0  0   0  0  0   0  0  0
    (h0.f).<4>              0  0  0   0  0  0   0  0  0   0  0  0
    
    <dervish> exprPrint -header -unfold -limited 1 h0.f
    h0.f                 PTR
    (h0.f).<0><0>          0  0  0
    (h0.f).<0><1>          0  0  0
    (h0.f).<0><2>          0  0  0
    (h0.f).<0><3>          0  0  0
    (h0.f).<1><0>          0  0  0
    (h0.f).<1><1>          0  0  0
    (h0.f).<1><2>          0  0  0
    (h0.f).<1><3>          0  0  0
    (h0.f).<2><0>          0  0  0
    (h0.f).<2><1>          0  0  0
    (h0.f).<2><2>          0  0  0
    (h0.f).<2><3>          0  0  0
    (h0.f).<3><0>          0  0  0
    (h0.f).<3><1>          0  0  0
    (h0.f).<3><2>          0  0  0
    (h0.f).<3><3>          0  0  0
    (h0.f).<4><0>          0  0  0
    (h0.f).<4><1>          0  0  0
    (h0.f).<4><2>          0  0  0
    (h0.f).<4><3>          0  0  0
    

    Functions to Set the Contents of Handles.

    handleSet <handle expr> value
    Set memory pointed to by <handle expr> to <value>.
    <value> can be of numerical type, or a string, or a list (in which case we do the equivalent of an arraySet).
    handleSetFromHandle <handle expr> <handle>
    Copy the contents of handle to the location pointed to by <handle expr>
    The value passed to handleSet must be of the same type as the the object pointed to by the handle expression. For arrays and struct you can pass a list of value.

    Examples:

    <dervish> handleSet $header { 100 0x109283091 }
    
    <dervish> handleSet $region { Name 100 100 TYPE_U16 0x01298301 0x0 0x
    0x01298301 0x0 0x0 0x0 0x0 0x0 10 10 { 50 0x119823 } 0x987126 }
    
    

    Limitations with Character Strings

    When character strings are returned as part of an array of character strings ( char* or char[] ), they are quoted to allow Tcl lists to represent the array. This behaviour can cause a problem. Consider a character string which contains one or more quote characters (open or close brace ({})) that is returned as part of an array of character strings (here, the field contains 2 character strings per row):

         <dervish> exprGet h1
         {name {abc}def}} {value {0}}
    
    Problems will occur when trying to access one of the array elements. Consider:
         <dervish> set x [exprGet h1.name]
         {name {abc}def}} {value {0}}
         <dervish> lindex $x 0
         Error: list element in braces followed by "def}" instead of space
    

    NOTE: If exprGet were to quote the brace with a backslash (\), behaviour would not be as expected. Consider:

         <dervish> set x [exprGet h1.name]
         {abc\}def}  {xyz}
         <dervish> string index [lindex $x 0] 3
         \
    
    Notice that the backslash (\) is treated by Tcl as part of the string rather than quoting the character following it.

    Reference Pages

    Summary

    A few of these functions are not yet available (NA).

    exprGet

    Return a nested keyed list of the value of an handle expression. See the overview on exprGet for more details.

    exprGet h4 exprGet &h4 exprGet h4.mask exprGet (&h4)->mask exprGet h4.mask->nrow exprGet h4.mask->rows<1><2> exprGet *((FOO*)h12.first)->next->next exprGet "*((FOO *)h12.first)->next->next" The quotes are needed if you want to include white space in your expression.

    Note well 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]). This will be fixed when I get a chance to work on the schema package a little more.

    TCL SYNTAX: exprGet -enum -flat -header -nostring -recurse -unfold <expr> -help <expr> An expression involving a handle, e.g. h4.mask->nrow. -enum: Do not remove the '(enum)' in front of enums values -flat: Present the arrays in a flat fashion rather than a nested way -header: Add an additionnal element containing the description of the handle itself (eg. {type REGION}) -limited n:Same as -flat but limit the 'flatening' of an array to the last n dimensions. n==0 means flatenning all the dimensions. -nostring: Return the address of strings (char*, char[]) rather than their contents -recurse: Recursively returns the contents of internal struct -unfold: Add the content of the arrays rather than the starting address -help: Print summary of command-line options and abort RETURNS: TCL_OK Successful completion. Returns the value of the expression. TCL_ERROR Error occurred.

    exprPrint

    Print the value(s) of an expression involving an handle. The result is a formatted version of the result returned by exprGet. See the overview on exprPrint for more details.

    TCL SYNTAX: exprPrint -enum -flat -header -noname -noquote -nostring -recurse -unfold <expr> -help <expr> An expression involving a handle, e.g. h4.mask->nrow. -enum: Do not remove the '(enum)' in front of enums values -flat: Present the arrays in a flat fashion rather than a nested way -header: Add an additionnal element containing the description of the handle itself (eg. {type REGION}) -limited n:Same as -flat but limit the 'flatening' of an array to the last n dimensions. n==0 means flatenning all the dimensions. -noname: Don't try to interpret address as handle -noquote: Don't put double quotes around strings! -nostring: Return the address of strings (char*, char[]) rather than their contents -recurse: Recursively returns the contents of internal struct -unfold: Add the content of the arrays rather than the starting address -help: Print summary of command-line options and abort RETURNS: TCL_OK Successful completion. TCL_ERROR Error occurred.

    schemaGetFullFromType

    Return the complete definition of a Schema in the form used by schemaDefine. TCL SYNTAX: schemaGetFullFromType <type> <type> The type under scrutiny. You have to use a symbolic name such as REGION. RETURNS: TCL_OK Successful completion. TCL_ERROR Error occurred.

    schemaGetFull

    Return the complete definition of a schema in the form used by schemaDefine. TCL SYNTAX: schemaGetFullFromType <expr> <expr> An handle expression pointing to a object of the type under scrutiny. RETURNS: TCL_OK Successful completion. TCL_ERROR Error occurred.

    schemaKindGetFromType

    return UNKNOWN, PRIM, ENUM or STRUCT for the schema given by the type. TCL SYNTAX: schemaKindGetFromType <type> <type> The type of the schema RETURNS: TCL_OK Successful completion. TCL_ERROR Error occurred.

    schemaKindGet

    return UNKNOWN, PRIM, ENUM or STRUCT for the schema of the object pointed to by the handle expression. TCL SYNTAX: schemaKindGetFromType <expr> <expr> An handle expression pointing to the object to examine RETURNS: TCL_OK Successful completion. TCL_ERROR Error occurred.

    schemaPrint

    Print the schema associated with a <handle> TCL SYNTAX: schemaPrint <handle> <handle> The handle which schema we wish to inspect RETURNS: TCL_OK Successful completion. TCL_ERROR Error occurred.

    schemaPrintFromType

    Print the schema associated with a given type TCL SYNTAX: schemaPrintFromType <type> <type> The type of the schema to print RETURNS: TCL_OK Successful completion. TCL_ERROR Error occurred.

    Appendixes

    Translation From Dervish v5_1 And Earlier To v5_2 And Later

    Please note that the new xxxPrint functions only ECHO their results to the screen! In order to use the value of an handle expression you MUST use an xxxGet function. The xxxGet functions returns a single value or a tcl list to the tcl interpreter.

    exprGet used to return strings between double quotes. Now exprGet puts curly brackets - { ... } - around the string when necessary.

    If you used to get a string directly by

     exprGet h5.Label 
    and then removed manually the double quotes, you might find the following instruction useful:
     lindex [exprGet h0.Label] 0 
    This will return the string without the curly brackets.

    Old Syntax Replacing Syntax Example
    exprPrintAsArray <array> <dimension> exprPrint -unfold (array definition)<array> exprPrint -unfold (INT<10><10>)h1.rows
    exprPrintMember <handle> <elem> exprPrint <handle.elem> exprPrint h1.ncol
    structsPrint <handle expr> exprPrint -header -enum -recurse <handle expr> exprPrint -header -enum -recurse h1
    structPrint <handle expr> exprPrint -noquote <handle expr> exprPrint -noquote h1
    structGet <handle expr> exprGet -noquote <handle expr> exprGet -noquote h1
    exprPrint <handle expr> exprPrint -noquote -noname <handle expr> exprPrint -noquote -noname h1
    membersGet <handle expr> exprGet -header <handle expr> exprGet -header h1
    memberGet <handle> <member> exprGet <handle.member> exprGet h1.nrow
    exprSet <handle expression> handleSet <handle expression> handleSet h1.vec<2> 4
    arraySet <handle expression> <array member> <values> handleSet <handle expression> <values> handleSet h1.name<2> {this is a label}
    arrayShow <handle-expression> <array-member> exprGet -unfold -flat -enum <handle-expression.array-member> exprGet -unfold -flat -enum h1.name
    ptype <handle> handleType <handle> handleType h1
    typeGet <type> None. Use -enum if necessary

    List Of Functions Removed In Dervish v5_1

    handleShow

    handleShow is a tcl Script around exprGet that only return simple values. If the handle expression passed to handleShow is not a simple value handleShow will return the handle expression itself.

    Known 'Bugs'

    Know bugs: exprPrint print
    "(h1).j         <0> 0"
    rather than
    "(h1).j<0>      0"
    for a one element array ! (who cares?!)
    Comments and suggestions to Philippe Canal (pcanal@sdss.fnal.gov)