Dumping Data to Disk

TCL API

C Routine Interface

Object Schema

  • An introduction to Object Schema
  • Manipulating Values from TCL
  • An introduction to Object Schema

    An object's schema is a term stolen from the world of databases, and means a description of the internals of a complex object (the sort of information that is available from the symbol table information generated by compilers). Because one incarnation of DERVISH is as a high-level debugger, DERVISH needs access to this information. It is automatically generated by a program called make_io, which reads the definitions in C header files (.h files) and generates the requisite C.

    Manipulating Values from TCL

    The source code for this example may be found in $DERVISH_DIR/etc/dump_example.tcl. An executable that knows about the type FOO that this example uses may be built as $DERVISH_DIR/examples/dervish_foo, but analogous examples could be built around any of the SDSS data types (e.g. Regions).

    Let us imagine that you are running dervish_foo, and are curious about what a FOO is. That's easily discovered, type:

    schemaPrintFromType FOO and dervish will say: type TYPE next FOO* prev FOO* name char* i int l long f float If you now look for the relevant include file, $DERVISH_DIR/examples/foo.h, you'll find that the C is: typedef struct foo { TYPE type; struct foo *next, *prev; char *name; int i; long l; float f; } FOO; which is reassuring. Let's now make a FOO and print it: set foo [fooNew] exprPrint -header $foo to which the reply is: h7 FOO (h7).type (enum)1009 (h7).next 0x0 (h7).prev 0x0 (h7).name (null) (h7).i 0 (h7).l 0 (h7).f 0 The first line "h7 FOO" tells you that $foo is a handle-to-FOO, the rest are the values of the elements (and are not very interesting). Let's set one of them: handleSet $foo.name "Hello World" exprPrint -header -noquote $foo to which the reply is: h7 FOO (h7).type (enum)1009 (h7).next 0x0 (h7).prev 0x0 (h7).name Hello World (h7).i 0 (h7).l 0 (h7).f 0

    Thus emboldened, we can write a procedure to initialise FOOs:

    proc fooInit { foo name i l f } { foreach el "name i l f" { handleSet $foo.$el [set $el] } return $foo } and say things like set foo2 [fooInit [fooNew] "God Bless the Queen" 12 65536 1.234] exprPrint -header -noquote $foo2 h9 FOO (h9).type (enum)1009 (h9).next 0x0 (h9).prev 0x0 (h9).name God Bless the Queen (h9).i 12 (h9).l 65536 (h9).f 1.234 If you want to know how these procedures work, you should look at the description of the TCL interface for schema or for accessing handle and their contents; the basic routines are schemaGet and exprGet which return TCL lists. For example: exprGet -header $foo2 {type FOO} {type (enum)1009} {next 0x0} {prev 0x0} {name {God Bless the Queen}} {i 12} {l 65536} {f 1.234}

    Dumping and Restoring Complex Objects to Disk

  • An introduction to disk dumps
  • An example of generating and reading a dump from TCL
  • An introduction to disk dumps

    Details of the C and TCL interfaces may be found elsewhere.

    An example of generating and reading a dump from TCL

    The source code for this example may be found in $DERVISH_DIR/etc/dump_example.tcl. An executable that knows about the type FOO that this example uses may be built as $DERVISH_DIR/examples/dervish_foo, but the code will work even with a vanilla version of dervish.

    This code generates a dump, and then reads it back. There are two procs:

    fooInit
    Initialises a FOO
    testDumpWrite
    Writes a test dump file
    There is then a section of code that writes a dump file, and reads it back.

    There are also a number of other procs in dervishStartup.tcl, which should have been read for you automatically. These deal with disk dumps. The way that dumpRead works is to generate a list of handles; I put this list into a variable d1. So to look at the results of the dump say

    dumpPrint $d1 which will print something like: tst_dump.dat: Created Fri Jun 11 09:01:18 1993 h3 REGION h4 REGION h5 REGION h6 FLOAT h7 STR h8 INT h9 FOO h10 LIST Then you can say exprPrint h4 to look at things. I pretty soon get fed up with typing exprPrint, so: alias p exprPrint alias pl listPrint and p h10 pl h10 You get the point.

    First a utility proc to initialise FOOs:

    # # TCL procedures to manipulate FOOs # # Initialise a FOO # proc fooInit { foo name i l f } { foreach el "name i l f" { handleSet $foo.$el [set $el] } return $foo } And then a proc to generate things to dump, and then dump them: # # Write a test disk dump to <file> # proc testDumpWrite { file } { # # create a set of regions # set r0 [regNew -type=S16 -mask 20 10] regSetWithDbl $r0 10 regPixSetWithDbl $r0 5 8 100 set r1 [subRegNew $r0 10 5 2 4] set r2 [subRegNew $r0 8 5 1 4] # # dump various things to a file; first these [sub]regions, # then some primitive types, then a FOO and a list of FOOs # if FOOs are available # dumpOpen $file w dumpHandleWrite $r0 dumpHandleWrite $r1 dumpHandleWrite $r2 dumpValueWrite 3.14159 FLOAT dumpValueWrite "For the Snark was a Boojum, you see" STR dumpValueWrite 32767 INT catch { # we may not be FOO capable set foo [fooInit [fooNew] "Hello World" 10 1000 3.14159] dumpHandleWrite $foo; handleDel $foo set list [listNew FOO] foreach n {"Yr Wyfdda" "Carnedd Llewellyn" "Pen Yr Oleu Wen"} { set foo [fooInit [fooNew] $n 0 1 2.71828] listAdd $list $foo handleDel $foo } dumpHandleWrite $list; handleDel $list } dumpClose } We can now actually write a dump, read it back, and see what we got: # # write a dump # set test_file_name "tst_dump.dat" testDumpWrite $test_file_name # # and read it back. The list of handles is in $d1 # set d1 [dumpRead $test_file_name] dumpPrint $d1